Repository: Klocman/Bulk-Crap-Uninstaller Branch: master Commit: 4ecea11bfb08 Files: 1537 Total size: 14.5 MB Directory structure: gitextract_hlbvlrwh/ ├── .github/ │ └── workflows/ │ ├── ci.yaml │ └── winget.yml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Licence.txt ├── NOTICE ├── PrivacyPolicy.txt ├── README.md ├── doc/ │ ├── BCU_manual.html │ └── BCU_manual.odt ├── installer/ │ ├── .gitignore │ ├── BcuSetup.iss │ ├── CodeDependencies.iss │ ├── PortablePage.iss │ ├── assets/ │ │ └── bigImage.pdn │ └── lang/ │ ├── ChineseSimplified.isl │ ├── Hindi.isl │ └── Vietnamese.isl ├── publish.bat └── source/ ├── BCU-console/ │ ├── BCU-console.csproj │ └── Program.cs ├── BCU-launcher/ │ ├── BCU-launcher.rc │ ├── BCU-launcher.vcxproj │ ├── main.cpp │ └── resource.h ├── BulkCrapUninstaller/ │ ├── BulkCrapUninstaller.csproj │ ├── CleanLogs.bat │ ├── Controls/ │ │ ├── AdvancedClipboardCopy.Designer.cs │ │ ├── AdvancedClipboardCopy.ar.resx │ │ ├── AdvancedClipboardCopy.cs │ │ ├── AdvancedClipboardCopy.cs.resx │ │ ├── AdvancedClipboardCopy.de.resx │ │ ├── AdvancedClipboardCopy.es.resx │ │ ├── AdvancedClipboardCopy.fr.resx │ │ ├── AdvancedClipboardCopy.hu.resx │ │ ├── AdvancedClipboardCopy.it.resx │ │ ├── AdvancedClipboardCopy.ja.resx │ │ ├── AdvancedClipboardCopy.nl.resx │ │ ├── AdvancedClipboardCopy.pl.resx │ │ ├── AdvancedClipboardCopy.pt-BR.resx │ │ ├── AdvancedClipboardCopy.pt.resx │ │ ├── AdvancedClipboardCopy.resx │ │ ├── AdvancedClipboardCopy.ru.resx │ │ ├── AdvancedClipboardCopy.sl.resx │ │ ├── AdvancedClipboardCopy.sv.resx │ │ ├── AdvancedClipboardCopy.tr.resx │ │ ├── AdvancedClipboardCopy.vi.resx │ │ ├── AdvancedClipboardCopy.zh-Hans.resx │ │ ├── AdvancedClipboardCopy.zh-Hant.resx │ │ ├── ClipboardCopyItem.cs │ │ ├── FileTargeter.Designer.cs │ │ ├── FileTargeter.ar.resx │ │ ├── FileTargeter.cs │ │ ├── FileTargeter.cs.resx │ │ ├── FileTargeter.de.resx │ │ ├── FileTargeter.es.resx │ │ ├── FileTargeter.fr.resx │ │ ├── FileTargeter.hu.resx │ │ ├── FileTargeter.it.resx │ │ ├── FileTargeter.ja.resx │ │ ├── FileTargeter.nl.resx │ │ ├── FileTargeter.pl.resx │ │ ├── FileTargeter.pt-BR.resx │ │ ├── FileTargeter.pt.resx │ │ ├── FileTargeter.resx │ │ ├── FileTargeter.ru.resx │ │ ├── FileTargeter.sl.resx │ │ ├── FileTargeter.sv.resx │ │ ├── FileTargeter.tr.resx │ │ ├── FileTargeter.vi.resx │ │ ├── FileTargeter.zh-Hans.resx │ │ ├── FileTargeter.zh-Hant.resx │ │ ├── ListLegend.Designer.cs │ │ ├── ListLegend.ar.resx │ │ ├── ListLegend.cs │ │ ├── ListLegend.cs.resx │ │ ├── ListLegend.de.resx │ │ ├── ListLegend.es.resx │ │ ├── ListLegend.fr.resx │ │ ├── ListLegend.hu.resx │ │ ├── ListLegend.it.resx │ │ ├── ListLegend.ja.resx │ │ ├── ListLegend.nl.resx │ │ ├── ListLegend.pl.resx │ │ ├── ListLegend.pt-BR.resx │ │ ├── ListLegend.pt.resx │ │ ├── ListLegend.resx │ │ ├── ListLegend.ru.resx │ │ ├── ListLegend.sl.resx │ │ ├── ListLegend.sv.resx │ │ ├── ListLegend.tr.resx │ │ ├── ListLegend.vi.resx │ │ ├── ListLegend.zh-Hans.resx │ │ ├── ListLegend.zh-Hant.resx │ │ ├── RelatedUninstallerAdder.Designer.cs │ │ ├── RelatedUninstallerAdder.ar.resx │ │ ├── RelatedUninstallerAdder.cs │ │ ├── RelatedUninstallerAdder.cs.resx │ │ ├── RelatedUninstallerAdder.de.resx │ │ ├── RelatedUninstallerAdder.es.resx │ │ ├── RelatedUninstallerAdder.fr.resx │ │ ├── RelatedUninstallerAdder.hu.resx │ │ ├── RelatedUninstallerAdder.it.resx │ │ ├── RelatedUninstallerAdder.ja.resx │ │ ├── RelatedUninstallerAdder.nl.resx │ │ ├── RelatedUninstallerAdder.pl.resx │ │ ├── RelatedUninstallerAdder.pt-BR.resx │ │ ├── RelatedUninstallerAdder.pt.resx │ │ ├── RelatedUninstallerAdder.resx │ │ ├── RelatedUninstallerAdder.ru.resx │ │ ├── RelatedUninstallerAdder.sl.resx │ │ ├── RelatedUninstallerAdder.tr.resx │ │ ├── RelatedUninstallerAdder.vi.resx │ │ ├── RelatedUninstallerAdder.zh-Hans.resx │ │ ├── RelatedUninstallerAdder.zh-Hant.resx │ │ ├── Settings/ │ │ │ ├── AdvancedFilters.Designer.cs │ │ │ ├── AdvancedFilters.ar.resx │ │ │ ├── AdvancedFilters.cs │ │ │ ├── AdvancedFilters.cs.resx │ │ │ ├── AdvancedFilters.de.resx │ │ │ ├── AdvancedFilters.es.resx │ │ │ ├── AdvancedFilters.fr.resx │ │ │ ├── AdvancedFilters.hu.resx │ │ │ ├── AdvancedFilters.it.resx │ │ │ ├── AdvancedFilters.ja.resx │ │ │ ├── AdvancedFilters.nl.resx │ │ │ ├── AdvancedFilters.pl.resx │ │ │ ├── AdvancedFilters.pt-BR.resx │ │ │ ├── AdvancedFilters.pt.resx │ │ │ ├── AdvancedFilters.resx │ │ │ ├── AdvancedFilters.ru.resx │ │ │ ├── AdvancedFilters.sl.resx │ │ │ ├── AdvancedFilters.sv.resx │ │ │ ├── AdvancedFilters.tr.resx │ │ │ ├── AdvancedFilters.vi.resx │ │ │ ├── AdvancedFilters.zh-Hans.resx │ │ │ ├── AdvancedFilters.zh-Hant.resx │ │ │ ├── CacheSettings.Designer.cs │ │ │ ├── CacheSettings.ar.resx │ │ │ ├── CacheSettings.cs │ │ │ ├── CacheSettings.cs.resx │ │ │ ├── CacheSettings.de.resx │ │ │ ├── CacheSettings.es.resx │ │ │ ├── CacheSettings.fr.resx │ │ │ ├── CacheSettings.hu.resx │ │ │ ├── CacheSettings.it.resx │ │ │ ├── CacheSettings.ja.resx │ │ │ ├── CacheSettings.nl.resx │ │ │ ├── CacheSettings.pl.resx │ │ │ ├── CacheSettings.pt-BR.resx │ │ │ ├── CacheSettings.pt.resx │ │ │ ├── CacheSettings.resx │ │ │ ├── CacheSettings.ru.resx │ │ │ ├── CacheSettings.sl.resx │ │ │ ├── CacheSettings.sv.resx │ │ │ ├── CacheSettings.tr.resx │ │ │ ├── CacheSettings.vi.resx │ │ │ ├── CacheSettings.zh-Hans.resx │ │ │ ├── CacheSettings.zh-Hant.resx │ │ │ ├── PropertiesSidebar.Designer.cs │ │ │ ├── PropertiesSidebar.ar.resx │ │ │ ├── PropertiesSidebar.cs │ │ │ ├── PropertiesSidebar.cs.resx │ │ │ ├── PropertiesSidebar.de.resx │ │ │ ├── PropertiesSidebar.es.resx │ │ │ ├── PropertiesSidebar.fr.resx │ │ │ ├── PropertiesSidebar.hu.resx │ │ │ ├── PropertiesSidebar.it.resx │ │ │ ├── PropertiesSidebar.ja.resx │ │ │ ├── PropertiesSidebar.nl.resx │ │ │ ├── PropertiesSidebar.pl.resx │ │ │ ├── PropertiesSidebar.pt-BR.resx │ │ │ ├── PropertiesSidebar.pt.resx │ │ │ ├── PropertiesSidebar.resx │ │ │ ├── PropertiesSidebar.ru.resx │ │ │ ├── PropertiesSidebar.sl.resx │ │ │ ├── PropertiesSidebar.sv.resx │ │ │ ├── PropertiesSidebar.tr.resx │ │ │ ├── PropertiesSidebar.vi.resx │ │ │ ├── PropertiesSidebar.zh-Hans.resx │ │ │ ├── PropertiesSidebar.zh-Hant.resx │ │ │ ├── UninstallationSettings.Designer.cs │ │ │ ├── UninstallationSettings.ar.resx │ │ │ ├── UninstallationSettings.cs │ │ │ ├── UninstallationSettings.cs.resx │ │ │ ├── UninstallationSettings.de.resx │ │ │ ├── UninstallationSettings.es.resx │ │ │ ├── UninstallationSettings.fr.resx │ │ │ ├── UninstallationSettings.hu.resx │ │ │ ├── UninstallationSettings.it.resx │ │ │ ├── UninstallationSettings.ja.resx │ │ │ ├── UninstallationSettings.nl.resx │ │ │ ├── UninstallationSettings.pl.resx │ │ │ ├── UninstallationSettings.pt-BR.resx │ │ │ ├── UninstallationSettings.pt.resx │ │ │ ├── UninstallationSettings.resx │ │ │ ├── UninstallationSettings.ru.resx │ │ │ ├── UninstallationSettings.sl.resx │ │ │ ├── UninstallationSettings.sv.resx │ │ │ ├── UninstallationSettings.tr.resx │ │ │ ├── UninstallationSettings.vi.resx │ │ │ ├── UninstallationSettings.zh-Hans.resx │ │ │ └── UninstallationSettings.zh-Hant.resx │ │ ├── TabControlWithoutHeader.cs │ │ ├── UninstallConfirmation.Designer.cs │ │ ├── UninstallConfirmation.ar.resx │ │ ├── UninstallConfirmation.cs │ │ ├── UninstallConfirmation.cs.resx │ │ ├── UninstallConfirmation.de.resx │ │ ├── UninstallConfirmation.es.resx │ │ ├── UninstallConfirmation.fr.resx │ │ ├── UninstallConfirmation.hu.resx │ │ ├── UninstallConfirmation.it.resx │ │ ├── UninstallConfirmation.ja.resx │ │ ├── UninstallConfirmation.nl.resx │ │ ├── UninstallConfirmation.pl.resx │ │ ├── UninstallConfirmation.pt-BR.resx │ │ ├── UninstallConfirmation.pt.resx │ │ ├── UninstallConfirmation.resx │ │ ├── UninstallConfirmation.ru.resx │ │ ├── UninstallConfirmation.sl.resx │ │ ├── UninstallConfirmation.sv.resx │ │ ├── UninstallConfirmation.tr.resx │ │ ├── UninstallConfirmation.vi.resx │ │ ├── UninstallConfirmation.zh-Hans.resx │ │ └── UninstallConfirmation.zh-Hant.resx │ ├── CultureConfigurator.cs │ ├── EntryPoint.cs │ ├── Forms/ │ │ ├── Helpers/ │ │ │ ├── AdvancedClipboardCopyWindow.Designer.cs │ │ │ ├── AdvancedClipboardCopyWindow.ar.resx │ │ │ ├── AdvancedClipboardCopyWindow.cs │ │ │ ├── AdvancedClipboardCopyWindow.cs.resx │ │ │ ├── AdvancedClipboardCopyWindow.de.resx │ │ │ ├── AdvancedClipboardCopyWindow.es.resx │ │ │ ├── AdvancedClipboardCopyWindow.fr.resx │ │ │ ├── AdvancedClipboardCopyWindow.hu.resx │ │ │ ├── AdvancedClipboardCopyWindow.it.resx │ │ │ ├── AdvancedClipboardCopyWindow.ja.resx │ │ │ ├── AdvancedClipboardCopyWindow.nl.resx │ │ │ ├── AdvancedClipboardCopyWindow.pl.resx │ │ │ ├── AdvancedClipboardCopyWindow.pt-BR.resx │ │ │ ├── AdvancedClipboardCopyWindow.pt.resx │ │ │ ├── AdvancedClipboardCopyWindow.resx │ │ │ ├── AdvancedClipboardCopyWindow.ru.resx │ │ │ ├── AdvancedClipboardCopyWindow.sl.resx │ │ │ ├── AdvancedClipboardCopyWindow.sv.resx │ │ │ ├── AdvancedClipboardCopyWindow.tr.resx │ │ │ ├── AdvancedClipboardCopyWindow.vi.resx │ │ │ ├── AdvancedClipboardCopyWindow.zh-Hans.resx │ │ │ ├── AdvancedClipboardCopyWindow.zh-Hant.resx │ │ │ ├── DebugWindow.Designer.cs │ │ │ ├── DebugWindow.cs │ │ │ ├── DebugWindow.resx │ │ │ ├── FeedbackBox.Designer.cs │ │ │ ├── FeedbackBox.ar.resx │ │ │ ├── FeedbackBox.cs │ │ │ ├── FeedbackBox.cs.resx │ │ │ ├── FeedbackBox.de.resx │ │ │ ├── FeedbackBox.es.resx │ │ │ ├── FeedbackBox.fr.resx │ │ │ ├── FeedbackBox.hu.resx │ │ │ ├── FeedbackBox.it.resx │ │ │ ├── FeedbackBox.ja.resx │ │ │ ├── FeedbackBox.nl.resx │ │ │ ├── FeedbackBox.pl.resx │ │ │ ├── FeedbackBox.pt-BR.resx │ │ │ ├── FeedbackBox.pt.resx │ │ │ ├── FeedbackBox.resx │ │ │ ├── FeedbackBox.ru.resx │ │ │ ├── FeedbackBox.sl.resx │ │ │ ├── FeedbackBox.sv.resx │ │ │ ├── FeedbackBox.tr.resx │ │ │ ├── FeedbackBox.vi.resx │ │ │ ├── FeedbackBox.zh-Hans.resx │ │ │ ├── FeedbackBox.zh-Hant.resx │ │ │ ├── FeedbackWindow.Designer.cs │ │ │ ├── FeedbackWindow.ar.resx │ │ │ ├── FeedbackWindow.cs │ │ │ ├── FeedbackWindow.cs.resx │ │ │ ├── FeedbackWindow.de.resx │ │ │ ├── FeedbackWindow.es.resx │ │ │ ├── FeedbackWindow.fr.resx │ │ │ ├── FeedbackWindow.hu.resx │ │ │ ├── FeedbackWindow.it.resx │ │ │ ├── FeedbackWindow.ja.resx │ │ │ ├── FeedbackWindow.nl.resx │ │ │ ├── FeedbackWindow.pl.resx │ │ │ ├── FeedbackWindow.pt-BR.resx │ │ │ ├── FeedbackWindow.pt.resx │ │ │ ├── FeedbackWindow.resx │ │ │ ├── FeedbackWindow.ru.resx │ │ │ ├── FeedbackWindow.sl.resx │ │ │ ├── FeedbackWindow.sv.resx │ │ │ ├── FeedbackWindow.tr.resx │ │ │ ├── FeedbackWindow.vi.resx │ │ │ ├── FeedbackWindow.zh-Hans.resx │ │ │ ├── FeedbackWindow.zh-Hant.resx │ │ │ ├── ListLegendWindow.Designer.cs │ │ │ ├── ListLegendWindow.cs │ │ │ ├── ListLegendWindow.resx │ │ │ ├── NewsPopup.Designer.cs │ │ │ ├── NewsPopup.ar.resx │ │ │ ├── NewsPopup.cs │ │ │ ├── NewsPopup.cs.resx │ │ │ ├── NewsPopup.de.resx │ │ │ ├── NewsPopup.es.resx │ │ │ ├── NewsPopup.fr.resx │ │ │ ├── NewsPopup.hu.resx │ │ │ ├── NewsPopup.it.resx │ │ │ ├── NewsPopup.ja.resx │ │ │ ├── NewsPopup.nl.resx │ │ │ ├── NewsPopup.pl.resx │ │ │ ├── NewsPopup.pt-br.resx │ │ │ ├── NewsPopup.pt.resx │ │ │ ├── NewsPopup.resx │ │ │ ├── NewsPopup.ru.resx │ │ │ ├── NewsPopup.sl.resx │ │ │ ├── NewsPopup.sv.resx │ │ │ ├── NewsPopup.tr.resx │ │ │ ├── NewsPopup.vi.resx │ │ │ ├── NewsPopup.zh-Hans.resx │ │ │ ├── NewsPopup.zh-Hant.resx │ │ │ ├── PropertiesWindow.Designer.cs │ │ │ ├── PropertiesWindow.ar.resx │ │ │ ├── PropertiesWindow.cs │ │ │ ├── PropertiesWindow.cs.resx │ │ │ ├── PropertiesWindow.de.resx │ │ │ ├── PropertiesWindow.es.resx │ │ │ ├── PropertiesWindow.fr.resx │ │ │ ├── PropertiesWindow.hu.resx │ │ │ ├── PropertiesWindow.it.resx │ │ │ ├── PropertiesWindow.ja.resx │ │ │ ├── PropertiesWindow.nl.resx │ │ │ ├── PropertiesWindow.pl.resx │ │ │ ├── PropertiesWindow.pt-BR.resx │ │ │ ├── PropertiesWindow.pt.resx │ │ │ ├── PropertiesWindow.resx │ │ │ ├── PropertiesWindow.ru.resx │ │ │ ├── PropertiesWindow.sl.resx │ │ │ ├── PropertiesWindow.sv.resx │ │ │ ├── PropertiesWindow.tr.resx │ │ │ ├── PropertiesWindow.vi.resx │ │ │ ├── PropertiesWindow.zh-Hans.resx │ │ │ ├── PropertiesWindow.zh-Hant.resx │ │ │ ├── RatingPopup.Designer.cs │ │ │ ├── RatingPopup.ar.resx │ │ │ ├── RatingPopup.cs │ │ │ ├── RatingPopup.cs.resx │ │ │ ├── RatingPopup.de.resx │ │ │ ├── RatingPopup.es.resx │ │ │ ├── RatingPopup.fr.resx │ │ │ ├── RatingPopup.hu.resx │ │ │ ├── RatingPopup.it.resx │ │ │ ├── RatingPopup.ja.resx │ │ │ ├── RatingPopup.nl.resx │ │ │ ├── RatingPopup.pl.resx │ │ │ ├── RatingPopup.pt-BR.resx │ │ │ ├── RatingPopup.pt.resx │ │ │ ├── RatingPopup.resx │ │ │ ├── RatingPopup.ru.resx │ │ │ ├── RatingPopup.sl.resx │ │ │ ├── RatingPopup.sv.resx │ │ │ ├── RatingPopup.tr.resx │ │ │ ├── RatingPopup.vi.resx │ │ │ ├── RatingPopup.zh-Hans.resx │ │ │ ├── RatingPopup.zh-Hant.resx │ │ │ ├── TargetWindow.Designer.cs │ │ │ ├── TargetWindow.ar.resx │ │ │ ├── TargetWindow.cs │ │ │ ├── TargetWindow.cs.resx │ │ │ ├── TargetWindow.de.resx │ │ │ ├── TargetWindow.es.resx │ │ │ ├── TargetWindow.fr.resx │ │ │ ├── TargetWindow.hu.resx │ │ │ ├── TargetWindow.it.resx │ │ │ ├── TargetWindow.ja.resx │ │ │ ├── TargetWindow.nl.resx │ │ │ ├── TargetWindow.pl.resx │ │ │ ├── TargetWindow.pt-BR.resx │ │ │ ├── TargetWindow.pt.resx │ │ │ ├── TargetWindow.resx │ │ │ ├── TargetWindow.ru.resx │ │ │ ├── TargetWindow.sl.resx │ │ │ ├── TargetWindow.sv.resx │ │ │ ├── TargetWindow.tr.resx │ │ │ ├── TargetWindow.vi.resx │ │ │ ├── TargetWindow.zh-Hans.resx │ │ │ └── TargetWindow.zh-Hant.resx │ │ ├── UninstallerListDoubleClickAction.cs │ │ ├── Windows/ │ │ │ ├── AboutBox.Designer.cs │ │ │ ├── AboutBox.ar.resx │ │ │ ├── AboutBox.cs │ │ │ ├── AboutBox.cs.resx │ │ │ ├── AboutBox.de.resx │ │ │ ├── AboutBox.es.resx │ │ │ ├── AboutBox.fr.resx │ │ │ ├── AboutBox.hu.resx │ │ │ ├── AboutBox.it.resx │ │ │ ├── AboutBox.ja.resx │ │ │ ├── AboutBox.nl.resx │ │ │ ├── AboutBox.pl.resx │ │ │ ├── AboutBox.pt-BR.resx │ │ │ ├── AboutBox.pt.resx │ │ │ ├── AboutBox.resx │ │ │ ├── AboutBox.ru.resx │ │ │ ├── AboutBox.sl.resx │ │ │ ├── AboutBox.sv.resx │ │ │ ├── AboutBox.tr.resx │ │ │ ├── AboutBox.vi.resx │ │ │ ├── AboutBox.zh-Hans.resx │ │ │ ├── AboutBox.zh-Hant.resx │ │ │ ├── JunkRemoveWindow.Designer.cs │ │ │ ├── JunkRemoveWindow.ar.resx │ │ │ ├── JunkRemoveWindow.cs │ │ │ ├── JunkRemoveWindow.cs.resx │ │ │ ├── JunkRemoveWindow.de.resx │ │ │ ├── JunkRemoveWindow.es.resx │ │ │ ├── JunkRemoveWindow.fr.resx │ │ │ ├── JunkRemoveWindow.hu.resx │ │ │ ├── JunkRemoveWindow.it.resx │ │ │ ├── JunkRemoveWindow.ja.resx │ │ │ ├── JunkRemoveWindow.nl.resx │ │ │ ├── JunkRemoveWindow.pl.resx │ │ │ ├── JunkRemoveWindow.pt-BR.resx │ │ │ ├── JunkRemoveWindow.pt.resx │ │ │ ├── JunkRemoveWindow.resx │ │ │ ├── JunkRemoveWindow.ru.resx │ │ │ ├── JunkRemoveWindow.sl.resx │ │ │ ├── JunkRemoveWindow.sv.resx │ │ │ ├── JunkRemoveWindow.tr.resx │ │ │ ├── JunkRemoveWindow.vi.resx │ │ │ ├── JunkRemoveWindow.zh-Hans.resx │ │ │ ├── JunkRemoveWindow.zh-Hant.resx │ │ │ ├── MainWindow.Designer.cs │ │ │ ├── MainWindow.ar.resx │ │ │ ├── MainWindow.cs │ │ │ ├── MainWindow.cs.resx │ │ │ ├── MainWindow.de.resx │ │ │ ├── MainWindow.es.resx │ │ │ ├── MainWindow.fr.resx │ │ │ ├── MainWindow.hu.resx │ │ │ ├── MainWindow.it.resx │ │ │ ├── MainWindow.ja.resx │ │ │ ├── MainWindow.nl.resx │ │ │ ├── MainWindow.pl.resx │ │ │ ├── MainWindow.pt-BR.resx │ │ │ ├── MainWindow.pt.resx │ │ │ ├── MainWindow.resx │ │ │ ├── MainWindow.ru.resx │ │ │ ├── MainWindow.sl.resx │ │ │ ├── MainWindow.sv.resx │ │ │ ├── MainWindow.tr.resx │ │ │ ├── MainWindow.vi.resx │ │ │ ├── MainWindow.zh-Hans.resx │ │ │ ├── MainWindow.zh-Hant.resx │ │ │ ├── SettingsWindow.Designer.cs │ │ │ ├── SettingsWindow.ar.resx │ │ │ ├── SettingsWindow.cs │ │ │ ├── SettingsWindow.cs.resx │ │ │ ├── SettingsWindow.de.resx │ │ │ ├── SettingsWindow.es.resx │ │ │ ├── SettingsWindow.fr.resx │ │ │ ├── SettingsWindow.hu.resx │ │ │ ├── SettingsWindow.it.resx │ │ │ ├── SettingsWindow.ja.resx │ │ │ ├── SettingsWindow.nl.resx │ │ │ ├── SettingsWindow.pl.resx │ │ │ ├── SettingsWindow.pt-BR.resx │ │ │ ├── SettingsWindow.pt.resx │ │ │ ├── SettingsWindow.resx │ │ │ ├── SettingsWindow.ru.resx │ │ │ ├── SettingsWindow.sl.resx │ │ │ ├── SettingsWindow.sv.resx │ │ │ ├── SettingsWindow.tr.resx │ │ │ ├── SettingsWindow.vi.resx │ │ │ ├── SettingsWindow.zh-Hans.resx │ │ │ ├── SettingsWindow.zh-Hant.resx │ │ │ ├── UninstallProgressWindow.Designer.cs │ │ │ ├── UninstallProgressWindow.ar.resx │ │ │ ├── UninstallProgressWindow.cs │ │ │ ├── UninstallProgressWindow.cs.resx │ │ │ ├── UninstallProgressWindow.de.resx │ │ │ ├── UninstallProgressWindow.es.resx │ │ │ ├── UninstallProgressWindow.fr.resx │ │ │ ├── UninstallProgressWindow.hu.resx │ │ │ ├── UninstallProgressWindow.it.resx │ │ │ ├── UninstallProgressWindow.ja.resx │ │ │ ├── UninstallProgressWindow.nl.resx │ │ │ ├── UninstallProgressWindow.pl.resx │ │ │ ├── UninstallProgressWindow.pt-BR.resx │ │ │ ├── UninstallProgressWindow.pt.resx │ │ │ ├── UninstallProgressWindow.resx │ │ │ ├── UninstallProgressWindow.ru.resx │ │ │ ├── UninstallProgressWindow.sl.resx │ │ │ ├── UninstallProgressWindow.sv.resx │ │ │ ├── UninstallProgressWindow.tr.resx │ │ │ ├── UninstallProgressWindow.vi.resx │ │ │ ├── UninstallProgressWindow.zh-Hans.resx │ │ │ └── UninstallProgressWindow.zh-Hant.resx │ │ └── Wizards/ │ │ ├── BeginUninstallTaskWizard.Designer.cs │ │ ├── BeginUninstallTaskWizard.ar.resx │ │ ├── BeginUninstallTaskWizard.cs │ │ ├── BeginUninstallTaskWizard.cs.resx │ │ ├── BeginUninstallTaskWizard.de.resx │ │ ├── BeginUninstallTaskWizard.es.resx │ │ ├── BeginUninstallTaskWizard.fr.resx │ │ ├── BeginUninstallTaskWizard.hu.resx │ │ ├── BeginUninstallTaskWizard.it.resx │ │ ├── BeginUninstallTaskWizard.ja.resx │ │ ├── BeginUninstallTaskWizard.nl.resx │ │ ├── BeginUninstallTaskWizard.pl.resx │ │ ├── BeginUninstallTaskWizard.pt-BR.resx │ │ ├── BeginUninstallTaskWizard.pt.resx │ │ ├── BeginUninstallTaskWizard.resx │ │ ├── BeginUninstallTaskWizard.ru.resx │ │ ├── BeginUninstallTaskWizard.sl.resx │ │ ├── BeginUninstallTaskWizard.sv.resx │ │ ├── BeginUninstallTaskWizard.tr.resx │ │ ├── BeginUninstallTaskWizard.vi.resx │ │ ├── BeginUninstallTaskWizard.zh-Hans.resx │ │ ├── BeginUninstallTaskWizard.zh-Hant.resx │ │ ├── FirstStartBox.Designer.cs │ │ ├── FirstStartBox.ar.resx │ │ ├── FirstStartBox.cs │ │ ├── FirstStartBox.cs.resx │ │ ├── FirstStartBox.de.resx │ │ ├── FirstStartBox.es.resx │ │ ├── FirstStartBox.fr.resx │ │ ├── FirstStartBox.hu.resx │ │ ├── FirstStartBox.it.resx │ │ ├── FirstStartBox.ja.resx │ │ ├── FirstStartBox.nl.resx │ │ ├── FirstStartBox.pl.resx │ │ ├── FirstStartBox.pt-BR.resx │ │ ├── FirstStartBox.pt.resx │ │ ├── FirstStartBox.resx │ │ ├── FirstStartBox.ru.resx │ │ ├── FirstStartBox.sl.resx │ │ ├── FirstStartBox.sv.resx │ │ ├── FirstStartBox.tr.resx │ │ ├── FirstStartBox.vi.resx │ │ ├── FirstStartBox.zh-Hans.resx │ │ └── FirstStartBox.zh-Hant.resx │ ├── Functions/ │ │ ├── AppPropertiesGatherer.cs │ │ ├── AppUninstaller.cs │ │ ├── ApplicationList/ │ │ │ ├── ApplicationListColors.cs │ │ │ ├── ApplicationListConstants.cs │ │ │ ├── CertificateCache.cs │ │ │ ├── ListViewDelegates.cs │ │ │ ├── UninstallerListConfigurator.cs │ │ │ ├── UninstallerListPostProcesser.cs │ │ │ └── UninstallerListViewUpdater.cs │ │ ├── MessageBoxes.cs │ │ ├── Ratings/ │ │ │ ├── RatingEntry.cs │ │ │ ├── RatingManagerWrapper.cs │ │ │ ├── RatingRenderer.cs │ │ │ ├── UninstallerRating.cs │ │ │ ├── UninstallerRatingManager.Utils.cs │ │ │ └── UninstallerRatingManager.cs │ │ ├── Tools/ │ │ │ ├── ImportExport.cs │ │ │ ├── LocalizedX509Certificate.cs │ │ │ ├── OnlineSearchTools.cs │ │ │ ├── SettingTools.cs │ │ │ ├── SystemRestore.cs │ │ │ └── UpdateGrabber.cs │ │ └── Tracking/ │ │ ├── DatabaseStatSender.cs │ │ ├── EventHook.cs │ │ ├── SingleEventHook.cs │ │ ├── UsageManager.cs │ │ └── UsageTracker.cs │ ├── NBugConfigurator.cs │ ├── Program.cs │ ├── Properties/ │ │ ├── Localisable.Designer.cs │ │ ├── Localisable.ar.resx │ │ ├── Localisable.cs.resx │ │ ├── Localisable.de.resx │ │ ├── Localisable.es.resx │ │ ├── Localisable.fr.resx │ │ ├── Localisable.hu.resx │ │ ├── Localisable.it.resx │ │ ├── Localisable.ja.resx │ │ ├── Localisable.nl.resx │ │ ├── Localisable.pl.resx │ │ ├── Localisable.pt-BR.resx │ │ ├── Localisable.pt.resx │ │ ├── Localisable.resx │ │ ├── Localisable.ru.resx │ │ ├── Localisable.sl.resx │ │ ├── Localisable.sv.resx │ │ ├── Localisable.tr.resx │ │ ├── Localisable.vi.resx │ │ ├── Localisable.zh-Hans.resx │ │ ├── Localisable.zh-Hant.resx │ │ ├── Resources.Designer.cs │ │ ├── Resources.resx │ │ ├── Settings.Designer.cs │ │ ├── Settings.cs │ │ └── Settings.settings │ └── Resources/ │ └── MicrosoftProgram_Install_and_Uninstall.meta.diagcab ├── BulkCrapUninstaller.sln ├── BulkCrapUninstallerTests/ │ ├── BulkCrapUninstallerTests.csproj │ ├── DynamicStringArrayConverterTests.cs │ ├── Functions/ │ │ └── UninstallerRatingManagerTests.cs │ └── Properties/ │ └── AssemblyInfo.cs ├── Directory.Build.props ├── GlobalAssemblyInfo.cs ├── HelperTools/ │ ├── HelperTools.cs │ ├── HelperTools.projitems │ ├── HelperTools.shproj │ ├── LogWriter.cs │ ├── ResultWin32.cs │ └── ResultWin32Extensions.cs ├── KlocTools/ │ ├── Collections/ │ │ └── ObservedList.cs │ ├── Controls/ │ │ ├── CommandLink.cs │ │ ├── ContentAlignmentBox.Designer.cs │ │ ├── ContentAlignmentBox.cs │ │ ├── ContentAlignmentBox.resx │ │ ├── DirectorySelectBox.Designer.cs │ │ ├── DirectorySelectBox.cs │ │ ├── DirectorySelectBox.cs.resx │ │ ├── DirectorySelectBox.de.resx │ │ ├── DirectorySelectBox.es.resx │ │ ├── DirectorySelectBox.fr.resx │ │ ├── DirectorySelectBox.hu.resx │ │ ├── DirectorySelectBox.it.resx │ │ ├── DirectorySelectBox.ja.resx │ │ ├── DirectorySelectBox.nl.resx │ │ ├── DirectorySelectBox.pl.resx │ │ ├── DirectorySelectBox.pt-BR.resx │ │ ├── DirectorySelectBox.pt.resx │ │ ├── DirectorySelectBox.resx │ │ ├── DirectorySelectBox.ru.resx │ │ ├── DirectorySelectBox.sl.resx │ │ ├── DirectorySelectBox.sv.resx │ │ ├── DirectorySelectBox.tr.resx │ │ ├── DirectorySelectBox.vi.resx │ │ ├── DirectorySelectBox.zh-Hans.resx │ │ ├── DirectorySelectBox.zh-Hant.resx │ │ ├── EditableCheckedListView.Designer.cs │ │ ├── EditableCheckedListView.cs │ │ ├── EditableCheckedListView.resx │ │ ├── EditableListView.Designer.cs │ │ ├── EditableListView.cs │ │ ├── EditableListView.resx │ │ ├── FacebookButton.cs │ │ ├── FacebookStatusButton.cs │ │ ├── FixedFlowLayoutPanel.cs │ │ ├── LineSeparator.Designer.cs │ │ ├── LineSeparator.cs │ │ ├── LineSeparator.resx │ │ ├── PassThroughLabel.cs │ │ ├── PathSelectBox.Designer.cs │ │ ├── PathSelectBox.cs │ │ ├── PathSelectBox.cs.resx │ │ ├── PathSelectBox.de.resx │ │ ├── PathSelectBox.es.resx │ │ ├── PathSelectBox.fr.resx │ │ ├── PathSelectBox.hu.resx │ │ ├── PathSelectBox.it.resx │ │ ├── PathSelectBox.ja.resx │ │ ├── PathSelectBox.nl.resx │ │ ├── PathSelectBox.pl.resx │ │ ├── PathSelectBox.pt-BR.resx │ │ ├── PathSelectBox.pt.resx │ │ ├── PathSelectBox.resx │ │ ├── PathSelectBox.ru.resx │ │ ├── PathSelectBox.sl.resx │ │ ├── PathSelectBox.sv.resx │ │ ├── PathSelectBox.tr.resx │ │ ├── PathSelectBox.vi.resx │ │ ├── PathSelectBox.zh-Hans.resx │ │ ├── PathSelectBox.zh-Hant.resx │ │ ├── SearchBox.Designer.cs │ │ ├── SearchBox.ar.resx │ │ ├── SearchBox.cs │ │ ├── SearchBox.cs.resx │ │ ├── SearchBox.de.resx │ │ ├── SearchBox.es.resx │ │ ├── SearchBox.fr.resx │ │ ├── SearchBox.hu.resx │ │ ├── SearchBox.it.resx │ │ ├── SearchBox.ja.resx │ │ ├── SearchBox.nl.resx │ │ ├── SearchBox.pl.resx │ │ ├── SearchBox.pt-BR.resx │ │ ├── SearchBox.pt.resx │ │ ├── SearchBox.resx │ │ ├── SearchBox.ru.resx │ │ ├── SearchBox.sl.resx │ │ ├── SearchBox.sv.resx │ │ ├── SearchBox.tr.resx │ │ ├── SearchBox.vi.resx │ │ ├── SearchBox.zh-Hans.resx │ │ ├── SearchBox.zh-Hant.resx │ │ ├── ToolStripNumberControl.cs │ │ ├── TwitterButton.cs │ │ ├── TwitterStatusButton.cs │ │ ├── WindowTargeter.Designer.cs │ │ ├── WindowTargeter.ar.resx │ │ ├── WindowTargeter.cs │ │ ├── WindowTargeter.cs.resx │ │ ├── WindowTargeter.de.resx │ │ ├── WindowTargeter.es.resx │ │ ├── WindowTargeter.fr.resx │ │ ├── WindowTargeter.hu.resx │ │ ├── WindowTargeter.it.resx │ │ ├── WindowTargeter.ja.resx │ │ ├── WindowTargeter.nl.resx │ │ ├── WindowTargeter.pl.resx │ │ ├── WindowTargeter.pt-BR.resx │ │ ├── WindowTargeter.pt.resx │ │ ├── WindowTargeter.resx │ │ ├── WindowTargeter.ru.resx │ │ ├── WindowTargeter.sl.resx │ │ ├── WindowTargeter.sv.resx │ │ ├── WindowTargeter.tr.resx │ │ ├── WindowTargeter.vi.resx │ │ ├── WindowTargeter.zh-Hans.resx │ │ └── WindowTargeter.zh-Hant.resx │ ├── DisplayMode.cs │ ├── Events/ │ │ ├── CountingUpdateEventArgs.cs │ │ └── PropertyChangedEventArgs.cs │ ├── Extensions/ │ │ ├── BooleanTools.cs │ │ ├── CheckBoxExtension.cs │ │ ├── CollectionExtensions.cs │ │ ├── DictionaryExtensions.cs │ │ ├── EnumerableExtensions.cs │ │ ├── EventExtensions.cs │ │ ├── FormsExtensions.cs │ │ ├── IconExtensions.cs │ │ ├── IoExtensions.cs │ │ ├── MiscExtensions.cs │ │ ├── ParentProcessUtilities.cs │ │ ├── ProcessExtensions.cs │ │ ├── ReadOnlyDictionaryWrapper.cs │ │ ├── RegistryKeyExtensions.cs │ │ ├── RichTextBoxExtensions.cs │ │ ├── StreamExtensions.cs │ │ ├── StringExtensions.cs │ │ ├── TimeExtensions.cs │ │ ├── WebExtensions.cs │ │ └── XmlExtensions.cs │ ├── Forms/ │ │ ├── CmbBasicSettings.cs │ │ ├── CmbCheckboxSettings.cs │ │ ├── CmbHyperlinkSettings.cs │ │ ├── CustomMessageBox.cs │ │ ├── CustomMessageBox.designer.cs │ │ ├── CustomMessageBox.resx │ │ ├── LoadingDialog.Designer.cs │ │ ├── LoadingDialog.cs │ │ ├── LoadingDialog.resx │ │ ├── LoadingDialogInterface.cs │ │ ├── OverlaySplashScreen.Designer.cs │ │ ├── OverlaySplashScreen.cs │ │ ├── OverlaySplashScreen.resx │ │ ├── ProcessWaiter.Designer.cs │ │ ├── ProcessWaiter.ar.resx │ │ ├── ProcessWaiter.cs │ │ ├── ProcessWaiter.cs.resx │ │ ├── ProcessWaiter.de.resx │ │ ├── ProcessWaiter.es.resx │ │ ├── ProcessWaiter.fr.resx │ │ ├── ProcessWaiter.hu.resx │ │ ├── ProcessWaiter.it.resx │ │ ├── ProcessWaiter.ja.resx │ │ ├── ProcessWaiter.nl.resx │ │ ├── ProcessWaiter.pl.resx │ │ ├── ProcessWaiter.pt-BR.resx │ │ ├── ProcessWaiter.pt.resx │ │ ├── ProcessWaiter.resx │ │ ├── ProcessWaiter.ru.resx │ │ ├── ProcessWaiter.sl.resx │ │ ├── ProcessWaiter.sv.resx │ │ ├── ProcessWaiter.tr.resx │ │ ├── ProcessWaiter.vi.resx │ │ ├── ProcessWaiter.zh-Hans.resx │ │ ├── ProcessWaiter.zh-Hant.resx │ │ ├── ProcessWaiterControl.Designer.cs │ │ ├── ProcessWaiterControl.ar.resx │ │ ├── ProcessWaiterControl.cs │ │ ├── ProcessWaiterControl.cs.resx │ │ ├── ProcessWaiterControl.de.resx │ │ ├── ProcessWaiterControl.es.resx │ │ ├── ProcessWaiterControl.fr.resx │ │ ├── ProcessWaiterControl.hu.resx │ │ ├── ProcessWaiterControl.it.resx │ │ ├── ProcessWaiterControl.ja.resx │ │ ├── ProcessWaiterControl.nl.resx │ │ ├── ProcessWaiterControl.pl.resx │ │ ├── ProcessWaiterControl.pt-BR.resx │ │ ├── ProcessWaiterControl.pt.resx │ │ ├── ProcessWaiterControl.resx │ │ ├── ProcessWaiterControl.ru.resx │ │ ├── ProcessWaiterControl.sl.resx │ │ ├── ProcessWaiterControl.sv.resx │ │ ├── ProcessWaiterControl.tr.resx │ │ ├── ProcessWaiterControl.vi.resx │ │ ├── ProcessWaiterControl.zh-Hans.resx │ │ ├── ProcessWaiterControl.zh-Hant.resx │ │ ├── SplashScreen.cs │ │ ├── StringEditBox.Designer.cs │ │ ├── StringEditBox.cs │ │ ├── StringEditBox.resx │ │ ├── Tools/ │ │ │ ├── Buttons.Designer.cs │ │ │ ├── Buttons.ar.resx │ │ │ ├── Buttons.cs.resx │ │ │ ├── Buttons.de.resx │ │ │ ├── Buttons.es.resx │ │ │ ├── Buttons.fr.resx │ │ │ ├── Buttons.hu.resx │ │ │ ├── Buttons.it.resx │ │ │ ├── Buttons.ja.resx │ │ │ ├── Buttons.nl.resx │ │ │ ├── Buttons.pl.resx │ │ │ ├── Buttons.pt-BR.resx │ │ │ ├── Buttons.pt.resx │ │ │ ├── Buttons.resx │ │ │ ├── Buttons.ru.resx │ │ │ ├── Buttons.sl.resx │ │ │ ├── Buttons.sv.resx │ │ │ ├── Buttons.tr.resx │ │ │ ├── Buttons.vi.resx │ │ │ ├── Buttons.zh-Hans.resx │ │ │ ├── Buttons.zh-Hant.resx │ │ │ ├── ComboBoxWrapper.cs │ │ │ ├── GlobalMouseMove.cs │ │ │ ├── MouseMovedEvent.cs │ │ │ ├── PremadeDialogs.cs │ │ │ ├── ReferencedComponent.cs │ │ │ ├── SingleColorTable.cs │ │ │ ├── StandardSystemColorTable.cs │ │ │ └── WindowStyleController.cs │ │ ├── WindowTargeterDialog.Designer.cs │ │ ├── WindowTargeterDialog.ar.resx │ │ ├── WindowTargeterDialog.cs │ │ ├── WindowTargeterDialog.cs.resx │ │ ├── WindowTargeterDialog.de.resx │ │ ├── WindowTargeterDialog.es.resx │ │ ├── WindowTargeterDialog.fr.resx │ │ ├── WindowTargeterDialog.hu.resx │ │ ├── WindowTargeterDialog.it.resx │ │ ├── WindowTargeterDialog.ja.resx │ │ ├── WindowTargeterDialog.nl.resx │ │ ├── WindowTargeterDialog.pl.resx │ │ ├── WindowTargeterDialog.pt-BR.resx │ │ ├── WindowTargeterDialog.pt.resx │ │ ├── WindowTargeterDialog.resx │ │ ├── WindowTargeterDialog.ru.resx │ │ ├── WindowTargeterDialog.sl.resx │ │ ├── WindowTargeterDialog.sv.resx │ │ ├── WindowTargeterDialog.tr.resx │ │ ├── WindowTargeterDialog.vi.resx │ │ ├── WindowTargeterDialog.zh-Hans.resx │ │ └── WindowTargeterDialog.zh-Hant.resx │ ├── IO/ │ │ ├── AdvancedFileInfo.cs │ │ ├── Arguments.cs │ │ ├── DismTools.cs │ │ ├── FileSize.cs │ │ ├── MsiTools.cs │ │ ├── NetFrameworkTools.cs │ │ ├── SysRestore.cs │ │ ├── WindowsFeatureInfo.cs │ │ └── WmiQueries.cs │ ├── KlocTools.csproj │ ├── Licence.licenseheader │ ├── Limited.cs │ ├── Localising/ │ │ ├── LocalisationExtensions.cs │ │ ├── LocalisedEnumWrapper.cs │ │ └── LocalisedNameAttribute.cs │ ├── Native/ │ │ ├── CSIDL.cs │ │ ├── ControlPanelCanonicalNames.cs │ │ └── MsiWrapper.cs │ ├── Properties/ │ │ ├── Localisation.Designer.cs │ │ ├── Localisation.ar.resx │ │ ├── Localisation.cs.resx │ │ ├── Localisation.de.resx │ │ ├── Localisation.es.resx │ │ ├── Localisation.fr.resx │ │ ├── Localisation.hu.resx │ │ ├── Localisation.it.resx │ │ ├── Localisation.ja.resx │ │ ├── Localisation.nl.resx │ │ ├── Localisation.pl.resx │ │ ├── Localisation.pt-BR.resx │ │ ├── Localisation.pt.resx │ │ ├── Localisation.resx │ │ ├── Localisation.ru.resx │ │ ├── Localisation.sl.resx │ │ ├── Localisation.sv.resx │ │ ├── Localisation.tr.resx │ │ ├── Localisation.vi.resx │ │ ├── Localisation.zh-Hans.resx │ │ ├── Localisation.zh-Hant.resx │ │ ├── Resources.Designer.cs │ │ └── Resources.resx │ ├── Resources/ │ │ ├── CommonStrings.Designer.cs │ │ ├── CommonStrings.ar.resx │ │ ├── CommonStrings.cs.resx │ │ ├── CommonStrings.de.resx │ │ ├── CommonStrings.es.resx │ │ ├── CommonStrings.fr.resx │ │ ├── CommonStrings.hu.resx │ │ ├── CommonStrings.it.resx │ │ ├── CommonStrings.ja.resx │ │ ├── CommonStrings.nl.resx │ │ ├── CommonStrings.pl.resx │ │ ├── CommonStrings.pt-BR.resx │ │ ├── CommonStrings.pt.resx │ │ ├── CommonStrings.resx │ │ ├── CommonStrings.ru.resx │ │ ├── CommonStrings.sl.resx │ │ ├── CommonStrings.sv.resx │ │ ├── CommonStrings.tr.resx │ │ ├── CommonStrings.vi.resx │ │ ├── CommonStrings.zh-Hans.resx │ │ └── CommonStrings.zh-Hant.resx │ ├── Sorters/ │ │ └── ColumnSorter.cs │ ├── Subsystems/ │ │ ├── FontGrabber.cs │ │ ├── GlobalHotkeys.cs │ │ ├── HotkeyEntry.cs │ │ ├── RandomFilePicker.cs │ │ ├── WindowHoverEventArgs.cs │ │ └── WindowHoverSearcher.cs │ ├── Tools/ │ │ ├── CompiledPropertyInfo.cs │ │ ├── CompressionTools.cs │ │ ├── DrawingTools.cs │ │ ├── FilesystemTools.cs │ │ ├── GuidTools.cs │ │ ├── MachineType.cs │ │ ├── PathTools.cs │ │ ├── ProcessStartCommand.cs │ │ ├── ProcessTools.cs │ │ ├── ReflectionTools.cs │ │ ├── RegistryTools.cs │ │ ├── SerializationTools.cs │ │ ├── Sift4.cs │ │ ├── SleepControls.cs │ │ ├── StringTools.cs │ │ ├── SymbolicLinkType.cs │ │ └── WindowsTools.cs │ └── YesNoAsk.cs ├── Licence.licenseheader ├── NBug_custom/ │ ├── Core/ │ │ ├── Reporting/ │ │ │ ├── BugReport.cs │ │ │ ├── Feedback.cs │ │ │ ├── Info/ │ │ │ │ ├── AssemblyInfo.cs │ │ │ │ ├── ConfigurationInfo.cs │ │ │ │ ├── GeneralInfo.cs │ │ │ │ ├── Report.cs │ │ │ │ └── SystemInfo.cs │ │ │ └── MiniDump/ │ │ │ ├── DumpTypeFlag.cs │ │ │ └── DumpWriter.cs │ │ ├── Submission/ │ │ │ ├── Custom/ │ │ │ │ └── Custom.cs │ │ │ ├── Database/ │ │ │ │ ├── Ado.cs │ │ │ │ ├── MsSql.cs │ │ │ │ └── MySql.cs │ │ │ ├── Dispatcher.cs │ │ │ ├── IProtocol.cs │ │ │ ├── IProtocolFactory.cs │ │ │ ├── ProtocolBase.cs │ │ │ ├── Protocols.cs │ │ │ ├── Tracker/ │ │ │ │ ├── BugNet.cs │ │ │ │ ├── Bugzilla.cs │ │ │ │ ├── GitHub.cs │ │ │ │ ├── GoogleCode.cs │ │ │ │ ├── Mantis/ │ │ │ │ │ ├── AccountData.cs │ │ │ │ │ ├── AttachmentData.cs │ │ │ │ │ ├── CustomFieldValueForIssueData.cs │ │ │ │ │ ├── IssueData.cs │ │ │ │ │ ├── IssueNoteData.cs │ │ │ │ │ ├── ObjectRef.cs │ │ │ │ │ ├── ProjectVersionData.cs │ │ │ │ │ ├── RelationshipData.cs │ │ │ │ │ ├── UserData.cs │ │ │ │ │ └── nusoap.php.patch │ │ │ │ ├── Redmine.cs │ │ │ │ └── Trac.cs │ │ │ └── Web/ │ │ │ ├── Ftp.cs │ │ │ ├── Http.cs │ │ │ └── Mail.cs │ │ ├── UI/ │ │ │ ├── Console/ │ │ │ │ └── ConsoleUI.cs │ │ │ ├── Custom/ │ │ │ │ └── CustomUI.cs │ │ │ ├── Developer/ │ │ │ │ ├── InternalExceptionViewer.Designer.cs │ │ │ │ ├── InternalExceptionViewer.cs │ │ │ │ ├── InternalExceptionViewer.resx │ │ │ │ ├── InternalLogViewer.Designer.cs │ │ │ │ ├── InternalLogViewer.cs │ │ │ │ └── InternalLogViewer.resx │ │ │ ├── UIDialogResult.cs │ │ │ ├── UISelector.cs │ │ │ ├── WPF/ │ │ │ │ └── WPFUI.cs │ │ │ └── WinForms/ │ │ │ ├── Feedback.Designer.cs │ │ │ ├── Feedback.cs │ │ │ ├── Feedback.resx │ │ │ ├── Full.Designer.cs │ │ │ ├── Full.cs │ │ │ ├── Full.es.resx │ │ │ ├── Full.fr.resx │ │ │ ├── Full.hu.resx │ │ │ ├── Full.ja.resx │ │ │ ├── Full.nl.resx │ │ │ ├── Full.pt-BR.resx │ │ │ ├── Full.resx │ │ │ ├── Full.sv.resx │ │ │ ├── Full.tr.resx │ │ │ ├── Full.vi.resx │ │ │ ├── Full.zh-Hans.resx │ │ │ ├── Full.zh-Hant.resx │ │ │ ├── Minimal.cs │ │ │ ├── Normal.Designer.cs │ │ │ ├── Normal.cs │ │ │ ├── Normal.resx │ │ │ ├── Panels/ │ │ │ │ ├── ExceptionDetailView.Designer.cs │ │ │ │ ├── ExceptionDetailView.cs │ │ │ │ ├── ExceptionDetailView.resx │ │ │ │ ├── ExceptionDetails.Designer.cs │ │ │ │ ├── ExceptionDetails.cs │ │ │ │ └── ExceptionDetails.resx │ │ │ └── WinFormsUI.cs │ │ └── Util/ │ │ ├── ConnectionStringParser.cs │ │ ├── ExceptionThread.cs │ │ ├── Exceptions/ │ │ │ ├── NBugConfigurationException.cs │ │ │ ├── NBugException.cs │ │ │ └── NBugRuntimeException.cs │ │ ├── Logging/ │ │ │ └── Logger.cs │ │ ├── ProtectedConfiguration.cs │ │ ├── PublicResources.cs │ │ ├── Serialization/ │ │ │ ├── SerializableDictionary.cs │ │ │ └── SerializableException.cs │ │ ├── Storage/ │ │ │ ├── StoragePath.cs │ │ │ ├── StoredItemFile.cs │ │ │ ├── Storer.cs │ │ │ └── ZipStorer.cs │ │ └── Web/ │ │ └── StreamUpload.cs │ ├── Enums/ │ │ ├── LoggerCategory.cs │ │ ├── MiniDumpType.cs │ │ ├── StoragePath.cs │ │ ├── UIMode.cs │ │ └── UIProvider.cs │ ├── Events/ │ │ ├── CustomSubmissionEventArgs.cs │ │ └── CustomUIEventArgs.cs │ ├── Exceptions.cs │ ├── Handler.cs │ ├── Helpers/ │ │ └── EmailDestinationBuilder.cs │ ├── NBug.Configurator/ │ │ ├── NBug.Configurator.exe.config │ │ └── NBug.Examples.WinForms.exe.config │ ├── NBug.csproj │ ├── NBug_LICENSE.md │ ├── NBug_README.md │ ├── Properties/ │ │ ├── AssemblyInfo.cs │ │ ├── Localization.Designer.cs │ │ ├── Localization.ar.resx │ │ ├── Localization.cs.resx │ │ ├── Localization.de.resx │ │ ├── Localization.es.resx │ │ ├── Localization.fi-FI.resx │ │ ├── Localization.fr.resx │ │ ├── Localization.hr.resx │ │ ├── Localization.hu.resx │ │ ├── Localization.it.resx │ │ ├── Localization.ja.resx │ │ ├── Localization.ko-KR.resx │ │ ├── Localization.nl.resx │ │ ├── Localization.pl.resx │ │ ├── Localization.pt-BR.resx │ │ ├── Localization.pt.resx │ │ ├── Localization.resx │ │ ├── Localization.ru.resx │ │ ├── Localization.sl.resx │ │ ├── Localization.sv.resx │ │ ├── Localization.tr.resx │ │ ├── Localization.vi.resx │ │ ├── Localization.zh-Hans.resx │ │ ├── Localization.zh-Hant.resx │ │ ├── Resources.Designer.cs │ │ ├── Resources.resx │ │ ├── Settings.Designer.cs │ │ ├── Settings.settings │ │ └── SettingsOverride.cs │ └── Settings.cs ├── NetSettingBinder/ │ ├── ISettingChangedHandlerEntry.cs │ ├── LockedList.cs │ ├── NetSettingBinder.csproj │ ├── Properties/ │ │ └── AssemblyInfo.cs │ ├── ReflectionTools.cs │ ├── SettingBinder.Forms.cs │ ├── SettingBinder.cs │ ├── SettingChangedEventArgs.cs │ ├── SettingChangedEventHandler.cs │ └── SettingChangedHandlerEntry.cs ├── ObjectListView/ │ ├── CellEditing/ │ │ ├── CellEditKeyEngine.cs │ │ ├── CellEditors.cs │ │ └── EditorRegistry.cs │ ├── CustomDictionary.xml │ ├── DataListView.cs │ ├── DataTreeListView.cs │ ├── DragDrop/ │ │ ├── DragSource.cs │ │ ├── DropSink.cs │ │ └── OLVDataObject.cs │ ├── FastDataListView.cs │ ├── FastObjectListView.cs │ ├── Filtering/ │ │ ├── Cluster.cs │ │ ├── ClusteringStrategy.cs │ │ ├── ClustersFromGroupsStrategy.cs │ │ ├── DateTimeClusteringStrategy.cs │ │ ├── FilterMenuBuilder.cs │ │ ├── Filters.cs │ │ ├── FlagClusteringStrategy.cs │ │ ├── ICluster.cs │ │ ├── IClusteringStrategy.cs │ │ └── TextMatchFilter.cs │ ├── FullClassDiagram.cd │ ├── GlobalSuppressions.cs │ ├── Implementation/ │ │ ├── Attributes.cs │ │ ├── Comparers.cs │ │ ├── DataSourceAdapter.cs │ │ ├── Delegates.cs │ │ ├── DragSource.cs │ │ ├── DropSink.cs │ │ ├── Enums.cs │ │ ├── Events.cs │ │ ├── GroupingParameters.cs │ │ ├── Groups.cs │ │ ├── Munger.cs │ │ ├── NativeMethods.cs │ │ ├── NullableDictionary.cs │ │ ├── OLVListItem.cs │ │ ├── OLVListSubItem.cs │ │ ├── OlvListViewHitTestInfo.cs │ │ ├── TreeDataSourceAdapter.cs │ │ ├── VirtualGroups.cs │ │ └── VirtualListDataSource.cs │ ├── OLVColumn.cs │ ├── ObjectListView.DesignTime.cs │ ├── ObjectListView.FxCop │ ├── ObjectListView.cs │ ├── ObjectListView.csproj │ ├── ObjectListView.shfb │ ├── Properties/ │ │ ├── AssemblyInfo.cs │ │ ├── Resources.Designer.cs │ │ └── Resources.resx │ ├── Rendering/ │ │ ├── Adornments.cs │ │ ├── Decorations.cs │ │ ├── Overlays.cs │ │ ├── Renderers.cs │ │ ├── Styles.cs │ │ └── TreeRenderer.cs │ ├── SubControls/ │ │ ├── GlassPanelForm.cs │ │ ├── HeaderControl.cs │ │ ├── ToolStripCheckedListBox.cs │ │ └── ToolTipControl.cs │ ├── TreeListView.cs │ ├── Utilities/ │ │ ├── ColumnSelectionForm.Designer.cs │ │ ├── ColumnSelectionForm.cs │ │ ├── ColumnSelectionForm.resx │ │ ├── Generator.cs │ │ ├── OLVExporter.cs │ │ └── TypedObjectListView.cs │ └── VirtualObjectListView.cs ├── OculusHelper/ │ ├── OculusApp.cs │ ├── OculusHelper.csproj │ ├── OculusManager.cs │ └── Program.cs ├── PortableSettingsProvider/ │ ├── PortableSettingsProvider.cs │ ├── PortableSettingsProvider.csproj │ ├── Properties/ │ │ └── AssemblyInfo.cs │ └── U3SettingsProvider.cs ├── ScriptHelper/ │ ├── Program.cs │ ├── Properties/ │ │ └── launchSettings.json │ ├── ScriptHelper.csproj │ └── Tweaks.cs ├── SimpleTreeMap/ │ ├── Element.cs │ ├── Properties/ │ │ └── AssemblyInfo.cs │ ├── SimpleTreeMap.csproj │ ├── Slice.cs │ ├── SliceMaker.cs │ ├── SliceRectangle.cs │ ├── SliceResult.cs │ ├── TreeMap.Designer.cs │ ├── TreeMap.cs │ └── TreeMap.resx ├── SimpleTreeMapTests/ │ ├── Form1.Designer.cs │ ├── Form1.cs │ ├── Form1.resx │ ├── Program.cs │ ├── Properties/ │ │ ├── AssemblyInfo.cs │ │ ├── Resources.Designer.cs │ │ ├── Settings.Designer.cs │ │ └── Settings.settings │ └── SimpleTreeMapTestApp.csproj ├── SteamHelper/ │ ├── Misc.cs │ ├── Program.cs │ ├── Properties/ │ │ └── launchSettings.json │ ├── SteamApplicationInfo.cs │ ├── SteamHelper.csproj │ ├── SteamInstallation.cs │ └── SteamUninstaller.cs ├── StoreAppHelper/ │ ├── App.cs │ ├── AppManager.cs │ ├── Program.cs │ └── StoreAppHelper.csproj ├── UninstallTools/ │ ├── ApplicationEntrySerializer.cs │ ├── ApplicationUninstallerEntry.cs │ ├── Controls/ │ │ ├── FilterEditor.Designer.cs │ │ ├── FilterEditor.ar.resx │ │ ├── FilterEditor.cs │ │ ├── FilterEditor.cs.resx │ │ ├── FilterEditor.de.resx │ │ ├── FilterEditor.es.resx │ │ ├── FilterEditor.fr.resx │ │ ├── FilterEditor.hu.resx │ │ ├── FilterEditor.it.resx │ │ ├── FilterEditor.ja.resx │ │ ├── FilterEditor.nl.resx │ │ ├── FilterEditor.pl.resx │ │ ├── FilterEditor.pt-BR.resx │ │ ├── FilterEditor.pt.resx │ │ ├── FilterEditor.resx │ │ ├── FilterEditor.ru.resx │ │ ├── FilterEditor.sl.resx │ │ ├── FilterEditor.sv.resx │ │ ├── FilterEditor.tr.resx │ │ ├── FilterEditor.vi.resx │ │ ├── FilterEditor.zh-Hans.resx │ │ ├── FilterEditor.zh-Hant.resx │ │ ├── UninstallListEditor.Designer.cs │ │ ├── UninstallListEditor.ar.resx │ │ ├── UninstallListEditor.cs │ │ ├── UninstallListEditor.cs.resx │ │ ├── UninstallListEditor.de.resx │ │ ├── UninstallListEditor.es.resx │ │ ├── UninstallListEditor.fr.resx │ │ ├── UninstallListEditor.hu.resx │ │ ├── UninstallListEditor.it.resx │ │ ├── UninstallListEditor.ja.resx │ │ ├── UninstallListEditor.nl.resx │ │ ├── UninstallListEditor.pl.resx │ │ ├── UninstallListEditor.pt-BR.resx │ │ ├── UninstallListEditor.pt.resx │ │ ├── UninstallListEditor.resx │ │ ├── UninstallListEditor.ru.resx │ │ ├── UninstallListEditor.sl.resx │ │ ├── UninstallListEditor.sv.resx │ │ ├── UninstallListEditor.tr.resx │ │ ├── UninstallListEditor.vi.resx │ │ ├── UninstallListEditor.zh-Hans.resx │ │ ├── UninstallListEditor.zh-Hant.resx │ │ └── UninstallerIconGetter.cs │ ├── Dialogs/ │ │ ├── StartupManagerWindow.Designer.cs │ │ ├── StartupManagerWindow.ar.resx │ │ ├── StartupManagerWindow.cs │ │ ├── StartupManagerWindow.cs.resx │ │ ├── StartupManagerWindow.de.resx │ │ ├── StartupManagerWindow.es.resx │ │ ├── StartupManagerWindow.fr.resx │ │ ├── StartupManagerWindow.hu.resx │ │ ├── StartupManagerWindow.it.resx │ │ ├── StartupManagerWindow.ja.resx │ │ ├── StartupManagerWindow.nl.resx │ │ ├── StartupManagerWindow.pl.resx │ │ ├── StartupManagerWindow.pt-BR.resx │ │ ├── StartupManagerWindow.pt.resx │ │ ├── StartupManagerWindow.resx │ │ ├── StartupManagerWindow.ru.resx │ │ ├── StartupManagerWindow.sl.resx │ │ ├── StartupManagerWindow.sv.resx │ │ ├── StartupManagerWindow.tr.resx │ │ ├── StartupManagerWindow.vi.resx │ │ ├── StartupManagerWindow.zh-Hans.resx │ │ └── StartupManagerWindow.zh-Hant.resx │ ├── Factory/ │ │ ├── ApplicationEntryTools.cs │ │ ├── ApplicationUninstallerFactory.cs │ │ ├── ApplicationUninstallerFactoryCache.cs │ │ ├── ChocolateyFactory.cs │ │ ├── ConcurrentApplicationFactory.cs │ │ ├── DirectoryFactory.cs │ │ ├── FactoryThreadedHelpers.cs │ │ ├── FactoryTools.cs │ │ ├── IUninstallerFactory.cs │ │ ├── InfoAdders/ │ │ │ ├── AppExecutablesSearcher.cs │ │ │ ├── BasicIconGetter.cs │ │ │ ├── CertificateGetter.cs │ │ │ ├── ExecutableAttributeExtractor.cs │ │ │ ├── FastSizeGenerator.cs │ │ │ ├── FileIconGetter.cs │ │ │ ├── GenerateSteamHelperStrings.cs │ │ │ ├── IMissingInfoAdder.cs │ │ │ ├── InfoAdderManager.cs │ │ │ ├── InfoAdderPriority.cs │ │ │ ├── InnoSetupQuietUninstallStringGenerator.cs │ │ │ ├── InstallDateAdder.cs │ │ │ ├── InstallLocationGenerator.cs │ │ │ ├── Is64BitGetter.cs │ │ │ ├── KnownNameIconGetter.cs │ │ │ ├── MsiInfoAdder.cs │ │ │ ├── MsiUninstallStringGenerator.cs │ │ │ ├── NsisQuietUninstallStringGenerator.cs │ │ │ ├── PredefinedAppQuietUninstallStringGenerator.cs │ │ │ ├── QuietUninstallStringCopier.cs │ │ │ ├── SimpleDeleteUninstallStringGenerator.cs │ │ │ ├── UninstallerSearcher.cs │ │ │ ├── UninstallerTypeAdder.cs │ │ │ ├── VersionCleaner.cs │ │ │ └── WebBrowserMarker.cs │ │ ├── Json/ │ │ │ ├── DynamicStringArrayConverter.cs │ │ │ └── PowerShellDateTimeOffsetConverter.cs │ │ ├── OculusFactory.cs │ │ ├── PredefinedFactory.cs │ │ ├── RegistryFactory.cs │ │ ├── ScoopFactory.cs │ │ ├── ScriptFactory.cs │ │ ├── SteamFactory.cs │ │ ├── StoreAppFactory.cs │ │ ├── WindowsFeatureFactory.cs │ │ └── WindowsUpdateFactory.cs │ ├── Junk/ │ │ ├── Confidence/ │ │ │ ├── ConfidenceCollection.cs │ │ │ ├── ConfidenceGenerators.cs │ │ │ ├── ConfidenceLevel.cs │ │ │ ├── ConfidenceRecord.cs │ │ │ └── ConfidenceRecords.cs │ │ ├── Containers/ │ │ │ ├── FileSystemJunk.cs │ │ │ ├── IJunkResult.cs │ │ │ ├── JunkResultBase.cs │ │ │ ├── RegistryKeyJunk.cs │ │ │ ├── RegistryValueJunk.cs │ │ │ ├── RunProcessJunk.cs │ │ │ └── StartupJunkNode.cs │ │ ├── Finders/ │ │ │ ├── Drive/ │ │ │ │ ├── CommonDriveJunkScanner.cs │ │ │ │ ├── InstallLocationScanner.cs │ │ │ │ ├── PrefetchScanner.cs │ │ │ │ ├── SpecificUninstallerKindScanner.cs │ │ │ │ ├── UninstallerLocationScanner.cs │ │ │ │ └── WerScanner.cs │ │ │ ├── JunkCreatorBase.cs │ │ │ ├── Misc/ │ │ │ │ ├── ShortcutJunk.cs │ │ │ │ └── StartupJunk.cs │ │ │ └── Registry/ │ │ │ ├── AppCompatFlagScanner.cs │ │ │ ├── AudioPolicyConfigScanner.cs │ │ │ ├── ComScanner.cs │ │ │ ├── DebugTracingScanner.cs │ │ │ ├── EventLogScanner.cs │ │ │ ├── FirewallRuleScanner.cs │ │ │ ├── HeapLeakDetectionScanner.cs │ │ │ ├── InstallerFoldersScanner.cs │ │ │ ├── RegisteredApplicationsFinder.cs │ │ │ ├── SoftwareRegKeyScanner.cs │ │ │ ├── TracingScanner.cs │ │ │ ├── UninstallerKeySearcher.cs │ │ │ └── UserAssistScanner.cs │ │ ├── IJunkCreator.cs │ │ ├── JunkManager.cs │ │ └── ProgramFilesOrphans.cs │ ├── KnownFolders.cs │ ├── ListGenerationProgress.cs │ ├── Lists/ │ │ ├── ComparisonMethod.cs │ │ ├── ComparisonTargetAttribute.cs │ │ ├── ComparisonTargetInfo.cs │ │ ├── Filter.cs │ │ ├── FilterCondition.cs │ │ ├── ITestEntry.cs │ │ └── UninstallList.cs │ ├── Properties/ │ │ ├── Localisation.Designer.cs │ │ ├── Localisation.ar.resx │ │ ├── Localisation.cs.resx │ │ ├── Localisation.de.resx │ │ ├── Localisation.es.resx │ │ ├── Localisation.fr.resx │ │ ├── Localisation.hu.resx │ │ ├── Localisation.it.resx │ │ ├── Localisation.ja.resx │ │ ├── Localisation.nl.resx │ │ ├── Localisation.pl.resx │ │ ├── Localisation.pt-BR.resx │ │ ├── Localisation.pt.resx │ │ ├── Localisation.resx │ │ ├── Localisation.ru.resx │ │ ├── Localisation.sl.resx │ │ ├── Localisation.sv.resx │ │ ├── Localisation.tr.resx │ │ ├── Localisation.vi.resx │ │ ├── Localisation.zh-Hans.resx │ │ ├── Localisation.zh-Hant.resx │ │ ├── Resources.Designer.cs │ │ └── Resources.resx │ ├── SimplifiedClassDiagram.cd │ ├── Startup/ │ │ ├── Browser/ │ │ │ ├── BrowserEntryFactory.cs │ │ │ └── BrowserHelperEntry.cs │ │ ├── Normal/ │ │ │ ├── IStartupDisable.cs │ │ │ ├── NewStartupDisable.cs │ │ │ ├── OldStartupDisable.cs │ │ │ ├── StartupEntry.cs │ │ │ ├── StartupEntryFactory.cs │ │ │ ├── StartupEntryManager.cs │ │ │ └── StartupPointData.cs │ │ ├── Service/ │ │ │ ├── ServiceEntry.cs │ │ │ └── ServiceEntryFactory.cs │ │ ├── StartupEntryBase.cs │ │ ├── StartupManager.cs │ │ └── Task/ │ │ ├── TaskEntry.cs │ │ └── TaskEntryFactory.cs │ ├── ThreadedWorkSpreader.cs │ ├── UninstallTools.csproj │ ├── UninstallToolsGlobalConfig.cs │ ├── Uninstaller/ │ │ ├── BulkUninstallConfiguration.cs │ │ ├── BulkUninstallEntry.cs │ │ ├── BulkUninstallTask.cs │ │ ├── MsiUninstallModes.cs │ │ ├── UninstallManager.cs │ │ └── UninstallStatus.cs │ └── UninstallerType.cs ├── UninstallerAutomatizer/ │ ├── Automation/ │ │ ├── AutomatedUninstallManager.cs │ │ ├── UninstallHandler.cs │ │ ├── UninstallHandlerUpdateArgs.cs │ │ └── UninstallHandlerUpdateKind.cs │ ├── Extensions/ │ │ ├── TestStackWhiteExtensions.cs │ │ └── WindowExtensions.cs │ ├── Forms/ │ │ ├── MainWindow.Designer.cs │ │ ├── MainWindow.ar.resx │ │ ├── MainWindow.cs │ │ ├── MainWindow.cs.resx │ │ ├── MainWindow.de.resx │ │ ├── MainWindow.es.resx │ │ ├── MainWindow.fr.resx │ │ ├── MainWindow.hu.resx │ │ ├── MainWindow.it.resx │ │ ├── MainWindow.ja.resx │ │ ├── MainWindow.nl.resx │ │ ├── MainWindow.pl.resx │ │ ├── MainWindow.pt-BR.resx │ │ ├── MainWindow.pt.resx │ │ ├── MainWindow.resx │ │ ├── MainWindow.ru.resx │ │ ├── MainWindow.sl.resx │ │ ├── MainWindow.sv.resx │ │ ├── MainWindow.tr.resx │ │ ├── MainWindow.vi.resx │ │ ├── MainWindow.zh-Hans.resx │ │ └── MainWindow.zh-Hant.resx │ ├── Program.cs │ ├── Properties/ │ │ ├── Localization.Designer.cs │ │ ├── Localization.ar.resx │ │ ├── Localization.cs.resx │ │ ├── Localization.de.resx │ │ ├── Localization.es.resx │ │ ├── Localization.fr.resx │ │ ├── Localization.it.resx │ │ ├── Localization.ja.resx │ │ ├── Localization.nl.resx │ │ ├── Localization.pl.resx │ │ ├── Localization.pt-BR.resx │ │ ├── Localization.pt.resx │ │ ├── Localization.resx │ │ ├── Localization.ru.resx │ │ ├── Localization.sl.resx │ │ ├── Localization.sv.resx │ │ ├── Localization.tr.resx │ │ ├── Localization.vi.resx │ │ ├── Localization.zh-Hans.resx │ │ └── Localization.zh-Hant.resx │ └── UninstallerAutomatizer.csproj ├── UniversalUninstaller/ │ ├── Program.cs │ ├── Properties/ │ │ ├── Localisation.Designer.cs │ │ ├── Localisation.ar.resx │ │ ├── Localisation.cs.resx │ │ ├── Localisation.de.resx │ │ ├── Localisation.es.resx │ │ ├── Localisation.fr.resx │ │ ├── Localisation.hu.resx │ │ ├── Localisation.it.resx │ │ ├── Localisation.ja.resx │ │ ├── Localisation.nl.resx │ │ ├── Localisation.pl.resx │ │ ├── Localisation.pt-BR.resx │ │ ├── Localisation.pt.resx │ │ ├── Localisation.resx │ │ ├── Localisation.ru.resx │ │ ├── Localisation.sl.resx │ │ ├── Localisation.sv.resx │ │ ├── Localisation.tr.resx │ │ ├── Localisation.vi.resx │ │ ├── Localisation.zh-Hans.resx │ │ ├── Localisation.zh-Hant.resx │ │ ├── Resources.Designer.cs │ │ ├── Resources.resx │ │ ├── Settings.Designer.cs │ │ └── Settings.settings │ ├── TargetList.Designer.cs │ ├── TargetList.ar.resx │ ├── TargetList.cs │ ├── TargetList.cs.resx │ ├── TargetList.de.resx │ ├── TargetList.es.resx │ ├── TargetList.fr.resx │ ├── TargetList.hu.resx │ ├── TargetList.it.resx │ ├── TargetList.ja.resx │ ├── TargetList.nl.resx │ ├── TargetList.pl.resx │ ├── TargetList.pt-BR.resx │ ├── TargetList.pt.resx │ ├── TargetList.resx │ ├── TargetList.ru.resx │ ├── TargetList.sl.resx │ ├── TargetList.sv.resx │ ├── TargetList.tr.resx │ ├── TargetList.vi.resx │ ├── TargetList.zh-Hans.resx │ ├── TargetList.zh-Hant.resx │ ├── TreeEntry.cs │ ├── UninstallSelection.Designer.cs │ ├── UninstallSelection.ar.resx │ ├── UninstallSelection.cs │ ├── UninstallSelection.cs.resx │ ├── UninstallSelection.de.resx │ ├── UninstallSelection.es.resx │ ├── UninstallSelection.fr.resx │ ├── UninstallSelection.hu.resx │ ├── UninstallSelection.it.resx │ ├── UninstallSelection.ja.resx │ ├── UninstallSelection.nl.resx │ ├── UninstallSelection.pl.resx │ ├── UninstallSelection.pt-BR.resx │ ├── UninstallSelection.pt.resx │ ├── UninstallSelection.resx │ ├── UninstallSelection.ru.resx │ ├── UninstallSelection.sl.resx │ ├── UninstallSelection.sv.resx │ ├── UninstallSelection.tr.resx │ ├── UninstallSelection.vi.resx │ ├── UninstallSelection.zh-Hans.resx │ ├── UninstallSelection.zh-Hant.resx │ └── UniversalUninstaller.csproj ├── WinUpdateHelper/ │ ├── Hresult.cs │ ├── Program.cs │ ├── UpdateManager.cs │ └── WinUpdateHelper.csproj └── app.manifest ================================================ FILE CONTENTS ================================================ ================================================ FILE: .github/workflows/ci.yaml ================================================ name: CI on: push: branches: - master pull_request: jobs: build: runs-on: windows-latest steps: - uses: actions/checkout@v4 - uses: microsoft/setup-msbuild@v2 - name: Restore run: msbuild source\BulkCrapUninstaller.sln /t:Restore /p:Configuration=Release /p:Platform="Any CPU" /verbosity:minimal - name: Build run: > msbuild source\BulkCrapUninstaller.sln /t:Publish /p:Configuration=Release /p:Platform="Any CPU" /verbosity:minimal /p:filealignment=512 /p:DeployOnBuild=true /p:PublishSingleFile=False /p:SelfContained=False /p:PublishReadyToRun=false /p:PublishTrimmed=False /p:PublishProtocol=FileSystem /p:PublishDir="${{ github.workspace }}\bin\publish" - uses: actions/upload-artifact@v4 with: name: ${{ github.event.repository.name }}_${{ github.sha }} path: bin\publish ================================================ FILE: .github/workflows/winget.yml ================================================ name: Publish to WinGet on: release: types: [released] jobs: publish: runs-on: ubuntu-latest steps: - name: Get version id: get-version run: | # Find the version from tag name and pad to 4 components version=$(echo "${{ github.event.release.tag_name }}" | awk -F. '{printf "%d.%d.%d.%d\n", substr($1, 2), $2, $3, $4}') echo "version=$VERSION" >> $GITHUB_OUTPUT - uses: vedantmgoyal9/winget-releaser@main with: identifier: Klocman.BulkCrapUninstaller version: ${{ steps.get-version.outputs.version }} token: ${{ secrets.WINGET_TOKEN }} ================================================ FILE: .gitignore ================================================ ## Ignore Visual Studio temporary files, build results, and ## files generated by popular Visual Studio add-ons. # User-specific files *.suo *.user *.userosscache *.sln.docstates # User-specific files (MonoDevelop/Xamarin Studio) *.userprefs # Build results [Dd]ebug/ [Dd]ebugPublic/ [Rr]elease/ [Rr]eleases/ x64/ x86/ build/ bld/ [Bb]in/ [Oo]bj/ # Visual Studio 2015 cache/options directory .vs/ # Uncomment if you have tasks that create the project's static files in wwwroot #wwwroot/ # MSTest test Results [Tt]est[Rr]esult*/ [Bb]uild[Ll]og.* # NUNIT *.VisualState.xml TestResult.xml # Build Results of an ATL Project [Dd]ebugPS/ [Rr]eleasePS/ dlldata.c # DNX project.lock.json artifacts/ *_i.c *_p.c *_i.h *.ilk *.meta *.obj *.pch *.pdb *.pgc *.pgd *.rsp *.sbr *.tlb *.tli *.tlh *.tmp *.tmp_proj *.log *.vspscc *.vssscc .builds *.pidb *.svclog *.scc # Chutzpah Test files _Chutzpah* # Visual C++ cache files ipch/ *.aps *.ncb *.opensdf *.sdf *.cachefile # Visual Studio profiler *.psess *.vsp *.vspx *.sap # TFS 2012 Local Workspace $tf/ # Guidance Automation Toolkit *.gpState # ReSharper is a .NET coding add-in _ReSharper*/ *.[Rr]e[Ss]harper *.DotSettings.user # JustCode is a .NET coding add-in .JustCode # TeamCity is a build add-in _TeamCity* # DotCover is a Code Coverage Tool *.dotCover # NCrunch _NCrunch_* .*crunch*.local.xml nCrunchTemp_* # MightyMoose *.mm.* AutoTest.Net/ # Web workbench (sass) .sass-cache/ # Installshield output folder [Ee]xpress/ # DocProject is a documentation generator add-in DocProject/buildhelp/ DocProject/Help/*.HxT DocProject/Help/*.HxC DocProject/Help/*.hhc DocProject/Help/*.hhk DocProject/Help/*.hhp DocProject/Help/Html2 DocProject/Help/html # Click-Once directory publish/ # Publish Web Output *.[Pp]ublish.xml *.azurePubxml # TODO: Comment the next line if you want to checkin your web deploy settings # but database connection strings (with potential passwords) will be unencrypted # *.pubxml *.publishproj # NuGet Packages *.nupkg # The packages folder can be ignored because of Package Restore **/packages/* # except build/, which is used as an MSBuild target. !**/packages/build/ # Uncomment if necessary however generally it will be regenerated when needed #!**/packages/repositories.config # Windows Azure Build Output csx/ *.build.csdef # Windows Store app package directory AppPackages/ # Visual Studio cache files # files ending in .cache can be ignored *.[Cc]ache # but keep track of directories ending in .cache !*.[Cc]ache/ # Others ClientBin/ [Ss]tyle[Cc]op.* ~$* *~ *.dbmdl *.dbproj.schemaview *.pfx *.publishsettings node_modules/ orleans.codegen.cs # RIA/Silverlight projects Generated_Code/ # Backup & report files from converting an old project file # to a newer Visual Studio version. Backup files are not needed, # because we have git ;-) _UpgradeReport_Files/ Backup*/ UpgradeLog*.XML UpgradeLog*.htm # SQL Server files *.mdf *.ldf # Business Intelligence projects *.rdl.data *.bim.layout *.bim_*.settings # Microsoft Fakes FakesAssemblies/ # Node.js Tools for Visual Studio .ntvs_analysis.dat # Visual Studio 6 build log *.plg # Visual Studio 6 workspace options file *.opt # Visual Studio LightSwitch build output **/*.HTMLClient/GeneratedArtifacts **/*.DesktopClient/GeneratedArtifacts **/*.DesktopClient/ModelManifest.xml **/*.Server/GeneratedArtifacts **/*.Server/ModelManifest.xml _Pvt_Extensions # Misc *.odt# *.DotSettings ================================================ FILE: CODE_OF_CONDUCT.md ================================================ # Contributor Covenant Code of Conduct - Don't be a d*ck to others - Don't be afraid to point out bad behavior - Do focus on making the project better ================================================ FILE: CONTRIBUTING.md ================================================ ## How to file a bug report Create a new issue with as much description of the problem as possible. Include steps needed for reproduction if the bug is not obvious. It's also possible to submit bug reports anonymously to my [feedback form](http://klocmansoftware.weebly.com/feedback--contact.html). ## How to suggest a new feature The same as bug report. Well-explained suggestions are preferred. ## How to donate Check [README.md](README.md) or main window of BCUninstaller for the donate link. Only donate using the official donate links. ## How to help translate Translations are stored in .resx files (almost all except for Resources.resx). It's suggested to use the [ResxTranslator](https://github.com/HakanL/resxtranslator) to translate these files. It will save you a lot of work. Most if not all of translators here use it. ### How-to list 1. Download latest version of the translation tool (ResxTranslator) from https://github.com/HakanL/resxtranslator 2. - If you are familiar with how git and GitHub works, you can create a branch, translate it, and then start a pull request. - Otherwise download the latest translation pack from the [releases](https://github.com/Klocman/Bulk-Crap-Uninstaller/releases). 3. Run the ResxTranslator and click "File > Open directory". Point it to the extracted translation pack or clone of your branch. 4. Click on any of the items in the left tree, it will open on the right. You will need to translate all of those items, most are quite small. 5. Put the translation into the column marked with your language's code. For example, if you are translating to German use the "de" column. 5. - For a list of all language codes click "Languages > Add > More Languages". If possible, use only neutral languages. - If possible, use a more general locale. For example try using "en" or "ru" instead of "en-GB" or "ru-RU". - If the column doesn't exist, click "Languages > Add > Your Code". If your code is not available, click "More Languages". - You can hide columns for different languages using the checkboxes below the list. 6. Once in a while click "File > Save all modified" (or ctrl+s) to save your work in case something crashes. 7. Create a pull request or compress the folder you just modified to a .zip and send it back to me. If you don't have my e-mailaddress you can use the [feedback form](http://klocmansoftware.weebly.com/feedback--contact.html). ## How to contribute code The best way is to push any changes you wish to make to your fork of this repository and then start a Pull Request. Try to limit the contents of your PRs to a single bug fix or a single feature (it's best to create a new branch for each bugfix or feature). This makes it much easier to review and verify, and makes merging easier. ### How to set up your environment Visual Studio 2019 or 2022 is recommended to edit and compile the source. You need the `.NET desktop development` and `Desktop development with C++` workloads. Optionally get the `Class Designer` component if you wish to view/edit the included class diagrams. The source should compile from within VS without any extra work. If the compile fails the first time, try to Rebuild Solution. Some of the tests require running as 64bit to pass, or some specific applications to be installed. ### Overview of the codebase The codebase is split into the user interfaces (BCU-Console and BulkCrapUninstaller), libraries that do the actual work (UninstallTools), and small helper applications (SteamHelper, WinUpdateHelper). The helpers adapt different kinds of applications into something that BCUninstaller can easily digest, and decouple highly specialized code from the main application. All of the helpers use CLI to talk with the UninstallTools library, and can be freely used by themselves in batch scripts and such. Here's a simplified class diagram of UninstallTools, the place where most of the magic happens: ![preview](./doc/SimplifiedClassDiagram.png) ================================================ FILE: Licence.txt ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "{}" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright 2017 Marcin Szeniak Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: NOTICE ================================================ Bulk Crap Uninstaller is a free open-source project hosted on GitHub. Marcin Szeniak is the project manager and lead developer. The official project is hosted at https://github.com/Klocman/Bulk-Crap-Uninstaller In case of issues, please update to the latest official release. Non-official releases are not supported. If the issue presists, please post a bug report to https://github.com/Klocman/Bulk-Crap-Uninstaller/issues If you wish to contribute, donate or otherwise help the project, please read the CONTRIBUTING file. https://github.com/Klocman/Bulk-Crap-Uninstaller/blob/master/CONTRIBUTING.md ================================================ FILE: PrivacyPolicy.txt ================================================ BCUninstaller by Marcin Szeniak collects the following information: - Anonymous usage statistics - Anonymous error reports - User-selected application ratings All collected information is not personally identifiable, and does not include any sensitive information. During first start of BCU an user ID is generated to help keep track of application ratings and usage statistics. It can be freely changed and is not guaranteed to be unique. Marcin Szeniak collects this information in order to provide the following benefits: - Improve BCUninstaller - Provide overall application ratings - Help plan future features and/or applications Marcin Szeniak shares this information with the following parties: - No one User-selected application ratings are used to generate overall application ratings, which are visible to all users. This policy is subject to change without notice. Please check this page for the latest privacy policy. If you disagree with this policy, please discontinue use of the application. ================================================ FILE: README.md ================================================ [![Donate](https://img.shields.io/badge/donate-paypal-brightgreen.svg)](http://klocmansoftware.weebly.com/donate.html) [![GitHub release](https://img.shields.io/github/release/klocman/Bulk-Crap-Uninstaller.svg)](https://github.com/Klocman/Bulk-Crap-Uninstaller/releases) [![license](https://img.shields.io/github/license/klocman/Bulk-Crap-Uninstaller.svg)](https://github.com/Klocman/Bulk-Crap-Uninstaller/blob/master/Licence.txt) ### [:warning: Looking for maintainers :warning:](https://github.com/Klocman/Bulk-Crap-Uninstaller/discussions/289) # Bulk Crap Uninstaller Bulk Crap Uninstaller (or BCUninstaller) is a free (as in speech) program uninstaller. It excels at removing large amounts of applications with minimal user input. It can clean up leftovers, detect orphaned applications, run uninstallers according to premade lists, and much more! Even though BCU was made with IT pros in mind, it can be used by anyone with a basic understanding of how applications are installed/uninstalled in Windows. BCU is fully compatible with Windows Store Apps, Steam, Windows Features and has special support for many uninstalling systems (NSIS, InnoSetup, Msiexec, and many other). Check below for a full list of functions. Bulk Crap Uninstaller is licensed under Apache 2.0 open source license, and can be used in both private and commercial settings for free and with no obligations, as long as no conditions of the license are broken. [Visit the official homepage](https://www.bcuninstaller.com/) to see the full list of quirks and features! [Read the online documentation](https://htmlpreview.github.io/?https://github.com/Klocman/Bulk-Crap-Uninstaller/blob/master/doc/BCU_manual.html) if you have any questions or issues (the help file included with all releases). If you didn't find an answer to your question, feel free to [open a new issue](https://github.com/Klocman/Bulk-Crap-Uninstaller/issues/new). ## Download You can get the latest version from the releases page. Alternatively you can download it from one of these hosts: - [Download from dAppCDN](https://dappcdn.com/download/utilities/bulk-crap-uninstaller) - [Download from FossHub](https://www.fosshub.com/Bulk-Crap-Uninstaller.html) - [Download from SourceForge](https://sourceforge.net/projects/bulk-crap-uninstaller/) #### What are the different variants? - Setup - Installs BCU as a normal application. If your system is missing the required .NET runtime, it is automatically installed as well. - Portable - Self-contained version that does not require the .NET runtime to run. It includes a runtime which is why the file size is so large. - net - Stand-alone portable version that requires the .NET runtime to be installed. Much smaller file size than the full Portable version. #### Nightly builds If you want to get the latest features and fixes as soon as they are available, you can download a nightly build from the [actions page](https://github.com/Klocman/Bulk-Crap-Uninstaller/actions/workflows/ci.yaml). ## System requirements #### BCUninstaller v6 - Earliest supported OS: Windows 10 (may work on Windows 7) - Requirements: .NET 8 desktop runtime (not needed for portable) To get this version download the latest release from the links below. _*Note: Since none of the supported systems have x86 versions, v6 releases no longer include an x86 build. If you need one you can still compile it yourself, or you can use the AnyCPU build instead._ #### BCUninstaller v5 - Earliest supported OS: Windows 7 SP1 with all Platform Updates (KB2670838, KB2533623, etc.) - Requirements: .NET 6 desktop runtime (not needed for portable) If you get a DLL error on startup then try running Windows Update. If you get a framework error, install .NET6 either manually or through Windows Update. To get this version download the [latest available 5.x release](https://github.com/Klocman/Bulk-Crap-Uninstaller/releases/tag/v5.9). _*Note: The Portable version does not require the .NET6 runtime to be installed, since it is included (that's why the portable version is so large)._ #### BCUninstaller v1 - v4 - Earliest supported OS: Windows XP (XP support may be dodgy in later releases) - Requirements: .Net Framework 4.5 (some versions can run on .Net Framework 3.5 with reduced functionality) Make sure you have .Net Framework 4.5 installed with all available updates for your system (it is not installed on XP by default). To get this version compile the [legacy 4.x branch](https://github.com/Klocman/Bulk-Crap-Uninstaller/tree/legacy-4.x) or download the [latest available 4.x release](https://github.com/Klocman/Bulk-Crap-Uninstaller/releases/tag/v4.16). ## How can I help? Please check the [contribution](CONTRIBUTING.md) notes! ## Compiling Development is done on Visual Studio 2022. The solution should just load and build without doing anything extra, provided necessary VS features are installed. The installer is compiled with InnoSetup v6.4. To make a release you have to first run the `publish.bat` script. ## Screenshots ![preview](../gh-pages/assets/1.png) ![preview](../gh-pages/assets/4.png) ================================================ FILE: doc/BCU_manual.html ================================================ Bulk Crap Uninstaller Documentation
 

Bulk Crap

Uninstaller

Documentation

 

Table of Contents

1 Introduction

1.1 System Requirements

2 Main Window

2.1 Application List

2.1.1 Highlight Colors

2.1.2 Certificates and verification

2.1.3 User rating

2.2 Left sidebar

2.3 Treemap

2.4 Functions

2.4.1 Uninstall / Uninstall quietly

2.4.2 Uninstall using MsiExec / Windows Installer

2.4.3 Uninstall manually

2.4.4 Clean up “Program Files” folders

2.4.5 Find by window

2.4.6 Uninstall Windows Features

3 Application properties

3.1 Missing uninstaller

3.2 Unregistered application

3.3 Protected

3.4 Store App

3.5 System component

3.6 Update

4 Settings

4.1 Uninstallation

4.1.1 Concurrent uninstallation

5 Advanced copy to clipboard

6 Advanced filtering / Uninstall lists

6.1 Enabling advanced filtering

6.2 Filters

6.3 Conditions

6.3.1 Comparison methods

6.3.2 Target property

6.4 Saving and loading filters in .bcul files

7 Uninstallation

7.1 Loud / Quiet uninstallers

7.2 Preparations

7.2.1 Process kill window

7.3 Uninstall progress window

7.3.1 Manual controls, dealing with stuck uninstallers

7.3.2 Aborting the entire uninstall task

7.4 Leftover / Junk removal

7.4.1 Confidence

7.4.2 Backup

8 Custom rules, Scripts and Tweaks

8.1 Specification of Script files

8.1.1 Example script file (remove-onedrive.xml)

8.1.2 Standard elements

8.1.3 Acceptable values

8.1.4 Special elements

9 Command line options

9.1 BCUninstaller.exe

9.2 BCU-console.exe

9.3 StoreAppHelper.exe

9.4 SteamHelper.exe

9.5 OculusHelper.exe

9.6 UninstallerAutomatizer.exe

1 Introduction

Bulk Crap Uninstaller (or BCUninstaller) is a free (as in speech) program uninstaller. It excels at removing large amounts of applications with minimal user input. It can clean up leftovers, detect orphaned applications, run uninstallers according to premade lists, and much more!

BCU is fully compatible with Windows Store Apps, Steam, Windows Features and has special support for many uninstalling systems (NSIS, InnoSetup, Msiexec, and many other). Check below for a full list of functions.

Bulk Crap Uninstaller is licensed under Apache 2.0 open source license, and can be used in both private and commercial settings for free and with no obligations, as long as no conditions of the license are broken.

Official website and a contact form can be found at https://www.bcuninstaller.com/

Get the latest version or view the code at https://github.com/Klocman/Bulk-Crap-Uninstaller

1.1 System Requirements

BCUninstaller needs administrator rights to start and function. They are needed to access some system functions during application scan, to uninstall applications and to delete leftovers. Some other functions might also need elevated permissions to function, therefore it’s not possible to run BCU with standard user permissions.

2 Main Window

 

2.1 Application List

A list of applications that BCU managed to find in your system takes up most of the main window. The list can be sorted by the columns and filtered using options on the left.

2.1.1 Highlight Colors

By default, many items on the list have colored backgrounds according to their properties. Their meanings can be found in the Color legend in the bottom right corner. If the list is not visible, it can be enabled from the “View” menu.

Items with white backgrounds have no special properties.

2.1.2 Certificates and verification

BCU can read and verify certificates of uninstallers. Their details can be viewed in the properties window. This function not meant to indicate good or bad applications, use it only as a hint.

Verified certificate means that the executable is guaranteed to not have been modified in any way since leaving its publisher.

The following can cause a certificate to fail verification:

2.1.3 User rating

Most applications can be rated by users of BCU. The ratings are automatically synchronized with the statistics server. The rating can be between 0 and 4 stars, color of the stars corresponds to their number.

If the stars are black, it means that they represent your own vote instead of the user average. You can hover over the stars to see the average rating.

2.2 Left sidebar

Settings Sidebar contains mostly filtering options for the application list. It can be hidden from the “View” menu.

Search box is the same as a condition used in advanced filtering, check 6.3 Conditions for more information.

If Advanced filtering is enabled, the sidebar is automatically hidden.

2.3 Treemap

At the bottom of the application, just above the status bar, you should see a bunch of colored tiles. This is a treemap – a visual representation of all the applications currently visible on the list.

The size of the square is based on application’s estimated size. If an application doesn’t have an estimated size, it will not be shown. The tiles are scaled using a non-linear algorithm - size differences will appear smaller than they really are.

You can hover over the treemap, and the application currently under cursor will be shown below. You can click and right-click on any of the tiles to open context menu, and left-click to select the applications. It works the same as the main list. Selected tiles will change color to the selection color.

2.4 Functions

2.4.1 Uninstall / Uninstall quietly

Begins uninstallation of selected applications. Quiet uninstallation means that you do not have to click anything – the process is automatic. If it is impossible to quietly uninstall some items, a dialog will be shown with ability to remove the “loud” uninstallers from the selection.

2.4.2 Uninstall using MsiExec / Windows Installer

If the application has a Product code / GUID attached to it you can try using MsiExec to uninstall it. It is not guaranteed to work on all applications.

2.4.3 Uninstall manually

Skips running the uninstaller (if it is available) and instead gives a list of files and registry keys that you can choose to delete manually.

It is not recommended to use this method unless it is impossible to uninstall the application in any other way.

2.4.4 Clean up “Program Files” folders

Search all folders that are defined as default installation locations (usually only the Program Files folders) for leftovers. This includes empty folders and partially uninstalled applications. You will be given a choice of items to remove.

2.4.5 Find by window

Opens a small tool window. Drag and drop the cross over a window you want to scan. BCU will try to find the application that owns the specified window and show it on the list.

2.4.6 Uninstall Windows Features

Scan the system for installed Windows Features and add them to the application list. They are treated as normal applications after that point and can be uninstalled in bulk. The scan can take a while.

3 Application properties

Some properties are displayed as background colors, check 2.1.1 Highlight Colors for more information.

Additional information not displayed on the list is available in the properties window.

3.1 Missing uninstaller

The application is registered in the system registry, but its uninstaller is either corrupted or missing. It will have to be removed manually.

3.2 Unregistered application

The application is not registered in the system registry, but is present on the drive. If the application still has a working uninstaller, BCU can often manage to find it and let you run it. If the uninstaller is not found, BCU will automatically generate a simple uninstaller.

3.3 Protected

The application is marked as protected in system registry. This is often used to indicate that it is a part of another package, or is required by other applications.

3.4 Store App

The new Windows 10 – styled applications are all called Store Apps, even if they do not come from Windows Store. They normally require a completely different method of removal, but BCU presents them as normal applications.

3.5 System component

The application is marked to be important in some way to your system. Drivers and parts of bigger software packages are often marked as system components to hide them from the user. They are not actually required by the operating system.

3.6 Update

Means that the item is an update to another application, or the OS. Uninstalling the actual application will usually remove all related updates automatically.

4 Settings

Settings are automatically applied and saved on application exit. It is possible to reset settings to their defaults by “Help\Reset settings” menu option, or by removing the “BCUninstaller.settings” file in BCU's directory.

4.1 Uninstallation

4.1.1 Concurrent uninstallation

Concurrent uninstallation is an experimental feature that will schedule multiple uninstallers to be ran at the same time. It will do its best to prevent any collisions and sometimes this functionality will be completely unavailable.

It is not recommended to run more than 2 uninstallers at the same time unless you are using a fast SSD.

You can manually force uninstallers to run concurrently from the bulk uninstall window. Doing so will still be tested for collisions, but the check can be disabled (not recommended).

5 Advanced copy to clipboard

The pattern is a Composite Format String. It is automatically processed when written.

To enable use of escaped characters (\r, \t, \n, etc.) enable the “Unescape” check-box. It will convert any escaped characters to their unescaped form.

To insert a newline add “\r\n” (standard newline on Windows) to the pattern and enable “Unescape“. You should see the newline appear in the Results box.

The combo box contains all available variables that can be added to the pattern. Selecting one of the variables will automatically paste it at cursor position.

6 Advanced filtering / Uninstall lists

 

6.1 Enabling advanced filtering

Advanced filtering can be enabled by clicking the “Advanced button” on the sidebar or by opening an existing uninstall list from the “File” menu.

If an uninstall list is loaded, its path is displayed in the application's title bar.

When advanced filtering is enabled, all basic filtering settings are ignored.

6.2 Filters

Filters are displayed in the “Filter list”. Each filter can contain multiple conditions.

It is possible to add filters from an existing uninstall list by the option on the toolbar. New filters are appended to the end of the list.

If the filter's type is set to include, it will only allow applications that match all of its conditions to appear on the list. They are executed before the exclude filters.

If the type is set to exclude, the filter will remove all applications that match all of its conditions from the list. They override the include filters.

If there are only exclude filters all applications are automatically included.

6.3 Conditions

For a filter to match an application all of its conditions must match it. If any of the conditions fails to match the application the entire filter fails the match.

The filter text is compared against target property using selected comparison method. The result of the comparison can be optionally inverted (negated).

6.3.1 Comparison methods

6.3.2 Target property

Property of the application that will be compared against. “All properties” will try to match the filter text to any of the available properties.

The properties can be previewed by viewing properties of the applications.

6.4 Saving and loading filters in .bcul files

.bcul files (also called “advanced filter lists” or “uninstall lists”) are used to store advanced filters information for later use. You can save your set of filters into a .bcul file that you can later use with the command line tool to automatically uninstall all applications that are matched by your filters.

To save a .bcul file, first open the Advanced filtering panel, specify your filters, and click on the “Save as…” button in the toolbar above the filter list. You should see a save file dialog with the .bcul extension.

To load a .bcul file, either click “File” > “Open Uninstall List…”, or open Advanced filtering panel and click on the “Open…” toolbar item.

To use a .bcul file with the command line tool to automatically uninstall applications (for example in a script), check the BCU-console.exe parameter list.

7 Uninstallation

BCU can uninstall single applications or multiple applications at the same time. To uninstall, select applications that you want to uninstall in the main list (you can select multiple by holding shift or control), and then click on the Uninstall / Uninstall Quietly button on the toolbar above or right click on your selection and select Uninstall / Uninstall Quietly in the context menu.

If you uninstalled any applications that were integrated into the system (e.g. drivers, extensions, antiviruses) then you should reboot the PC after BCU finishes uninstalling to make sure everything gets fully removed (some uninstallers continue to run after a reboot, while in other cases Windows is still using some of the files so they have to be removed on the next system boot).

7.1 Loud / Quiet uninstallers

There are two ways to uninstall an application – loud and quiet.

BCU is capable of generating quiet uninstallers for many applications using many techniques (e.g. UI automation).

7.2 Preparations

After clicking on any of the Uninstall buttons you might be asked a few questions, most notably:

7.2.1 Process kill window

 

The above window is shown if there are any running applications that might be using files that will be uninstalled in the task. It is recommended to close all of them, but false positives are possible – keep an eye out to avoid losing opened work.

7.3 Uninstall progress window

 

The Uninstall progress window will appear to display progress of the uninstallation after the configuration. Uninstallers are grouped in following categories:

7.3.1 Manual controls, dealing with stuck uninstallers

By selecting an uninstaller on the list user can use functions located on the toolbar above.

7.3.2 Aborting the entire uninstall task

At any point it is possible to abort the uninstall task by clicking “Cancel” or attempting to close the window. BCU will ask for confirmation before skipping all the remaining uninstallers.

Already running uninstallers are not closed, BCU will wait for them to complete. If the remaining uninstallers are stuck it might be necessary to manually skip or terminate them.

7.4 Leftover / Junk removal

 

Once the uninstallation is completed BCU will ask to search for leftovers. If any are found, the above window will be displayed.

It is possible to open locations of the items and view their details through their context menus.

Export will only save data visible in the window (item paths, confidence ratings, etc.). This is not a backup tool.

7.4.1 Confidence

All items are given a “Confidence” rating. The higher the confidence, the safer it is to remove an item. By default, only items of at least Good confidence are selected.

It is possible to show items with Bad confidence, but removing them is dangerous and recommended only for experienced users.

7.4.2 Backup

BCU will ask to create a backup of the registry entries before removing them.

Files and folders are moved to the recycle bin. If the recycle bin is disabled or has not enough capacity the items are removed permanently.

8 Custom rules, Scripts and Tweaks

Starting with BCU version 4.9 it’s possible to add custom detection rules (from now on referred to as “Scripts”) that will create custom entries on the application list. This allows end-user to add custom rules to their installation of BCU and to later automate them.

Scripts are placed in the Resources\Scripts folder inside of BCU’s installation directory and have .xml extensions. They can be placed in subfolders.

System Tweaks introduced in version 4.9 are implemented as scripts and can be used as examples.

8.1 Specification of Script files

Scripts are simple .xml files that contain information necessary to create a new entry on the application list, as well as an optional condition.

8.1.1 Example script file (remove-onedrive.xml)

<script>

    <ConditionScript>remove-onedrive_check.ps1</ConditionScript>

    <Script>remove-onedrive.ps1</Script>

    <DisplayName>OneDrive</DisplayName>

    <Publisher>Microsoft Corporation</Publisher>

    <RatingId>OneDrive</RatingId>

    <AboutUrl>https://onedrive.live.com/</AboutUrl>

    <InstallLocation>Registry::HKEY_CURRENT_USER\SOFTWARE\Microsoft\OneDrive\CurrentVersionPath</InstallLocation>

    <DisplayVersion>Registry::HKEY_CURRENT_USER\SOFTWARE\Microsoft\OneDrive\Version</DisplayVersion>

    <DisplayIcon>Registry::HKEY_CURRENT_USER\SOFTWARE\Microsoft\OneDrive\OneDriveTrigger</DisplayIcon>

</script>

8.1.2 Standard elements

Most properties of the ApplicationUninstallerEntry class, for example DisplayName, InstallLocation, can be assigned by creating an element with the property’s name.

To get a list of available element names with example values, open BCU and select File>Export, or right click on any application in the list and open Advanced Clipboard Copy. You can also check the source code.

8.1.3 Acceptable values

Most elements can take an arbitrary constant string. It will be copied as-is to the entry on the application list, unless it’s invalid in some way.

If the value starts with “Registry::”, it will be treated as a full registry path to a value. The pointed value will be read from the registry and used instead of the registry path.

For example, using Registry::HKEY_CURRENT_USER\SOFTWARE\Microsoft\OneDrive\CurrentVersionPath in the InstallLocation element will cause BCU to read the value named CurrentVersionPath from registry key named  HKEY_CURRENT_USER\SOFTWARE\Microsoft\OneDrive, and put its contents into the InstallLocation property.

8.1.4 Special elements

9 Command line options

List of valid command line options to BCUninstaller and its helpers.

9.1 BCUninstaller.exe

BCUninstaller [drive:][path]filename

 

[drive:][path] – Specifies drive and directory of the uninstall list.

filename   – Specifies filename of the uninstall list

 

BCUninstaller /sm – Start only the Startup Manager. Does not enumerate installed applications so it

                    starts much faster. If BCU is already running, this switch will be ignored and

                    the running instance will be focused. (You can also use /startupmanager)

9.2 BCU-console.exe

BCU-console [help | /?] - Show help (this screen)

 

BCU-console uninstall [drive:][path]filename [/Q] [/U] [/V] [/J=<Level>] - Uninstall applications.

 [drive:][path] – Specifies drive and directory of the uninstall list.

 filename       – Specifies filename of the .bcul uninstall list that contains information about.

                  what applications to uninstall.

 

BCU-console export [drive:][path]filename [/Q] [/U] [/V] - Export installed application data to xml file.

 [drive:][path] – Specifies drive and directory to where the export should be saved.

 filename       – Specifies filename of the .xml file to save the exported application information to.

 

Switches:

 /Q             - Use quiet uninstallers wherever possible (by default only use loud).

 /U             - Unattended mode (do not ask user for confirmation). WARNING: ONLY USE AFTER

                  THOROUGH TESTING. UNINSTALL LISTS SHOULD BE AS SPECIFIC AS POSSIBLE TO AVOID.

                  FALSE POSITIVES. THERE ARE NO WARRANTIES, USE WITH CAUTION.

 /J=<Level>     - Attempt to clean up leftover "junk" (Registry entries and files/folders) after

                  uninstall. If no level is passed then defaults to "VeryGood". ***WARNING***: USE

                  EXTREME CAUTION WHEN CHOOSING ANY LEVEL BELOW VeryGood. THERE ARE NO WARRANTIES.

                  Valid levels are: VeryGood, Good, Questionable, Bad, Unknown

 /V             - Verbose logging mode (show more information about what is currently happening).

 

Return codes:

0 - The operation completed successfully.

1 - Invalid arguments.

1223 - The operation was canceled by the user.

 

Examples:

BCU-console uninstall “D:\Test\my_list.bcul” /Q /U

BCU-console export out.xml

9.3 StoreAppHelper.exe

StoreAppHelper /query

StoreAppHelper /uninstall FullName

 

query  – Returns a list of installed Store Apps for current user.

uninstall – Uninstalls a single Store App specified by its FullName.

 

Return codes:

0 - The operation completed successfully.

1627 - An unexpected error occurred.

10022 - Invalid arguments.

9.4 SteamHelper.exe

SteamHelper u[ninstall] [/s[ilent]] AppID

SteamHelper i[nfo] AppID

SteamHelper l[ist]

SteamHelper steam

 

AppID  - Steam application ID.

u[ninstall] - Uninstall a Steam app.

i[nfo] - Show info about a Steam app.

l[ist] - List Steam app ID's.

steam  - Show Steam install location.

s[ilent] - Don’t prompt for any user input.

 

Return codes:

0 - The operation completed successfully.

59 - An unexpected error occurred.

1223 - The operation was canceled by the user.

10022 - Invalid arguments.

9.5 OculusHelper.exe

OculusHelper /query

OculusHelper /uninstall CanonicalName

 

query  – Returns a list of installed Oculus Apps for current user.

uninstall – Uninstalls a single Store App specified by its CanonicalName.

 

Return codes:

0 - The operation completed successfully.

1627 - An unexpected error occurred.

10022 - Invalid arguments.

9.6 UninstallerAutomatizer.exe

UninstallerAutomatizer UninstallerType [/K] UninstallCommand

 

UninstallerType - Type of the uninstaller, taken from UninstallerType enumeration. At the moment of writing only “Nsis” is supported.

K    - Kill the uninstaller if automatic uninstallation failed.

UninstallCommand - Path to the target uninstaller with optional arguments.

 

Return codes:

0 - The operation completed successfully.

1627 - An unexpected error occurred.

10022 - Invalid arguments.

================================================ FILE: installer/.gitignore ================================================ ## Ignore for InnoSetup [Ii]nput [Oo]utput *.tmp ================================================ FILE: installer/BcuSetup.iss ================================================ ; Tested with innosetup-6.4.3 ; Normal: include self-contained binaries for both x86 and x64 ; Light: include only AnyCPU binaries and automatically download net8 if needed #define Light ; ============================================================================= #define MyAppName "BCUninstaller" #define MyAppNameShort "BCUninstaller" #define MyAppPublisher "Marcin Szeniak" #define MyAppURL "https://github.com/Klocman/Bulk-Crap-Uninstaller" #define MyAppExeName "BCUninstaller.exe" #define CurrentYear GetDateTimeString('yyyy','','') #define MyAppCopyright "Copyright " + CurrentYear + " " + MyAppPublisher #ifdef Light #define InputDir "..\bin\publish-AnyCPU-net8.0" #define MainExePath InputDir+'\'+MyAppExeName ; Downloading net8 is only necessary in light mode #include "CodeDependencies.iss" #else #define InputDir "..\bin\publish" #define MainExePath InputDir+'\win-x64\'+MyAppExeName ; Portable page only works in normal mode #include "PortablePage.iss" #endif #define MajorVersion #define MinorVersion #define RevisionVersion #define BuildVersion #define TempVersion ParseVersion(MainExePath, MajorVersion, MinorVersion, RevisionVersion, BuildVersion) #define MyAppVersion str(MajorVersion) + "." + str(MinorVersion) + "." + str(RevisionVersion) + "." + str(BuildVersion) #define MyAppVersionShort str(MajorVersion) + "." + str(MinorVersion) + "." + str(RevisionVersion) [Setup] AppId={{f4fef76c-1aa9-441c-af7e-d27f58d898d1} AppName={#MyAppName} AppVersion={#MyAppVersion} AppVerName={#MyAppName} {#MyAppVersion} AppPublisher={#MyAppPublisher} AppPublisherURL={#MyAppURL} AppSupportURL={#MyAppURL} AppUpdatesURL={#MyAppURL} DefaultDirName={commonpf}\{#MyAppName} DefaultGroupName={#MyAppName} UninstallDisplayIcon={app}\{#MyAppExeName} WizardImageFile=assets\bigImage.bmp WizardSmallImageFile=assets\smallImage.bmp SetupIconFile=assets\logo.ico AllowNoIcons=yes DisableDirPage=no LicenseFile={#InputDir}\Licence.txt OutputBaseFilename={#MyAppNameShort}_{#MyAppVersionShort}_setup Compression=lzma2/ultra SolidCompression=yes LZMAUseSeparateProcess=yes LZMADictionarySize=548570 LZMANumFastBytes=273 LZMANumBlockThreads=8 PrivilegesRequired=admin ArchitecturesAllowed=x86compatible ArchitecturesInstallIn64BitMode=x64compatible VersionInfoCompany={#MyAppPublisher} ;VersionInfoDescription=desc VersionInfoCopyright={#MyAppCopyright} VersionInfoProductName={#MyAppName} VersionInfoProductTextVersion={#MyAppVersion} VersionInfoTextVersion={#MyAppVersion} [Languages] Name: "en"; MessagesFile: "compiler:Default.isl" Name: "fr"; MessagesFile: "compiler:Languages\French.isl" Name: "pl"; MessagesFile: "compiler:Languages\Polish.isl" Name: "de"; MessagesFile: "compiler:Languages\German.isl" Name: "sl"; MessagesFile: "compiler:Languages\Slovenian.isl" Name: "nl"; MessagesFile: "compiler:Languages\Dutch.isl" Name: "es"; MessagesFile: "compiler:Languages\Spanish.isl" Name: "bpt"; MessagesFile: "compiler:Languages\BrazilianPortuguese.isl" Name: "ru"; MessagesFile: "compiler:Languages\Russian.isl" Name: "it"; MessagesFile: "compiler:Languages\Italian.isl" Name: "hu"; MessagesFile: "compiler:Languages\Hungarian.isl" Name: "tr"; MessagesFile: "compiler:Languages\Turkish.isl" Name: "vi"; MessagesFile: "lang\Vietnamese.isl" Name: "hi"; MessagesFile: "lang\Hindi.isl" Name: "zh_cn"; MessagesFile: "lang\ChineseSimplified.isl" [Components] Name: "main"; Description: "{cm:MainFiles}"; Types: full compact custom; Flags: fixed Name: "lang"; Description: "{cm:ExtraLanguages}"; Types: full [Files] #ifdef Light ; Need to do this to separate the language resource folders from main app file Source: "{#InputDir}\*"; DestDir: "{app}\"; Components: main; Flags: ignoreversion recursesubdirs; Excludes: "CleanLogs.bat,\??\*,\??-??\*,\??-????\*"; ; If installing languages, copy everything Source: "{#InputDir}\*"; DestDir: "{app}\"; Components: lang; Flags: ignoreversion recursesubdirs; Excludes: "CleanLogs.bat"; #else Source: "{#InputDir}\*"; DestDir: "{app}"; Components: main; Flags: ignoreversion; Check: IsPortable or not IsPortable Source: "{#InputDir}\BCU_manual.html"; DestDir: "{app}"; Components: main; Flags: ignoreversion isreadme; Check: IsPortable or not IsPortable ; Need to do this to separate the language resource folders from main app files Source: "{#InputDir}\win-x64\*"; DestDir: "{app}\win-x64"; Components: main; Flags: ignoreversion; Excludes: "CleanLogs.bat"; Check: Is64BitInstallMode or IsPortable Source: "{#InputDir}\win-x64\Resources\*"; DestDir: "{app}\win-x64\Resources"; Components: main; Flags: ignoreversion recursesubdirs; Check: Is64BitInstallMode or IsPortable Source: "{#InputDir}\win-x86\*"; DestDir: "{app}\win-x86"; Components: main; Flags: ignoreversion; Excludes: "CleanLogs.bat"; Check: not Is64BitInstallMode or IsPortable Source: "{#InputDir}\win-x86\Resources\*"; DestDir: "{app}\win-x86\Resources"; Components: main; Flags: ignoreversion recursesubdirs; Check: not Is64BitInstallMode or IsPortable ; If installing languages, copy everything Source: "{#InputDir}\win-x64\*"; DestDir: "{app}\win-x64"; Components: lang; Flags: ignoreversion recursesubdirs; Excludes: "CleanLogs.bat"; Check: Is64BitInstallMode or IsPortable Source: "{#InputDir}\win-x86\*"; DestDir: "{app}\win-x86"; Components: lang; Flags: ignoreversion recursesubdirs; Excludes: "CleanLogs.bat"; Check: not Is64BitInstallMode or IsPortable ; Only copy the cleaning script if installing as portable Source: "{#InputDir}\win-x64\CleanLogs.bat"; DestDir: "{app}\win-x64"; Components: main; Flags: ignoreversion; Check: IsPortable Source: "{#InputDir}\win-x86\CleanLogs.bat"; DestDir: "{app}\win-x86"; Components: main; Flags: ignoreversion; Check: IsPortable #endif [InstallDelete] Name: {app}\BCU-launcher.exe; Type: files ; Make sure there are no old stale versions. Settings file is kept in the root directory so it will survive. Name: {app}\win-x64; Type: filesandordirs Name: {app}\win-x86; Type: filesandordirs [Tasks] Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; Check: IsNotPortable [Icons] Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Check: IsNotPortable; Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}"; Check: IsNotPortable; Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon; Check: IsNotPortable; [Run] Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent shellexec #ifdef Light [Code] function IsPortable(): Boolean; begin Result := False end; function IsNotPortable(): Boolean; begin Result := True end; function InitializeSetup: Boolean; begin Dependency_AddDotNet80Desktop; Result := True; end; #endif [CustomMessages] en.MainFiles=Main Files pl.MainFiles=Główne pliki fr.MainFiles=Principaux fichiers de.MainFiles=Haupt Dateien hu.MainFiles=Fő fájlok sl.MainFiles=Glavne datoteke nl.MainFiles=Hoofdbestanden es.MainFiles=Archivos principales bpt.MainFiles=Arquivos principais ru.MainFiles=Основные файлы программы it.MainFiles=File programma vi.MainFiles=Các tập tin chương trình chính tr.MainFiles=Ana Dosyalar zh_cn.MainFiles=主文件 hi.MainFiles=मुख्य फ़ाइलें en.ExtraLanguages=Extra Languages pl.ExtraLanguages=Dodatkowe języki fr.ExtraLanguages=Langues supplémentaires de.ExtraLanguages=Zusätzliche Sprachen hu.ExtraLanguages=Extra nyelvek sl.ExtraLanguages=Dodatni jeziki nl.ExtraLanguages=Extra talen es.ExtraLanguages=Idiomas adicionales bpt.ExtraLanguages=Línguas extras ru.ExtraLanguages=Дополнительные языки it.ExtraLanguages=Lingue aggiuntive vi.ExtraLanguages=Ngôn ngữ bổ sung tr.ExtraLanguages=İlave Diller zh_cn.ExtraLanguages=其他语言 hi.ExtraLanguages=अतिरिक्त भाषाएँ ================================================ FILE: installer/CodeDependencies.iss ================================================ [Code] // https://github.com/DomGries/InnoDependencyInstaller // types and variables type TDependency_Entry = record Filename: String; Parameters: String; Title: String; URL: String; Checksum: String; ForceSuccess: Boolean; RestartAfter: Boolean; end; var Dependency_Memo: String; Dependency_List: array of TDependency_Entry; Dependency_NeedToRestart, Dependency_ForceX86: Boolean; Dependency_DownloadPage: TDownloadWizardPage; procedure Dependency_Add(const Filename, Parameters, Title, URL, Checksum: String; const ForceSuccess, RestartAfter: Boolean); var Dependency: TDependency_Entry; DependencyCount: Integer; begin Dependency_Memo := Dependency_Memo + #13#10 + '%1' + Title; Dependency.Filename := Filename; Dependency.Parameters := Parameters; Dependency.Title := Title; if FileExists(ExpandConstant('{tmp}{\}') + Filename) then begin Dependency.URL := ''; end else begin Dependency.URL := URL; end; Dependency.Checksum := Checksum; Dependency.ForceSuccess := ForceSuccess; Dependency.RestartAfter := RestartAfter; DependencyCount := GetArrayLength(Dependency_List); SetArrayLength(Dependency_List, DependencyCount + 1); Dependency_List[DependencyCount] := Dependency; end; procedure Dependency_InitializeWizard; begin Dependency_DownloadPage := CreateDownloadPage(SetupMessage(msgWizardPreparing), SetupMessage(msgPreparingDesc), nil); end; function Dependency_PrepareToInstall(var NeedsRestart: Boolean): String; var DependencyCount, DependencyIndex, ResultCode: Integer; Retry: Boolean; TempValue: String; begin DependencyCount := GetArrayLength(Dependency_List); if DependencyCount > 0 then begin Dependency_DownloadPage.Show; for DependencyIndex := 0 to DependencyCount - 1 do begin if Dependency_List[DependencyIndex].URL <> '' then begin Dependency_DownloadPage.Clear; Dependency_DownloadPage.Add(Dependency_List[DependencyIndex].URL, Dependency_List[DependencyIndex].Filename, Dependency_List[DependencyIndex].Checksum); Retry := True; while Retry do begin Retry := False; try Dependency_DownloadPage.Download; except if Dependency_DownloadPage.AbortedByUser then begin Result := Dependency_List[DependencyIndex].Title; DependencyIndex := DependencyCount; end else begin case SuppressibleMsgBox(AddPeriod(GetExceptionMessage), mbError, MB_ABORTRETRYIGNORE, IDIGNORE) of IDABORT: begin Result := Dependency_List[DependencyIndex].Title; DependencyIndex := DependencyCount; end; IDRETRY: begin Retry := True; end; end; end; end; end; end; end; if Result = '' then begin for DependencyIndex := 0 to DependencyCount - 1 do begin Dependency_DownloadPage.SetText(Dependency_List[DependencyIndex].Title, ''); Dependency_DownloadPage.SetProgress(DependencyIndex + 1, DependencyCount + 1); while True do begin ResultCode := 0; #ifdef Dependency_CustomExecute if {#Dependency_CustomExecute}(ExpandConstant('{tmp}{\}') + Dependency_List[DependencyIndex].Filename, Dependency_List[DependencyIndex].Parameters, ResultCode) then begin #else if ShellExec('', ExpandConstant('{tmp}{\}') + Dependency_List[DependencyIndex].Filename, Dependency_List[DependencyIndex].Parameters, '', SW_SHOWNORMAL, ewWaitUntilTerminated, ResultCode) then begin #endif if Dependency_List[DependencyIndex].RestartAfter then begin if DependencyIndex = DependencyCount - 1 then begin Dependency_NeedToRestart := True; end else begin NeedsRestart := True; Result := Dependency_List[DependencyIndex].Title; end; break; end else if (ResultCode = 0) or Dependency_List[DependencyIndex].ForceSuccess then begin // ERROR_SUCCESS (0) break; end else if ResultCode = 1641 then begin // ERROR_SUCCESS_REBOOT_INITIATED (1641) NeedsRestart := True; Result := Dependency_List[DependencyIndex].Title; break; end else if ResultCode = 3010 then begin // ERROR_SUCCESS_REBOOT_REQUIRED (3010) Dependency_NeedToRestart := True; break; end; end; case SuppressibleMsgBox(FmtMessage(SetupMessage(msgErrorFunctionFailed), [Dependency_List[DependencyIndex].Title, IntToStr(ResultCode)]), mbError, MB_ABORTRETRYIGNORE, IDIGNORE) of IDABORT: begin Result := Dependency_List[DependencyIndex].Title; break; end; IDIGNORE: begin break; end; end; end; if Result <> '' then begin break; end; end; if NeedsRestart then begin TempValue := '"' + ExpandConstant('{srcexe}') + '" /restart=1 /LANG="' + ExpandConstant('{language}') + '" /DIR="' + WizardDirValue + '" /GROUP="' + WizardGroupValue + '" /TYPE="' + WizardSetupType(False) + '" /COMPONENTS="' + WizardSelectedComponents(False) + '" /TASKS="' + WizardSelectedTasks(False) + '"'; if WizardNoIcons then begin TempValue := TempValue + ' /NOICONS'; end; RegWriteStringValue(HKA, 'SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce', '{#SetupSetting("AppName")}', TempValue); end; end; Dependency_DownloadPage.Hide; end; end; #ifndef Dependency_NoUpdateReadyMemo #endif function Dependency_UpdateReadyMemo(const Space, NewLine, MemoUserInfoInfo, MemoDirInfo, MemoTypeInfo, MemoComponentsInfo, MemoGroupInfo, MemoTasksInfo: String): String; begin Result := ''; if MemoUserInfoInfo <> '' then begin Result := Result + MemoUserInfoInfo + Newline + NewLine; end; if MemoDirInfo <> '' then begin Result := Result + MemoDirInfo + Newline + NewLine; end; if MemoTypeInfo <> '' then begin Result := Result + MemoTypeInfo + Newline + NewLine; end; if MemoComponentsInfo <> '' then begin Result := Result + MemoComponentsInfo + Newline + NewLine; end; if MemoGroupInfo <> '' then begin Result := Result + MemoGroupInfo + Newline + NewLine; end; if MemoTasksInfo <> '' then begin Result := Result + MemoTasksInfo; end; if Dependency_Memo <> '' then begin if MemoTasksInfo = '' then begin Result := Result + SetupMessage(msgReadyMemoTasks); end; Result := Result + FmtMessage(Dependency_Memo, [Space]); end; end; function Dependency_NeedRestart: Boolean; begin Result := Dependency_NeedToRestart; end; function Dependency_IsX64: Boolean; begin Result := not Dependency_ForceX86 and Is64BitInstallMode; end; function Dependency_String(const x86, x64: String): String; begin if Dependency_IsX64 then begin Result := x64; end else begin Result := x86; end; end; function Dependency_ArchSuffix: String; begin Result := Dependency_String('', '_x64'); end; function Dependency_ArchTitle: String; begin Result := Dependency_String(' (x86)', ' (x64)'); end; function Dependency_IsNetCoreInstalled(Runtime: String; Major, Minor, Revision: Word): Boolean; var Path: String; ResultCode: Integer; Output: TExecOutput; LineIndex: Integer; LineParts: TArrayOfString; PackedVersion: Int64; LineMajor, LineMinor, LineRevision, LineBuild: Word; begin if not RegQueryStringValue(HKLM32, 'SOFTWARE\dotnet\Setup\InstalledVersions\x' + Dependency_String('86', '64'), 'InstallLocation', Path) or not FileExists(Path + 'dotnet.exe') then begin Path := ExpandConstant(Dependency_String('{commonpf32}', '{commonpf64}')) + '\dotnet\'; end; if ExecAndCaptureOutput(Path + 'dotnet.exe', '--list-runtimes', '', SW_HIDE, ewWaitUntilTerminated, ResultCode, Output) and (ResultCode = 0) then begin for LineIndex := 0 to Length(Output.StdOut) - 1 do begin LineParts := StringSplit(Trim(Output.StdOut[LineIndex]), [' '], stExcludeEmpty); if (Length(LineParts) > 1) and (Lowercase(LineParts[0]) = Lowercase(Runtime)) and StrToVersion(LineParts[1], PackedVersion) then begin UnpackVersionComponents(PackedVersion, LineMajor, LineMinor, LineRevision, LineBuild); if (LineMajor = Major) and (LineMinor = Minor) and (LineRevision >= Revision) then begin Result := True; exit; end; end; end; end; Result := False; end; procedure Dependency_AddDotNet35; begin // https://dotnet.microsoft.com/download/dotnet-framework/net35-sp1 if not IsDotNetInstalled(net35, 1) then begin Dependency_Add('dotnetfx35.exe', '/lang:enu /passive /norestart', '.NET Framework 3.5 Service Pack 1', 'https://download.microsoft.com/download/2/0/E/20E90413-712F-438C-988E-FDAA79A8AC3D/dotnetfx35.exe', '', False, False); end; end; procedure Dependency_AddDotNet40; begin // https://dotnet.microsoft.com/download/dotnet-framework/net40 if not IsDotNetInstalled(net4full, 0) then begin Dependency_Add('dotNetFx40_Full_setup.exe', '/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart', '.NET Framework 4.0', 'https://download.microsoft.com/download/1/B/E/1BE39E79-7E39-46A3-96FF-047F95396215/dotNetFx40_Full_setup.exe', '', False, False); end; end; procedure Dependency_AddDotNet45; begin // https://dotnet.microsoft.com/download/dotnet-framework/net452 if not IsDotNetInstalled(net452, 0) then begin Dependency_Add('dotnetfx45.exe', '/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart', '.NET Framework 4.5.2', 'https://go.microsoft.com/fwlink/?LinkId=397707', '', False, False); end; end; procedure Dependency_AddDotNet46; begin // https://dotnet.microsoft.com/download/dotnet-framework/net462 if not IsDotNetInstalled(net462, 0) then begin Dependency_Add('dotnetfx46.exe', '/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart', '.NET Framework 4.6.2', 'https://go.microsoft.com/fwlink/?linkid=780596', '', False, False); end; end; procedure Dependency_AddDotNet47; begin // https://dotnet.microsoft.com/download/dotnet-framework/net472 if not IsDotNetInstalled(net472, 0) then begin Dependency_Add('dotnetfx47.exe', '/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart', '.NET Framework 4.7.2', 'https://go.microsoft.com/fwlink/?LinkId=863262', '', False, False); end; end; procedure Dependency_AddDotNet48; begin // https://dotnet.microsoft.com/download/dotnet-framework/net48 if not IsDotNetInstalled(net48, 0) then begin Dependency_Add('dotnetfx48.exe', '/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart', '.NET Framework 4.8', 'https://go.microsoft.com/fwlink/?LinkId=2085155', '', False, False); end; end; procedure Dependency_AddDotNet481; begin // https://dotnet.microsoft.com/download/dotnet-framework/net481 if not IsDotNetInstalled(net481, 0) then begin Dependency_Add('dotnetfx481.exe', '/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart', '.NET Framework 4.8.1', 'https://go.microsoft.com/fwlink/?LinkId=2203304', '', False, False); end; end; procedure Dependency_AddNetCore31; begin // https://dotnet.microsoft.com/download/dotnet-core/3.1 if not Dependency_IsNetCoreInstalled('Microsoft.NETCore.App', 3, 1, 32) then begin Dependency_Add('netcore31' + Dependency_ArchSuffix + '.exe', '/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart', '.NET Core Runtime 3.1.32' + Dependency_ArchTitle, Dependency_String('https://download.visualstudio.microsoft.com/download/pr/de4b3438-24a2-4d1d-a845-97355cf97b71/515abb880478b49f7c1bced8fbf07b16/dotnet-runtime-3.1.32-win-x86.exe', 'https://download.visualstudio.microsoft.com/download/pr/476eba79-f17f-49c8-a213-0f24a22cd026/37c02de81ff5b76ac57a5427462395f1/dotnet-runtime-3.1.32-win-x64.exe'), '', False, False); end; end; procedure Dependency_AddNetCore31Asp; begin // https://dotnet.microsoft.com/download/dotnet-core/3.1 if not Dependency_IsNetCoreInstalled('Microsoft.AspNetCore.App', 3, 1, 32) then begin Dependency_Add('netcore31asp' + Dependency_ArchSuffix + '.exe', '/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart', 'ASP.NET Core Runtime 3.1.32' + Dependency_ArchTitle, Dependency_String('https://download.visualstudio.microsoft.com/download/pr/63b482d2-04b2-4dd4-baaf-d1e78de80738/40321091c872f4e77337b68fc61a5a07/aspnetcore-runtime-3.1.32-win-x86.exe', 'https://download.visualstudio.microsoft.com/download/pr/98910750-2644-472c-ab2b-17f315ccb953/c2a4c223ee11e2eec7d13744e7a45547/aspnetcore-runtime-3.1.32-win-x64.exe'), '', False, False); end; end; procedure Dependency_AddNetCore31Desktop; begin // https://dotnet.microsoft.com/download/dotnet-core/3.1 if not Dependency_IsNetCoreInstalled('Microsoft.WindowsDesktop.App', 3, 1, 32) then begin Dependency_Add('netcore31desktop' + Dependency_ArchSuffix + '.exe', '/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart', '.NET Desktop Runtime 3.1.32' + Dependency_ArchTitle, Dependency_String('https://download.visualstudio.microsoft.com/download/pr/3f353d2c-0431-48c5-bdf6-fbbe8f901bb5/542a4af07c1df5136a98a1c2df6f3d62/windowsdesktop-runtime-3.1.32-win-x86.exe', 'https://download.visualstudio.microsoft.com/download/pr/b92958c6-ae36-4efa-aafe-569fced953a5/1654639ef3b20eb576174c1cc200f33a/windowsdesktop-runtime-3.1.32-win-x64.exe'), '', False, False); end; end; procedure Dependency_AddDotNet50; begin // https://dotnet.microsoft.com/download/dotnet/5.0 if not Dependency_IsNetCoreInstalled('Microsoft.NETCore.App', 5, 0, 17) then begin Dependency_Add('dotnet50' + Dependency_ArchSuffix + '.exe', '/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart', '.NET Runtime 5.0.17' + Dependency_ArchTitle, Dependency_String('https://download.visualstudio.microsoft.com/download/pr/54683c13-6b04-4d7d-b4d4-1f055b50ea43/e99048e2840d57040e8312058853a5b9/dotnet-runtime-5.0.17-win-x86.exe', 'https://download.visualstudio.microsoft.com/download/pr/a0832b5a-6900-442b-af79-6ffddddd6ba4/e2df0b25dd851ee0b38a86947dd0e42e/dotnet-runtime-5.0.17-win-x64.exe'), '', False, False); end; end; procedure Dependency_AddDotNet50Asp; begin // https://dotnet.microsoft.com/download/dotnet/5.0 if not Dependency_IsNetCoreInstalled('Microsoft.AspNetCore.App', 5, 0, 17) then begin Dependency_Add('dotnet50asp' + Dependency_ArchSuffix + '.exe', '/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart', 'ASP.NET Core Runtime 5.0.17' + Dependency_ArchTitle, Dependency_String('https://download.visualstudio.microsoft.com/download/pr/4bfa247d-321d-4b29-a34b-62320849059b/8df7a17d9aad4044efe9b5b1c423e82c/aspnetcore-runtime-5.0.17-win-x86.exe', 'https://download.visualstudio.microsoft.com/download/pr/3789ec90-2717-424f-8b9c-3adbbcea6c16/2085cc5ff077b8789ff938015392e406/aspnetcore-runtime-5.0.17-win-x64.exe'), '', False, False); end; end; procedure Dependency_AddDotNet50Desktop; begin // https://dotnet.microsoft.com/download/dotnet/5.0 if not Dependency_IsNetCoreInstalled('Microsoft.WindowsDesktop.App', 5, 0, 17) then begin Dependency_Add('dotnet50desktop' + Dependency_ArchSuffix + '.exe', '/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart', '.NET Desktop Runtime 5.0.17' + Dependency_ArchTitle, Dependency_String('https://download.visualstudio.microsoft.com/download/pr/b6fe5f2a-95f4-46f1-9824-f5994f10bc69/db5ec9b47ec877b5276f83a185fdb6a0/windowsdesktop-runtime-5.0.17-win-x86.exe', 'https://download.visualstudio.microsoft.com/download/pr/3aa4e942-42cd-4bf5-afe7-fc23bd9c69c5/64da54c8864e473c19a7d3de15790418/windowsdesktop-runtime-5.0.17-win-x64.exe'), '', False, False); end; end; procedure Dependency_AddDotNet60; begin // https://dotnet.microsoft.com/download/dotnet/6.0 if not Dependency_IsNetCoreInstalled('Microsoft.NETCore.App', 6, 0, 36) then begin Dependency_Add('dotnet60' + Dependency_ArchSuffix + '.exe', '/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart', '.NET Runtime 6.0.36' + Dependency_ArchTitle, Dependency_String('https://download.visualstudio.microsoft.com/download/pr/727d79cb-6a4c-4a6b-bd9e-af99ad62de0b/5cd3550f1589a2f1b3a240c745dd1023/dotnet-runtime-6.0.36-win-x86.exe', 'https://download.visualstudio.microsoft.com/download/pr/1a5fc50a-9222-4f33-8f73-3c78485a55c7/1cb55899b68fcb9d98d206ba56f28b66/dotnet-runtime-6.0.36-win-x64.exe'), '', False, False); end; end; procedure Dependency_AddDotNet60Asp; begin // https://dotnet.microsoft.com/download/dotnet/6.0 if not Dependency_IsNetCoreInstalled('Microsoft.AspNetCore.App', 6, 0, 36) then begin Dependency_Add('dotnet60asp' + Dependency_ArchSuffix + '.exe', '/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart', 'ASP.NET Core Runtime 6.0.36' + Dependency_ArchTitle, Dependency_String('https://download.visualstudio.microsoft.com/download/pr/8cfa7f46-88f2-4521-a2d8-59b827420344/447de18a48115ac0fe6f381f0528e7a5/aspnetcore-runtime-6.0.36-win-x86.exe', 'https://download.visualstudio.microsoft.com/download/pr/0f0ea01c-ef7c-4493-8960-d1e9269b718b/3f95c5bd383be65c2c3384e9fa984078/aspnetcore-runtime-6.0.36-win-x64.exe'), '', False, False); end; end; procedure Dependency_AddDotNet60Desktop; begin // https://dotnet.microsoft.com/download/dotnet/6.0 if not Dependency_IsNetCoreInstalled('Microsoft.WindowsDesktop.App', 6, 0, 36) then begin Dependency_Add('dotnet60desktop' + Dependency_ArchSuffix + '.exe', '/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart', '.NET Desktop Runtime 6.0.36' + Dependency_ArchTitle, Dependency_String('https://download.visualstudio.microsoft.com/download/pr/cdc314df-4a4c-4709-868d-b974f336f77f/acd5ab7637e456c8a3aa667661324f6d/windowsdesktop-runtime-6.0.36-win-x86.exe', 'https://download.visualstudio.microsoft.com/download/pr/f6b6c5dc-e02d-4738-9559-296e938dabcb/b66d365729359df8e8ea131197715076/windowsdesktop-runtime-6.0.36-win-x64.exe'), '', False, False); end; end; procedure Dependency_AddDotNet70; begin // https://dotnet.microsoft.com/download/dotnet/7.0 if not Dependency_IsNetCoreInstalled('Microsoft.NETCore.App', 7, 0, 20) then begin Dependency_Add('dotnet70' + Dependency_ArchSuffix + '.exe', '/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart', '.NET Runtime 7.0.20' + Dependency_ArchTitle, Dependency_String('https://download.visualstudio.microsoft.com/download/pr/b2e820bd-b591-43df-ab10-1eeb7998cc18/661ca79db4934c6247f5c7a809a62238/dotnet-runtime-7.0.20-win-x86.exe', 'https://download.visualstudio.microsoft.com/download/pr/be7eaed0-4e32-472b-b53e-b08ac3433a22/fc99a5977c57cbfb93b4afb401953818/dotnet-runtime-7.0.20-win-x64.exe'), '', False, False); end; end; procedure Dependency_AddDotNet70Asp; begin // https://dotnet.microsoft.com/download/dotnet/7.0 if not Dependency_IsNetCoreInstalled('Microsoft.AspNetCore.App', 7, 0, 20) then begin Dependency_Add('dotnet70asp' + Dependency_ArchSuffix + '.exe', '/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart', 'ASP.NET Core Runtime 7.0.20' + Dependency_ArchTitle, Dependency_String('https://download.visualstudio.microsoft.com/download/pr/d84ac38e-a248-4c8d-b1fe-4ee092d6b4b1/9f0bf370619ab3da8869e467827a6dc6/aspnetcore-runtime-7.0.20-win-x86.exe', 'https://download.visualstudio.microsoft.com/download/pr/10651a65-8afc-46e3-9287-fecb0e68504e/4c2bf0cdb44612f29d9b3f901098e13e/aspnetcore-runtime-7.0.20-win-x64.exe'), '', False, False); end; end; procedure Dependency_AddDotNet70Desktop; begin // https://dotnet.microsoft.com/download/dotnet/7.0 if not Dependency_IsNetCoreInstalled('Microsoft.WindowsDesktop.App', 7, 0, 20) then begin Dependency_Add('dotnet70desktop' + Dependency_ArchSuffix + '.exe', '/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart', '.NET Desktop Runtime 7.0.20' + Dependency_ArchTitle, Dependency_String('https://download.visualstudio.microsoft.com/download/pr/b840017b-c69f-4724-a152-11020a0039e6/b74aa12e4ee765a3387a7dcd4ba56187/windowsdesktop-runtime-7.0.20-win-x86.exe', 'https://download.visualstudio.microsoft.com/download/pr/08bbfe8f-812d-479f-803b-23ea0bffce47/c320e4b037f3e92ab7ea92c3d7ea3ca1/windowsdesktop-runtime-7.0.20-win-x64.exe'), '', False, False); end; end; procedure Dependency_AddDotNet80; begin // https://dotnet.microsoft.com/download/dotnet/8.0 if not Dependency_IsNetCoreInstalled('Microsoft.NETCore.App', 8, 0, 13) then begin Dependency_Add('dotnet80' + Dependency_ArchSuffix + '.exe', '/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart', '.NET Runtime 8.0.13' + Dependency_ArchTitle, Dependency_String('https://download.visualstudio.microsoft.com/download/pr/5bac19ad-0711-4eba-a5a3-5e818c5f2fdf/cdec118c18b8457fe4d3ff918f78b4bd/dotnet-runtime-8.0.13-win-x86.exe', 'https://download.visualstudio.microsoft.com/download/pr/9c2068f2-dd3e-46cb-a88d-3c2d35b5181f/9ce26210851b0720c5382c6cd056b126/dotnet-runtime-8.0.13-win-x64.exe'), '', False, False); end; end; procedure Dependency_AddDotNet80Asp; begin // https://dotnet.microsoft.com/download/dotnet/8.0 if not Dependency_IsNetCoreInstalled('Microsoft.AspNetCore.App', 8, 0, 13) then begin Dependency_Add('dotnet80asp' + Dependency_ArchSuffix + '.exe', '/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart', 'ASP.NET Core Runtime 8.0.13' + Dependency_ArchTitle, Dependency_String('https://download.visualstudio.microsoft.com/download/pr/b11da59f-561b-466b-bfa8-d2dfc9b5bf48/f8dce6a44fd7be61ff97fe4949e57015/aspnetcore-runtime-8.0.13-win-x86.exe', 'https://download.visualstudio.microsoft.com/download/pr/86b8931f-09f6-4fce-b546-8139350da0c4/d6a5f16bcf81e0b5e9a733b892b1240f/aspnetcore-runtime-8.0.13-win-x64.exe'), '', False, False); end; end; procedure Dependency_AddDotNet80Desktop; begin // https://dotnet.microsoft.com/download/dotnet/8.0 if not Dependency_IsNetCoreInstalled('Microsoft.WindowsDesktop.App', 8, 0, 13) then begin Dependency_Add('dotnet80desktop' + Dependency_ArchSuffix + '.exe', '/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart', '.NET Desktop Runtime 8.0.13' + Dependency_ArchTitle, Dependency_String('https://download.visualstudio.microsoft.com/download/pr/b1827c52-ec83-4b3e-8d24-f321276bcdea/812e8d5871111cdc02cc82209c7d45fd/windowsdesktop-runtime-8.0.13-win-x86.exe', 'https://download.visualstudio.microsoft.com/download/pr/fc8c9dea-8180-4dad-bf1b-5f229cf47477/c3f0536639ab40f1470b6bad5e1b95b8/windowsdesktop-runtime-8.0.13-win-x64.exe'), '', False, False); end; end; procedure Dependency_AddDotNet90; begin // https://dotnet.microsoft.com/download/dotnet/9.0 if not Dependency_IsNetCoreInstalled('Microsoft.NETCore.App', 9, 0, 4) then begin Dependency_Add('dotnet90' + Dependency_ArchSuffix + '.exe', '/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart', '.NET Runtime 9.0.4' + Dependency_ArchTitle, Dependency_String('https://builds.dotnet.microsoft.com/dotnet/Runtime/9.0.4/dotnet-runtime-9.0.4-win-x86.exe', 'https://builds.dotnet.microsoft.com/dotnet/Runtime/9.0.4/dotnet-runtime-9.0.4-win-x64.exe'), '', False, False); end; end; procedure Dependency_AddDotNet90Asp; begin // https://dotnet.microsoft.com/download/dotnet/9.0 if not Dependency_IsNetCoreInstalled('Microsoft.AspNetCore.App', 9, 0, 4) then begin Dependency_Add('dotnet90asp' + Dependency_ArchSuffix + '.exe', '/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart', 'ASP.NET Core Runtime 9.0.4' + Dependency_ArchTitle, Dependency_String('https://builds.dotnet.microsoft.com/dotnet/aspnetcore/Runtime/9.0.4/aspnetcore-runtime-9.0.4-win-x86.exe', 'https://builds.dotnet.microsoft.com/dotnet/aspnetcore/Runtime/9.0.4/aspnetcore-runtime-9.0.4-win-x64.exe'), '', False, False); end; end; procedure Dependency_AddDotNet90Desktop; begin // https://dotnet.microsoft.com/download/dotnet/9.0 if not Dependency_IsNetCoreInstalled('Microsoft.WindowsDesktop.App', 9, 0, 4) then begin Dependency_Add('dotnet90desktop' + Dependency_ArchSuffix + '.exe', '/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart', '.NET Desktop Runtime 9.0.4' + Dependency_ArchTitle, Dependency_String('https://builds.dotnet.microsoft.com/dotnet/WindowsDesktop/9.0.4/windowsdesktop-runtime-9.0.4-win-x86.exe', 'https://builds.dotnet.microsoft.com/dotnet/WindowsDesktop/9.0.4/windowsdesktop-runtime-9.0.4-win-x64.exe'), '', False, False); end; end; procedure Dependency_AddVC2005; begin // https://www.microsoft.com/en-us/download/details.aspx?id=26347 if not IsMsiProductInstalled(Dependency_String('{86C9D5AA-F00C-4921-B3F2-C60AF92E2844}', '{A8D19029-8E5C-4E22-8011-48070F9E796E}'), PackVersionComponents(8, 0, 61000, 0)) then begin Dependency_Add('vcredist2005' + Dependency_ArchSuffix + '.exe', '/q', 'Visual C++ 2005 Service Pack 1 Redistributable' + Dependency_ArchTitle, Dependency_String('https://download.microsoft.com/download/8/B/4/8B42259F-5D70-43F4-AC2E-4B208FD8D66A/vcredist_x86.EXE', 'https://download.microsoft.com/download/8/B/4/8B42259F-5D70-43F4-AC2E-4B208FD8D66A/vcredist_x64.EXE'), '', False, False); end; end; procedure Dependency_AddVC2008; begin // https://www.microsoft.com/en-us/download/details.aspx?id=26368 if not IsMsiProductInstalled(Dependency_String('{DE2C306F-A067-38EF-B86C-03DE4B0312F9}', '{FDA45DDF-8E17-336F-A3ED-356B7B7C688A}'), PackVersionComponents(9, 0, 30729, 6161)) then begin Dependency_Add('vcredist2008' + Dependency_ArchSuffix + '.exe', '/q', 'Visual C++ 2008 Service Pack 1 Redistributable' + Dependency_ArchTitle, Dependency_String('https://download.microsoft.com/download/5/D/8/5D8C65CB-C849-4025-8E95-C3966CAFD8AE/vcredist_x86.exe', 'https://download.microsoft.com/download/5/D/8/5D8C65CB-C849-4025-8E95-C3966CAFD8AE/vcredist_x64.exe'), '', False, False); end; end; procedure Dependency_AddVC2010; begin // https://www.microsoft.com/en-us/download/details.aspx?id=26999 if not IsMsiProductInstalled(Dependency_String('{1F4F1D2A-D9DA-32CF-9909-48485DA06DD5}', '{5B75F761-BAC8-33BC-A381-464DDDD813A3}'), PackVersionComponents(10, 0, 40219, 0)) then begin Dependency_Add('vcredist2010' + Dependency_ArchSuffix + '.exe', '/passive /norestart', 'Visual C++ 2010 Service Pack 1 Redistributable' + Dependency_ArchTitle, Dependency_String('https://download.microsoft.com/download/1/6/5/165255E7-1014-4D0A-B094-B6A430A6BFFC/vcredist_x86.exe', 'https://download.microsoft.com/download/1/6/5/165255E7-1014-4D0A-B094-B6A430A6BFFC/vcredist_x64.exe'), '', False, False); end; end; procedure Dependency_AddVC2012; begin // https://www.microsoft.com/en-us/download/details.aspx?id=30679 if not IsMsiProductInstalled(Dependency_String('{4121ED58-4BD9-3E7B-A8B5-9F8BAAE045B7}', '{EFA6AFA1-738E-3E00-8101-FD03B86B29D1}'), PackVersionComponents(11, 0, 61030, 0)) then begin Dependency_Add('vcredist2012' + Dependency_ArchSuffix + '.exe', '/passive /norestart', 'Visual C++ 2012 Update 4 Redistributable' + Dependency_ArchTitle, Dependency_String('https://download.microsoft.com/download/1/6/B/16B06F60-3B20-4FF2-B699-5E9B7962F9AE/VSU_4/vcredist_x86.exe', 'https://download.microsoft.com/download/1/6/B/16B06F60-3B20-4FF2-B699-5E9B7962F9AE/VSU_4/vcredist_x64.exe'), '', False, False); end; end; procedure Dependency_AddVC2013; begin // https://support.microsoft.com/en-us/help/4032938 if not IsMsiProductInstalled(Dependency_String('{B59F5BF1-67C8-3802-8E59-2CE551A39FC5}', '{20400CF0-DE7C-327E-9AE4-F0F38D9085F8}'), PackVersionComponents(12, 0, 40664, 0)) then begin Dependency_Add('vcredist2013' + Dependency_ArchSuffix + '.exe', '/passive /norestart', 'Visual C++ 2013 Update 5 Redistributable' + Dependency_ArchTitle, Dependency_String('https://download.visualstudio.microsoft.com/download/pr/10912113/5da66ddebb0ad32ebd4b922fd82e8e25/vcredist_x86.exe', 'https://download.visualstudio.microsoft.com/download/pr/10912041/cee5d6bca2ddbcd039da727bf4acb48a/vcredist_x64.exe'), '', False, False); end; end; procedure Dependency_AddVC2015To2022; begin // https://docs.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist if not IsMsiProductInstalled(Dependency_String('{65E5BD06-6392-3027-8C26-853107D3CF1A}', '{36F68A90-239C-34DF-B58C-64B30153CE35}'), PackVersionComponents(14, 42, 34433, 0)) then begin Dependency_Add('vcredist2022' + Dependency_ArchSuffix + '.exe', '/passive /norestart', 'Visual C++ 2015-2022 Redistributable' + Dependency_ArchTitle, Dependency_String('https://aka.ms/vs/17/release/vc_redist.x86.exe', 'https://aka.ms/vs/17/release/vc_redist.x64.exe'), '', False, False); end; end; procedure Dependency_AddDirectX; begin #ifdef Dependency_Files_DirectX ExtractTemporaryFile('dxwebsetup.exe'); #endif // https://www.microsoft.com/en-us/download/details.aspx?id=35 Dependency_Add('dxwebsetup.exe', '/q', 'DirectX Runtime', 'https://download.microsoft.com/download/1/7/1/1718CCC4-6315-4D8E-9543-8E28A4E18C4C/dxwebsetup.exe', '', True, False); end; procedure Dependency_AddSql2008Express; var Version: String; PackedVersion: Int64; begin // https://www.microsoft.com/en-us/download/details.aspx?id=30438 if not RegQueryStringValue(HKLM, 'SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQLServer\CurrentVersion', 'CurrentVersion', Version) or not StrToVersion(Version, PackedVersion) or (ComparePackedVersion(PackedVersion, PackVersionComponents(10, 50, 4000, 0)) < 0) then begin Dependency_Add('sql2008express' + Dependency_ArchSuffix + '.exe', '/QS /IACCEPTSQLSERVERLICENSETERMS /ACTION=INSTALL /FEATURES=SQL /INSTANCENAME=MSSQLSERVER', 'SQL Server 2008 R2 Service Pack 2 Express', Dependency_String('https://download.microsoft.com/download/0/4/B/04BE03CD-EAF3-4797-9D8D-2E08E316C998/SQLEXPR32_x86_ENU.exe', 'https://download.microsoft.com/download/0/4/B/04BE03CD-EAF3-4797-9D8D-2E08E316C998/SQLEXPR_x64_ENU.exe'), '', False, False); end; end; procedure Dependency_AddSql2012Express; var Version: String; PackedVersion: Int64; begin // https://www.microsoft.com/en-us/download/details.aspx?id=56042 if not RegQueryStringValue(HKLM, 'SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQLServer\CurrentVersion', 'CurrentVersion', Version) or not StrToVersion(Version, PackedVersion) or (ComparePackedVersion(PackedVersion, PackVersionComponents(11, 0, 7001, 0)) < 0) then begin Dependency_Add('sql2012express' + Dependency_ArchSuffix + '.exe', '/QS /IACCEPTSQLSERVERLICENSETERMS /ACTION=INSTALL /FEATURES=SQL /INSTANCENAME=MSSQLSERVER', 'SQL Server 2012 Service Pack 4 Express', Dependency_String('https://download.microsoft.com/download/B/D/E/BDE8FAD6-33E5-44F6-B714-348F73E602B6/SQLEXPR32_x86_ENU.exe', 'https://download.microsoft.com/download/B/D/E/BDE8FAD6-33E5-44F6-B714-348F73E602B6/SQLEXPR_x64_ENU.exe'), '', False, False); end; end; procedure Dependency_AddSql2014Express; var Version: String; PackedVersion: Int64; begin // https://www.microsoft.com/en-us/download/details.aspx?id=57473 if not RegQueryStringValue(HKLM, 'SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQLServer\CurrentVersion', 'CurrentVersion', Version) or not StrToVersion(Version, PackedVersion) or (ComparePackedVersion(PackedVersion, PackVersionComponents(12, 0, 6024, 0)) < 0) then begin Dependency_Add('sql2014express' + Dependency_ArchSuffix + '.exe', '/QS /IACCEPTSQLSERVERLICENSETERMS /ACTION=INSTALL /FEATURES=SQL /INSTANCENAME=MSSQLSERVER', 'SQL Server 2014 Service Pack 3 Express', Dependency_String('https://download.microsoft.com/download/3/9/F/39F968FA-DEBB-4960-8F9E-0E7BB3035959/SQLEXPR32_x86_ENU.exe', 'https://download.microsoft.com/download/3/9/F/39F968FA-DEBB-4960-8F9E-0E7BB3035959/SQLEXPR_x64_ENU.exe'), '', False, False); end; end; procedure Dependency_AddSql2016Express; var Version: String; PackedVersion: Int64; begin // https://www.microsoft.com/en-us/download/details.aspx?id=103447 if not RegQueryStringValue(HKLM, 'SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQLServer\CurrentVersion', 'CurrentVersion', Version) or not StrToVersion(Version, PackedVersion) or (ComparePackedVersion(PackedVersion, PackVersionComponents(13, 0, 6404, 1)) < 0) then begin Dependency_Add('sql2016express' + Dependency_ArchSuffix + '.exe', '/QS /IACCEPTSQLSERVERLICENSETERMS /ACTION=INSTALL /FEATURES=SQL /INSTANCENAME=MSSQLSERVER', 'SQL Server 2016 Service Pack 3 Express', 'https://download.microsoft.com/download/f/a/8/fa83d147-63d1-449c-b22d-5fef9bd5bb46/SQLServer2016-SSEI-Expr.exe', '', False, False); end; end; procedure Dependency_AddSql2017Express; var Version: String; PackedVersion: Int64; begin // https://www.microsoft.com/en-us/download/details.aspx?id=55994 if not RegQueryStringValue(HKLM, 'SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL14.MSSQLSERVER\MSSQLServer\CurrentVersion', 'CurrentVersion', Version) or not StrToVersion(Version, PackedVersion) or (ComparePackedVersion(PackedVersion, PackVersionComponents(14, 0, 0, 0)) < 0) then begin Dependency_Add('sql2017express' + Dependency_ArchSuffix + '.exe', '/QS /IACCEPTSQLSERVERLICENSETERMS /ACTION=INSTALL /FEATURES=SQL /INSTANCENAME=MSSQLSERVER', 'SQL Server 2017 Express', 'https://download.microsoft.com/download/5/E/9/5E9B18CC-8FD5-467E-B5BF-BADE39C51F73/SQLServer2017-SSEI-Expr.exe', '', False, False); end; end; procedure Dependency_AddSql2019Express; var Version: String; PackedVersion: Int64; begin // https://www.microsoft.com/en-us/download/details.aspx?id=101064 if not RegQueryStringValue(HKLM, 'SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL15.MSSQLSERVER\MSSQLServer\CurrentVersion', 'CurrentVersion', Version) or not StrToVersion(Version, PackedVersion) or (ComparePackedVersion(PackedVersion, PackVersionComponents(15, 0, 0, 0)) < 0) then begin Dependency_Add('sql2019express' + Dependency_ArchSuffix + '.exe', '/QS /IACCEPTSQLSERVERLICENSETERMS /ACTION=INSTALL /FEATURES=SQL /INSTANCENAME=MSSQLSERVER', 'SQL Server 2019 Express', 'https://download.microsoft.com/download/7/f/8/7f8a9c43-8c8a-4f7c-9f92-83c18d96b681/SQL2019-SSEI-Expr.exe', '', False, False); end; end; procedure Dependency_AddSql2022Express; var Version: String; PackedVersion: Int64; begin // https://www.microsoft.com/en-us/download/details.aspx?id=104781 if not RegQueryStringValue(HKLM, 'SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL16.MSSQLSERVER\MSSQLServer\CurrentVersion', 'CurrentVersion', Version) or not StrToVersion(Version, PackedVersion) or (ComparePackedVersion(PackedVersion, PackVersionComponents(16, 0, 1000, 6)) < 0) then begin Dependency_Add('sql2022express' + Dependency_ArchSuffix + '.exe', '/QS /IACCEPTSQLSERVERLICENSETERMS /ACTION=INSTALL /FEATURES=SQL /INSTANCENAME=MSSQLSERVER', 'SQL Server 2022 Express', 'https://go.microsoft.com/fwlink/p/?linkid=2216019', '', False, False); end; end; procedure Dependency_AddWebView2; begin // https://developer.microsoft.com/en-us/microsoft-edge/webview2 if not RegValueExists(HKLM, Dependency_String('SOFTWARE', 'SOFTWARE\WOW6432Node') + '\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}', 'pv') then begin Dependency_Add('MicrosoftEdgeWebview2Setup.exe', '/silent /install', 'WebView2 Runtime', 'https://go.microsoft.com/fwlink/p/?LinkId=2124703', '', False, False); end; end; procedure Dependency_AddAccessDatabaseEngine2010; begin // https://www.microsoft.com/en-us/download/details.aspx?id=13255 if not RegKeyExists(HKLM, 'SOFTWARE\Microsoft\Office\14.0\Access Connectivity Engine\Engines\ACE') then begin Dependency_Add('AccessDatabaseEngine2010' + Dependency_ArchSuffix + '.exe', '/quiet', 'Microsoft Access Database Engine 2010' + Dependency_ArchTitle, Dependency_String('https://download.microsoft.com/download/2/4/3/24375141-E08D-4803-AB0E-10F2E3A07AAA/AccessDatabaseEngine.exe', 'https://download.microsoft.com/download/2/4/3/24375141-E08D-4803-AB0E-10F2E3A07AAA/AccessDatabaseEngine_X64.exe'), '', False, False); end; end; procedure Dependency_AddAccessDatabaseEngine2016; begin // https://www.microsoft.com/en-us/download/details.aspx?id=54920 if not RegKeyExists(HKLM, 'SOFTWARE\Microsoft\Office\16.0\Access Connectivity Engine\Engines\ACE') then begin Dependency_Add('AccessDatabaseEngine2016' + Dependency_ArchSuffix + '.exe', '/quiet', 'Microsoft Access Database Engine 2016' + Dependency_ArchTitle, Dependency_String('https://download.microsoft.com/download/3/5/C/35C84C36-661A-44E6-9324-8786B8DBE231/accessdatabaseengine.exe', 'https://download.microsoft.com/download/3/5/C/35C84C36-661A-44E6-9324-8786B8DBE231/accessdatabaseengine_X64.exe'), '', False, False); end; end; [Files] #ifdef Dependency_Path_DirectX Source: "{#Dependency_Path_DirectX}dxwebsetup.exe"; Flags: dontcopy noencryption #endif ================================================ FILE: installer/PortablePage.iss ================================================ [Setup] Uninstallable=not IsPortable() DisableProgramGroupPage=no [CustomMessages] InstallPortableTitle =Portable Installation pl.InstallPortableTitle =Instalacja przenośna de.InstallPortableTitle =Tragbar Installation fr.InstallPortableTitle =Installation Portable hu.InstallPortableTitle =Portable telepítés sl.InstallPortableTitle =Prenosna namestitev nl.InstallPortableTitle =Portabele installatie es.InstallPortableTitle =Instalación portable bpt.InstallPortableTitle =Instalação Portátil ru.InstallPortableTitle =Переносимая установка it.InstallPortableTitle =Installazione portatile vi.InstallPortableTitle =Cài đặt di động tr.InstallPortableTitle =Taşınabilir Kurulum zh_cn.InstallPortableTitle =便携式安装 hi.InstallPortableTitle=पोर्टेबल स्थापना InstallTypeChoiceTitle =Installation type pl.InstallTypeChoiceTitle =Typ instalacji de.InstallTypeChoiceTitle =Installationstyp fr.InstallTypeChoiceTitle =Type d'installation hu.InstallTypeChoiceTitle =Telepítési típus sl.InstallTypeChoiceTitle =Vrsta namestitve nl.InstallTypeChoiceTitle =Installatie type es.InstallTypeChoiceTitle =Tipo de instalación bpt.InstallTypeChoiceTitle =Tipo Instalação ru.InstallTypeChoiceTitle =Тип установки it.InstallTypeChoiceTitle =Tipo di installazione vi.InstallTypeChoiceTitle =Loại cài đặt tr.InstallTypeChoiceTitle =Kurulum tipi zh_cn.InstallTypeChoiceTitle =安装方式 hi.InstallTypeChoiceTitle=स्थापना प्रकार InstallStandardTitle =Standard Installation pl.InstallStandardTitle =Instalacja standardowa de.InstallStandardTitle =Standardinstallation fr.InstallStandardTitle =Installation Standard hu.InstallStandardTitle =Szabványos telepítés sl.InstallStandardTitle =Standardna namestitev nl.InstallStandardTitle =Standaad installatie es.InstallStandardTitle =Instalación estándar bpt.InstallStandardTitle =Instalação Padrão ru.InstallStandardTitle =Стандартная установка it.InstallStandardTitle =Installazione standard vi.InstallStandardTitle =Cài đặt chuẩn tr.InstallStandardTitle =Standart Kurulum zh_cn.InstallStandardTitle =标准安装 hi.InstallStandardTitle=मानक स्थापना InstallPortableInfo =Portable installation will not register itself in the system, it will only extract files to the specified directory. You can set the directory to anything you''d like, for example to a USB drive. You will be able to move this directory freely since the whole app is inside of it. pl.InstallPortableInfo =Instalacja przenośna nie zostanie zarejestrowana w systemie, zostaną tylko wypakowane pliki. Pliki mogą zostać wypakowane do dowolnego folderu i mogą być bez problemu przenoszone. Wszystkie pliki używane przez tą aplikację będą przechowywane w wybranym folderze. de.InstallPortableInfo =Die Portable Installation registriert sich nicht selbst im System, es werden nur Dateien in das angegebene Verzeichnis entpackt. Sie können das Verzeichnis beliebig festlegen, z.B. auf einem USB-Laufwerk. Dieses Verzeichnis können Sie frei verschieben, da darin die gesamte Anwendung ist. fr.InstallPortableInfo =L'installation Portable ne s'enregistrera pas elle-même dans le système, elle extraira seulement les fichiers dans le dossier spécifié. Vous pouvez placer le dossier sur tout ce que vous souhaitez, par exemple sur un lecteur USB. Vous pourrez déplacer librement ce dossier du moment que l'application complète se trouve à l'intérieur. hu.InstallPortableInfo =A hordozható telepítés esetén a program nem jegyzi ba magát a rendszerbe, a fájljai csak kicsomagolásra kerülnek a megadott könyvtárba. Ez a könyvtár bárhol lehet, akár egy USB meghajtón is. Ezzel a könyvtárat bárhova magával viheti, mivel az az egész alkalmazást tartalmazza. sl.InstallPortableInfo =Prenosna namestitev se ne bo prijavila v sistem, ampak bo samo izpisala datoteke v doloceni imenik. Imenik lahko nastavite na vse, kar vam je všec, na primer na pogon USB. Ta imenik boste lahko prosto premaknili, saj je celotna aplikacija znotraj nje. nl.InstallPortableInfo =Portabele installatie registreert zich zelf niet in het systeem, het pakt alleen bestanden uit in de opgegeven map. U kunt naar eigen voorkeur een map opgeven, bijvoorbeeld op een USB schijf. Het is mogelijk om deze map later te verplaatsen, omdat daarin het hele programma zit. es.InstallPortableInfo =La instalación portable no se registrará en el sistema, sólo extrae los archivos al directorio especificado. Puede colocarlo en cualquier sitio, por ejemplo en una unidad USB. Podrá moverlo libremente ya que la aplicación está dentro del directorio. bpt.InstallPortableInfo =A instalação portátil não se registrará no sistema, ela só extrairá arquivos para o diretório especificado. Você pode configurar o diretório para qualquer coisa que você gostaria, por exemplo, para uma unidade USB. Você poderá mover este diretório livremente, já que todo o aplicativo está dentro dele. ru.InstallPortableInfo =Переносимая установка не регистрируется в системе, она только извлекает файлы в указанный каталог. Вы можете выбрать любой каталог, например, на USB-накопителе. Вы сможете свободно перемещать этот каталог, поскольку все приложение находится внутри него. it.InstallPortableInfo =L'installazione portatile non si registrerà nel sistema, estrarrà solo i file nella cartella specificata. Puoi impostare la cartella in qualsiasi percorso, ad esempio in un'unità USB. Sarai in grado di spostare questa cartella liberamente poiché l'intera app è al suo interno. tr.InstallPortableInfo =Taşınabilir kurulumda dosyaları sisteme kaydetmez, sadece dosyaları belirtilen dizine çıkarır. Yazılımı istediğiniz herhangi bir yer yapabilirsiniz, örneğin bir USB sürücüsüne ayarlayabilirsiniz. Tüm yazılım, tek bir dosyanın içinde olduğu için bu yazılımı serbestçe taşıyabileceksiniz. zh_cn.InstallPortableInfo =便携式安装不会在系统中注册,只会将文件解压缩到指定目录。您可以将目录设置为任何您想要的位置,例如 USB 驱动器。您可以自由移动该目录,因为整个程序都在其中。 hi.InstallPortableInfo=पोर्टेबल स्थापना अपने आप सिस्टम में रजिस्टर नहीं होगी, बल्कि केवल निर्दिष्ट निर्देशिका में फाइलें एक्सट्रैक्ट करेगी। आप इस निर्देशिका को किसी भी स्थान पर सेट कर सकते हैं, उदाहरण के लिए USB ड्राइव पर। चूंकि सम्पूर्ण ऐप उसी निर्देशिका में है, आप इसे स्वतंत्र रूप से स्थानांतरित कर सकेंगे। InstallStandardInfo =This option will install BCUninstaller on your computer as a normal application. Standard uninstaller will be created and it will be visible under "Programs and Features" as well as in other third-party uninstallers. pl.InstallStandardInfo =Ta aplikacja zostanie zainstalowana i zarejestrowana w tym systemie. Zostanie stworzony deinstalator i będzie on widoczny w panelu sterowania i innych deinstalatorach. de.InstallStandardInfo =Diese Option installiert BCUninstaller auf Ihrem Computer als normale Anwendung. Ein normales Deinstallationsprogramm wird erstellt, und der Eintrag wird unter "Programme und Features" ebenso wie in anderen Drittanbieter-Uninstallern angezeigt. fr.InstallStandardInfo =Cette option installera BCUninstaller sur votre ordinateur comme une application normale. Un désinstalleur standard sera créé et sera visible sous "Programmes et Fonctionnalités" aussi bien que pour tout autre désinstalleur tiers. hu.InstallStandardInfo =Ezzel a lehetõséggel úgy kerül telepítésre a BCUninstaller, mint egy normál alkalmazás. A szabványos eltávolítója megtalálható lesz a "Programok és szolgáltatások" ablakban, valamint az egyéb eltávolítókban. sl.InstallStandardInfo =Ta možnost bo BCUninstaller namestila v racunalnik kot obicajno aplikacijo. Ustvarjen bo standardni odstranjevalec, ki bo viden v razdelku "Programi in funkcije", kot tudi v drugih odstranjevalcih tretjih avtorjev. nl.InstallStandardInfo =Deze optie installeert BCUnistaller op uw computer als een normaal programma. Er wordt een standaard uninstaller gecreëerd en deze wordt zichtbaar onder "Programma's en Features" net zoals in andere derde-partij uninstallers. es.InstallStandardInfo =Esta opción instalará BCUninstaller en su equipo como una aplicación normal. Se creará un desinstalador estándar y estará visible en "Programas y características", así como otros desinstaladores de terceros. bpt.InstallStandardInfo =Esta opção irá instalar o BCUninstaller em seu computador como um aplicativo normal. O desinstalador padrão será criado e estará visível em "Programas e recursos", bem como em outros desinstaladores de terceiros. ru.InstallStandardInfo =Эта опция установит BCUninstaller на ваш компьютер как обычное приложение. Будет создана стандартная программа удаления, которая будет видна в разделе «Программы и компоненты», а также в других сторонних программах удаления. it.InstallStandardInfo =Questa opzione abiliterà l'installazione di BCUninstaller nel computer come una normale applicazione. Verrà creato il programma di disinstallazione standard e sarà visibile in "Programmi e funzionalità" così come in altri programmi di disinstallazione di terze parti. tr.InstallStandardInfo =Bu seçenek BCUninstaller'ı bilgisayarınıza normal bir yazılım olarak yükleyecektir. Standart kaldırıcı oluşturulacak ve diğer üçüncü taraf kaldırıcıların yanı sıra “Program ekle ve kaldır” altında da görülebilecektir. zh_cn.InstallStandardInfo =此选项会将 BCUninstaller 作为普通应用程序安装到电脑上。标准卸载程序将被创建,并在 “程序和功能 ”以及其他第三方卸载程序中可见。 hi.InstallStandardInfo=यह विकल्प BCUninstaller को आपके कंप्यूटर पर सामान्य ऐप्लिकेशन के रूप में इंस्टॉल करेगा। एक मानक अनइंस्टॉलर बनाया जाएगा और यह 'प्रोग्राम्स और फीचर्स' के अंतर्गत तथा अन्य थर्ड-पार्टी अनइंस्टॉलर में दिखाई देगा. [Code] var CustomPage: TWizardPage; StandardDescLabel: TLabel; {*StandardRadioButton: TNewRadioButton; AdvancedRadioButton: TNewRadioButton; *} AdvancedDescLabel: TLabel; StandardRadioButton: TNewRadioButton; AdvancedRadioButton: TNewRadioButton; function IsPortable(): Boolean; begin if(StandardRadioButton.Checked = True) then Result := False else Result := True; end; function IsNotPortable(): Boolean; begin if(StandardRadioButton.Checked = True) then Result := True else Result := False; end; procedure InitializeWizard; begin CustomPage := CreateCustomPage(wpWelcome, CustomMessage('InstallTypeChoiceTitle'), ''); StandardRadioButton := TNewRadioButton.Create(WizardForm); StandardRadioButton.Parent := CustomPage.Surface; StandardRadioButton.Checked := True; StandardRadioButton.Top := 16; StandardRadioButton.Width := CustomPage.SurfaceWidth; StandardRadioButton.Font.Style := [fsBold]; StandardRadioButton.Font.Size := 9; StandardRadioButton.Caption := CustomMessage('InstallStandardTitle'); StandardDescLabel := TLabel.Create(WizardForm); StandardDescLabel.Parent := CustomPage.Surface; StandardDescLabel.Left := 8; StandardDescLabel.Top := StandardRadioButton.Top + StandardRadioButton.Height + 8; StandardDescLabel.Width := CustomPage.SurfaceWidth - 10; StandardDescLabel.Height := 60; StandardDescLabel.AutoSize := False; StandardDescLabel.Wordwrap := True; StandardDescLabel.Caption := CustomMessage('InstallStandardInfo'); AdvancedRadioButton := TNewRadioButton.Create(WizardForm); AdvancedRadioButton.Parent := CustomPage.Surface; AdvancedRadioButton.Top := StandardDescLabel.Top + StandardDescLabel.Height + 16; AdvancedRadioButton.Width := CustomPage.SurfaceWidth; AdvancedRadioButton.Font.Style := [fsBold]; AdvancedRadioButton.Font.Size := 9; AdvancedRadioButton.Caption := CustomMessage('InstallPortableTitle'); AdvancedDescLabel := TLabel.Create(WizardForm); AdvancedDescLabel.Parent := CustomPage.Surface; AdvancedDescLabel.Left := 8; AdvancedDescLabel.Top := AdvancedRadioButton.Top + AdvancedRadioButton.Height + 8; AdvancedDescLabel.Width := CustomPage.SurfaceWidth - 10; AdvancedDescLabel.Height := 60; AdvancedDescLabel.AutoSize := False; AdvancedDescLabel.Wordwrap := True; AdvancedDescLabel.Caption := CustomMessage('InstallPortableInfo'); end; function ShouldSkipPage(PageID: Integer): Boolean; begin // initialize result to not skip any page (not necessary, but safer) Result := False; if PageID = wpSelectProgramGroup then Result := IsPortable(); end; procedure CurPageChanged(CurPageID: Integer); begin // Change the default install path if user selected portable install if CurPageID = wpLicense then begin if(AdvancedRadioButton.Checked = True) then WizardForm.DirEdit.Text := ExpandConstant('{sd}\{#MyAppName}'); end; end; ================================================ FILE: installer/lang/ChineseSimplified.isl ================================================ ; *** Inno Setup version 6.4.0+ Chinese Simplified messages *** ; ; To download user-contributed translations of this file, go to: ; https://jrsoftware.org/files/istrans/ ; ; Note: When translating this text, do not add periods (.) to the end of ; messages that didn't have them already, because on those messages Inno ; Setup adds the periods automatically (appending a period would result in ; two periods being displayed). ; ; Maintained by Zhenghan Yang ; Email: 847320916@QQ.com ; Translation based on network resource ; The latest Translation is on https://github.com/kira-96/Inno-Setup-Chinese-Simplified-Translation ; [LangOptions] ; The following three entries are very important. Be sure to read and ; understand the '[LangOptions] section' topic in the help file. LanguageName=简体中文 ; If Language Name display incorrect, uncomment next line ; LanguageName=<7B80><4F53><4E2D><6587> ; About LanguageID, to reference link: ; https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-lcid/a9eac961-e77d-41a6-90a5-ce1a8b0cdb9c LanguageID=$0804 ; About CodePage, to reference link: ; https://docs.microsoft.com/en-us/windows/win32/intl/code-page-identifiers LanguageCodePage=936 ; If the language you are translating to requires special font faces or ; sizes, uncomment any of the following entries and change them accordingly. ;DialogFontName= ;DialogFontSize=8 ;WelcomeFontName=Verdana ;WelcomeFontSize=12 ;TitleFontName=Arial ;TitleFontSize=29 ;CopyrightFontName=Arial ;CopyrightFontSize=8 [Messages] ; *** 应用程序标题 SetupAppTitle=安装 SetupWindowTitle=安装 - %1 UninstallAppTitle=卸载 UninstallAppFullTitle=%1 卸载 ; *** Misc. common InformationTitle=信息 ConfirmTitle=确认 ErrorTitle=错误 ; *** SetupLdr messages SetupLdrStartupMessage=现在将安装 %1。您想要继续吗? LdrCannotCreateTemp=无法创建临时文件。安装程序已中止 LdrCannotExecTemp=无法执行临时目录中的文件。安装程序已中止 HelpTextNote= ; *** 启动错误消息 LastErrorMessage=%1。%n%n错误 %2: %3 SetupFileMissing=安装目录中缺少文件 %1。请修正这个问题或者获取程序的新副本。 SetupFileCorrupt=安装文件已损坏。请获取程序的新副本。 SetupFileCorruptOrWrongVer=安装文件已损坏,或是与这个安装程序的版本不兼容。请修正这个问题或获取新的程序副本。 InvalidParameter=无效的命令行参数:%n%n%1 SetupAlreadyRunning=安装程序正在运行。 WindowsVersionNotSupported=此程序不支持当前计算机运行的 Windows 版本。 WindowsServicePackRequired=此程序需要 %1 服务包 %2 或更高版本。 NotOnThisPlatform=此程序不能在 %1 上运行。 OnlyOnThisPlatform=此程序只能在 %1 上运行。 OnlyOnTheseArchitectures=此程序只能安装到为下列处理器架构设计的 Windows 版本中:%n%n%1 WinVersionTooLowError=此程序需要 %1 版本 %2 或更高。 WinVersionTooHighError=此程序不能安装于 %1 版本 %2 或更高。 AdminPrivilegesRequired=在安装此程序时您必须以管理员身份登录。 PowerUserPrivilegesRequired=在安装此程序时您必须以管理员身份或有权限的用户组身份登录。 SetupAppRunningError=安装程序发现 %1 当前正在运行。%n%n请先关闭正在运行的程序,然后点击“确定”继续,或点击“取消”退出。 UninstallAppRunningError=卸载程序发现 %1 当前正在运行。%n%n请先关闭正在运行的程序,然后点击“确定”继续,或点击“取消”退出。 ; *** 启动问题 PrivilegesRequiredOverrideTitle=选择安装程序模式 PrivilegesRequiredOverrideInstruction=选择安装模式 PrivilegesRequiredOverrideText1=%1 可以为所有用户安装(需要管理员权限),或仅为您安装。 PrivilegesRequiredOverrideText2=%1 只能为您安装,或为所有用户安装(需要管理员权限)。 PrivilegesRequiredOverrideAllUsers=为所有用户安装(&A) PrivilegesRequiredOverrideAllUsersRecommended=为所有用户安装(&A) (建议选项) PrivilegesRequiredOverrideCurrentUser=只为我安装(&M) PrivilegesRequiredOverrideCurrentUserRecommended=只为我安装(&M) (建议选项) ; *** 其他错误 ErrorCreatingDir=安装程序无法创建目录“%1” ErrorTooManyFilesInDir=无法在目录“%1”中创建文件,因为里面包含太多文件 ; *** 安装程序公共消息 ExitSetupTitle=退出安装程序 ExitSetupMessage=安装程序尚未完成。如果现在退出,将不会安装该程序。%n%n您之后可以再次运行安装程序完成安装。%n%n现在退出安装程序吗? AboutSetupMenuItem=关于安装程序(&A)... AboutSetupTitle=关于安装程序 AboutSetupMessage=%1 版本 %2%n%3%n%n%1 主页:%n%4 AboutSetupNote= TranslatorNote=简体中文翻译由Kira(847320916@qq.com)维护。项目地址:https://github.com/kira-96/Inno-Setup-Chinese-Simplified-Translation ; *** 按钮 ButtonBack=< 上一步(&B) ButtonNext=下一步(&N) > ButtonInstall=安装(&I) ButtonOK=确定 ButtonCancel=取消 ButtonYes=是(&Y) ButtonYesToAll=全是(&A) ButtonNo=否(&N) ButtonNoToAll=全否(&O) ButtonFinish=完成(&F) ButtonBrowse=浏览(&B)... ButtonWizardBrowse=浏览(&R)... ButtonNewFolder=新建文件夹(&M) ; *** “选择语言”对话框消息 SelectLanguageTitle=选择安装语言 SelectLanguageLabel=选择安装时使用的语言。 ; *** 公共向导文字 ClickNext=点击“下一步”继续,或点击“取消”退出安装程序。 BeveledLabel= BrowseDialogTitle=浏览文件夹 BrowseDialogLabel=在下面的列表中选择一个文件夹,然后点击“确定”。 NewFolderName=新建文件夹 ; *** “欢迎”向导页 WelcomeLabel1=欢迎使用 [name] 安装向导 WelcomeLabel2=现在将安装 [name/ver] 到您的电脑中。%n%n建议您在继续安装前关闭所有其他应用程序。 ; *** “密码”向导页 WizardPassword=密码 PasswordLabel1=这个安装程序有密码保护。 PasswordLabel3=请输入密码,然后点击“下一步”继续。密码区分大小写。 PasswordEditLabel=密码(&P): IncorrectPassword=您输入的密码不正确,请重新输入。 ; *** “许可协议”向导页 WizardLicense=许可协议 LicenseLabel=请在继续安装前阅读以下重要信息。 LicenseLabel3=请仔细阅读下列许可协议。在继续安装前您必须同意这些协议条款。 LicenseAccepted=我同意此协议(&A) LicenseNotAccepted=我不同意此协议(&D) ; *** “信息”向导页 WizardInfoBefore=信息 InfoBeforeLabel=请在继续安装前阅读以下重要信息。 InfoBeforeClickLabel=准备好继续安装后,点击“下一步”。 WizardInfoAfter=信息 InfoAfterLabel=请在继续安装前阅读以下重要信息。 InfoAfterClickLabel=准备好继续安装后,点击“下一步”。 ; *** “用户信息”向导页 WizardUserInfo=用户信息 UserInfoDesc=请输入您的信息。 UserInfoName=用户名(&U): UserInfoOrg=组织(&O): UserInfoSerial=序列号(&S): UserInfoNameRequired=您必须输入用户名。 ; *** “选择目标目录”向导页 WizardSelectDir=选择目标位置 SelectDirDesc=您想将 [name] 安装在哪里? SelectDirLabel3=安装程序将安装 [name] 到下面的文件夹中。 SelectDirBrowseLabel=点击“下一步”继续。如果您想选择其他文件夹,点击“浏览”。 DiskSpaceGBLabel=至少需要有 [gb] GB 的可用磁盘空间。 DiskSpaceMBLabel=至少需要有 [mb] MB 的可用磁盘空间。 CannotInstallToNetworkDrive=安装程序无法安装到一个网络驱动器。 CannotInstallToUNCPath=安装程序无法安装到一个 UNC 路径。 InvalidPath=您必须输入一个带驱动器卷标的完整路径,例如:%n%nC:\APP%n%n或UNC路径:%n%n\\server\share InvalidDrive=您选定的驱动器或 UNC 共享不存在或不能访问。请选择其他位置。 DiskSpaceWarningTitle=磁盘空间不足 DiskSpaceWarning=安装程序至少需要 %1 KB 的可用空间才能安装,但选定驱动器只有 %2 KB 的可用空间。%n%n您一定要继续吗? DirNameTooLong=文件夹名称或路径太长。 InvalidDirName=文件夹名称无效。 BadDirName32=文件夹名称不能包含下列任何字符:%n%n%1 DirExistsTitle=文件夹已存在 DirExists=文件夹:%n%n%1%n%n已经存在。您一定要安装到这个文件夹中吗? DirDoesntExistTitle=文件夹不存在 DirDoesntExist=文件夹:%n%n%1%n%n不存在。您想要创建此文件夹吗? ; *** “选择组件”向导页 WizardSelectComponents=选择组件 SelectComponentsDesc=您想安装哪些程序组件? SelectComponentsLabel2=选中您想安装的组件;取消您不想安装的组件。然后点击“下一步”继续。 FullInstallation=完全安装 ; if possible don't translate 'Compact' as 'Minimal' (I mean 'Minimal' in your language) CompactInstallation=简洁安装 CustomInstallation=自定义安装 NoUninstallWarningTitle=组件已存在 NoUninstallWarning=安装程序检测到下列组件已安装在您的电脑中:%n%n%1%n%n取消选中这些组件不会卸载它们。%n%n确定要继续吗? ComponentSize1=%1 KB ComponentSize2=%1 MB ComponentsDiskSpaceGBLabel=当前选择的组件需要至少 [gb] GB 的磁盘空间。 ComponentsDiskSpaceMBLabel=当前选择的组件需要至少 [mb] MB 的磁盘空间。 ; *** “选择附加任务”向导页 WizardSelectTasks=选择附加任务 SelectTasksDesc=您想要安装程序执行哪些附加任务? SelectTasksLabel2=选择您想要安装程序在安装 [name] 时执行的附加任务,然后点击“下一步”。 ; *** “选择开始菜单文件夹”向导页 WizardSelectProgramGroup=选择开始菜单文件夹 SelectStartMenuFolderDesc=安装程序应该在哪里放置程序的快捷方式? SelectStartMenuFolderLabel3=安装程序将在下列“开始”菜单文件夹中创建程序的快捷方式。 SelectStartMenuFolderBrowseLabel=点击“下一步”继续。如果您想选择其他文件夹,点击“浏览”。 MustEnterGroupName=您必须输入一个文件夹名。 GroupNameTooLong=文件夹名或路径太长。 InvalidGroupName=无效的文件夹名字。 BadGroupName=文件夹名不能包含下列任何字符:%n%n%1 NoProgramGroupCheck2=不创建开始菜单文件夹(&D) ; *** “准备安装”向导页 WizardReady=准备安装 ReadyLabel1=安装程序准备就绪,现在可以开始安装 [name] 到您的电脑。 ReadyLabel2a=点击“安装”继续此安装程序。如果您想重新考虑或修改任何设置,点击“上一步”。 ReadyLabel2b=点击“安装”继续此安装程序。 ReadyMemoUserInfo=用户信息: ReadyMemoDir=目标位置: ReadyMemoType=安装类型: ReadyMemoComponents=已选择组件: ReadyMemoGroup=开始菜单文件夹: ReadyMemoTasks=附加任务: ; *** TExtractionWizardPage wizard page and Extract7ZipArchive ExtractionLabel=正在提取附加文件... ButtonStopExtraction=停止提取(&S) StopExtraction=您确定要停止提取吗? ErrorExtractionAborted=提取已中止 ErrorExtractionFailed=提取失败:%1 ; *** TDownloadWizardPage wizard page and DownloadTemporaryFile DownloadingLabel=正在下载附加文件... ButtonStopDownload=停止下载(&S) StopDownload=您确定要停止下载吗? ErrorDownloadAborted=下载已中止 ErrorDownloadFailed=下载失败:%1 %2 ErrorDownloadSizeFailed=获取下载大小失败:%1 %2 ErrorFileHash1=校验文件哈希失败:%1 ErrorFileHash2=无效的文件哈希:预期 %1,实际 %2 ErrorProgress=无效的进度:%1 / %2 ErrorFileSize=文件大小错误:预期 %1,实际 %2 ; *** “正在准备安装”向导页 WizardPreparing=正在准备安装 PreparingDesc=安装程序正在准备安装 [name] 到您的电脑。 PreviousInstallNotCompleted=先前的程序安装或卸载未完成,您需要重启您的电脑以完成。%n%n在重启电脑后,再次运行安装程序以完成 [name] 的安装。 CannotContinue=安装程序不能继续。请点击“取消”退出。 ApplicationsFound=以下应用程序正在使用将由安装程序更新的文件。建议您允许安装程序自动关闭这些应用程序。 ApplicationsFound2=以下应用程序正在使用将由安装程序更新的文件。建议您允许安装程序自动关闭这些应用程序。安装完成后,安装程序将尝试重新启动这些应用程序。 CloseApplications=自动关闭应用程序(&A) DontCloseApplications=不要关闭应用程序(&D) ErrorCloseApplications=安装程序无法自动关闭所有应用程序。建议您在继续之前,关闭所有在使用需要由安装程序更新的文件的应用程序。 PrepareToInstallNeedsRestart=安装程序必须重启您的计算机。计算机重启后,请再次运行安装程序以完成 [name] 的安装。%n%n是否立即重新启动? ; *** “正在安装”向导页 WizardInstalling=正在安装 InstallingLabel=安装程序正在安装 [name] 到您的电脑,请稍候。 ; *** “安装完成”向导页 FinishedHeadingLabel=[name] 安装完成 FinishedLabelNoIcons=安装程序已在您的电脑中安装了 [name]。 FinishedLabel=安装程序已在您的电脑中安装了 [name]。您可以通过已安装的快捷方式运行此应用程序。 ClickFinish=点击“完成”退出安装程序。 FinishedRestartLabel=为完成 [name] 的安装,安装程序必须重新启动您的电脑。要立即重启吗? FinishedRestartMessage=为完成 [name] 的安装,安装程序必须重新启动您的电脑。%n%n要立即重启吗? ShowReadmeCheck=是,我想查阅自述文件 YesRadio=是,立即重启电脑(&Y) NoRadio=否,稍后重启电脑(&N) ; used for example as 'Run MyProg.exe' RunEntryExec=运行 %1 ; used for example as 'View Readme.txt' RunEntryShellExec=查阅 %1 ; *** “安装程序需要下一张磁盘”提示 ChangeDiskTitle=安装程序需要下一张磁盘 SelectDiskLabel2=请插入磁盘 %1 并点击“确定”。%n%n如果这个磁盘中的文件可以在下列文件夹之外的文件夹中找到,请输入正确的路径或点击“浏览”。 PathLabel=路径(&P): FileNotInDir2=“%2”中找不到文件“%1”。请插入正确的磁盘或选择其他文件夹。 SelectDirectoryLabel=请指定下一张磁盘的位置。 ; *** 安装状态消息 SetupAborted=安装程序未完成安装。%n%n请修正这个问题并重新运行安装程序。 AbortRetryIgnoreSelectAction=选择操作 AbortRetryIgnoreRetry=重试(&T) AbortRetryIgnoreIgnore=忽略错误并继续(&I) AbortRetryIgnoreCancel=关闭安装程序 ; *** 安装状态消息 StatusClosingApplications=正在关闭应用程序... StatusCreateDirs=正在创建目录... StatusExtractFiles=正在解压缩文件... StatusCreateIcons=正在创建快捷方式... StatusCreateIniEntries=正在创建 INI 条目... StatusCreateRegistryEntries=正在创建注册表条目... StatusRegisterFiles=正在注册文件... StatusSavingUninstall=正在保存卸载信息... StatusRunProgram=正在完成安装... StatusRestartingApplications=正在重启应用程序... StatusRollback=正在撤销更改... ; *** 其他错误 ErrorInternal2=内部错误:%1 ErrorFunctionFailedNoCode=%1 失败 ErrorFunctionFailed=%1 失败;错误代码 %2 ErrorFunctionFailedWithMessage=%1 失败;错误代码 %2.%n%3 ErrorExecutingProgram=无法执行文件:%n%1 ; *** 注册表错误 ErrorRegOpenKey=打开注册表项时出错:%n%1\%2 ErrorRegCreateKey=创建注册表项时出错:%n%1\%2 ErrorRegWriteKey=写入注册表项时出错:%n%1\%2 ; *** INI 错误 ErrorIniEntry=在文件“%1”中创建 INI 条目时出错。 ; *** 文件复制错误 FileAbortRetryIgnoreSkipNotRecommended=跳过此文件(&S) (不推荐) FileAbortRetryIgnoreIgnoreNotRecommended=忽略错误并继续(&I) (不推荐) SourceIsCorrupted=源文件已损坏 SourceDoesntExist=源文件“%1”不存在 ExistingFileReadOnly2=无法替换现有文件,它是只读的。 ExistingFileReadOnlyRetry=移除只读属性并重试(&R) ExistingFileReadOnlyKeepExisting=保留现有文件(&K) ErrorReadingExistingDest=尝试读取现有文件时出错: FileExistsSelectAction=选择操作 FileExists2=文件已经存在。 FileExistsOverwriteExisting=覆盖已存在的文件(&O) FileExistsKeepExisting=保留现有的文件(&K) FileExistsOverwriteOrKeepAll=为所有冲突文件执行此操作(&D) ExistingFileNewerSelectAction=选择操作 ExistingFileNewer2=现有的文件比安装程序将要安装的文件还要新。 ExistingFileNewerOverwriteExisting=覆盖已存在的文件(&O) ExistingFileNewerKeepExisting=保留现有的文件(&K) (推荐) ExistingFileNewerOverwriteOrKeepAll=为所有冲突文件执行此操作(&D) ErrorChangingAttr=尝试更改下列现有文件的属性时出错: ErrorCreatingTemp=尝试在目标目录创建文件时出错: ErrorReadingSource=尝试读取下列源文件时出错: ErrorCopying=尝试复制下列文件时出错: ErrorReplacingExistingFile=尝试替换现有文件时出错: ErrorRestartReplace=重启并替换失败: ErrorRenamingTemp=尝试重命名下列目标目录中的一个文件时出错: ErrorRegisterServer=无法注册 DLL/OCX:%1 ErrorRegSvr32Failed=RegSvr32 失败;退出代码 %1 ErrorRegisterTypeLib=无法注册类库:%1 ; *** 卸载显示名字标记 ; used for example as 'My Program (32-bit)' UninstallDisplayNameMark=%1 (%2) ; used for example as 'My Program (32-bit, All users)' UninstallDisplayNameMarks=%1 (%2, %3) UninstallDisplayNameMark32Bit=32 位 UninstallDisplayNameMark64Bit=64 位 UninstallDisplayNameMarkAllUsers=所有用户 UninstallDisplayNameMarkCurrentUser=当前用户 ; *** 安装后错误 ErrorOpeningReadme=尝试打开自述文件时出错。 ErrorRestartingComputer=安装程序无法重启电脑,请手动重启。 ; *** 卸载消息 UninstallNotFound=文件“%1”不存在。无法卸载。 UninstallOpenError=文件“%1”不能被打开。无法卸载。 UninstallUnsupportedVer=此版本的卸载程序无法识别卸载日志文件“%1”的格式。无法卸载 UninstallUnknownEntry=卸载日志中遇到一个未知条目 (%1) ConfirmUninstall=您确认要完全移除 %1 及其所有组件吗? UninstallOnlyOnWin64=仅允许在 64 位 Windows 中卸载此程序。 OnlyAdminCanUninstall=仅使用管理员权限的用户能完成此卸载。 UninstallStatusLabel=正在从您的电脑中移除 %1,请稍候。 UninstalledAll=已顺利从您的电脑中移除 %1。 UninstalledMost=%1 卸载完成。%n%n有部分内容未能被删除,但您可以手动删除它们。 UninstalledAndNeedsRestart=为完成 %1 的卸载,需要重启您的电脑。%n%n立即重启电脑吗? UninstallDataCorrupted=文件“%1”已损坏。无法卸载 ; *** 卸载状态消息 ConfirmDeleteSharedFileTitle=删除共享的文件吗? ConfirmDeleteSharedFile2=系统表示下列共享的文件已不有其他程序使用。您希望卸载程序删除这些共享的文件吗?%n%n如果删除这些文件,但仍有程序在使用这些文件,则这些程序可能出现异常。如果您不能确定,请选择“否”,在系统中保留这些文件以免引发问题。 SharedFileNameLabel=文件名: SharedFileLocationLabel=位置: WizardUninstalling=卸载状态 StatusUninstalling=正在卸载 %1... ; *** Shutdown block reasons ShutdownBlockReasonInstallingApp=正在安装 %1。 ShutdownBlockReasonUninstallingApp=正在卸载 %1。 ; The custom messages below aren't used by Setup itself, but if you make ; use of them in your scripts, you'll want to translate them. [CustomMessages] NameAndVersion=%1 版本 %2 AdditionalIcons=附加快捷方式: CreateDesktopIcon=创建桌面快捷方式(&D) CreateQuickLaunchIcon=创建快速启动栏快捷方式(&Q) ProgramOnTheWeb=%1 网站 UninstallProgram=卸载 %1 LaunchProgram=运行 %1 AssocFileExtension=将 %2 文件扩展名与 %1 建立关联(&A) AssocingFileExtension=正在将 %2 文件扩展名与 %1 建立关联... AutoStartProgramGroupDescription=启动: AutoStartProgram=自动启动 %1 AddonHostProgramNotFound=您选择的文件夹中无法找到 %1。%n%n您要继续吗? ================================================ FILE: installer/lang/Hindi.isl ================================================ ; *** Inno Setup version 5.5.3+ Hindi messages *** ; ; To download user-contributed translations of this file, go to: ; http://www.jrsoftware.org/files/istrans/ ; ; Note: When translating this text, do not add periods (.) to the end of ; messages that didn't have them already, because on those messages Inno ; Setup adds the periods automatically (appending a period would result in ; two periods being displayed). [LangOptions] ; निम्नलिखित तीन प्रविष्टियाँ बहुत महत्वपूर्ण हैं। कृपया सहायता फ़ाइल में ; '[LangOptions] अनुभाग' विषय को पढ़ें और समझें। LanguageName=Hindi (हिंदी) LanguageID=$0439 LanguageCodePage=0 ; यदि जिस भाषा में अनुवाद कर रहे हैं, उसके लिए विशेष फॉन्ट फेस या ; आकार की आवश्यकता है, तो निम्न में से किसी भी प्रविष्टि को अनकॉमेंट करें और उन्हें अनुकूलित करें। ;DialogFontName= ;DialogFontSize=8 ;WelcomeFontName=Verdana ;WelcomeFontSize=12 ;TitleFontName=Arial ;TitleFontSize=29 ;CopyrightFontName=Arial ;CopyrightFontSize=8 [Messages] ; *** Application titles SetupAppTitle=स्थापना SetupWindowTitle=स्थापना - %1 UninstallAppTitle=अनइंस्टॉल UninstallAppFullTitle=अनइंस्टॉल %1 ; *** Misc. common InformationTitle=सूचना ConfirmTitle=पुष्टि ErrorTitle=त्रुटि ; *** SetupLdr messages SetupLdrStartupMessage=यह प्रोग्राम %1 की स्थापना करेगा। क्या आप जारी रखना चाहते हैं? LdrCannotCreateTemp=अस्थायी फ़ाइल बनाने में असमर्थ। स्थापना रद्द कर दी गई। LdrCannotExecTemp=अस्थायी फ़ोल्डर में फ़ाइल चलाने में असमर्थ। स्थापना रद्द कर दी गई। ; *** Startup error messages LastErrorMessage=%1.%n%nत्रुटि %2: %3 SetupFileMissing=फ़ाइल %1 स्थापना फ़ोल्डर में नहीं मिली। कृपया समस्या ठीक करें या प्रोग्राम का कोई अन्य संस्करण खोजें. SetupFileCorrupt=स्थापना फ़ाइल भ्रष्ट है। कृपया प्रोग्राम का कोई अन्य संस्करण खोजें. SetupFileCorruptOrWrongVer=स्थापना फ़ाइल भ्रष्ट है, या इस संस्करण के साथ संगत नहीं है। कृपया समस्या ठीक करें या प्रोग्राम का कोई अन्य संस्करण खोजें. InvalidParameter=एक अमान्य पॉइंटर कमांड लाइन पर पारित किया गया:%n%n%1 SetupAlreadyRunning=स्थापना पहले से चल रही है. WindowsVersionNotSupported=यह प्रोग्राम आपके वर्तमान Windows संस्करण का समर्थन नहीं करता. WindowsServicePackRequired=यह प्रोग्राम %1 सेवा पैक %2 या उससे उच्चतर की आवश्यकता है. NotOnThisPlatform=यह प्रोग्राम %1 पर नहीं चलेगा. OnlyOnThisPlatform=यह प्रोग्राम केवल %1 पर चलना चाहिए. OnlyOnTheseArchitectures=यह प्रोग्राम केवल उन Windows संस्करणों पर स्थापित किया जा सकता है जो निम्नलिखित प्रोसेसर आर्किटेक्चर के लिए डिज़ाइन किए गए हैं:%n%n%1 MissingWOW64APIs=आपके Windows संस्करण में आवश्यक WOW64 APIs शामिल नहीं हैं ताकि 64-बिट प्रोग्राम की स्थापना की जा सके। इस समस्या को ठीक करने के लिए, कृपया %1 सेवा पैक स्थापित करें. WinVersionTooLowError=यह प्रोग्राम %1, संस्करण %2 या उससे उच्चतर की आवश्यकता करता है. WinVersionTooHighError=यह प्रोग्राम %1, संस्करण %2 या उससे उच्चतर पर स्थापित नहीं किया जा सकता. AdminPrivilegesRequired=इस प्रोग्राम को स्थापित करने के लिए आपको व्यवस्थापक होना आवश्यक है. PowerUserPrivilegesRequired=इस प्रोग्राम को स्थापित करने के लिए आपको व्यवस्थापक या शक्तिशाली उपयोगकर्ता समूह का सदस्य होना आवश्यक है. SetupAppRunningError=स्थापना विंडो बाधित है क्योंकि %1 चल रहा है.%n%nकृपया इन्हें बंद करें, फिर OK पर क्लिक करें जारी रखने के लिए, या रद्द करने के लिए Cancel पर क्लिक करें. UninstallAppRunningError=अनइंस्टॉल विंडो बाधित है क्योंकि %1 चल रहा है.%n%nकृपया इन्हें बंद करें, फिर OK पर क्लिक करें जारी रखने के लिए, या रद्द करने के लिए Cancel पर क्लिक करें. ; *** Misc. errors ErrorCreatingDir=फ़ोल्डर "%1" नहीं बनाया जा सका. ErrorTooManyFilesInDir=फ़ोल्डर "%1" में बहुत अधिक फ़ाइलें होने के कारण फ़ाइल नहीं बनाई जा सकती. ; *** Setup common messages ExitSetupTitle=स्थापना से बाहर निकलें ExitSetupMessage=स्थापना अधूरी है। यदि आप अभी बाहर निकलते हैं, तो प्रोग्राम स्थापित नहीं होगा.%n%nआपको स्थापना पूरी करने के लिए इंस्टॉलर को फिर से चलाना होगा.%n%nक्या आप बाहर निकलना चाहते हैं? AboutSetupMenuItem=&स्थापना के बारे में... AboutSetupTitle=स्थापना के बारे में AboutSetupMessage=%1 संस्करण %2%n%3%n%n%1 की होम पेज:%n%4 AboutSetupNote=मूल भाषा संस्करण: अंग्रेज़ी TranslatorNote=अनुवादक: ChatGPT ; *** Buttons ButtonBack=< &पिछला ButtonNext=आ&गे > ButtonInstall=&स्थापना ButtonOK=OK ButtonCancel=रद्द करें ButtonYes=हाँ ButtonYesToAll=सभी के लिए हाँ ButtonNo=नहीं ButtonNoToAll=सभी के लिए नहीं ButtonFinish=समाप्त ButtonBrowse=ब्राउज़... ButtonWizardBrowse=खोजें... ButtonNewFolder=नया फ़ोल्डर बनाएँ ; *** "Select Language" dialog messages SelectLanguageTitle=स्थापना के लिए भाषा चुनें SelectLanguageLabel=स्थापना के दौरान प्रदर्शित करने के लिए भाषा चुनें: ; *** Common wizard text ClickNext=जारी रखने के लिए 'आगे' पर क्लिक करें, या बाहर निकलने के लिए 'रद्द करें' पर क्लिक करें. BeveledLabel= BrowseDialogTitle=फ़ोल्डर खोजें BrowseDialogLabel=नीचे सूची में से एक फ़ोल्डर चुनें, फिर OK पर क्लिक करें. NewFolderName=नया फ़ोल्डर ; *** "Welcome" wizard page WelcomeLabel1=[name] स्थापना में आपका स्वागत है WelcomeLabel2=[name/ver] आपके कंप्यूटर पर स्थापित किया जाएगा.%n%nजारी रखने से पहले आपको सभी संबंधित प्रोग्राम बंद करने होंगे. ; *** "Password" wizard page WizardPassword=पासवर्ड PasswordLabel1=यह स्थापना पासवर्ड द्वारा संरक्षित है. PasswordLabel3=कृपया पासवर्ड दर्ज करें, फिर जारी रखने के लिए 'आगे' पर क्लिक करें. पासवर्ड 100% सही दर्ज करें (बड़े और छोटे अक्षरों में भेद होता है). PasswordEditLabel=&पासवर्ड: IncorrectPassword=आपने जो पासवर्ड दर्ज किया है वह गलत है. कृपया पुनः प्रयास करें. ; *** "License Agreement" wizard page WizardLicense=लाइसेंस समझौता LicenseLabel=कृपया जारी रखने से पहले निम्नलिखित महत्वपूर्ण जानकारी पढ़ें. LicenseLabel3=कृपया नीचे दिया गया लाइसेंस समझौता पढ़ें. जारी रखने से पहले आपको इसकी शर्तों को स्वीकार करना अनिवार्य है. LicenseAccepted=मैं &शर्तों को स्वीकार करता हूँ LicenseNotAccepted=मैं शर्तों को &स्वीकार नहीं करता ; *** "Information" wizard pages WizardInfoBefore=जानकारी InfoBeforeLabel=कृपया जारी रखने से पहले निम्नलिखित महत्वपूर्ण जानकारी पढ़ें. InfoBeforeClickLabel=जब आप स्थापना जारी रखने के लिए तैयार हों, तो 'आगे' पर क्लिक करें. WizardInfoAfter=जानकारी InfoAfterLabel=कृपया जारी रखने से पहले निम्नलिखित महत्वपूर्ण जानकारी पढ़ें. InfoAfterClickLabel=जब आप स्थापना जारी रखने के लिए तैयार हों, तो 'आगे' पर क्लिक करें. ; *** "User Information" wizard page WizardUserInfo=उपयोगकर्ता जानकारी UserInfoDesc=कृपया अपनी जानकारी दर्ज करें. UserInfoName=उपयोगकर्ता का &नाम: UserInfoOrg=संग&ठन: UserInfoSerial=&सीरियल: UserInfoNameRequired=आपको एक नाम दर्ज करना आवश्यक है. ; *** "Select Destination Location" wizard page WizardSelectDir=गंतव्य फ़ोल्डर चुनें SelectDirDesc=[name] कहाँ स्थापित किया जाए? SelectDirLabel3=स्थापना [name] को निम्नलिखित फ़ोल्डर में स्थापित करेगी. SelectDirBrowseLabel=जारी रखने के लिए 'आगे' पर क्लिक करें. यदि आप कोई अन्य फ़ोल्डर चुनना चाहते हैं, तो 'ब्राउज़' पर क्लिक करें. DiskSpaceMBLabel=स्थापना के लिए कम से कम [mb] MB खाली स्थान आवश्यक है. CannotInstallToNetworkDrive=स्थापना नेटवर्क ड्राइव पर नहीं की जा सकती. CannotInstallToUNCPath=स्थापना UNC पथ पर नहीं की जा सकती. InvalidPath=आपको पूर्ण पथ दर्ज करना होगा जिसमें ड्राइव अक्षर शामिल हो; उदाहरण:%n%nC:\APP%n%nया एक UNC पथ जैसे:%n%n\\server\share InvalidDrive=आपके द्वारा चयनित ड्राइव या UNC शेयर मौजूद नहीं है या एक्सेस नहीं किया जा सकता. कृपया कोई अन्य चुनें. DiskSpaceWarningTitle=अपर्याप्त डिस्क स्थान DiskSpaceWarning=स्थापना के लिए कम से कम %1 KB की आवश्यकता है, लेकिन चयनित ड्राइव में केवल %2 KB उपलब्ध है.%n%nक्या आप जारी रखना चाहते हैं? DirNameTooLong=फ़ोल्डर का नाम या पथ बहुत लंबा है. InvalidDirName=अमान्य फ़ोल्डर नाम. BadDirName32=फ़ोल्डर नाम में निम्नलिखित वर्ण नहीं होने चाहिए:%n%n%1 DirExistsTitle=फ़ोल्डर पहले से मौजूद है DirExists=फ़ोल्डर:%n%n%1%n%nपहले से मौजूद है. क्या आप इस फ़ोल्डर का उपयोग करना चाहते हैं? DirDoesntExistTitle=फ़ोल्डर मौजूद नहीं है DirDoesntExist=फ़ोल्डर:%n%n%1%n%nमौजूद नहीं है. क्या आप इसे बनाना चाहते हैं? ; *** "Select Components" wizard page WizardSelectComponents=अतिरिक्त घटक चुनें SelectComponentsDesc=कौन से अतिरिक्त घटक स्थापित किए जाने चाहिए? SelectComponentsLabel2=अपने पसंदीदा अतिरिक्त घटक चुनें; जिनकी आप स्थापना नहीं चाहते उन्हें हटाएं. जब आप तैयार हों तो 'आगे' पर क्लिक करें. FullInstallation=पूर्ण स्थापना CompactInstallation=बेसिक स्थापना CustomInstallation=कस्टम स्थापना NoUninstallWarningTitle=कुछ घटक पहले से स्थापित हैं NoUninstallWarning=स्थापना बाधित की गई क्योंकि आपके कंप्यूटर पर निम्नलिखित अतिरिक्त घटक पहले से स्थापित हैं:%n%n%1%n%nइन घटकों को हटाने से इन्हें पुनः स्थापित नहीं किया जाएगा.%n%nक्या आप जारी रखना चाहते हैं? ComponentSize1=%1 KB ComponentSize2=%1 MB ComponentsDiskSpaceMBLabel=इस विकल्प के लिए कम से कम [mb] MB खाली स्थान आवश्यक है. ; *** "Select Additional Tasks" wizard page WizardSelectTasks=अतिरिक्त कार्य चुनें SelectTasksDesc=कौन से अतिरिक्त कार्य जोड़े जाने चाहिए? SelectTasksLabel2=उस कार्य को चुनें जिसे आप [name] की स्थापना के दौरान जोड़ना चाहते हैं, फिर 'आगे' पर क्लिक करें. ; *** "Select Start Menu Folder" wizard page WizardSelectProgramGroup=स्टार्ट मेन्यू फ़ोल्डर चुनें SelectStartMenuFolderDesc=प्रोग्राम का शॉर्टकट स्टार्ट मेन्यू में कहाँ रखा जाना चाहिए? SelectStartMenuFolderLabel3=स्थापना स्टार्ट मेन्यू में निम्नलिखित फ़ोल्डर में प्रोग्राम के शॉर्टकट बनाएगी. SelectStartMenuFolderBrowseLabel=जारी रखने के लिए 'आगे' पर क्लिक करें. यदि आप कोई अन्य फ़ोल्डर चुनना चाहते हैं, तो 'ब्राउज़' पर क्लिक करें. MustEnterGroupName=आपको एक फ़ोल्डर का नाम दर्ज करना होगा. GroupNameTooLong=फ़ोल्डर का नाम या पथ बहुत लंबा है. InvalidGroupName=अमान्य फ़ोल्डर नाम. BadGroupName=फ़ोल्डर नाम में निम्नलिखित वर्ण नहीं होने चाहिए:%n%n%1 NoProgramGroupCheck2=&स्टार्ट मेन्यू में फ़ोल्डर न बनाएं ; *** "Ready to Install" wizard page WizardReady=स्थापना के लिए तैयार ReadyLabel1=आपके कंप्यूटर पर [name] की स्थापना के लिए तैयार है. ReadyLabel2a=स्थापना जारी रखने के लिए 'स्थापना' पर क्लिक करें, या समीक्षा/परिवर्तन के लिए 'पिछला' पर क्लिक करें. ReadyLabel2b=स्थापना जारी रखने के लिए 'स्थापना' पर क्लिक करें. ReadyMemoUserInfo=उपयोगकर्ता जानकारी: ReadyMemoDir=गंतव्य फ़ोल्डर: ReadyMemoType=स्थापना प्रकार: ReadyMemoComponents=चयनित अतिरिक्त घटक: ReadyMemoGroup=स्टार्ट मेन्यू में फ़ोल्डर: ReadyMemoTasks=अतिरिक्त कार्य: ; *** "Preparing to Install" wizard page WizardPreparing=स्थापना के लिए तैयारी PreparingDesc=आपके कंप्यूटर पर [name] की स्थापना की तैयारी हो रही है. PreviousInstallNotCompleted=पिछली स्थापना (या अनइंस्टॉल) अधूरी है. स्थापना पूरी करने के लिए आपको कंप्यूटर को पुनरारंभ करना होगा.%n%nपुनरारंभ के बाद, कृपया [name] की स्थापना पूरी करने के लिए इंस्टॉलर को पुनः चलाएँ. CannotContinue=स्थापना जारी नहीं रह सकती. बाहर निकलने के लिए 'रद्द करें' पर क्लिक करें. ApplicationsFound=निम्नलिखित प्रोग्राम उन फ़ाइलों का उपयोग कर रहे हैं जिन्हें स्थापना द्वारा अद्यतन किया जाना है. कृपया इन्हें बंद करें. ApplicationsFound2=निम्नलिखित प्रोग्राम उन फ़ाइलों का उपयोग कर रहे हैं जिन्हें स्थापना द्वारा अद्यतन किया जाना है. स्थापना से पहले इन्हें बंद करना आवश्यक है. स्थापना पूर्ण होने के बाद, इंस्टॉलर इन्हें फिर से खोल देगा. CloseApplications=इन प्रोग्रामों को &स्वत: बंद करें DontCloseApplications=&इन प्रोग्रामों को बंद न करें ErrorCloseApplications=कुछ प्रोग्राम बंद नहीं हो सके. स्थापना जारी रखने से पहले कृपया उन प्रोग्रामों को बंद करें जो अद्यतन की जाने वाली फ़ाइलों का उपयोग कर रहे हैं. ; *** "Installing" wizard page WizardInstalling=स्थापना चल रही है InstallingLabel=कृपया प्रतीक्षा करें, [name] की स्थापना आपके कंप्यूटर पर हो रही है. ; *** "Setup Completed" wizard page FinishedHeadingLabel=[name] की स्थापना पूरी हुई FinishedLabelNoIcons=[name] आपके कंप्यूटर पर सफलतापूर्वक स्थापित हो गया है. FinishedLabel=[name] आपके कंप्यूटर पर सफलतापूर्वक स्थापित हो गया है. इसे उसके आइकन पर क्लिक करके चलाया जा सकता है. ClickFinish=स्थापना से बाहर निकलने के लिए 'समाप्त' पर क्लिक करें. FinishedRestartLabel=स्थापना पूरी करने के लिए, आपके कंप्यूटर को पुनरारंभ करना होगा. क्या आप पुनरारंभ करना चाहते हैं? FinishedRestartMessage=स्थापना पूरी करने के लिए, आपके कंप्यूटर को पुनरारंभ करना होगा.%n%nक्या आप पुनरारंभ करना चाहते हैं? ShowReadmeCheck=हाँ, मैं README फ़ाइल देखना चाहता हूँ YesRadio=&हाँ, अभी कंप्यूटर पुनरारंभ करें NoRadio=&नहीं, मैं बाद में पुनरारंभ करूँगा RunEntryExec=%1 चलाएं RunEntryShellExec=%1 प्रदर्शित करें ; *** "Setup Needs the Next Disk" stuff ChangeDiskTitle=अगला डिस्क आवश्यक SelectDiskLabel2=कृपया %1 डिस्क डालें और OK पर क्लिक करें.%n%nयदि उस डिस्क पर फ़ाइलें कहीं और स्थित हैं, तो सही पथ दर्ज करें या 'ब्राउज़' पर क्लिक करें. PathLabel=&पथ: FileNotInDir2=फ़ाइल "%1" "%2" में नहीं पाई गई. कृपया सही डिस्क डालें या कोई अन्य फ़ोल्डर चुनें. SelectDirectoryLabel=कृपया अगले डिस्क का स्थान निर्दिष्ट करें. ; *** Installation phase messages SetupAborted=स्थापना पूरी नहीं हुई.%n%nकृपया त्रुटि को सुधारें और स्थापना को पुनः चलाएँ. EntryAbortRetryIgnore=पुनः प्रयास करने के लिए 'पुनः प्रयास करें', छोड़ने के लिए 'छोड़ें' (अनुशंसित नहीं), या स्थापना रद्द करने के लिए 'रद्द करें' पर क्लिक करें. ; *** Installation status messages StatusClosingApplications=प्रोग्राम बंद किए जा रहे हैं... StatusCreateDirs=फ़ोल्डर बनाए जा रहे हैं... StatusExtractFiles=फ़ाइलें निकाली जा रही हैं... StatusCreateIcons=शॉर्टकट बनाए जा रहे हैं... StatusCreateIniEntries=INI प्रविष्टियाँ बनाई जा रही हैं... StatusCreateRegistryEntries=Registry प्रविष्टियाँ बनाई जा रही हैं... StatusRegisterFiles=फ़ाइलें सत्यापित की जा रही हैं... StatusSavingUninstall=अनइंस्टॉल जानकारी सहेजी जा रही है... StatusRunProgram=स्थापना पूरी की जा रही है... StatusRestartingApplications=प्रोग्राम पुनः प्रारंभ किए जा रहे हैं... StatusRollback=परिवर्तनों को पूर्ववत किया जा रहा है... ; *** Misc. errors ErrorInternal2=त्रुटि: %1 ErrorFunctionFailedNoCode=%1 विफल हुआ ErrorFunctionFailed=%1 विफल हुआ; कोड %2 ErrorFunctionFailedWithMessage=%1 विफल हुआ; कोड %2.%n%3 ErrorExecutingProgram=प्रोग्राम निष्पादित करने में विफल:%n%1 ; *** Registry errors ErrorRegOpenKey=Registry कुंजी खोलने में त्रुटि:%n%1\%2 ErrorRegCreateKey=Registry कुंजी बनाने में त्रुटि:%n%1\%2 ErrorRegWriteKey=Registry कुंजी में लिखने में त्रुटि:%n%1\%2 ; *** INI errors ErrorIniEntry=फ़ाइल "%1" में INI प्रविष्टि बनाने में त्रुटि. ; *** File copying errors FileAbortRetryIgnore=पुनः प्रयास करने के लिए 'पुनः प्रयास करें', फ़ाइल छोड़ने के लिए 'छोड़ें' (अनुशंसित नहीं), या स्थापना रद्द करने के लिए 'रद्द करें' पर क्लिक करें. FileAbortRetryIgnore2=पुनः प्रयास करने के लिए 'पुनः प्रयास करें', त्रुटि छोड़ने के लिए 'छोड़ें' (अनुशंसित नहीं), या स्थापना रद्द करने के लिए 'रद्द करें' पर क्लिक करें. SourceIsCorrupted=स्रोत फ़ाइल भ्रष्ट है SourceDoesntExist=स्रोत फ़ाइल "%1" मौजूद नहीं है ExistingFileReadOnly=यह फ़ाइल केवल-पढ़ने के रूप में चिह्नित है.%n%nकेवल-पढ़ने का चिह्न हटाने और पुनः प्रयास करने के लिए 'पुनः प्रयास करें', छोड़ने के लिए 'छोड़ें', या स्थापना रद्द करने के लिए 'रद्द करें' पर क्लिक करें. ErrorReadingExistingDest=फ़ाइल पढ़ने में त्रुटि: FileExists=फ़ाइल पहले से मौजूद है.%n%nक्या आप इसे बदलना चाहते हैं? ExistingFileNewer=यह फ़ाइल उस फ़ाइल से नई है जिसे स्थापना द्वारा स्थापित किया जाना है. आपको इसे रखना आवश्यक है.%n%nक्या आप इसे रखना चाहते हैं? ErrorChangingAttr=फ़ाइल की विशेषताएँ बदलने में त्रुटि: ErrorCreatingTemp=गंतव्य फ़ोल्डर में अस्थायी फ़ाइल बनाने में त्रुटि: ErrorReadingSource=स्रोत फ़ाइल पढ़ने में त्रुटि: ErrorCopying=फ़ाइल कॉपी करते समय त्रुटि: ErrorReplacingExistingFile=फ़ाइल बदलने में त्रुटि: ErrorRestartReplace=पुनरारंभ के बाद फ़ाइल बदलना विफल रहा: ErrorRenamingTemp=गंतव्य फ़ोल्डर में अस्थायी फ़ाइल का नाम बदलने में त्रुटि: ErrorRegisterServer=DLL/OCX पंजीकृत करने में विफल: %1 ErrorRegSvr32Failed=RegSvr32 विफल, निकास कोड %1 ErrorRegisterTypeLib=टाइप लाइब्रेरी पंजीकृत करने में विफल: %1 ; *** Post-installation errors ErrorOpeningReadme=README फ़ाइल खोलने में त्रुटि. ErrorRestartingComputer=कंप्यूटर पुनरारंभ करने में विफल. कृपया मैन्युअल रूप से पुनरारंभ करें. ; *** Uninstaller messages UninstallNotFound=फ़ाइल "%1" नहीं मिली. अनइंस्टॉल नहीं किया जा सकता. UninstallOpenError=फ़ाइल "%1" खोलने में विफल. अनइंस्टॉल नहीं किया जा सकता. UninstallUnsupportedVer=अनइंस्टॉलर लॉग फ़ाइल "%1" असमर्थित प्रकार की है. अनइंस्टॉल नहीं किया जा सकता. UninstallUnknownEntry=अनइंस्टॉलर लॉग में अज्ञात प्रविष्टि (%1) मिली. ConfirmUninstall=क्या आप वाकई %1 और उससे संबंधित सभी घटकों को अनइंस्टॉल करना चाहते हैं? UninstallOnlyOnWin64=यह अनइंस्टॉल केवल Windows 64-bit संस्करण पर किया जा सकता है. OnlyAdminCanUninstall=यह अनइंस्टॉल केवल व्यवस्थापक द्वारा किया जा सकता है. UninstallStatusLabel=कृपया प्रतीक्षा करें, %1 को आपके कंप्यूटर से अनइंस्टॉल किया जा रहा है. UninstalledAll=%1 को आपके कंप्यूटर से सफलतापूर्वक अनइंस्टॉल कर दिया गया है. UninstalledMost=%1 का अनइंस्टॉल पूरा हुआ है.%n%nकुछ घटकों को अनइंस्टॉल नहीं किया जा सका. इन्हें मैन्युअल रूप से अनइंस्टॉल किया जा सकता है. UninstalledAndNeedsRestart=अनइंस्टॉल पूरा करने के लिए, आपको कंप्यूटर को पुनरारंभ करना होगा.%n%nक्या आप पुनरारंभ करना चाहते हैं? UninstallDataCorrupted=फ़ाइल "%1" भ्रष्ट है. अनइंस्टॉल नहीं किया जा सकता. ; *** Uninstallation phase messages ConfirmDeleteSharedFileTitle=साझा फ़ाइल हटाएं? ConfirmDeleteSharedFile2=सिस्टम ने संकेत दिया है कि निम्नलिखित साझा फ़ाइलें किसी अन्य प्रोग्राम द्वारा उपयोग में नहीं हैं. क्या आप इन्हें हटाना चाहते हैं?%n%nयदि कोई प्रोग्राम अभी भी इन फ़ाइलों का उपयोग कर रहा है, तो ये ठीक से काम नहीं कर सकतीं. यदि आप सुनिश्चित नहीं हैं, तो 'नहीं' चुनें. आपके सिस्टम से इन्हें हटाने से कोई नुकसान नहीं होगा. SharedFileNameLabel=फ़ाइल का नाम: SharedFileLocationLabel=स्थान: WizardUninstalling=अनइंस्टॉल स्थिति StatusUninstalling=%1 को अनइंस्टॉल किया जा रहा है... ; *** Shutdown block reasons ShutdownBlockReasonInstallingApp=%1 की स्थापना चल रही है. ShutdownBlockReasonUninstallingApp=%1 का अनइंस्टॉल चल रहा है. [CustomMessages] NameAndVersion=%1 संस्करण %2 AdditionalIcons=अतिरिक्त शॉर्टकट: CreateDesktopIcon=डेस्कटॉप पर शॉर्टकट बनाएँ CreateQuickLaunchIcon=क्विक लॉन्च पर शॉर्टकट बनाएँ ProgramOnTheWeb=%1 वेब पर UninstallProgram=%1 का अनइंस्टॉल LaunchProgram=%1 चलाएं AssocFileExtension=&%1 को %2 फ़ाइल एक्सटेंशन के साथ जोड़ें AssocingFileExtension=%1 को %2 फ़ाइल एक्सटेंशन के साथ जोड़ा जा रहा है... AutoStartProgramGroupDescription=स्वचालित प्रारंभ: AutoStartProgram=%1 को स्वचालित रूप से प्रारंभ करें AddonHostProgramNotFound=%1 को चुने गए फ़ोल्डर में स्थापित नहीं किया जा सका.%n%nक्या आप जारी रखना चाहते हैं? ================================================ FILE: installer/lang/Vietnamese.isl ================================================ ; *** Inno Setup version 6.1.0+ Vietnamese messages *** ; Translated by Vu Khac Hiep (email: vukhachiep@gmail.com) ; To download user-contributed translations of this file, go to: ; https://jrsoftware.org/files/istrans/ ; ; Note: When translating this text, do not add periods (.) to the end of ; messages that didn't have them already, because on those messages Inno ; Setup adds the periods automatically (appending a period would result in ; two periods being displayed). [LangOptions] ; The following three entries are very important. Be sure to read and ; understand the '[LangOptions] section' topic in the help file. LanguageName=Vietnamese LanguageID=$042A LanguageCodePage=0 ; If the language you are translating to requires special font faces or ; sizes, uncomment any of the following entries and change them accordingly. ;DialogFontName= ;DialogFontSize=8 ;WelcomeFontName=Verdana ;WelcomeFontSize=12 ;TitleFontName=Arial ;TitleFontSize=29 ;CopyrightFontName=Arial ;CopyrightFontSize=8 [Messages] ; *** Application titles SetupAppTitle=Cài đặt SetupWindowTitle=Cài đặt - %1 UninstallAppTitle=Gỡ cài đặt UninstallAppFullTitle=Gỡ cài đặt - %1 ; *** Misc. common InformationTitle=Thông tin ConfirmTitle=Xác nhận ErrorTitle=Lỗi ; *** SetupLdr messages SetupLdrStartupMessage=Chương trình này sẽ cài đặt %1. Bạn có muốn tiếp tục không? LdrCannotCreateTemp=Không thể tạo tệp tạm thời. Cài đặt bị hủy bỏ LdrCannotExecTemp=Không thể chạy tệp trong thư mục tạm thời. Cài đặt bị hủy bỏ HelpTextNote= ; *** Startup error messages LastErrorMessage=%1.%n%nLỗi %2: %3 SetupFileMissing=Tệp %1 bị thiếu trong thư mục cài đặt. Hãy sửa lỗi hoặc lấy một bản sao mới của chương trình. SetupFileCorrupt=Các tệp cài đặt đã bị hỏng. Hãy sửa lỗi hoặc lấy một bản sao của chương trình. SetupFileCorruptOrWrongVer=Các tệp cài đặt bị hỏng, hoặc không tương thích với bản cài đặt này. Hãy sửa lỗi hoặc lấy một bản sao mới của chương trình. InvalidParameter=Một thông số không hợp lệ đã được đưa vào dòng lệnh:%n%n%1 SetupAlreadyRunning=Cài đặt này đang chạy. WindowsVersionNotSupported=Chương trình này không tương thích với phiên bản Windows bạn đang chạy. WindowsServicePackRequired=Chương trình này yêu cầu %1 Service Pack %2 hoặc mới hơn. NotOnThisPlatform=Chương trình này sẽ không chạy trên %1. OnlyOnThisPlatform=Chương trình này phải chạy trên %1. OnlyOnTheseArchitectures=Chương trình này chỉ có thể được cài đặt trên phiên bản Windows được thiết kế cho các hệ vi xử lí:%n%n%1 WinVersionTooLowError=Chương trình này yêu cầu %1 phiên bản %2 hoặc mới hơn. WinVersionTooHighError=Chương trình này không thể được cài đặt trên %1 phiên bản %2 hoặc mới hơn. AdminPrivilegesRequired=Bạn phải được đăng nhập như người quản trị khi cài đặt chương trình này. PowerUserPrivilegesRequired=Bạn phải được đăng nhập như người quản trị hoặc thành viên trong nhóm Người dùng mạnh khi cài đặt chương trình này. SetupAppRunningError=Cài đặt phát hiện %1 đang chạy.%n%nHãy đóng tất cả các tiến trình của nó ngay, rồi click OK để tiếp tục, hoặc Hủy để thoát. UninstallAppRunningError=Gỡ cài đặt phát hiện %1 đang chạy.%n%nHãy đóng tất cả các tiến trình của nó ngay, rồi click OK để tiếp tục, hoặc Hủy để thoát. ; *** Startup questions PrivilegesRequiredOverrideTitle=Select Setup Install Mode PrivilegesRequiredOverrideInstruction=Select install mode PrivilegesRequiredOverrideText1=%1 can be installed for all users (requires administrative privileges), or for you only. PrivilegesRequiredOverrideText2=%1 can be installed for you only, or for all users (requires administrative privileges). PrivilegesRequiredOverrideAllUsers=Install for &all users PrivilegesRequiredOverrideAllUsersRecommended=Install for &all users (recommended) PrivilegesRequiredOverrideCurrentUser=Install for &me only PrivilegesRequiredOverrideCurrentUserRecommended=Install for &me only (recommended) ; *** Misc. errors ErrorCreatingDir=Cài đặt không thể tạo ra thư mục "%1" ErrorTooManyFilesInDir=Không thể tạo một tệp trong thư mục "%1" vì nó chứa quá nhiều tệp ; *** Setup common messages ExitSetupTitle=Thoát cài đặt ExitSetupMessage=Cài đặt chưa hoàn thành. Nếu bạn thoát bây giờ, chương trình sẽ không được cài đặt.%n%nBạn có thể chạy lại Cài đặt một lần khác để hoàn thành cài đặt.%n%nThoát ngay? AboutSetupMenuItem=&Về trình cài đặt... AboutSetupTitle=Về trình cài đặt AboutSetupMessage=%1 phiên bản %2%n%3%n%n%1 trang chủ:%n%4 AboutSetupNote= TranslatorNote=Giao diện người dùng tiếng Việt bởi: Vũ Khắc Hiệp ; *** Buttons ButtonBack=< &Trước ButtonNext=T&iếp > ButtonInstall=&Cài đặt ButtonOK=OK ButtonCancel=Hủy ButtonYes=&Có ButtonYesToAll=Có c&ho tất cả ButtonNo=&Không ButtonNoToAll=Khô&ng cho tất cả ButtonFinish=&Hoàn thành ButtonBrowse=&Duyệt... ButtonWizardBrowse=D&uyệt... ButtonNewFolder=Tạ&o thư mục mới ; *** "Select Language" dialog messages SelectLanguageTitle=Chọn ngôn ngữ cài đặt SelectLanguageLabel=Chọn ngôn ngữ để sử dụng khi cài đặt: ; *** Common wizard text ClickNext=Nhấn Tiếp để tiếp tục, hoặc Hủy để thoát cài đặt BeveledLabel= BrowseDialogTitle=Tìm thư mục BrowseDialogLabel=Chọn một thư mục trong danh sách sau rồi ấn OK. NewFolderName=Tạo thư mục mới ; *** "Welcome" wizard page WelcomeLabel1=Chào mừng tới trình cài đặt [name] WelcomeLabel2=Chương trình này sẽ cài [name/ver] trên máy tính của bạn.%n%nChúng tôi khuyên bạn đóng mọi chương trình khác lại trước khi cài đặt. ; *** "Password" wizard page WizardPassword=Mật khẩu PasswordLabel1=Việc cài đặt được bảo vệ bằng mật khẩu. PasswordLabel3=Hãy nhập mật khẩu, rồi nhấn Tiếp để tiếp tục. Mật khẩu phân biệt chữ hoa/thường. PasswordEditLabel=&Mật khẩu: IncorrectPassword=Mật khẩu bạn đã nhập không đúng. Hãy thử lại. ; *** "License Agreement" wizard page WizardLicense=Thỏa thuận cấp phép LicenseLabel=Hãy đọc những thông tin quan trọng sau trước khi tiếp tục. LicenseLabel3=Hãy đọc Thỏa thuận cấp phép sau. Bạn phải chấp nhận các điều khoản của cài đặt này trước khi tiếp tục. LicenseAccepted=Tô&i chấp nhận thỏa thuận LicenseNotAccepted=Tôi khôn&g chấp nhận thỏa thuận ; *** "Information" wizard pages WizardInfoBefore=Thông tin InfoBeforeLabel=Hãy đọc những thông tin quan trọng sau trước khi tiếp tục. InfoBeforeClickLabel=Khi bạn đã sẵn sàng cài đặt tiếp, click Tiếp. WizardInfoAfter=Thông tin InfoAfterLabel=Hãy đọc những thông tin quan trọng sau trước khi tiếp tục. InfoAfterClickLabel=Khi bạn đã sẵn sàng cài đặt tiếp, click Tiếp. ; *** "User Information" wizard page WizardUserInfo=Thông tin người dùng UserInfoDesc=Hãy nhập thông tin của bạn. UserInfoName=Tên n&gười dùng: UserInfoOrg=Tổ c&hức: UserInfoSerial=&Số serial: UserInfoNameRequired=Bạn phải nhập một tên. ; *** "Select Destination Location" wizard page WizardSelectDir=Chọn vị trí cài đặt SelectDirDesc=[name] nên được cài đặt ở đâu? SelectDirLabel3=[name] sẽ được cài đặt vào thư mục sau: SelectDirBrowseLabel=Để tiếp tục. nhấn Tiếp. Nếu bạn muốn chọn một thư mục khác, nhấn Duyệt. DiskSpaceGBLabel=Cần có ít nhất [gb] GB ổ đĩa trống. DiskSpaceMBLabel=Cần có ít nhất [mb] MB ổ đĩa trống. CannotInstallToNetworkDrive=Cài đặt không thể cài vào một ổ đĩa mạng. CannotInstallToUNCPath=Cài đặt không thể cài vào đường dẫn UNC. InvalidPath=Bạn phải nhập đường dẫn đầy đủ với chữ cái ổ đĩa, ví dụ:%n%nC:\APP%n%nhoặc một đường dẫn UNC theo mẫu:%n%n\\server\share InvalidDrive=Ổ đĩa hoặc chia sẻ UNC bạn đã chọn không tồn tại hoặc không truy cập được. Hãy chọn cái khác. DiskSpaceWarningTitle=Không đủ dung lượng đĩa DiskSpaceWarning=Cài đặt yêu cầu ít nhất %1 KB dung lượng trống để cài đặt, nhưng ổ đĩa đã chọn chỉ còn %2KB.%n%nBạn muốn tiếp tục bằng mọi giá? DirNameTooLong=Tên thư mục hoặc đường dẫn quá dài. InvalidDirName=Tên thư mục không hợp lệ. BadDirName32=Tên thư mục không được chứa các kí tự sau:%n%n%1 DirExistsTitle=Thư mục đã tồn tại DirExists=Thư mục:%n%n%1%n%nđã tồn tại. Bạn có muốn cài đặt vào thư mục đó bằng mọi giá? DirDoesntExistTitle=Thư mục không tồn tại DirDoesntExist=Thư mục:%n%n%1%n%nkhông tồn tại. Bạn có muốn tạo thư mục không? ; *** "Select Components" wizard page WizardSelectComponents=Chọn các thành phần SelectComponentsDesc=Những thành phần nào nên được cài đặt? SelectComponentsLabel2=Chọn các thành phần bạn muốn cài đặt, bỏ chọn các thành phần bạn không muốn. Click Tiếp khi bạn đã sẵn sàng để tiếp tục. FullInstallation=Cài đặt đầy đủ ; if possible don't translate 'Compact' as 'Minimal' (I mean 'Minimal' in your language) CompactInstallation=Cài đặt rút gọn CustomInstallation=Cài đặt tủy chỉnh NoUninstallWarningTitle=Thành phần đã tồn tại NoUninstallWarning=Cài đặt phát hiện các thành phần sau đã được cài đặt trên máy tính của bạn:%n%n%1%n%nBỏ chọn những thành phần này sẽ không cài đặt chúng.%n%nBạn có muốn tiếp tục bằng mọi giá? ComponentSize1=%1 KB ComponentSize2=%1 MB ComponentsDiskSpaceGBLabel=Lựa chọn này yêu cầu ít nhất [gb] GB không gian đĩa. ComponentsDiskSpaceMBLabel=Lựa chọn này yêu cầu ít nhất [mb] MB không gian đĩa. ; *** "Select Additional Tasks" wizard page WizardSelectTasks=Chọn các tác vụ bổ sung SelectTasksDesc=Các tác vụ bổ sung nào nên được thực hiện? SelectTasksLabel2=Chọn các tác vụ bổ sung mà bạn muốn cài đặt thực hiện khi cài đặt [name], rồi nhấn Tiếp. ; *** "Select Start Menu Folder" wizard page WizardSelectProgramGroup=Chọn thư mục bắt đầu SelectStartMenuFolderDesc=Các lối tắt đến chương trình nên được đặt ở đâu? SelectStartMenuFolderLabel3=Cài đặt sẽ tạo các lối tắt đến chương trình trong thư mục bắt đầu sau. SelectStartMenuFolderBrowseLabel=Để tiếp tục, click Tiếp. Nếu bạn muốn chọn thư mục khác, click Duyệt. MustEnterGroupName=Bạn phải nhập tên một thư mục. GroupNameTooLong=Tên thư mục hoặc đường dẫn quá dài. InvalidGroupName=Tên thư mục không hợp lệ. BadGroupName=Tên thư mục không được chứa các kí tự sau:%n%n%1 NoProgramGroupCheck2=&Không tạo thư mục bắt đầu ; *** "Ready to Install" wizard page WizardReady=Sẵn sàng cài đặt ReadyLabel1=[name] đã sẵn sàng để dược cài đặt trên máy tính của bạn. ReadyLabel2a=Click Cài đặt để tiếp tục, hoặc click Trước nếu bạn muốn xem lại/thay đổi bất kì cài đặt nào. ReadyLabel2b=Click Cài đặt để tiếp tục cài đặt. ReadyMemoUserInfo=Thông tin người dùng: ReadyMemoDir=Vị trí đích: ReadyMemoType=Kiểu cài đặt: ReadyMemoComponents=Các thành phần được chọn: ReadyMemoGroup=Thư mục bắt đầu: ReadyMemoTasks=Các tác vụ bổ sung: ; *** TDownloadWizardPage wizard page and DownloadTemporaryFile DownloadingLabel=Đang tải các tập tin bổ sung... ButtonStopDownload=&Dừng tải xuống StopDownload=Bạn có chắc chắn muốn dừng tải xuống không? ErrorDownloadAborted=Tải xuống bị hủy bỏ ErrorDownloadFailed=Tải xuống không thành công: %1 %2 ErrorDownloadSizeFailed=Getting size failed: %1 %2 ErrorFileHash1=File hash failed: %1 ErrorFileHash2=Invalid file hash: expected %1, found %2 ErrorProgress=Invalid progress: %1 of %2 ErrorFileSize=Invalid file size: expected %1, found %2 ; *** "Preparing to Install" wizard page WizardPreparing=Chuẩn bị cài đặt PreparingDesc=[name] đang chuẩn bị được cài đặt trên máy tính của bạn. PreviousInstallNotCompleted=Việc cài đặt/gỡ bỏ một chương trình chưa được hoàn tất trước đó. Bạn sẽ phải khởi động lại máy tính để hoàn tất cài đặt đó.%n%nSau khi chởi động lại, chạy Cài đặt một lần nữa để hoàn tất cài đặt [name]. CannotContinue=Cài đặt không thể tiếp tục. Nhấn Hủy để thoát. ApplicationsFound=Những chương trình sau đang sử dụng các tệp cần được cập nhật bởi trình cài đặt. Chúng tôi khuyên bạn cho phép Cài đặt đóng các chương trình này. ApplicationsFound2=Những chương trình sau đang sử dụng các tệp cần được cập nhật bởi trình cài đặt. Chúng tôi khuyên bạn cho phép Cài đặt đóng các chương trình này. Sau khi hoàn thành cài đặt, chúng tôi sẽ thử khởi động lại các chương trình này. CloseApplications=Tự độn&g đóng các chương trình này DontCloseApplications=Không đóng các chương t&rình này ErrorCloseApplications=Cài đặt không thể đóng mọi chương trình. Chúng tôi khuyên bạn đóng các chương trình đang sử dụng các tệp cần được cập nhật bởi Cài đặt một cách thủ công trước khi tiếp tục. PrepareToInstallNeedsRestart=Setup must restart your computer. After restarting your computer, run Setup again to complete the installation of [name].%n%nWould you like to restart now? ; *** "Installing" wizard page WizardInstalling=Đang cài đặt InstallingLabel=Hãy đợi khi [name] đang được cài đặt trên máy tính của bạn. ; *** "Setup Completed" wizard page FinishedHeadingLabel=Hoàn thành cài đặt [name] FinishedLabelNoIcons=[name] đã được cài đặt xong trên máy tính của bạn. FinishedLabel=[name] đã được cài đặt xong trên máy tính của bạn. Chương trình có thể được khởi động bằng cách click vào lối tắt đến chương trình. ClickFinish=Click Hoàn thành để thoát Cài đặt. FinishedRestartLabel=Để hoàn thành cài đặt [name], máy tính của bạn cần đươc khởi động lại. Bạn có muốn khởi động lại ngay? FinishedRestartMessage=Để hoàn thành cài đặt [name], máy tính của bạn cần đươc khởi động lại.%n%nBạn có muốn khởi động lại ngay? ShowReadmeCheck=Có, tôi muốn xem tệp README YesRadio=&Có, khởi động lại máy tính ngay NoRadio=&Không, tôi sẽ khởi động lại máy tính sau ; used for example as 'Run MyProg.exe' RunEntryExec=Chạy %1 ; used for example as 'View Readme.txt' RunEntryShellExec=Xem %1 ; *** "Setup Needs the Next Disk" stuff ChangeDiskTitle=Cài đặt cần đĩa tiếp theo SelectDiskLabel2=Hãy chèn đĩa %1 và click OK.%n%nNếu các tệp trên đĩa này có thể được tìm thấy trên một thư mục khác với được hiển thị dưới đây, nhập đường dẫn hoặc click Duyệt. PathLabel=Đườ&ng dẫn: FileNotInDir2=Tệp "%1" không thể được xác định trong "%2". Hãy chọn đia xđúng hoặc chọn thư mục khác. SelectDirectoryLabel=Hãy chọn vị trí của đĩa tiếp theo. ; *** Installation phase messages SetupAborted=Cài đặt không được hoàn thành.%n%nHãy sửa lỗi và chạy Cài đặt lại. AbortRetryIgnoreSelectAction=Chọn hành động AbortRetryIgnoreRetry=&Thử lại AbortRetryIgnoreIgnore=&Bỏ qua lỗi và tiếp tục AbortRetryIgnoreCancel=Hủy ; *** Installation status messages StatusClosingApplications=Đang đóng các chương trình... StatusCreateDirs=Đang tạo các thư mục... StatusExtractFiles=Đang giải nén các tệp... StatusCreateIcons=Đang tạo các lối tắt... StatusCreateIniEntries=Đang tạo các đầu vào INI... StatusCreateRegistryEntries=Đang tạo các đầu vào registry... StatusRegisterFiles=Đang đăng kí các tệp... StatusSavingUninstall=Đang lưu thông tin gỡ cài đặt... StatusRunProgram=Đang hoàn thành cài đặt... StatusRestartingApplications=Đang khởi động lại các chương trình... StatusRollback=Đang hoàn lại các thay đổi... ; *** Misc. errors ErrorInternal2=Lỗi nội bộ: %1 ErrorFunctionFailedNoCode=%1 thất bại ErrorFunctionFailed=%1 thất bại với mã lỗi %2 ErrorFunctionFailedWithMessage=%1 thất bại với mã lỗi %2.%n%3 ErrorExecutingProgram=Không thể chạy tệp:%n%1 ; *** Registry errors ErrorRegOpenKey=Lỗi khi mở registry:%n%1\%2 ErrorRegCreateKey=Lỗi khi tạo registry:%n%1\%2 ErrorRegWriteKey=Lỗi khi viết registry:%n%1\%2 ; *** INI errors ErrorIniEntry=Lỗi tạo đầu vào INI cho tệp "%1". ; *** File copying errors FileAbortRetryIgnoreSkipNotRecommended=&Bỏ qua tệp này (không khuyến nghị) FileAbortRetryIgnoreIgnoreNotRecommended=&Bỏ qua để tiếp tục bằng mọi giá (không khuyến nghị) SourceIsCorrupted=Tệp nguồn bị hỏng SourceDoesntExist=Tệp nguồn "%1" không tồn tại ExistingFileReadOnly2=Tệp đã tồn tại với đánh dấu chỉ đọc. ExistingFileReadOnlyRetry=&Xóa thuộc tính chỉ đọc và thử lại ExistingFileReadOnlyKeepExisting=&Giữ tập tin hiện có ErrorReadingExistingDest=Một lỗi đã xảy ra khi đọc tệp: FileExistsSelectAction=Select action FileExists2=Tệp đã tồn tại. FileExistsOverwriteExisting=G&hi đè tệp hiện có FileExistsKeepExisting=&Giữ tệp hiện có FileExistsOverwriteOrKeepAll=&Do this for the next conflicts ExistingFileNewerSelectAction=Select action ExistingFileNewer2=Tệp hiện có mới hơn tệp mà Thiết lập đang cố gắng cài đặt. ExistingFileNewerOverwriteExisting=&Ghi đè tệp hiện có ExistingFileNewerKeepExisting=&Giữ tệp hiện có (khuyến nghị) ExistingFileNewerOverwriteOrKeepAll=&Do this for the next conflicts ErrorChangingAttr=Một lỗi đã xảy ra khi thay đổi thuộc tính của tệp sau: ErrorCreatingTemp=Một lỗi đã xảy ra khi tạo một tệp trong thư mục đích: ErrorReadingSource=Một lỗi đã xảy ra khi đọc tệp nguồn: ErrorCopying=Một lỗi đã xảy ra khi sao chép tệp: ErrorReplacingExistingFile=Một lỗi đã xảy ra khi thay thế tệp: ErrorRestartReplace=Khởi động lại & Thay thế (RestartReplace) thất bại: ErrorRenamingTemp=Một lỗi đã xảy ra khi đổi tên tệp trong thư mục đích: ErrorRegisterServer=Không thể đăng kí DLL/OCX: %1 ErrorRegSvr32Failed=RegSvr32 thất bại với mã thoát %1 ErrorRegisterTypeLib=Không thể đăng kí thư viện kiểu: %1 ; *** Uninstall display name markings ; used for example as 'My Program (32-bit)' UninstallDisplayNameMark=%1 (%2) ; used for example as 'My Program (32-bit, All users)' UninstallDisplayNameMarks=%1 (%2, %3) UninstallDisplayNameMark32Bit=32-bit UninstallDisplayNameMark64Bit=64-bit UninstallDisplayNameMarkAllUsers=All users UninstallDisplayNameMarkCurrentUser=Current user ; *** Post-installation errors ErrorOpeningReadme=Một lỗi đã xảy ra khi mở tệp README. ErrorRestartingComputer=Cài đặt không thể khởi động lại máy tính. Hãy làm việc này một cách thủ công. ; *** Uninstaller messages UninstallNotFound=Tệp "%1" không tồn tại. Không thể gỡ cài đặt. UninstallOpenError=Tệp "%1" không thể được mở. Không thể gỡ cài đặt UninstallUnsupportedVer=Tệp nhật kí gỡ cài đặt "%1" có định dạng không thể được xác định bởi phiên bản gỡ cài đặt này. Không thể gỡ cài đặt UninstallUnknownEntry=Một đầu vào không xác định (%1) đã bị phát hiện trong nhật kí gỡ cài đặt ConfirmUninstall=Bạn có muốn dỡ bỏ hoàn toàn %1 và mọi thành phần của nó? UninstallOnlyOnWin64=Cài đặt này chỉ có thể được gỡ bỏ trên Windows 64 bit. OnlyAdminCanUninstall=Cài đặt này chỉ có thể được gỡ bỏ bằng một người dùng có quyền người quản trị. UninstallStatusLabel=Hãy đợi khi %1 được gỡ khỏi máy tính của bạn. UninstalledAll=%1 đã được gỡ bỏ thành công khỏi máy tính của bạn. UninstalledMost=%1 đã được gỡ bỏ thành công.%n%nMột số thành phần không thể được gỡ bỏ. Hãy làm việc này một cách thủ công. UninstalledAndNeedsRestart=Để hoàn thành việc gỡ cài đặt %1, bạn phải khởi động lại máy tính.%n%nBạn có muốn khởi động lại ngay? UninstallDataCorrupted=Tệp "%1" bị hỏng. Không thể gỡ cài đặt ; *** Uninstallation phase messages ConfirmDeleteSharedFileTitle=Gỡ bỏ tệp được chia sẻ? ConfirmDeleteSharedFile2=Hệ thống chỉ ra các tệp được chia sẻ sau không được sử dụng bởi chương trình nào. Bạn có muốn gỡ bỏ tệp này?%n%nNếu có một chương trình vẫn sử dụng tệp này mà tệp bị gỡ bỏ, chúng có thể không chạy tốt. Nếu bạn không chắc chắn, chọn Không. Để lại tệp trên hệ thống của bạn sẽ không gây ra tổn hại. SharedFileNameLabel=Tên tệp: SharedFileLocationLabel=Vị trí: WizardUninstalling=Trạng thái gỡ cài đặt StatusUninstalling=Đang gỡ cài đặt %1... ; *** Shutdown block reasons ShutdownBlockReasonInstallingApp=Đang cài đặt %1. ShutdownBlockReasonUninstallingApp=Đang gỡ cài đặt %1. ; The custom messages below aren't used by Setup itself, but if you make ; use of them in your scripts, you'll want to translate them. [CustomMessages] NameAndVersion=%1 phiên bản %2 AdditionalIcons=Các lối tắt bổ sung: CreateDesktopIcon=Tạo một &lối tắt trên Desktop CreateQuickLaunchIcon=Tạo một lối tắt &Khởi động nhanh ProgramOnTheWeb=%1 trên Web UninstallProgram=Gỡ cài đặt %1 LaunchProgram=Khởi động %1 AssocFileExtension=&Gán %1 với đuôi tệp %2 AssocingFileExtension=Đang gán %1 với đuôi tệp %2... AutoStartProgramGroupDescription=Khởi động: AutoStartProgram=Tự động khởi động %1 AddonHostProgramNotFound=%1 không thể được xác định trong thư mục bạn đã chọn.%n%nBạn có muốn tiếp tục bằng mọi giá? ================================================ FILE: publish.bat ================================================ @echo off cls rem Release Debug set config=Release set msbuild="D:\Applications\VS2022\MSBuild\Current\Bin\amd64\MSBuild.exe" set publish=%CD%\bin\publish set netVer=net8.0 set netVerFull=net8.0-windows10.0.18362.0 rmdir /q /s "%publish%" if errorlevel 1 (pause) rmdir /q /s bin\launcher if errorlevel 1 (pause) set platform=x64 call :publish rem Since BCU is now on .NET8, realistically only Arm64 and x64 Windows systems are supported now, so there's no point in building x86 rem set platform=x86 rem call :publish copy bin\launcher\BCU-launcher.exe %publish%\BCUninstaller.exe copy "%target%\BCU_manual.html" "%publish%\BCU_manual.html" copy "%target%\Licence.txt" "%publish%\Licence.txt" copy "%target%\PrivacyPolicy.txt" "%publish%\PrivacyPolicy.txt" copy "%target%\NOTICE" "%publish%\NOTICE" rmdir /q /s bin\launcher IF %config%==Release (del /f /s /q "%publish%\*.pdb") rem --- AnyCPU -------------------------------------------------- set target=%CD%\bin\publish-AnyCPU-%netVer% rmdir /q /s "%target%" if errorlevel 1 (pause) echo ====== Building AnyCPU ====== %msbuild% "source\BulkCrapUninstaller.sln" /p:filealignment=512 /t:Publish /p:DeployOnBuild=true /p:PublishSingleFile=False /p:SelfContained=False /p:PublishProtocol=FileSystem /p:Configuration=%config% /p:Platform="Any CPU" /p:TargetFrameworks=%netVerFull% /p:PublishDir="%target%" /p:PublishReadyToRun=false /p:PublishTrimmed=False /verbosity:minimal IF %config%==Release (del /f /s /q "%target%\*.pdb") pause exit rem ------------------------------------------------------------- :publish set identifier=win-%platform% set target=%CD%\bin\publish\%identifier% echo ====== Building %identifier% ====== %msbuild% "source\BulkCrapUninstaller.sln" /p:filealignment=512 /t:Restore;Rebuild /p:DeployOnBuild=true /p:PublishSingleFile=False /p:SelfContained=True /p:PublishProtocol=FileSystem /p:Configuration=%config% /p:Platform=%platform% /p:TargetFrameworks=%netVerFull% /p:PublishDir="%target%" /p:RuntimeIdentifier=%identifier% /p:PublishReadyToRun=false /p:PublishTrimmed=False /verbosity:minimal %msbuild% "source\BulkCrapUninstaller.sln" /p:filealignment=512 /t:Publish /p:DeployOnBuild=true /p:PublishSingleFile=False /p:SelfContained=True /p:PublishProtocol=FileSystem /p:Configuration=%config% /p:Platform=%platform% /p:TargetFrameworks=%netVerFull% /p:PublishDir="%target%" /p:RuntimeIdentifier=%identifier% /p:PublishReadyToRun=false /p:PublishTrimmed=False /verbosity:minimal goto :eof rem ------------------------------------------------------------- ================================================ FILE: source/BCU-console/BCU-console.csproj ================================================  Exe BCU_console Command Line Interface for Bulk Crap Uninstaller Command line utility that offers some of BCU's functionality for scripting ..\BulkCrapUninstaller\Resources\logo.ico BCU_console.Program ================================================ FILE: source/BCU-console/Program.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using Klocman.Extensions; using System; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Text; using System.Threading; using UninstallTools; using UninstallTools.Factory; using UninstallTools.Junk; using UninstallTools.Junk.Confidence; using UninstallTools.Junk.Containers; using UninstallTools.Lists; using UninstallTools.Uninstaller; namespace BCU_console { internal static class Program { private static void ShowHelp() { Console.WriteLine(@"BCU-console [help | /?] - Show help (this screen) BCU-console uninstall [drive:][path]filename [/Q] [/U] [/V] [/J=] - Uninstall applications. [drive:][path] – Specifies drive and directory of the uninstall list. filename – Specifies filename of the .bcul uninstall list that contains information about what applications to uninstall. BCU-console export [drive:][path]filename [/Q] [/U] [/V] - Export installed application data to xml file. [drive:][path] – Specifies drive and directory to where the export should be saved. filename – Specifies filename of the .xml file to save the exported application information to. BCU-console list [/Q] [/U] [/V] - Display a list of installed applications. Switches: /Q - Use quiet uninstallers wherever possible (by default only use loud). /U - Unattended mode (do not ask user for confirmation). WARNING: ONLY USE AFTER THOROUGH TESTING. UNINSTALL LISTS SHOULD BE AS SPECIFIC AS POSSIBLE TO AVOID FALSE POSITIVES. THERE ARE NO WARRANTIES, USE WITH CAUTION. /J= - Attempt to clean up leftover ""junk"" (Registry entries and files/folders) after uninstall. If no level is passed then defaults to ""VeryGood"". ***WARNING***: USE EXTREME CAUTION WHEN CHOOSING ANY LEVEL BELOW VeryGood. THERE ARE NO WARRANTIES. Valid levels are: VeryGood, Good, Questionable, Bad, Unknown /V - Verbose logging mode (show more information about what is currently happening). Return codes: 0 - The operation completed successfully. 1 - Invalid arguments. 1223 - The operation was canceled by the user."); } private static int Main(string[] args) { Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; try { Console.OutputEncoding = Encoding.Unicode; } catch (SystemException) { } var info = Assembly.GetExecutingAssembly(); Console.WriteLine(info.FullName); Console.WriteLine(); if (args.Length == 0 || args.Any(x => x.Equals("help", StringComparison.OrdinalIgnoreCase) || x.Equals("/?", StringComparison.OrdinalIgnoreCase))) { ShowHelp(); Console.ReadKey(); return 0; } try { switch (args[0].Normalize().ToLowerInvariant()) { case "uninstall": return ProcessUninstallCommand(args.Skip(1).ToArray()); case "list": return ProcessListCommand(args.Skip(1).ToArray()); case "export": return ProcessExportCommand(args.Skip(1).ToArray()); default: Console.WriteLine($"Invalid command \"{args[0]}\"\n"); ShowHelp(); return 1; } } catch (SystemException ex) { Console.WriteLine(@"Encountered an unexpected error!"); Console.WriteLine(ex); return 13; } } private static int ProcessListCommand(string[] args) { var isVerbose = args.Any(x => x.Equals("/V", StringComparison.OrdinalIgnoreCase)); var isQuiet = args.Any(x => x.Equals("/Q", StringComparison.OrdinalIgnoreCase)); var isUnattended = args.Any(x => x.Equals("/U", StringComparison.OrdinalIgnoreCase)); var serializer = new ApplicationEntrySerializer(QueryApps(isQuiet, isUnattended, isVerbose)); Console.WriteLine($@"{"Display Name",-40} {"Version",-20} {"Source",-40}"); var sb = new StringBuilder(82); for (var i = 0; i < 102; i++) { sb.Append('-'); } Console.WriteLine(sb.ToString()); foreach (var entry in serializer.Items) { var displayName = entry.DisplayNameTrimmed; if (displayName.Length > 40) { displayName = displayName.Substring(0, 40); } var version = entry.DisplayVersion ?? string.Empty; if (version.Length > 20) { version = version.Substring(0, 20); } var source = entry.AboutUrl ?? string.Empty; if (source.Length > 40) { source = source.Substring(0, 40); } Console.WriteLine($@"{displayName,-40} {version,-20} {source,-40}"); } return 0; } private static int ProcessExportCommand(string[] args) { var isVerbose = args.Any(x => x.Equals("/V", StringComparison.OrdinalIgnoreCase)); var isQuiet = args.Any(x => x.Equals("/Q", StringComparison.OrdinalIgnoreCase)); var isUnattended = args.Any(x => x.Equals("/U", StringComparison.OrdinalIgnoreCase)); args = args.Where(x => !x.StartsWith("/", StringComparison.Ordinal)).ToArray(); if (args.Length != 1) return ShowInvalidSyntaxError("Missing export filename or invalid arguments"); Console.WriteLine($@"Starting export to {args[0]}"); var apps = QueryApps(isQuiet, isUnattended, isVerbose); Console.WriteLine(@"Exporting data..."); ApplicationEntrySerializer.SerializeApplicationEntries(args[0], apps); Console.WriteLine(@"Success!"); return 0; } private static int ProcessUninstallCommand(string[] args) { if (args.Length < 1) return ShowInvalidSyntaxError("Missing path argument"); if (!File.Exists(args[0])) return ShowInvalidSyntaxError("Invalid path or missing list file"); UninstallList list; try { list = UninstallList.ReadFromFile(args[0]); if (list == null || list.Filters.Count == 0) throw new IOException("List is empty"); } catch (SystemException ex) { return ShowInvalidSyntaxError( $"Invalid or damaged uninstall list file - \"{args[0]}\"\nError: {ex.Message}\n"); } var isVerbose = args.Any(x => x.Equals("/V", StringComparison.OrdinalIgnoreCase)); var isQuiet = args.Any(x => x.Equals("/Q", StringComparison.OrdinalIgnoreCase)); var isUnattended = args.Any(x => x.Equals("/U", StringComparison.OrdinalIgnoreCase)); int junkArgumentIndex = Array.FindIndex(args, a => a.Equals("/J", StringComparison.OrdinalIgnoreCase)); string junkArg = args.Where(a => a.Equals("/J", StringComparison.OrdinalIgnoreCase) || a.StartsWith("/J=", StringComparison.OrdinalIgnoreCase)).FirstOrDefault() ?? string.Empty; ConfidenceLevel? junkConfidenceLevel = null; if(junkArg.IsNotEmpty()) { string[] junkSplit = junkArg.Split('=', 2); junkConfidenceLevel = ConfidenceLevel.VeryGood; if (junkSplit.Length == 2) { if (!Enum.TryParse(junkSplit[1], out ConfidenceLevel parsedJunkConfidenceLevel)) { Console.WriteLine($"An invalid junk confidence level was passed: {junkSplit[1]}"); ShowHelp(); return 1; } junkConfidenceLevel = parsedJunkConfidenceLevel; } } if (isUnattended) Console.WriteLine(@"WARNING: Running in unattended mode. To abort press Ctrl+C or close the window."); return RunUninstall(list, isQuiet, isUnattended, isVerbose, junkConfidenceLevel); } private static int RunUninstall(UninstallList list, bool isQuiet, bool isUnattended, bool isVerbose, ConfidenceLevel? junkConfidenceLevel = null) { Console.WriteLine(@"Starting bulk uninstall..."); var apps = QueryApps(isQuiet, isUnattended, isVerbose); apps = apps.Where(a => list.TestEntry(a) == true).OrderBy(x => x.DisplayName).ToList(); if (apps.Count == 0) { Console.WriteLine(@"No applications matched the supplied uninstall list."); return 0; } Console.WriteLine(@"{0} application(s) were matched by the list: {1}", apps.Count, string.Join("; ", apps.Select(x => x.DisplayName))); Console.WriteLine(@"These applications will now be uninstalled PERMANENTLY."); if (!isUnattended) { Console.WriteLine(@"Do you want to continue? [Y]es/[N]o"); if (Console.ReadKey(true).Key != ConsoleKey.Y) return CancelledByUser(); } Console.WriteLine(@"Setting-up for the uninstall task..."); var targets = apps.Select(a => new BulkUninstallEntry(a, a.QuietUninstallPossible, UninstallStatus.Waiting)) .ToList(); var task = UninstallManager.CreateBulkUninstallTask(targets, new BulkUninstallConfiguration(false, isQuiet, false, true, true)); var isDone = false; task.OnStatusChanged += (sender, args) => { ClearCurrentConsoleLine(); var running = task.AllUninstallersList.Count(x => x.IsRunning); var waiting = task.AllUninstallersList.Count(x => x.CurrentStatus == UninstallStatus.Waiting); var finished = task.AllUninstallersList.Count(x => x.Finished); var errors = task.AllUninstallersList.Count(x => x.CurrentStatus == UninstallStatus.Failed || x.CurrentStatus == UninstallStatus.Invalid); Console.Write("Running: {0}, Waiting: {1}, Finished: {2}, Failed: {3}", running, waiting, finished, errors); if (task.Finished) { isDone = true; Console.WriteLine(); Console.WriteLine(@"Uninstall task Finished."); foreach (var error in task.AllUninstallersList.Where(x => x.CurrentStatus != UninstallStatus.Completed && x.CurrentError != null)) Console.WriteLine($@"Error: {error.UninstallerEntry.DisplayName} - {error.CurrentError.Message}"); } }; task.Start(); while (!isDone) Thread.Sleep(250); if (junkConfidenceLevel is not null) { Console.WriteLine($"Starting junk cleanup with a minimum confidence level of {junkConfidenceLevel}"); List remainingJunk = JunkManager.FindJunk(apps, apps, _ => { }) .Where(j => j.Confidence.GetConfidence() >= junkConfidenceLevel) .ToList(); if (!remainingJunk.Any()) { Console.WriteLine($"No remaining junk found for any target applications."); return 0; } Console.WriteLine("The following junk items will be permanently deleted:"); remainingJunk.ForEach(Console.WriteLine); if (!isUnattended) { Console.WriteLine(@"Do you want to continue? [Y]es/[N]o"); if (Console.ReadKey(true).Key != ConsoleKey.Y) return CancelledByUser(); } foreach (ApplicationUninstallerEntry entry in apps) { // ApplicationUninstallerEntry doesn't currently implement an equality operator so ToLongString() will do as an object "hash". List appJunk = remainingJunk.Where(j => j.Application.ToLongString().Equals(entry.ToLongString())).ToList(); Console.WriteLine($"{entry.DisplayName} Junk - {appJunk.Count} Entries Found"); appJunk.ForEach(j => j.Delete()); } } return 0; } public static void ClearCurrentConsoleLine() { var currentLineCursor = Console.CursorTop; Console.SetCursorPosition(0, Console.CursorTop); Console.Write(new string(' ', Console.WindowWidth)); Console.SetCursorPosition(0, currentLineCursor); } private static int CancelledByUser() { Console.WriteLine(@"Operation cancelled by the user."); return 1223; } private static IList QueryApps(bool isQuiet, bool isUnattended, bool isVerbose) { ConfigureUninstallTools(); Console.WriteLine(@"Looking for applications..."); string previousMain = null; IList result; if (isQuiet || isUnattended) { result = ApplicationUninstallerFactory.GetUninstallerEntries(_ => { }); } else { result = ApplicationUninstallerFactory.GetUninstallerEntries(report => { if (previousMain != report.Message) { previousMain = report.Message; Console.WriteLine(report.Message); } if (isVerbose) { if (!string.IsNullOrEmpty(report.Inner?.Message)) { Console.Write("-> "); Console.WriteLine(report.Inner.Message); } } }); } Console.WriteLine("Found {0} applications.", result.Count); return result; } private static void ConfigureUninstallTools() { UninstallToolsGlobalConfig.ScanWinUpdates = false; UninstallToolsGlobalConfig.QuietAutomatizationKillStuck = true; UninstallToolsGlobalConfig.QuietAutomatization = true; UninstallToolsGlobalConfig.UseQuietUninstallDaemon = true; UninstallToolsGlobalConfig.AutoDetectCustomProgramFiles = true; UninstallToolsGlobalConfig.EnableAppInfoCache = false; } private static int ShowInvalidSyntaxError(string message) { Console.WriteLine("Invalid command syntax. " + message); return 87; } } } ================================================ FILE: source/BCU-launcher/BCU-launcher.rc ================================================ // Microsoft Visual C++ generated resource script. // #include "resource.h" #define APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 2 resource. // #include "winres.h" ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // English (United Kingdom) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG) LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK #pragma code_page(1252) #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // TEXTINCLUDE // 1 TEXTINCLUDE BEGIN "resource.h\0" END 2 TEXTINCLUDE BEGIN "#include ""winres.h""\r\n" "\0" END 3 TEXTINCLUDE BEGIN "\r\n" "\0" END #endif // APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Icon // // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. IDI_ICON1 ICON "..\\BulkCrapUninstaller\\Resources\\logo.ico" ///////////////////////////////////////////////////////////////////////////// // // Version // VS_VERSION_INFO VERSIONINFO FILEVERSION 1,2,0,0 PRODUCTVERSION 1,2,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L #else FILEFLAGS 0x0L #endif FILEOS 0x40004L FILETYPE 0x1L FILESUBTYPE 0x0L BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "080904b0" BEGIN VALUE "CompanyName", "Marcin Szeniak" VALUE "FileDescription", "BCUninstaller launcher" VALUE "FileVersion", "1.2.0.0" VALUE "InternalName", "BCUninstaller.exe" VALUE "LegalCopyright", "Copyright (C) 2023" VALUE "OriginalFilename", "BCUninstaller.exe" VALUE "ProductName", "BCUninstaller launcher" VALUE "ProductVersion", "1.2.0.0" END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x809, 1200 END END #endif // English (United Kingdom) resources ///////////////////////////////////////////////////////////////////////////// #ifndef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 3 resource. // ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED ================================================ FILE: source/BCU-launcher/BCU-launcher.vcxproj ================================================ Debug Win32 Release Win32 Debug x64 Release x64 16.0 Win32Proj {c54b5afd-c079-4852-960e-906b8cee0e07} TestConsole 10.0 BCU-launcher Application true v143 Unicode Static Application false v143 true Unicode Static Application true v143 Unicode Static Application false v143 true Unicode Static true $(SolutionDir)..\bin\launcher\ $(ProjectName) false $(SolutionDir)..\bin\launcher\ true $(ProjectName) $(SolutionDir)..\bin\launcher false $(SolutionDir)..\bin\launcher Level3 true WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true MultiThreadedDebug Windows true mainCRTStartup RequireAdministrator Level3 true true true WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true MultiThreaded Windows true true true RequireAdministrator mainCRTStartup Level3 true _DEBUG;_CONSOLE;%(PreprocessorDefinitions) true MultiThreadedDebug Windows true mainCRTStartup RequireAdministrator Level3 true true true NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true MultiThreaded Windows true true true mainCRTStartup RequireAdministrator ================================================ FILE: source/BCU-launcher/main.cpp ================================================ #include #include #include #include #include std::wstring ExePath() { TCHAR buffer[MAX_PATH] = { 0 }; GetModuleFileName(NULL, buffer, MAX_PATH); std::wstring::size_type pos = std::wstring(buffer).find_last_of(L"\\/"); return std::wstring(buffer).substr(0, pos); } BOOL Is64BitOS() { BOOL bIs64BitOS = FALSE; // We check if the OS is 64 Bit typedef BOOL(WINAPI* LPFN_ISWOW64PROCESS) (HANDLE, PBOOL); LPFN_ISWOW64PROCESS fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle(L"kernel32"), "IsWow64Process"); if (NULL != fnIsWow64Process) { if (!fnIsWow64Process(GetCurrentProcess(), &bIs64BitOS)) { //error, try to start the app anyways return true; } } return bIs64BitOS; } std::wstring GetLastErrorAsString() { //Get the error message ID, if any. DWORD errorMessageID = ::GetLastError(); if (errorMessageID == 0) { return std::wstring(); //No error message has been recorded } LPWSTR messageBuffer = nullptr; //Ask Win32 to give us the string version of that message ID. //The parameters we pass in, tell Win32 to create the buffer that holds the message for us (because we don't yet know how long the message string will be). size_t size = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&messageBuffer, 0, NULL); //Copy the error message into a std::string. std::wstring message(messageBuffer, size); //Free the Win32's string's buffer. LocalFree(messageBuffer); return message; } #include bool fexists(const std::wstring& filename) { std::ifstream ifile(filename.c_str()); return (bool)ifile; } bool IsWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor) { OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0, {0}, 0, 0 }; DWORDLONG const dwlConditionMask = VerSetConditionMask( VerSetConditionMask( VerSetConditionMask( 0, VER_MAJORVERSION, VER_GREATER_EQUAL), VER_MINORVERSION, VER_GREATER_EQUAL), VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL); osvi.dwMajorVersion = wMajorVersion; osvi.dwMinorVersion = wMinorVersion; osvi.wServicePackMajor = wServicePackMajor; return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE; } bool isWin7orLater() { return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN7), LOBYTE(_WIN32_WINNT_WIN7), 1); } // Needed to get MessageBox working with MFC #pragma comment(lib, "user32.lib") int main() { std::wstring p; if (Is64BitOS()) { p = ExePath() + L"\\win-x64\\BCUninstaller.exe"; if (!fexists(p)) { MessageBox(nullptr, L"This installation of BCUninstaller does not have files needed to run on 64 bit versions of Windows.\n\nDownload a 64 bit version of BCUninstaller and try again. The installer includes both 32 and 64 bit versions.", L"Could not start BCUninstaller.", MB_ICONERROR | MB_OK); return 1; } } else { p = ExePath() + L"\\win-x86\\BCUninstaller.exe"; if (!fexists(p)) { MessageBox(nullptr, L"This installation of BCUninstaller does not have files needed to run on 32 bit versions of Windows.\n\nDownload a 32 bit version of BCUninstaller and try again. The installer includes both 32 and 64 bit versions.", L"Could not start BCUninstaller.", MB_ICONERROR | MB_OK); return 1; } } if(!isWin7orLater()) { MessageBox(nullptr, L"This version of BCUninstaller needs Windows 7 SP1 / Windows Server 2008 R2 SP1 or later. Either update your system, or use an old version of BCUninstaller.\n\nTo bypass this check you can run BCUninstaller.exe directly from one of the subfolders.", L"Could not start BCUninstaller.", MB_ICONERROR | MB_OK); return 2; } // Required on some systems or CreateProcess fails p = L"\"" + p + L"\""; auto cl = p.c_str(); size_t pSizeTerminated = p.size() + 1; wchar_t* cla = new wchar_t[pSizeTerminated]; wcscpy_s(cla, pSizeTerminated, cl); STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); ZeroMemory(&pi, sizeof(pi)); // Start the child process. if (!CreateProcess(NULL, // No module name (use command line) cla, // Command line NULL, // Process handle not inheritable NULL, // Thread handle not inheritable FALSE, // Set handle inheritance to FALSE 0, // No creation flags NULL, // Use parent's environment block NULL, // Use parent's starting directory &si, // Pointer to STARTUPINFO structure &pi) // Pointer to PROCESS_INFORMATION structure ) { MessageBox(nullptr, (L"Failed to start BCUninstaller - " + GetLastErrorAsString()).c_str(), L"Could not start BCUninstaller.", MB_ICONERROR | MB_OK); printf("CreateProcess failed (%d).\n", GetLastError()); return 3; } // Wait until child process exits. //WaitForSingleObject( pi.hProcess, INFINITE ); // Close process and thread handles. CloseHandle(pi.hProcess); CloseHandle(pi.hThread); } ================================================ FILE: source/BCU-launcher/resource.h ================================================ //{{NO_DEPENDENCIES}} // Microsoft Visual C++ generated include file. // Used by BCU-launcher.rc // #define IDI_ICON1 101 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 102 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1001 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif ================================================ FILE: source/BulkCrapUninstaller/BulkCrapUninstaller.csproj ================================================  WinExe BCUninstaller Bulk Crap Uninstaller Remove large amounts of unwanted applications quickly Resources\logo.ico BulkCrapUninstaller.EntryPoint NOTICE PreserveNewest False PrivacyPolicy.txt PreserveNewest False Licence.txt PreserveNewest False BCU_manual.html PreserveNewest False es.exe PreserveNewest False PreserveNewest False PreserveNewest False True True Localisable.resx True True Resources.resx ResXFileCodeGenerator Localisable.Designer.cs ResXFileCodeGenerator Resources.Designer.cs ================================================ FILE: source/BulkCrapUninstaller/CleanLogs.bat ================================================ title Removing BCU log files... @echo off cls if not exist %LOCALAPPDATA% ( REM LOCALAPPDATA doesn't exist on windows older than Vista set APPDATASAFE=%APPDATA% ) else ( set APPDATASAFE=%LOCALAPPDATA% ) REM Wait for BCU to exit so the logs are written echo Waiting for BCUninstaller to exit... :loop tasklist | find "BCUninstaller.exe " >nul if not errorlevel 1 ( REM Wait for 1 second before checking again ping -n 2 127.0.0.1 >nul goto :loop ) REM Wait some more to be safe ping -n 2 127.0.0.1 >nul REM Move to the log dir and remove all logs. They can be under following directories: REM \CLR_v2.0\UsageLogs \CLR_v2.0_32\UsageLogs \CLR_v4.0\UsageLogs \CLR_v4.0_32\UsageLogs cd /d "%APPDATASAFE%\Microsoft" echo Deleting Assembly Usage Logs... del /f /s BCUninstaller.exe.log SteamHelper.exe.log StoreAppHelper.exe.log UninstallerAutomatizer.exe.log UpdateHelper.exe.log echo Deleting .NET generated drectories... REM Settings directory automatically created by .NET set SETTINGSDIR=%APPDATASAFE%\Marcin_Szeniak if not exist %SETTINGSDIR% ( exit ) REM Remove all directories related to BCU for /d %%G in ("%SETTINGSDIR%\BCUninstaller*") do rd /s /q "%%~G" REM Check if the settings dir is empty. If there are directories left, exit. for /d %%i in ("%SETTINGSDIR%\*") do exit REM Dir is empty, so remove it. rd "%SETTINGSDIR%" exit ================================================ FILE: source/BulkCrapUninstaller/Controls/AdvancedClipboardCopy.Designer.cs ================================================ namespace BulkCrapUninstaller.Controls { partial class AdvancedClipboardCopy { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Component Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AdvancedClipboardCopy)); groupBox1 = new System.Windows.Forms.GroupBox(); panel2 = new System.Windows.Forms.Panel(); comboBoxInsert = new System.Windows.Forms.ComboBox(); panel3 = new System.Windows.Forms.Panel(); checkBoxUnescape = new System.Windows.Forms.CheckBox(); buttonHelp = new System.Windows.Forms.Button(); textBoxPatternInput = new System.Windows.Forms.TextBox(); groupBox2 = new System.Windows.Forms.GroupBox(); textBoxResults = new System.Windows.Forms.TextBox(); panel1 = new System.Windows.Forms.Panel(); groupBox1.SuspendLayout(); panel2.SuspendLayout(); groupBox2.SuspendLayout(); SuspendLayout(); // // groupBox1 // groupBox1.Controls.Add(panel2); groupBox1.Controls.Add(textBoxPatternInput); resources.ApplyResources(groupBox1, "groupBox1"); groupBox1.Name = "groupBox1"; groupBox1.TabStop = false; // // panel2 // resources.ApplyResources(panel2, "panel2"); panel2.Controls.Add(comboBoxInsert); panel2.Controls.Add(panel3); panel2.Controls.Add(checkBoxUnescape); panel2.Controls.Add(buttonHelp); panel2.Name = "panel2"; // // comboBoxInsert // resources.ApplyResources(comboBoxInsert, "comboBoxInsert"); comboBoxInsert.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; comboBoxInsert.FormattingEnabled = true; comboBoxInsert.Items.AddRange(new object[] { resources.GetString("comboBoxInsert.Items") }); comboBoxInsert.Name = "comboBoxInsert"; comboBoxInsert.SelectedIndexChanged += comboBox1_SelectedIndexChanged; // // panel3 // resources.ApplyResources(panel3, "panel3"); panel3.Name = "panel3"; // // checkBoxUnescape // resources.ApplyResources(checkBoxUnescape, "checkBoxUnescape"); checkBoxUnescape.Name = "checkBoxUnescape"; checkBoxUnescape.UseVisualStyleBackColor = true; checkBoxUnescape.CheckedChanged += checkBox1_CheckedChanged; // // buttonHelp // resources.ApplyResources(buttonHelp, "buttonHelp"); buttonHelp.Name = "buttonHelp"; buttonHelp.UseVisualStyleBackColor = true; buttonHelp.Click += buttonHelp_Click; // // textBoxPatternInput // resources.ApplyResources(textBoxPatternInput, "textBoxPatternInput"); textBoxPatternInput.Name = "textBoxPatternInput"; textBoxPatternInput.TextChanged += RefreshResult; // // groupBox2 // groupBox2.Controls.Add(textBoxResults); resources.ApplyResources(groupBox2, "groupBox2"); groupBox2.Name = "groupBox2"; groupBox2.TabStop = false; // // textBoxResults // textBoxResults.BackColor = System.Drawing.SystemColors.Window; resources.ApplyResources(textBoxResults, "textBoxResults"); textBoxResults.Name = "textBoxResults"; textBoxResults.ReadOnly = true; // // panel1 // resources.ApplyResources(panel1, "panel1"); panel1.Name = "panel1"; // // AdvancedClipboardCopy // resources.ApplyResources(this, "$this"); AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; Controls.Add(groupBox2); Controls.Add(panel1); Controls.Add(groupBox1); Name = "AdvancedClipboardCopy"; groupBox1.ResumeLayout(false); groupBox1.PerformLayout(); panel2.ResumeLayout(false); panel2.PerformLayout(); groupBox2.ResumeLayout(false); groupBox2.PerformLayout(); ResumeLayout(false); } #endregion private System.Windows.Forms.GroupBox groupBox1; private System.Windows.Forms.GroupBox groupBox2; private System.Windows.Forms.TextBox textBoxPatternInput; private System.Windows.Forms.TextBox textBoxResults; private System.Windows.Forms.Panel panel1; private System.Windows.Forms.Button buttonHelp; private System.Windows.Forms.ComboBox comboBoxInsert; private System.Windows.Forms.Panel panel2; private System.Windows.Forms.Panel panel3; private System.Windows.Forms.CheckBox checkBoxUnescape; } } ================================================ FILE: source/BulkCrapUninstaller/Controls/AdvancedClipboardCopy.ar.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 نمط التعليمات الغاء الهروب النتائج ادخال... ================================================ FILE: source/BulkCrapUninstaller/Controls/AdvancedClipboardCopy.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text.RegularExpressions; using System.Windows.Forms; using BulkCrapUninstaller.Functions; using UninstallTools; namespace BulkCrapUninstaller.Controls { public partial class AdvancedClipboardCopy : UserControl { [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public IEnumerable Targets { get; set; } public AdvancedClipboardCopy() { InitializeComponent(); comboBoxInsert.Items.AddRange(ClipboardCopyItem.Items.Cast().ToArray()); comboBoxInsert.SelectedIndex = 0; } [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public string PatternText { get { return textBoxPatternInput.Text; } set { textBoxPatternInput.Text = value; } } public string Result => textBoxResults.Text; private void RefreshResult(object sender, EventArgs e) { try { var pattern = checkBoxUnescape.Checked ? Regex.Unescape(textBoxPatternInput.Text) : textBoxPatternInput.Text; textBoxResults.Text = string.Join(Environment.NewLine, Targets.Select(x => ClipboardCopyItem.GetStringFromPattern(pattern, x)) .ToArray()); } catch (Exception ex) { textBoxResults.Text = ex.Message; } } private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) { if (comboBoxInsert.SelectedIndex == 0) return; if (comboBoxInsert.SelectedItem is ClipboardCopyItem x) textBoxPatternInput.SelectedText = x.Name; comboBoxInsert.SelectedIndex = 0; } private void checkBox1_CheckedChanged(object sender, EventArgs e) { RefreshResult(sender, e); } private void buttonHelp_Click(object sender, EventArgs e) { MessageBoxes.DisplayHelp(); } } } ================================================ FILE: source/BulkCrapUninstaller/Controls/AdvancedClipboardCopy.cs.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Vzor Pomoc Ukončit Výsledek Vybrat ================================================ FILE: source/BulkCrapUninstaller/Controls/AdvancedClipboardCopy.de.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Muster Hilfe Ergebnis Einfügen Ausgabe abbrechen ================================================ FILE: source/BulkCrapUninstaller/Controls/AdvancedClipboardCopy.es.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Patrón Ayuda Unescape Resultados Insertar... ================================================ FILE: source/BulkCrapUninstaller/Controls/AdvancedClipboardCopy.fr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Modèle Aide Déséchap Résultats Insérer... True pl ================================================ FILE: source/BulkCrapUninstaller/Controls/AdvancedClipboardCopy.hu.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Minta Súgó Unescape Eredmény Beszúrás... ================================================ FILE: source/BulkCrapUninstaller/Controls/AdvancedClipboardCopy.it.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Percorso Aiuto Unescape Risultati Inserisci... ================================================ FILE: source/BulkCrapUninstaller/Controls/AdvancedClipboardCopy.ja.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 挿入 アンエスケープ ヘルプ パターン 結果 ================================================ FILE: source/BulkCrapUninstaller/Controls/AdvancedClipboardCopy.nl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Patroon Help Onbeschermd Resultaten Invoegen... ================================================ FILE: source/BulkCrapUninstaller/Controls/AdvancedClipboardCopy.pl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Szablon Wstaw... Pomoc Wyniki Unescape ================================================ FILE: source/BulkCrapUninstaller/Controls/AdvancedClipboardCopy.pt-BR.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Padrão Ajuda Cancelar saída Resultados Inserir... ================================================ FILE: source/BulkCrapUninstaller/Controls/AdvancedClipboardCopy.pt.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Padrão Ajuda Cancelar saída Resultados Inserir... True pl ================================================ FILE: source/BulkCrapUninstaller/Controls/AdvancedClipboardCopy.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Top, Left, Right Fill Insert... 77, 0 4, 3, 4, 3 274, 23 1 comboBoxInsert System.Windows.Forms.ComboBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel2 0 Right 351, 0 4, 3, 4, 3 7, 25 7 panel3 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel2 1 True Left 0, 0 4, 3, 4, 3 77, 25 0 Unescape checkBoxUnescape System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel2 2 Right 358, 0 4, 3, 4, 3 106, 27 106, 27 106, 27 2 Help buttonHelp System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel2 3 10, 52 4, 3, 4, 3 464, 25 7 panel2 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBox1 0 Top, Left, Right 7, 22 4, 3, 4, 3 467, 23 0 textBoxPatternInput System.Windows.Forms.TextBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBox1 1 Top 0, 0 4, 3, 4, 3 4, 3, 4, 3 482, 84 0 Pattern groupBox1 System.Windows.Forms.GroupBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 2 Fill 7, 23 4, 3, 4, 3 True Both 468, 287 0 False textBoxResults System.Windows.Forms.TextBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBox2 0 Fill 0, 89 4, 3, 4, 3 7, 7, 7, 7 482, 317 1 Results groupBox2 System.Windows.Forms.GroupBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 0 Top 0, 84 4, 3, 4, 3 482, 5 2 panel1 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 1 True 7, 15 4, 3, 4, 3 482, 406 AdvancedClipboardCopy System.Windows.Forms.UserControl, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 ================================================ FILE: source/BulkCrapUninstaller/Controls/AdvancedClipboardCopy.ru.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Шаблон Справка И выйти Результат Выбрать... True pl ================================================ FILE: source/BulkCrapUninstaller/Controls/AdvancedClipboardCopy.sl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Vzorec Pomoč Ne zbeži Rezultati Vstavi ================================================ FILE: source/BulkCrapUninstaller/Controls/AdvancedClipboardCopy.sv.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Infoga... ... Avkoda tecken Hjälp Mönster Resultat ================================================ FILE: source/BulkCrapUninstaller/Controls/AdvancedClipboardCopy.tr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Ekle... Çıkmaktan vazgeç Yardım Desen Sonuçlar ================================================ FILE: source/BulkCrapUninstaller/Controls/AdvancedClipboardCopy.vi.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Chèn... Cho phép ký tự thoát Trợ giúp Định dạng Kết quả ================================================ FILE: source/BulkCrapUninstaller/Controls/AdvancedClipboardCopy.zh-Hans.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 插入... 反转义 帮助 模式 结果 ================================================ FILE: source/BulkCrapUninstaller/Controls/AdvancedClipboardCopy.zh-Hant.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 插入 反轉義 幫助 模式 結果 ================================================ FILE: source/BulkCrapUninstaller/Controls/ClipboardCopyItem.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Reflection; using Klocman.Localising; using UninstallTools; namespace BulkCrapUninstaller.Controls { internal sealed class ClipboardCopyItem { static ClipboardCopyItem() { var results = new List(typeof (ApplicationUninstallerEntry) .GetProperties(BindingFlags.Instance | BindingFlags.Public) .Select(p => new ClipboardCopyItem(p.Name, p.GetLocalisedName(), entry => p.GetValue(entry, null))) .OrderBy(x => x.FancyName)); for (var i = 0; i < results.Count; i++) results[i].Id = string.Concat("{", i.ToString(CultureInfo.CurrentCulture), "}"); Items = results.AsEnumerable(); FormatGetterFuncs = results.Select(x => x.Getter).ToArray(); } private ClipboardCopyItem(string name, string fancyName, Func getter) { Getter = getter; FancyName = fancyName; Name = string.Concat("{", name, "}"); } public static IEnumerable Items { get; } private static Func[] FormatGetterFuncs { get; } public Func Getter { get; } public string Name { get; } public string FancyName { get; } public string Id { get; private set; } public static string GetStringFromPattern(string pattern, ApplicationUninstallerEntry entry) { return string.Format(CultureInfo.CurrentCulture, Items.Aggregate(pattern, (current, clipboardCopyItem) => current.Replace(clipboardCopyItem.Name, clipboardCopyItem.Id)), FormatGetterFuncs.Select(x => x(entry)).ToArray()); } public override string ToString() { return Name + " - " + FancyName; } } } ================================================ FILE: source/BulkCrapUninstaller/Controls/FileTargeter.Designer.cs ================================================ namespace BulkCrapUninstaller.Controls { partial class FileTargeter { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Component Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FileTargeter)); panel1 = new System.Windows.Forms.Panel(); button1 = new System.Windows.Forms.Button(); pictureBox1 = new System.Windows.Forms.PictureBox(); flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); openFileDialog1 = new System.Windows.Forms.OpenFileDialog(); panel2 = new System.Windows.Forms.Panel(); button2 = new System.Windows.Forms.Button(); panel1.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)pictureBox1).BeginInit(); panel2.SuspendLayout(); SuspendLayout(); // // panel1 // resources.ApplyResources(panel1, "panel1"); panel1.Controls.Add(button1); panel1.Name = "panel1"; // // button1 // resources.ApplyResources(button1, "button1"); button1.Name = "button1"; button1.UseVisualStyleBackColor = true; button1.Click += button1_Click; // // pictureBox1 // resources.ApplyResources(pictureBox1, "pictureBox1"); pictureBox1.Image = Properties.Resources.layerdown; pictureBox1.Name = "pictureBox1"; pictureBox1.TabStop = false; // // flowLayoutPanel1 // resources.ApplyResources(flowLayoutPanel1, "flowLayoutPanel1"); flowLayoutPanel1.Name = "flowLayoutPanel1"; // // openFileDialog1 // openFileDialog1.DereferenceLinks = false; openFileDialog1.FileName = "openFileDialog1"; resources.ApplyResources(openFileDialog1, "openFileDialog1"); openFileDialog1.Multiselect = true; // // panel2 // resources.ApplyResources(panel2, "panel2"); panel2.Controls.Add(button2); panel2.Name = "panel2"; // // button2 // resources.ApplyResources(button2, "button2"); button2.Name = "button2"; button2.UseVisualStyleBackColor = true; button2.Click += button2_Click; // // FileTargeter // AllowDrop = true; resources.ApplyResources(this, "$this"); AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; Controls.Add(panel1); Controls.Add(panel2); Controls.Add(flowLayoutPanel1); Controls.Add(pictureBox1); Name = "FileTargeter"; panel1.ResumeLayout(false); panel1.PerformLayout(); ((System.ComponentModel.ISupportInitialize)pictureBox1).EndInit(); panel2.ResumeLayout(false); panel2.PerformLayout(); ResumeLayout(false); PerformLayout(); } #endregion private System.Windows.Forms.Panel panel1; private System.Windows.Forms.Button button1; private System.Windows.Forms.PictureBox pictureBox1; private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1; private System.Windows.Forms.OpenFileDialog openFileDialog1; private System.Windows.Forms.Panel panel2; private System.Windows.Forms.Button button2; } } ================================================ FILE: source/BulkCrapUninstaller/Controls/FileTargeter.ar.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 تثبيت الدليل... حدد اي الملفات التي تنتمي للتطبيق كل الملفات|*.* ملف الارتباط او التطبيق... ================================================ FILE: source/BulkCrapUninstaller/Controls/FileTargeter.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Windows.Forms; using BulkCrapUninstaller.Functions; using BulkCrapUninstaller.Properties; using Klocman.Extensions; using Klocman.Forms.Tools; using Klocman.Tools; using UninstallTools; namespace BulkCrapUninstaller.Controls { public partial class FileTargeter : UserControl { public FileTargeter() { InitializeComponent(); } private void ProcessFiles(ICollection files) { if (files == null || files.Count < 1) return; var folders = new List(); foreach (var file in files) { var fname = file; if (string.IsNullOrEmpty(fname)) continue; RewindDropLoop: if (Directory.Exists(fname)) { folders.Add(fname); continue; } if (!File.Exists(fname)) { try { fname = ProcessTools.SeparateArgsFromCommand(file).FileName; if (Directory.Exists(fname)) { folders.Add(fname); continue; } } catch (Exception ex) { Console.WriteLine(ex); } } if (fname.TrimEnd().EndsWith(".lnk", StringComparison.OrdinalIgnoreCase)) { try { var result = WindowsTools.ResolveShortcut(fname); if (result != null) { fname = result; goto RewindDropLoop; } } catch (Exception ex) { PremadeDialogs.GenericError(ex); } } else { try { var dirName = Path.GetDirectoryName(fname); folders.Add(dirName); } catch (Exception ex) { PremadeDialogs.GenericError(ex); } } } var distinctFolders = folders.Where(x => x != null) .Select(x => x.SafeNormalize().ToLowerInvariant().Trim().Trim('\'', '"').Trim()) .Distinct(); var folderInfos = distinctFolders.Select(x => { try { return new DirectoryInfo(x); } catch (Exception ex) { Console.WriteLine(ex); return null; } }).Where(x => x != null); var results = folderInfos.Where(x => !UninstallToolsGlobalConfig.IsSystemDirectory(x) && !UninstallToolsGlobalConfig.IsKnownFolder(x)).ToList(); DirectoriesSelected?.Invoke(this, new DirectoriesSelectedEventArgs(results)); } protected override void OnLoad(EventArgs e) { base.OnLoad(e); AllowDrop = true; } public event EventHandler DirectoriesSelected; private void button1_Click(object sender, EventArgs e) { if (openFileDialog1.ShowDialog() == DialogResult.OK && openFileDialog1.FileNames.Any()) ProcessFiles(openFileDialog1.FileNames); } private void button2_Click(object sender, EventArgs e) { if (ParentForm != null) ParentForm.Enabled = false; else Enabled = false; var path = MessageBoxes.SelectFolder(Localisable.FileTargeter_SelectDirectoryWithAppsToRemove); if (!string.IsNullOrEmpty(path)) ProcessFiles(new[] { path }); if (ParentForm != null) ParentForm.Enabled = true; else Enabled = true; } } public sealed class DirectoriesSelectedEventArgs : EventArgs { public DirectoriesSelectedEventArgs(ICollection selectedFiles) { SelectedFiles = selectedFiles; } public ICollection SelectedFiles { get; } } } ================================================ FILE: source/BulkCrapUninstaller/Controls/FileTargeter.cs.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Adresář instalace Vyberte všechny soubory, které patří k aplikaci Všechny soubory|*.* Odkaz nebo soubor aplikace... ================================================ FILE: source/BulkCrapUninstaller/Controls/FileTargeter.de.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Install Verzeichnis Wählen Sie alle Dateien aus, die zur Anwendung gehören Alle Dateien|*.* Link oder Anwendungsdatei... ================================================ FILE: source/BulkCrapUninstaller/Controls/FileTargeter.es.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Directorio de instalación Seleccione los archivos que pertenecen a la aplicación Todos los archivos|*.* Enlace o archivo de la aplicación... ================================================ FILE: source/BulkCrapUninstaller/Controls/FileTargeter.fr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Dossier d'installation... Sélectionner tout fichier appartenant à l'application Tous les fichiers|*.* Lien ou fichier d'application... ================================================ FILE: source/BulkCrapUninstaller/Controls/FileTargeter.hu.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Telepítési hely... Válassza ki az alkalmazáshoz tartozó fájlokat Minden fájl|*.* Hivatkozás vagy programfájl... ================================================ FILE: source/BulkCrapUninstaller/Controls/FileTargeter.it.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Cartella installazione Seleziona qualunque file che fa parte dell'applicazione Tutti i file|*.* Collegamento o file dell'applicazione ================================================ FILE: source/BulkCrapUninstaller/Controls/FileTargeter.ja.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 インストールディレクトリ アプリケーションに属するファイルを選択する 全てのファイル|*.* リンクまたはアプリケーションのファイル ================================================ FILE: source/BulkCrapUninstaller/Controls/FileTargeter.nl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Installatie map... Alle bestanden|*.* Link of programma bestand... Selecteer de bestanden die behoren tot het programma ================================================ FILE: source/BulkCrapUninstaller/Controls/FileTargeter.pl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Miejsce instalacji... Wybierz dowolne pliki należące do aplikacji Wszystkie pliki|*.* Link lub plik aplikacji... ================================================ FILE: source/BulkCrapUninstaller/Controls/FileTargeter.pt-BR.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Diretório de instalação... Selecione os arquivos que pertencem à aplicação Todos os arquivos|*.* Link ou arquivo do aplicativo ================================================ FILE: source/BulkCrapUninstaller/Controls/FileTargeter.pt.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Directório de Instalação Seleccione qualquer dos arquivos que pertencem à aplicação Todos os arquivos|*.* Link ou arquivo da aplicação... ================================================ FILE: source/BulkCrapUninstaller/Controls/FileTargeter.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 True GrowAndShrink True Bottom 14, 2 4, 3, 4, 3 182, 29 4 Link or application's file... button1 System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel1 0 Top 58, 35 4, 3, 4, 3 14, 2, 14, 2 210, 33 4 panel1 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 0 Left 2, 2 4, 3, 4, 3 6, 0, 0, 0 56, 87 AutoSize 5 pictureBox1 System.Windows.Forms.PictureBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 3 True Top 58, 2 4, 3, 4, 3 210, 0 7 flowLayoutPanel1 System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 2 17, 17 All files|*.* Select any files that belong to the application True GrowAndShrink True Bottom 14, 2 4, 3, 4, 3 182, 29 4 Install directory... button2 System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel2 0 Top 58, 2 4, 3, 4, 3 14, 2, 14, 2 210, 33 8 panel2 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 1 True 7, 15 4, 3, 4, 3 2, 2, 2, 2 270, 91 openFileDialog1 System.Windows.Forms.OpenFileDialog, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 FileTargeter System.Windows.Forms.UserControl, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 ================================================ FILE: source/BulkCrapUninstaller/Controls/FileTargeter.ru.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 папка установки Выберите файлы, принадлежащие приложению Все|*.* Ссылка или файл приложения ================================================ FILE: source/BulkCrapUninstaller/Controls/FileTargeter.sl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Mapa za nameščanje... Izberite vse datoteke, ki pripadajo aplikaciji Vse datoteke|*.* Povezava ali datoteka aplikacije... ================================================ FILE: source/BulkCrapUninstaller/Controls/FileTargeter.sv.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Installationsmapp... Välj de filer som tillhör appen Alla filer|*.* Länk eller programmets fil ================================================ FILE: source/BulkCrapUninstaller/Controls/FileTargeter.tr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Kurulum dizini Uygulamaya ait tüm dosyaları seçin Tüm dosyalar|*.* Bağlantı veya uygulamanın dosyası ... ================================================ FILE: source/BulkCrapUninstaller/Controls/FileTargeter.vi.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Thư mục cài đặt... Chọn bất kỳ tệp nào liên quan đến ứng dụng Tất cả tệp|*.* Đường dẫn hoặc tệp tin ứng dụng... ================================================ FILE: source/BulkCrapUninstaller/Controls/FileTargeter.zh-Hans.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 安装目录... 选择属于应用程序的所有文件 所有文件|*.* 链接或应用程序文件... ================================================ FILE: source/BulkCrapUninstaller/Controls/FileTargeter.zh-Hant.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 安裝目錄 選擇屬於應用程式的所有文件 所有檔案|*.* 連結應用程式檔案 ================================================ FILE: source/BulkCrapUninstaller/Controls/ListLegend.Designer.cs ================================================ namespace BulkCrapUninstaller.Controls { partial class ListLegend { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Component Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ListLegend)); labelWinFeature = new System.Windows.Forms.Label(); labelOrphaned = new System.Windows.Forms.Label(); labelInvalid = new System.Windows.Forms.Label(); labelUnverified = new System.Windows.Forms.Label(); labelVerified = new System.Windows.Forms.Label(); labelLegend = new System.Windows.Forms.Label(); labelStoreApp = new System.Windows.Forms.Label(); flowLayoutPanellabelVerified = new System.Windows.Forms.FlowLayoutPanel(); flowLayoutPanellabelUnverified = new System.Windows.Forms.FlowLayoutPanel(); flowLayoutPanellabelInvalid = new System.Windows.Forms.FlowLayoutPanel(); flowLayoutPanellabelOrphaned = new System.Windows.Forms.FlowLayoutPanel(); flowLayoutPanellabelWinFeature = new System.Windows.Forms.FlowLayoutPanel(); flowLayoutPanellabelStoreApp = new System.Windows.Forms.FlowLayoutPanel(); flowLayoutPanellabelVerified.SuspendLayout(); flowLayoutPanellabelUnverified.SuspendLayout(); flowLayoutPanellabelInvalid.SuspendLayout(); flowLayoutPanellabelOrphaned.SuspendLayout(); flowLayoutPanellabelWinFeature.SuspendLayout(); flowLayoutPanellabelStoreApp.SuspendLayout(); SuspendLayout(); // // labelWinFeature // resources.ApplyResources(labelWinFeature, "labelWinFeature"); labelWinFeature.Cursor = System.Windows.Forms.Cursors.Hand; labelWinFeature.Name = "labelWinFeature"; labelWinFeature.MouseDown += OnMouseDown; // // labelOrphaned // resources.ApplyResources(labelOrphaned, "labelOrphaned"); labelOrphaned.Cursor = System.Windows.Forms.Cursors.Hand; labelOrphaned.Name = "labelOrphaned"; labelOrphaned.MouseDown += OnMouseDown; // // labelInvalid // resources.ApplyResources(labelInvalid, "labelInvalid"); labelInvalid.Cursor = System.Windows.Forms.Cursors.Hand; labelInvalid.Name = "labelInvalid"; labelInvalid.MouseDown += OnMouseDown; // // labelUnverified // resources.ApplyResources(labelUnverified, "labelUnverified"); labelUnverified.Cursor = System.Windows.Forms.Cursors.Hand; labelUnverified.Name = "labelUnverified"; labelUnverified.MouseDown += OnMouseDown; // // labelVerified // resources.ApplyResources(labelVerified, "labelVerified"); labelVerified.Cursor = System.Windows.Forms.Cursors.Hand; labelVerified.Name = "labelVerified"; labelVerified.MouseDown += OnMouseDown; // // labelLegend // labelLegend.BackColor = System.Drawing.SystemColors.Control; labelLegend.Cursor = System.Windows.Forms.Cursors.Hand; resources.ApplyResources(labelLegend, "labelLegend"); labelLegend.Name = "labelLegend"; labelLegend.MouseDown += OnMouseDown; // // labelStoreApp // resources.ApplyResources(labelStoreApp, "labelStoreApp"); labelStoreApp.Cursor = System.Windows.Forms.Cursors.Hand; labelStoreApp.Name = "labelStoreApp"; // // flowLayoutPanellabelVerified // resources.ApplyResources(flowLayoutPanellabelVerified, "flowLayoutPanellabelVerified"); flowLayoutPanellabelVerified.BackColor = System.Drawing.Color.PaleGreen; flowLayoutPanellabelVerified.Controls.Add(labelVerified); flowLayoutPanellabelVerified.Name = "flowLayoutPanellabelVerified"; flowLayoutPanellabelVerified.MouseDown += OnMouseDown; // // flowLayoutPanellabelUnverified // resources.ApplyResources(flowLayoutPanellabelUnverified, "flowLayoutPanellabelUnverified"); flowLayoutPanellabelUnverified.BackColor = System.Drawing.Color.Aquamarine; flowLayoutPanellabelUnverified.Controls.Add(labelUnverified); flowLayoutPanellabelUnverified.Name = "flowLayoutPanellabelUnverified"; flowLayoutPanellabelUnverified.MouseDown += OnMouseDown; // // flowLayoutPanellabelInvalid // resources.ApplyResources(flowLayoutPanellabelInvalid, "flowLayoutPanellabelInvalid"); flowLayoutPanellabelInvalid.BackColor = System.Drawing.Color.LightSteelBlue; flowLayoutPanellabelInvalid.Controls.Add(labelInvalid); flowLayoutPanellabelInvalid.Name = "flowLayoutPanellabelInvalid"; flowLayoutPanellabelInvalid.MouseDown += OnMouseDown; // // flowLayoutPanellabelOrphaned // resources.ApplyResources(flowLayoutPanellabelOrphaned, "flowLayoutPanellabelOrphaned"); flowLayoutPanellabelOrphaned.BackColor = System.Drawing.Color.LightPink; flowLayoutPanellabelOrphaned.Controls.Add(labelOrphaned); flowLayoutPanellabelOrphaned.Name = "flowLayoutPanellabelOrphaned"; flowLayoutPanellabelOrphaned.MouseDown += OnMouseDown; // // flowLayoutPanellabelWinFeature // resources.ApplyResources(flowLayoutPanellabelWinFeature, "flowLayoutPanellabelWinFeature"); flowLayoutPanellabelWinFeature.BackColor = System.Drawing.Color.SlateBlue; flowLayoutPanellabelWinFeature.Controls.Add(labelWinFeature); flowLayoutPanellabelWinFeature.Name = "flowLayoutPanellabelWinFeature"; flowLayoutPanellabelWinFeature.MouseDown += OnMouseDown; // // flowLayoutPanellabelStoreApp // resources.ApplyResources(flowLayoutPanellabelStoreApp, "flowLayoutPanellabelStoreApp"); flowLayoutPanellabelStoreApp.BackColor = System.Drawing.Color.DeepSkyBlue; flowLayoutPanellabelStoreApp.Controls.Add(labelStoreApp); flowLayoutPanellabelStoreApp.Name = "flowLayoutPanellabelStoreApp"; flowLayoutPanellabelStoreApp.MouseDown += OnMouseDown; // // ListLegend // resources.ApplyResources(this, "$this"); AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; Controls.Add(flowLayoutPanellabelStoreApp); Controls.Add(flowLayoutPanellabelWinFeature); Controls.Add(flowLayoutPanellabelOrphaned); Controls.Add(flowLayoutPanellabelInvalid); Controls.Add(flowLayoutPanellabelUnverified); Controls.Add(flowLayoutPanellabelVerified); Controls.Add(labelLegend); Cursor = System.Windows.Forms.Cursors.Hand; Name = "ListLegend"; EnabledChanged += ThisEnabledChanged; MouseDown += OnMouseDown; flowLayoutPanellabelVerified.ResumeLayout(false); flowLayoutPanellabelVerified.PerformLayout(); flowLayoutPanellabelUnverified.ResumeLayout(false); flowLayoutPanellabelUnverified.PerformLayout(); flowLayoutPanellabelInvalid.ResumeLayout(false); flowLayoutPanellabelInvalid.PerformLayout(); flowLayoutPanellabelOrphaned.ResumeLayout(false); flowLayoutPanellabelOrphaned.PerformLayout(); flowLayoutPanellabelWinFeature.ResumeLayout(false); flowLayoutPanellabelWinFeature.PerformLayout(); flowLayoutPanellabelStoreApp.ResumeLayout(false); flowLayoutPanellabelStoreApp.PerformLayout(); ResumeLayout(false); PerformLayout(); } #endregion private System.Windows.Forms.Label labelWinFeature; private System.Windows.Forms.Label labelOrphaned; private System.Windows.Forms.Label labelInvalid; private System.Windows.Forms.Label labelUnverified; private System.Windows.Forms.Label labelVerified; private System.Windows.Forms.Label labelLegend; private System.Windows.Forms.Label labelStoreApp; private System.Windows.Forms.FlowLayoutPanel flowLayoutPanellabelVerified; private System.Windows.Forms.FlowLayoutPanel flowLayoutPanellabelUnverified; private System.Windows.Forms.FlowLayoutPanel flowLayoutPanellabelInvalid; private System.Windows.Forms.FlowLayoutPanel flowLayoutPanellabelOrphaned; private System.Windows.Forms.FlowLayoutPanel flowLayoutPanellabelWinFeature; private System.Windows.Forms.FlowLayoutPanel flowLayoutPanellabelStoreApp; } } ================================================ FILE: source/BulkCrapUninstaller/Controls/ListLegend.ar.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ميزة النوافذ تطبيق غير مسجل الغاء التثبيت مفقود شهادة غير متحقق منها شهادة تم التحقق منها توضيحات اللون نوافذ متجر التطبيق ================================================ FILE: source/BulkCrapUninstaller/Controls/ListLegend.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.ComponentModel; using System.Drawing; using System.Windows.Forms; using BulkCrapUninstaller.Functions.ApplicationList; using Klocman.Forms.Tools; namespace BulkCrapUninstaller.Controls { [WindowStyleController.ControlStyle(false)] public partial class ListLegend : UserControl { public ListLegend() { InitializeComponent(); } protected override void OnLoad(EventArgs e) { base.OnLoad(e); Properties.Settings.Default.SettingBinder.Subscribe((x, y) => UpdateColors(), settings => settings.MiscColorblind, this); UpdateColors(); } private void UpdateColors() { flowLayoutPanellabelInvalid.BackColor = ApplicationListConstants.Colors.InvalidColor; flowLayoutPanellabelOrphaned.BackColor = ApplicationListConstants.Colors.UnregisteredColor; flowLayoutPanellabelUnverified.BackColor = ApplicationListConstants.Colors.UnverifiedColor; flowLayoutPanellabelVerified.BackColor = ApplicationListConstants.Colors.VerifiedColor; flowLayoutPanellabelWinFeature.BackColor = ApplicationListConstants.Colors.WindowsFeatureColor; flowLayoutPanellabelStoreApp.BackColor = ApplicationListConstants.Colors.WindowsStoreAppColor; } [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool InvalidEnabled { get { return flowLayoutPanellabelInvalid.Visible; } set { flowLayoutPanellabelInvalid.Visible = value; } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool WinFeatureEnabled { get { return flowLayoutPanellabelWinFeature.Visible; } set { flowLayoutPanellabelWinFeature.Visible = value; } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool CertificatesEnabled { get { return flowLayoutPanellabelVerified.Visible; } set { flowLayoutPanellabelVerified.Visible = value; flowLayoutPanellabelUnverified.Visible = value; } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool OrphanedEnabled { get { return flowLayoutPanellabelOrphaned.Visible; } set { flowLayoutPanellabelOrphaned.Visible = value; } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool StoreAppEnabled { get { return flowLayoutPanellabelStoreApp.Visible; } set { flowLayoutPanellabelStoreApp.Visible = value; } } private void OnMouseDown(object sender, MouseEventArgs e) { CloseRequested?.Invoke(sender, e); } private void ThisEnabledChanged(object sender, EventArgs e) { BackColor = Enabled ? SystemColors.ControlLightLight : SystemColors.Control; } public event EventHandler CloseRequested; } } ================================================ FILE: source/BulkCrapUninstaller/Controls/ListLegend.cs.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Funkce systém Windows Neregistrované aplikace Neplatný odinstalátor Neověřené certifikáty Ověřený certifikát Barevná legenda Aplikace Windows Store ================================================ FILE: source/BulkCrapUninstaller/Controls/ListLegend.de.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Windowsfunktion Nicht registrierte Anwendung Ungültiger Uninstaller Ungeprüftes Zertifikat Geprüftes Zertifikat Farblegende Windows Store Programme ================================================ FILE: source/BulkCrapUninstaller/Controls/ListLegend.es.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Característica de Windows Aplicación no registrada No hay desinstalador Certificado sin verificar Certificado verificado Leyendo colores Apps de Windows Store ================================================ FILE: source/BulkCrapUninstaller/Controls/ListLegend.fr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Fonctionnalité Windows Application non enregistrée Désinstalleur manquant Certificat non vérifié Certificat vérifié Légende des couleurs Appli du Windows Store ================================================ FILE: source/BulkCrapUninstaller/Controls/ListLegend.hu.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Windows szolgáltatás Nem regisztrált alkalmazás Hiányzó eltávolító Nem ellenőrzött Ellenőrzött tanúsítvány Színjelmagyarázat Windows Store alkalmazás ================================================ FILE: source/BulkCrapUninstaller/Controls/ListLegend.it.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Funzionalità di Windows Applicazione non registrata Disinstallatore mancante Certificato non verificato Certificato verificato Legenda colori App di Windows Store ================================================ FILE: source/BulkCrapUninstaller/Controls/ListLegend.ja.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Windowsの機能 未登録のアプリケーション アンインストーラーが見つかりません 未認証の証明書 検証済み証明書 色の説明 Windowsストアアプリ ================================================ FILE: source/BulkCrapUninstaller/Controls/ListLegend.nl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Windows onderdeel Niet geregistreerd programma De-installer ontbreekt Ongeverifieerd certificaat Geverifieerd certificaat Kleuren legenda Windows Store app ================================================ FILE: source/BulkCrapUninstaller/Controls/ListLegend.pl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Funkcja systemu Windows Niezarejestrowana aplikacja Uszkodzony dezinstalator Niezweryfikowany certyfikat Zweryfikowany certyfikat Legenda kolorów Aplikacja Windows Store ================================================ FILE: source/BulkCrapUninstaller/Controls/ListLegend.pt-BR.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Recurso do Windows Aplicativo não registrado Desinstalador faltando Certificado não verificado Certificado verificado Legenda de cores App da Loja do Windows ================================================ FILE: source/BulkCrapUninstaller/Controls/ListLegend.pt.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Funcionalidade do Windows Aplicação não registada Desinstalador invélido Certificado não verificado Certificado verificado Legenda de cores App do Windows Store True ================================================ FILE: source/BulkCrapUninstaller/Controls/ListLegend.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 True 4, 2 4, 0, 4, 0 0, 3, 1, 3 97, 21 4 Windows feature labelWinFeature System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanellabelWinFeature 0 True 4, 2 4, 0, 4, 0 0, 3, 1, 3 137, 21 3 Unregistered application labelOrphaned System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanellabelOrphaned 0 True 4, 2 4, 0, 4, 0 0, 3, 1, 3 107, 21 2 Missing uninstaller labelInvalid System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanellabelInvalid 0 True 4, 2 4, 0, 4, 0 0, 3, 1, 3 117, 21 1 Unverified certificate labelUnverified System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanellabelUnverified 0 True 4, 2 4, 0, 4, 0 0, 3, 1, 3 102, 21 0 Verified certificate MiddleCenter labelVerified System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanellabelVerified 0 Top 0, 0 4, 0, 4, 0 182, 23 5 Color legend MiddleCenter labelLegend System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 6 True NoControl 4, 2 4, 0, 4, 0 0, 3, 1, 3 112, 21 6 Windows Store App labelStoreApp System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanellabelStoreApp 0 True GrowAndShrink Top 0, 23 4, 3, 4, 3 0, 2, 0, 0 182, 23 7 flowLayoutPanellabelVerified System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 5 True GrowAndShrink Top 0, 46 4, 3, 4, 3 0, 2, 0, 0 182, 23 8 flowLayoutPanellabelUnverified System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 4 True GrowAndShrink Top 0, 69 4, 3, 4, 3 0, 2, 0, 0 182, 23 9 flowLayoutPanellabelInvalid System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 3 True GrowAndShrink Top 0, 92 4, 3, 4, 3 0, 2, 0, 0 182, 23 10 flowLayoutPanellabelOrphaned System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 2 True GrowAndShrink Top 0, 115 4, 3, 4, 3 0, 2, 0, 0 182, 23 11 flowLayoutPanellabelWinFeature System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 1 True GrowAndShrink Top 0, 138 4, 3, 4, 3 0, 2, 0, 0 182, 23 12 flowLayoutPanellabelStoreApp System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 0 True 7, 15 True GrowAndShrink 4, 3, 4, 3 184, 2 182, 161 ListLegend System.Windows.Forms.UserControl, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 ================================================ FILE: source/BulkCrapUninstaller/Controls/ListLegend.ru.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Компонент Windows Незарегистрирован Без деинсталлятора Непроверен Проверен Легенда подсветки Приложение магазина Windows ================================================ FILE: source/BulkCrapUninstaller/Controls/ListLegend.sl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Windows funkcija Neregistrirane aplikacije Neveljaven odstranjevalec Nepreverjeno digitalno potrdilo Preverjeno digitalno potrdilo Barvna legenda Windows Store aplikacija ================================================ FILE: source/BulkCrapUninstaller/Controls/ListLegend.sv.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Windows-funktion Oregistrerad app Saknad avinstallerare Overifierat certifikat Verifierat certifikat Färgförklaring Windows Store App ================================================ FILE: source/BulkCrapUninstaller/Controls/ListLegend.tr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Pencere özelliği Kayıtsız uygulama Eksik kaldırıcı Doğrulanmamış sertifika Doğrulanmış Sertifika Renk açıklaması Windows Mağazası Uygulaması ================================================ FILE: source/BulkCrapUninstaller/Controls/ListLegend.vi.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Windows Feature Ứng dụng chưa đăng ký Thiếu trình gỡ cài đặt Chứng chỉ chưa được xác minh Chứng chỉ đã được xác minh Chú thích màu Ứng dụng từ Windows Store ================================================ FILE: source/BulkCrapUninstaller/Controls/ListLegend.zh-Hans.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Windows功能 未注册的应用程序 卸载程序丢失 未验证的证书 已验证的证书 颜色图例 Windows商店应用 ================================================ FILE: source/BulkCrapUninstaller/Controls/ListLegend.zh-Hant.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Windows 功能 未註冊的應用程式 遺失移除軟體 未驗證的憑證 已驗證的憑證 顏色圖例 Windows 商店應用程式 ================================================ FILE: source/BulkCrapUninstaller/Controls/RelatedUninstallerAdder.Designer.cs ================================================ namespace BulkCrapUninstaller.Forms { partial class RelatedUninstallerAdder { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(RelatedUninstallerAdder)); objectListView1 = new BrightIdeasSoftware.ObjectListView(); olvColumnName = new BrightIdeasSoftware.OLVColumn(); olvColumnEnabled = new BrightIdeasSoftware.OLVColumn(); olvColumnRelatedApps = new BrightIdeasSoftware.OLVColumn(); flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); labelInfo = new System.Windows.Forms.Label(); labelInfo2 = new System.Windows.Forms.Label(); pictureBox1 = new System.Windows.Forms.PictureBox(); ((System.ComponentModel.ISupportInitialize)objectListView1).BeginInit(); flowLayoutPanel1.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)pictureBox1).BeginInit(); SuspendLayout(); // // objectListView1 // objectListView1.AllColumns.Add(olvColumnName); objectListView1.AllColumns.Add(olvColumnEnabled); objectListView1.AllColumns.Add(olvColumnRelatedApps); objectListView1.CellEditUseWholeCell = false; objectListView1.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { olvColumnName, olvColumnEnabled, olvColumnRelatedApps }); resources.ApplyResources(objectListView1, "objectListView1"); objectListView1.FullRowSelect = true; objectListView1.GridLines = true; objectListView1.MultiSelect = false; objectListView1.Name = "objectListView1"; objectListView1.ShowGroups = false; objectListView1.ShowItemToolTips = true; objectListView1.UseCompatibleStateImageBehavior = false; objectListView1.View = System.Windows.Forms.View.Details; // // olvColumnName // resources.ApplyResources(olvColumnName, "olvColumnName"); // // olvColumnEnabled // olvColumnEnabled.CheckBoxes = true; olvColumnEnabled.Hideable = false; resources.ApplyResources(olvColumnEnabled, "olvColumnEnabled"); // // olvColumnRelatedApps // olvColumnRelatedApps.FillsFreeSpace = true; resources.ApplyResources(olvColumnRelatedApps, "olvColumnRelatedApps"); // // flowLayoutPanel1 // resources.ApplyResources(flowLayoutPanel1, "flowLayoutPanel1"); flowLayoutPanel1.Controls.Add(labelInfo); flowLayoutPanel1.Controls.Add(labelInfo2); flowLayoutPanel1.Name = "flowLayoutPanel1"; // // labelInfo // resources.ApplyResources(labelInfo, "labelInfo"); labelInfo.Name = "labelInfo"; // // labelInfo2 // resources.ApplyResources(labelInfo2, "labelInfo2"); labelInfo2.Name = "labelInfo2"; // // pictureBox1 // resources.ApplyResources(pictureBox1, "pictureBox1"); pictureBox1.Image = Properties.Resources.warning; pictureBox1.Name = "pictureBox1"; pictureBox1.TabStop = false; // // RelatedUninstallerAdder // resources.ApplyResources(this, "$this"); AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; Controls.Add(pictureBox1); Controls.Add(objectListView1); Controls.Add(flowLayoutPanel1); Name = "RelatedUninstallerAdder"; ((System.ComponentModel.ISupportInitialize)objectListView1).EndInit(); flowLayoutPanel1.ResumeLayout(false); flowLayoutPanel1.PerformLayout(); ((System.ComponentModel.ISupportInitialize)pictureBox1).EndInit(); ResumeLayout(false); PerformLayout(); } #endregion private BrightIdeasSoftware.ObjectListView objectListView1; private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1; private System.Windows.Forms.Label labelInfo; private BrightIdeasSoftware.OLVColumn olvColumnEnabled; private BrightIdeasSoftware.OLVColumn olvColumnName; private BrightIdeasSoftware.OLVColumn olvColumnRelatedApps; private System.Windows.Forms.PictureBox pictureBox1; private System.Windows.Forms.Label labelInfo2; } } ================================================ FILE: source/BulkCrapUninstaller/Controls/RelatedUninstallerAdder.ar.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 اسم الغاء التثبيت ذات الصلة اضافة الى المهمة تتعلق بما يلي: هذه قائمه بالتطبيقات التي قد تكون مرتبطة بالتطبيقات التي قمت بتحديدها للغاء التثبيت. يمكنك أضافه هذه التطبيقات إلى قائمه انتظار إلغاء التثبيت بواسطة التحقق منها. تاكد من عدم إلغاء تثبيت البرامج الهامه التي قد لا تزال التطبيقات الأخرى تحتاج إلى العمل بشكل صحيح. ================================================ FILE: source/BulkCrapUninstaller/Controls/RelatedUninstallerAdder.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System.Collections.Generic; using System.Linq; using System.Windows.Forms; using UninstallTools; namespace BulkCrapUninstaller.Forms { public partial class RelatedUninstallerAdder : UserControl { public RelatedUninstallerAdder() { InitializeComponent(); olvColumnEnabled.AspectGetter = rowObject => ((RelatedApplicationEntry)rowObject).Enabled; olvColumnEnabled.AspectPutter = (rowObject, value) => ((RelatedApplicationEntry)rowObject).Enabled = (bool)value; olvColumnRelatedApps.AspectGetter = rowObject => string.Join(", ", ((RelatedApplicationEntry)rowObject).RelatedEntries.Select(x => x.DisplayName).ToArray()); olvColumnName.AspectGetter = rowObject => ((RelatedApplicationEntry)rowObject).Entry.DisplayName; } private IEnumerable Entries => (objectListView1.Objects ?? Enumerable.Empty()).Cast(); public IEnumerable GetResults() { return Entries.Where(x => x.Enabled).Select(x => x.Entry); } public void SetRelatedApps(IEnumerable items) { objectListView1.SetObjects(items .OrderBy(x => x.RelatedEntries.FirstOrDefault()?.DisplayName ?? string.Empty) .ThenBy(x => x.Entry.DisplayName).ToList()); } public sealed class RelatedApplicationEntry { public RelatedApplicationEntry(ApplicationUninstallerEntry entry, IEnumerable relatedEntries) { Entry = entry; RelatedEntries = relatedEntries.OrderBy(x => x.DisplayName).ToList(); Enabled = false; } private bool _enabled; public bool Enabled { get { return _enabled; } set { _enabled = value; } } public ApplicationUninstallerEntry Entry { get; } public IEnumerable RelatedEntries { get; } } } } ================================================ FILE: source/BulkCrapUninstaller/Controls/RelatedUninstallerAdder.cs.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Související název odinstalátoru Přidat do úkolu Související s: Toto je seznam aplikací, které mohou být odinstalovány. Aplikace můžete přidat do fronty odinstalace a zkontrolovat je. Ujistěte se, že nechcete odinstalovat důležitý software, nebo že je nepoužívají jiné aplikace pro svoji práci. ================================================ FILE: source/BulkCrapUninstaller/Controls/RelatedUninstallerAdder.de.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Verbundener Uninstaller Aufgabe hinzufügen Verbunden mit: Dies ist eine Liste der Anwendungen welche im Zusammenhang mit den ausgewählten Anwendungen stehen, die du zum Deinstallieren markiert hast. Du kannst diese Anwendungen durch markieren zur Überprüfung in die Warteschlange zum Prüfen hinzufügen Bitte stelle sicher, dass keine wichtigen Dateien deinstalliert werden welche von anderen Anwendungen noch benötigt werden. ================================================ FILE: source/BulkCrapUninstaller/Controls/RelatedUninstallerAdder.es.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Nombre del desinstalador relacionado Añadir a la tarea Relacionado con: Esta es la lista de aplicaciones que podrían estar relacionadas con las aplicaciones que seleccionó para desinstalar. Puede añadir estas aplicaciones a la cola de desinstalación comprobándolas. Asegúrese de no desinstalar un software importante que otras aplicaciones podrían necesitar para funcionar correctamente. ================================================ FILE: source/BulkCrapUninstaller/Controls/RelatedUninstallerAdder.fr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Nom du désinstalleur relatif Ajouter à la tâche Relatif à: Ceci est une liste d'applications en relation avec les applications sélectionnées à désinstaller. Vous pouvez ajouter ces applications à la file de désinstallation en les cochant. Assurez-vous de ne pas désinstaller un logiciel important dont les autres applications auraient besoin pour fonctionner correctement. ================================================ FILE: source/BulkCrapUninstaller/Controls/RelatedUninstallerAdder.hu.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Kapcsolódó eltávolító neve Feladathoz adás Kapcsolódik ehhez: Ezek olyan alkalmazások, amelyek az eltávolítandó alkalmazásokhoz kapcsolódhatnak. Ezeket az alkalmazásokat hozzáadhatja az eltávolítási várólistához. Ne távolítson el fontos programokat, mert más alkalmazásoknak továbbra is szükségük lehet rájuk ahhoz, hogy megfelelően működjenek. ================================================ FILE: source/BulkCrapUninstaller/Controls/RelatedUninstallerAdder.it.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Nome disinstallatore associato Aggiungi alle operazioni Associato a: Questo è un elenco di applicazioni che potrebbero essere correlate alle applicazioni selezionate per la disinstallazione. Puoi aggiungere queste applicazioni alla coda di disinstallazione spuntandole. Assicurati di non disinstallare programmi importanti di cui necessitino altre applicazioni per funzionare correttamente ================================================ FILE: source/BulkCrapUninstaller/Controls/RelatedUninstallerAdder.ja.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 関連するアンインストーラー名 タスクに追加 関連アプリ: これは、アンインストールすることに選択したアプリケーションに関連している可能性があるアプリケーションのリストです。これらのアプリケーションをアンインストールキューに追加するには、チェックを入れてください。 他のアプリケーションが正常に動作するために必要な重要なソフトウェアをアンインストールしないようにしてください。 ================================================ FILE: source/BulkCrapUninstaller/Controls/RelatedUninstallerAdder.nl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Verbonden de-installer naam Aan taak toevoegen Verbonden met: Dit is een lijst met toepassingen die mogelijk verbonden zijn met toepassingen, die u selecteerde om te de-installeren. U kunt deze toepassingen toevoegen aan de de-installer wachtrij door deze aan te vinken. Overtuig u zelf ervan dat u geen belangrijke software de-installeert, die andere toepassingen nog nodig hebben om goed te werken. ================================================ FILE: source/BulkCrapUninstaller/Controls/RelatedUninstallerAdder.pl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Nazwa powiązanego dezinstalatora Dodaj do zadania Powiązany z: Jest to lista aplikacji, które mogą być związane z aplikacjami wybranymi do odinstalowania. Zaznaczając je, możesz dodać te aplikacje do kolejki dezinstalacji. Upewnij się że nie odinstalowujesz czegoś wymaganego do poprawnego działania innych aplikacji i systemu. ================================================ FILE: source/BulkCrapUninstaller/Controls/RelatedUninstallerAdder.pt-BR.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Nome do desinstalador relacionado Adicionar a tarefa Relacionado com: Isso é uma lista de aplicações que podem ser relacionadas às aplicações que você selecionou. Você pode adicionar essas aplicações à fila de desinstalação selecionando-as. Certifique-se de não desinstalar softwares que podem ser necessários para outras aplicações. ================================================ FILE: source/BulkCrapUninstaller/Controls/RelatedUninstallerAdder.pt.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Nome do correspondente desinstalador Juntar à tarefa Relacionado com: Esta é a lista de aplicativos que podem estar relacionados com os aplicativos que selecionou para desinstalar. Pode adicioná-los à lista de desinstalação, procedendo à sua verificação. Certifique-se de que não desinstala software importante que ainda é necessário para que outras aplicações funcionem correctamente. ================================================ FILE: source/BulkCrapUninstaller/Controls/RelatedUninstallerAdder.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Related uninstaller name 250 Add to task Center 85 Related to: 264 Fill 7, 65 4, 3, 4, 3 722, 268 1 objectListView1 BrightIdeasSoftware.ObjectListView, ObjectListView, Culture=neutral, PublicKeyToken=null $this 1 True True 4, 0 4, 0, 4, 0 58, 0, 0, 5 656, 35 0 This is a list of applications that might be related to the applications you selected to uninstall. You can add these applications to the uninstall queue by checking them. labelInfo System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel1 0 True 4, 35 4, 0, 4, 0 58, 0, 0, 0 649, 15 0 Make sure that you don't uninstall important software that other applications might still need to work properly. labelInfo2 System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel1 1 Top TopDown 7, 7 4, 3, 4, 3 0, 58 0, 0, 0, 7 722, 58 0 False flowLayoutPanel1 System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 2 Center NoControl 8, 3 4, 3, 4, 3 58, 58 11 pictureBox1 System.Windows.Forms.PictureBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 0 True 7, 15 4, 3, 4, 3 7, 7, 7, 7 736, 340 olvColumnName BrightIdeasSoftware.OLVColumn, ObjectListView, Culture=neutral, PublicKeyToken=null olvColumnEnabled BrightIdeasSoftware.OLVColumn, ObjectListView, Culture=neutral, PublicKeyToken=null olvColumnRelatedApps BrightIdeasSoftware.OLVColumn, ObjectListView, Culture=neutral, PublicKeyToken=null RelatedUninstallerAdder System.Windows.Forms.UserControl, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 ================================================ FILE: source/BulkCrapUninstaller/Controls/RelatedUninstallerAdder.ru.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Имя связанного деинсталлятора Добавить к задаче Связан с: Это список приложений, которые могут быть связаны с приложениями, выбранными для удаления. Их можно добавить в очередь удаления, предварительно проверив. Убедитесь, что Вы не удаляете компоненты, нужные для правильной работы других приложений. ================================================ FILE: source/BulkCrapUninstaller/Controls/RelatedUninstallerAdder.sl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Povezano ime odstranjevalca Dodaj v opravilo Povezan z: To je seznam aplikacij, ki so lahko povezane z izbranimi aplikacijami za odstranitev. Te programe lahko dodate v čakalno vrsto za odstranitev, tako da jih preverite. Prepričajte se, da ne odstranite pomembne programe, ki bi jih lahko še vedno uporabljale druge aplikacije za pravilno delovanje. ================================================ FILE: source/BulkCrapUninstaller/Controls/RelatedUninstallerAdder.tr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 İlgili kaldırıcı adı Görev ekle İlişkili; Bu, kaldırmak için seçtiğiniz uygulamalar ile ilgili olabilecek uygulamaların bir listesidir. Bu uygulamaları, kontrol ederek sırasına ekleyebilirsiniz. Diğer uygulamaların düzgün çalışması için gerekli olabilecek önemli yazılımları kaldırdığınızdan emin olun. ================================================ FILE: source/BulkCrapUninstaller/Controls/RelatedUninstallerAdder.vi.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Tên trình gỡ cài có đặt liên quan Thêm vào danh sách tác vụ Liên quan đến: Đây là danh sách các ứng dụng có thể liên quan đến ứng các dụng bạn đã chọn để gỡ cài đặt. Bằng cách kiểm tra các ứng dụng này, bạn có thể thêm chúng vào hàng đợi gỡ cài đặt. Hãy cẩn thận để không gỡ cài đặt phần mềm quan trọng mà các ứng dụng khác có thể cần để hoạt động bình thường. ================================================ FILE: source/BulkCrapUninstaller/Controls/RelatedUninstallerAdder.zh-Hans.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 关联卸载程序名称 添加到任务 关联到: 这是可能与所选应用程序相关的应用程序列表。你可以通过选中它们将这些应用程序添加到卸载队列。 确保不要卸载其他应用程序工作需要的重要软件。 ================================================ FILE: source/BulkCrapUninstaller/Controls/RelatedUninstallerAdder.zh-Hant.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 移除相關軟體名稱 新增任務 關聯到: 這些是相關的應用程式,你可以透過新增來將它們加入到移除列表內。 確保移除軟體時沒有相關的服務正在執行 ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/AdvancedFilters.Designer.cs ================================================ namespace BulkCrapUninstaller.Controls { partial class AdvancedFilters { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Component Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AdvancedFilters)); this.uninstallListEditor1 = new UninstallTools.Controls.UninstallListEditor(); this.toolStripUninstallerList = new System.Windows.Forms.ToolStrip(); this.toolStripButtonToBasicFilters = new System.Windows.Forms.ToolStripButton(); this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator(); this.toolStripButtonAddSelectedAsFilters = new System.Windows.Forms.ToolStripButton(); this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); this.toolStripButtonOpenUl = new System.Windows.Forms.ToolStripButton(); this.toolStripButtonSaveUl = new System.Windows.Forms.ToolStripButton(); this.toolStripButtonSaveUlDef = new System.Windows.Forms.ToolStripButton(); this.toolStripButtonDelete = new System.Windows.Forms.ToolStripButton(); this.saveUlDialog = new System.Windows.Forms.SaveFileDialog(); this.openUlDialog = new System.Windows.Forms.OpenFileDialog(); this.toolStripUninstallerList.SuspendLayout(); this.SuspendLayout(); // // uninstallListEditor1 // resources.ApplyResources(this.uninstallListEditor1, "uninstallListEditor1"); this.uninstallListEditor1.Name = "uninstallListEditor1"; // // toolStripUninstallerList // this.toolStripUninstallerList.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden; this.toolStripUninstallerList.ImageScalingSize = new System.Drawing.Size(22, 22); this.toolStripUninstallerList.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.toolStripButtonToBasicFilters, this.toolStripSeparator3, this.toolStripButtonAddSelectedAsFilters, this.toolStripSeparator1, this.toolStripButtonOpenUl, this.toolStripButtonSaveUl, this.toolStripButtonSaveUlDef, this.toolStripButtonDelete}); resources.ApplyResources(this.toolStripUninstallerList, "toolStripUninstallerList"); this.toolStripUninstallerList.Name = "toolStripUninstallerList"; // // toolStripButtonToBasicFilters // this.toolStripButtonToBasicFilters.Image = global::BulkCrapUninstaller.Properties.Resources.magnifyforward; resources.ApplyResources(this.toolStripButtonToBasicFilters, "toolStripButtonToBasicFilters"); this.toolStripButtonToBasicFilters.Name = "toolStripButtonToBasicFilters"; this.toolStripButtonToBasicFilters.Click += new System.EventHandler(this.toolStripButtonToBasicFilters_Click); // // toolStripSeparator3 // this.toolStripSeparator3.Name = "toolStripSeparator3"; resources.ApplyResources(this.toolStripSeparator3, "toolStripSeparator3"); // // toolStripButtonAddSelectedAsFilters // this.toolStripButtonAddSelectedAsFilters.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; this.toolStripButtonAddSelectedAsFilters.Image = global::BulkCrapUninstaller.Properties.Resources.add_multiple; resources.ApplyResources(this.toolStripButtonAddSelectedAsFilters, "toolStripButtonAddSelectedAsFilters"); this.toolStripButtonAddSelectedAsFilters.Name = "toolStripButtonAddSelectedAsFilters"; this.toolStripButtonAddSelectedAsFilters.Click += new System.EventHandler(this.toolStripButtonAddSelectedAsFilters_Click); // // toolStripSeparator1 // this.toolStripSeparator1.Name = "toolStripSeparator1"; resources.ApplyResources(this.toolStripSeparator1, "toolStripSeparator1"); // // toolStripButtonOpenUl // resources.ApplyResources(this.toolStripButtonOpenUl, "toolStripButtonOpenUl"); this.toolStripButtonOpenUl.Name = "toolStripButtonOpenUl"; this.toolStripButtonOpenUl.Click += new System.EventHandler(this.toolStripButtonOpenUl_Click); // // toolStripButtonSaveUl // resources.ApplyResources(this.toolStripButtonSaveUl, "toolStripButtonSaveUl"); this.toolStripButtonSaveUl.Name = "toolStripButtonSaveUl"; this.toolStripButtonSaveUl.Click += new System.EventHandler(this.ShowSaveDialog); // // toolStripButtonSaveUlDef // this.toolStripButtonSaveUlDef.Image = global::BulkCrapUninstaller.Properties.Resources.weather_sun_set; resources.ApplyResources(this.toolStripButtonSaveUlDef, "toolStripButtonSaveUlDef"); this.toolStripButtonSaveUlDef.Name = "toolStripButtonSaveUlDef"; this.toolStripButtonSaveUlDef.Click += new System.EventHandler(this.toolStripButtonSaveUlDef_Click); // // toolStripButtonDelete // this.toolStripButtonDelete.Image = global::BulkCrapUninstaller.Properties.Resources.delete; resources.ApplyResources(this.toolStripButtonDelete, "toolStripButtonDelete"); this.toolStripButtonDelete.Name = "toolStripButtonDelete"; this.toolStripButtonDelete.Click += new System.EventHandler(this.toolStripButtonDelete_Click); // // saveUlDialog // this.saveUlDialog.DefaultExt = "bcul"; resources.ApplyResources(this.saveUlDialog, "saveUlDialog"); this.saveUlDialog.FileOk += new System.ComponentModel.CancelEventHandler(this.saveUlDialog_FileOk); // // openUlDialog // this.openUlDialog.DefaultExt = "bcul"; resources.ApplyResources(this.openUlDialog, "openUlDialog"); this.openUlDialog.FileOk += new System.ComponentModel.CancelEventHandler(this.openUlDialog_FileOk); // // AdvancedFilters // resources.ApplyResources(this, "$this"); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.Controls.Add(this.uninstallListEditor1); this.Controls.Add(this.toolStripUninstallerList); this.Name = "AdvancedFilters"; this.toolStripUninstallerList.ResumeLayout(false); this.toolStripUninstallerList.PerformLayout(); this.ResumeLayout(false); this.PerformLayout(); } #endregion private UninstallTools.Controls.UninstallListEditor uninstallListEditor1; private System.Windows.Forms.ToolStrip toolStripUninstallerList; private System.Windows.Forms.ToolStripButton toolStripButtonToBasicFilters; private System.Windows.Forms.ToolStripSeparator toolStripSeparator3; private System.Windows.Forms.ToolStripButton toolStripButtonOpenUl; private System.Windows.Forms.ToolStripButton toolStripButtonSaveUl; private System.Windows.Forms.ToolStripButton toolStripButtonSaveUlDef; private System.Windows.Forms.SaveFileDialog saveUlDialog; private System.Windows.Forms.OpenFileDialog openUlDialog; private System.Windows.Forms.ToolStripButton toolStripButtonAddSelectedAsFilters; private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; private System.Windows.Forms.ToolStripButton toolStripButtonDelete; } } ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/AdvancedFilters.ar.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 الفلترة الاساسيه افتح... حفظ باسم... حفظ باسم افتراضي اضافه تطبيقات محدده باسم فلترة قوائم الغاء تثبيت|*.bcul حفظ قائمه الغاء التثبيت... قوائم الغاء تثبيت|*.bcul فتح قائمه الغاء التثبيت... حذف الافتراضي ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/AdvancedFilters.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using BulkCrapUninstaller.Functions; using BulkCrapUninstaller.Properties; using Klocman.Forms.Tools; using System; using System.Collections.Generic; using System.ComponentModel; using System.IO; using System.Linq; using System.Security; using System.Windows.Forms; using UninstallTools; using UninstallTools.Lists; namespace BulkCrapUninstaller.Controls { public partial class AdvancedFilters : UserControl { public event EventHandler CurrentListChanged; public event EventHandler CurrentListFileNameChanged; public event EventHandler FiltersChanged; public event EventHandler UnsavedChangesChanged; private static readonly string DefaultUninstallListPath = Path.Combine(Program.AssemblyLocation.FullName, Resources.DefaultUninstallListFilename); private string _currentListFileName; private bool _unsavedChanges; public UninstallList CurrentList => uninstallListEditor1.CurrentList; public bool UnsavedChanges { get { return _unsavedChanges; } private set { if (_unsavedChanges != value) { _unsavedChanges = value; UnsavedChangesChanged?.Invoke(this, EventArgs.Empty); } } } public string CurrentListFileName { get { return _currentListFileName; } private set { if (_currentListFileName != value) { _currentListFileName = value; CurrentListFileNameChanged?.Invoke(this, EventArgs.Empty); } } } public AdvancedFilters() { InitializeComponent(); } protected override void OnLoad(EventArgs e) { base.OnLoad(e); uninstallListEditor1.CurrentListChanged += OnCurrentListChanged; uninstallListEditor1.FiltersChanged += OnFiltersChanged; toolStripButtonDelete.Enabled = File.Exists(DefaultUninstallListPath); } private bool AskToSaveUnsaved() { if (!UnsavedChanges || uninstallListEditor1.CurrentList == null) return true; switch (MessageBoxes.AskToSaveUninstallList()) { case MessageBoxes.PressedButton.Cancel: return false; case MessageBoxes.PressedButton.Yes: return ShowSaveDialog(); case MessageBoxes.PressedButton.No: return true; default: throw new InvalidEnumArgumentException(); } } public void LoadUninstallList(UninstallList list) { CurrentListFileName = string.Empty; uninstallListEditor1.CurrentList = list; } /// /// Load a list silently from filename /// /// Filename of the list public void LoadUninstallList(string fileName) { try { var result = UninstallList.ReadFromFile(fileName); CurrentListFileName = fileName; uninstallListEditor1.CurrentList = result; UnsavedChanges = false; } catch (SecurityException ex) { PremadeDialogs.GenericError(ex); } catch (Exception ex) { PremadeDialogs.GenericError("File is not an uninstall list or it can't be opened", "Please note that uninstall lists are saved in the \"Advanced filtering\" view, not by exporting. Lists should have the .bcul extension.\n\nError message: " + ex.Message); } } /// /// Show file select gui /// public void LoadUninstallList() { toolStripButtonOpenUl_Click(this, EventArgs.Empty); } private void OnCurrentListChanged(object sender, EventArgs e) { if (CurrentList == null) CurrentListFileName = string.Empty; UnsavedChanges = false; CurrentListChanged?.Invoke(sender, e); } private void OnFiltersChanged(object sender, EventArgs e) { UnsavedChanges = true; FiltersChanged?.Invoke(sender, e); } private void openUlDialog_FileOk(object sender, CancelEventArgs e) { LoadUninstallList(openUlDialog.FileName); } private void saveUlDialog_FileOk(object sender, CancelEventArgs e) { try { CurrentList.SaveToFile(saveUlDialog.FileName); CurrentListFileName = saveUlDialog.FileName; UnsavedChanges = false; } catch (Exception ex) { PremadeDialogs.GenericError(ex); } } private void ShowSaveDialog(object sender, EventArgs e) { ShowSaveDialog(); } private bool ShowSaveDialog() { if (!string.IsNullOrEmpty(CurrentListFileName)) { try { saveUlDialog.InitialDirectory = Path.GetDirectoryName(CurrentListFileName); saveUlDialog.FileName = Path.GetFileName(CurrentListFileName); } catch (ArgumentException) { } catch (PathTooLongException) { } } return saveUlDialog.ShowDialog(this) == DialogResult.OK; } private void toolStripButtonOpenUl_Click(object sender, EventArgs e) { if (!AskToSaveUnsaved()) return; if (!string.IsNullOrEmpty(CurrentListFileName)) { try { openUlDialog.InitialDirectory = Path.GetDirectoryName(CurrentListFileName); openUlDialog.FileName = Path.GetFileName(CurrentListFileName); } catch (ArgumentException) { } catch (PathTooLongException) { } } openUlDialog.ShowDialog(this); } private void toolStripButtonSaveUlDef_Click(object sender, EventArgs e) { CurrentList.SaveToFile(DefaultUninstallListPath); CurrentListFileName = DefaultUninstallListPath; toolStripButtonDelete.Enabled = true; } private void toolStripButtonToBasicFilters_Click(object sender, EventArgs e) { if (!AskToSaveUnsaved()) return; uninstallListEditor1.CurrentList = null; } [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public Func> SelectedEntryGetter { get; set; } private void toolStripButtonAddSelectedAsFilters_Click(object sender, EventArgs e) { if (SelectedEntryGetter == null) throw new InvalidOperationException(nameof(SelectedEntryGetter) + " is null"); if (CurrentList == null) throw new InvalidOperationException(nameof(CurrentList) + " is null"); var entries = SelectedEntryGetter(); var filters = entries.Select(x => new Filter(x.DisplayName, false, new FilterCondition(x.DisplayName, ComparisonMethod.Equals, nameof(ApplicationUninstallerEntry.DisplayName)))); CurrentList.AddItems(filters); RepopulateList(); } public void RepopulateList() { uninstallListEditor1.PopulateList(); //OnCurrentListChanged(this, EventArgs.Empty); OnFiltersChanged(this, EventArgs.Empty); } private void toolStripButtonDelete_Click(object sender, EventArgs e) { try { File.Delete(DefaultUninstallListPath); toolStripButtonDelete.Enabled = false; } catch (SystemException ex) { PremadeDialogs.GenericError(ex); } } } } ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/AdvancedFilters.cs.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Uložení seznamu odinstalaci ... Uložit cíl jako ... Seznam odinstalací|*.bcul Otevřené... Otevřít seznam Odinstalací ... Seznam odinstalací|*.bcul Uložit jako výchozí Základní filtrování Přidat vybrané aplikace jako filtry Odstranit výchozí ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/AdvancedFilters.de.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Einfache Filterung Hinzufügen von ausgewählten Programmen als Filter Öffnen... Speichern unter... Als Standard speichern Standard Gelöscht Uninstall Listen|*.bcul Speichern einer Uninstall Liste... Uninstall Listen|*.bcul Öffnen einer Uninstall Liste... ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/AdvancedFilters.es.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Guardar una Lista de Desinstalación... Guardar como... Listas de Desinstalación|*.bcul Abrir... Abrir una Lista de Desinstalación... Listas de Desinstalación|*.bcul Guardar como predeterminado Filtrado básico Añadir seleccionados como filtros Eliminar por defecto ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/AdvancedFilters.fr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Enregistrer une Liste de Désinstallation... Enregistrer sous... Listes de désinstallation|*.bcul Ouvrir... Ouvrir une Liste de Désinstallation... Listes de désinstallation|*.bcul Enregistrer par défaut Filtrage basique Ajouter applis sélectionnées comme filtres Supprimer le défaut pl True 192, 17 314, 17 17, 17 ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/AdvancedFilters.hu.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Mentés egy eltávolítási listába... Mentés másként... Eltávolítási lista|*.bcul Megnyitás... Eltávolítási lista megnyitása... Eltávolítási lista|*.bcul Mentés alapértékként Alap szűrés Szűrőként adja hozzá a kiválasztott alkalmazásokat Alapértelmezett törlés ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/AdvancedFilters.it.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Salva elenco disinstallazione... Salva come... Elenco disinstallazione|*.bcul Apri... Apri elenco disinstallazione... Elenco disinstallazione|*.bcul Salva come predefinito Filtro base Aggiungi selezionati come filtri Elimina predefinito ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/AdvancedFilters.ja.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 基本フィルタ 選択したアプリケーションをフィルタとして追加 開く... 名前を付けて保存... デフォルトとして保存 デフォルトを削除 アンインストールリスト|*.bcul アンインストールリスト アンインストールリスト|*.bcul アンインストールリストを保存... ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/AdvancedFilters.nl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Basis filtering Openen... Opslaan als... Als standaard opslaan Voeg geselecteerde programma's toe als filters De-installeer lijsten|*.bcul Een de-installeer lijst opslaan... De-installeer lijsten|*.bcul Open een de-installeer lijst ... Standaard verwijderen ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/AdvancedFilters.pl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Podstawowe filtrowanie Otwórz... Zapisz jako... Zapisz jako domyślne Listy dezinstalatorów|*.bcul Zapisz listę dezinstalatorów... Listy dezinstalatorów|*.bcul Otwórz listę dezinstalatorów... Dodaj wybrane aplikacje jako filtry Usuń domyślne ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/AdvancedFilters.pt-BR.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Filtragem básica Adicionar os aplicativos selecionados como filtros Abrir... Salvar como... Salvar como padrão Listas de Desinstalação|*.bcul Salvar Lista de Desinstalação... Listas de Desinstalação|*.bcul Abrir uma Lista de Desinstalação... Excluir padrão ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/AdvancedFilters.pt.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Salvar Lista de Desinstalação... Salvar como... Listas de Desinstalação|*.bcul Abrir... Abrir uma Lista de Desinstalação... Listas de Desinstalação|*.bcul Salvar como padrão Filtragem básica Adicionar os aplicativos selecionados como filtros Excluir padrão pl True 192, 17 314, 17 17, 17 ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/AdvancedFilters.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Fill 0, 29 310, 0 319, 483 2 uninstallListEditor1 UninstallTools.Controls.UninstallListEditor, UninstallTools, Version=4.3.0.34856, Culture=neutral, PublicKeyToken=null $this 0 Magenta 104, 26 Basic filtering 6, 29 Magenta 26, 26 Add selected applications as filters 6, 29 iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAFdSURBVGhD7dehS8VQFIDxgYLBYjMYLILVZLBbzFYNgs1q MQoGMdoV/wCjxS6CxWATQbPFYhKZfkd24TIO292d7uzh+eCHj4173HvM3WfheZ7neZ73/1rAM746OMeo msINtIttM6q2oF1kilF1C+0iU/xq2i+w0ittoJVeaQOt9EobaKVX2sDgGhOT9gbEJ1YwMWlvQoSddx3a eQuNd4i24B3ytWMa99Uxa613iLboENIOtPMWztBYfcErZivyun7egtwh82isvmgX0hHq56wcoLV4wQPk 72IR8inE56y8QO6O1uJFG3KALhAft7SNpMKCn0dbWZar0TFrd0hOFsSPttx/kv7CGpKTBWHz20R9mJVL dCpsfjN4gjZ0aB9YQqeOq5/70IZaOEHn5NEmm80btKFDk014DlmdQhtqYQ9ZLUOeWtrQoT1CNuSsrqAN tRA2ZM/zPM/zPM/LrSi+AcolLVcO8kgZAAAAAElFTkSuQmCC Magenta 26, 26 Open... iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADQSURBVGhD7Zm9DcIwFAbTMgBj0DAAYgQaNqBCrMM8iHUY gSLwPSk09lOU2HrEiu6kkxv/XZMU7gAAoEV28taIdpdirvLTiHaXYlYf8pbPIG1v78yQkJeMwvb2ziTE IKQCQsYgpAJCxlh9yGr+7EtIiEFIgIQYhARIiEFIgH8JuchzobbW2zM1PqTv+63GIoa17r6JhBiETIWQ mZSEHGX2ddKcvcaMlkMe0pt3lxmEzIQQx0VDJj296TIbjT9O0pt3kBnDWm9+atXTGwAABNB1XwrCm1F2 tP9AAAAAAElFTkSuQmCC Magenta 26, 26 Save as... Magenta 111, 26 Save as default Magenta 106, 26 Delete default 0, 0 319, 29 3 toolStripUninstallerList System.Windows.Forms.ToolStrip, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 1 Uninstall lists|*.bcul Save an Uninstall List... Uninstall lists|*.bcul Open an Uninstall List... 6, 13 319, 512 toolStripButtonToBasicFilters System.Windows.Forms.ToolStripButton, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripSeparator3 System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripButtonAddSelectedAsFilters System.Windows.Forms.ToolStripButton, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripSeparator1 System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripButtonOpenUl System.Windows.Forms.ToolStripButton, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripButtonSaveUl System.Windows.Forms.ToolStripButton, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripButtonSaveUlDef System.Windows.Forms.ToolStripButton, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 saveUlDialog System.Windows.Forms.SaveFileDialog, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 openUlDialog System.Windows.Forms.OpenFileDialog, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripButtonDelete System.Windows.Forms.ToolStripButton, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 AdvancedFilters System.Windows.Forms.UserControl, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 17, 17 192, 17 314, 17 True ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/AdvancedFilters.ru.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Сохранить список деинсталляции... Сохранить как... Список деинсталляции|*.bcul Открыть... Открыть список деинсталляции... Список деинсталяции|*.bcul Сохранить по умолчанию Основная фильтрация Добавить выбранные приложения как фильтры Удалить значение по умолчанию pl True 192, 17 314, 17 17, 17 ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/AdvancedFilters.sl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Shrani seznam odstranjevanja... Shrani kot... Seznami odstranjevanja|*.bcul Odpri... Odpri seznam odstranjevanj... Seznami odstranjevanja|*.bcul Shrani kot privzeto Osnovno filtriranje Dodaj izbrane aplikacije kot filtre Izbriši privzeto pl True 192, 17 314, 17 17, 17 ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/AdvancedFilters.sv.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Grundläggande filtrering Lägg till markerade appar som filter Öppna... Spara som... Spara som standard Ta bort standard Avinstallera listor|*.bcul Spara en avinstallations-lista Avinstallera listor|*.bcul Öppna en avinstallations-lista ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/AdvancedFilters.tr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Kolay filtreleme Seçilen uygulamaları filtre olarak ekle Aç... Farklı kaydet... Varsayılan olarak kaydet Varsayılanı sil Kaldırma listeleri|*.bcul Bir Kaldırma Listesini Kaydet ... Kaldırma listeleri|*.bcul Bir Kaldırma Listesi Açın ... ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/AdvancedFilters.vi.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Bộ lọc cơ bản Thêm các ứng dụng đã chọn làm bộ lọc Mở... Lưu thành... Lưu làm mặc định Xoá danh sách mặc định Danh sách bộ lọc gỡ cài đặt|*.bcul Lưu danh sách bộ lọc gỡ cài đặt... Danh sách bộ lọc gỡ cài đặt|*.bcul Mở danh sách bộ lọc gỡ cài đặt... ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/AdvancedFilters.zh-Hans.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 基础筛选器 添加选中应用程序为筛选器 打开... 另存为... 另存为预设 删除预设 卸载列表|*.bcul 保存卸载列表... 卸载列表|*.bcul 打开卸载列表... ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/AdvancedFilters.zh-Hant.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 基本篩選 新增尋找應用程式條件 開啟... 儲存... 另存為預設值 刪除預設值 解除安裝清單|*.bcul 儲存解除安裝清單 開啟解除安裝清單|*.bcul 開啟解除安裝清單... ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/CacheSettings.Designer.cs ================================================ namespace BulkCrapUninstaller.Controls.Settings { partial class CacheSettings { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Component Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(CacheSettings)); flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); label1 = new System.Windows.Forms.Label(); panel1 = new System.Windows.Forms.Panel(); checkBoxCerts = new System.Windows.Forms.CheckBox(); checkBoxInfo = new System.Windows.Forms.CheckBox(); button1 = new System.Windows.Forms.Button(); groupBox1 = new System.Windows.Forms.GroupBox(); flowLayoutPanel1.SuspendLayout(); groupBox1.SuspendLayout(); SuspendLayout(); // // flowLayoutPanel1 // resources.ApplyResources(flowLayoutPanel1, "flowLayoutPanel1"); flowLayoutPanel1.Controls.Add(label1); flowLayoutPanel1.Controls.Add(panel1); flowLayoutPanel1.Controls.Add(checkBoxCerts); flowLayoutPanel1.Controls.Add(checkBoxInfo); flowLayoutPanel1.Controls.Add(button1); flowLayoutPanel1.Name = "flowLayoutPanel1"; // // label1 // resources.ApplyResources(label1, "label1"); label1.Name = "label1"; // // panel1 // resources.ApplyResources(panel1, "panel1"); panel1.Name = "panel1"; // // checkBoxCerts // resources.ApplyResources(checkBoxCerts, "checkBoxCerts"); checkBoxCerts.Name = "checkBoxCerts"; checkBoxCerts.UseVisualStyleBackColor = true; // // checkBoxInfo // resources.ApplyResources(checkBoxInfo, "checkBoxInfo"); checkBoxInfo.Name = "checkBoxInfo"; checkBoxInfo.UseVisualStyleBackColor = true; // // button1 // resources.ApplyResources(button1, "button1"); button1.Name = "button1"; button1.UseVisualStyleBackColor = true; // // groupBox1 // resources.ApplyResources(groupBox1, "groupBox1"); groupBox1.Controls.Add(flowLayoutPanel1); groupBox1.Name = "groupBox1"; groupBox1.TabStop = false; // // CacheSettings // resources.ApplyResources(this, "$this"); AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; Controls.Add(groupBox1); Name = "CacheSettings"; flowLayoutPanel1.ResumeLayout(false); flowLayoutPanel1.PerformLayout(); groupBox1.ResumeLayout(false); groupBox1.PerformLayout(); ResumeLayout(false); PerformLayout(); } #endregion private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1; private System.Windows.Forms.CheckBox checkBoxCerts; private System.Windows.Forms.CheckBox checkBoxInfo; private System.Windows.Forms.Button button1; private System.Windows.Forms.GroupBox groupBox1; private System.Windows.Forms.Label label1; private System.Windows.Forms.Panel panel1; } } ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/CacheSettings.ar.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 قد لا تلاحظ التغييرات. (مثلا الحجم) BCU يمكن للتخزين المؤقت تقليل أوقات البحث بشكل كبير ، ولكن إذا تم تعديل التطبيق لأعاده التشغيل.BCU ملاحظه: لتنفيذ هذه الإعدادات قد تتطلب نتائج تفحص شهادة تطبيق ذاكره التخزين المؤقت ذاكره التخزين المؤقت المجمعة معلومات مفقوده مسح مخابئ تخزين ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/CacheSettings.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System.Windows.Forms; using Klocman.Binding.Settings; namespace BulkCrapUninstaller.Controls.Settings { public partial class CacheSettings : UserControl { private readonly SettingBinder _settings = Properties.Settings.Default.SettingBinder; public CacheSettings() { InitializeComponent(); } protected override void OnLoad(System.EventArgs e) { base.OnLoad(e); if (DesignMode) return; _settings.BindControl(checkBoxCerts, x => x.CacheCertificates, this); _settings.BindControl(checkBoxInfo, x => x.CacheAppInfo, this); _settings.SendUpdates(this); Disposed += (x, y) => _settings.RemoveHandlers(this); button1.Click += (x, y) => { Program.ClearCaches(true); button1.Enabled = false; }; } } } ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/CacheSettings.cs.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Ukládání do mezipaměti může výrazně zkrátit dobu vyhledávání, ale jen pokud je aplikace upraveny, BCU nemusí zaznamenat změny. (např. velikost) Poznámka: Chcete-li aby se projevilo tato nastavení může být požadován restart BCU. Výsledky prohledávání certifikátů aplikací v mezipaměti Ve vyrovnávací paměti byly shromážděny chybějící informace Vymazání mezipamětí Mezipamět ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/CacheSettings.de.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Die Benutzung des Cache kann die Suchgeschwindigkeit stark verkürzen. Wenn ein Programm aber verändert wurde, kann BCU diese Änderung nicht finden. (z.B. Größe) Bemerkung: Um diese Änderung zu aktivieren muss BCU neu gestartet werden. Scan Ergebnisse der Cache Anwendung zertifizieren. Cache sammelt verlorene Informationen Cache löschen Caching ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/CacheSettings.es.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 El almacenamiento en caché puede reducir en gran medida los tiempos de búsqueda, pero si una aplicación se modifica, BCU podría no notar los cambios. (ej. el tamaño) NOTA: Para que estos ajustes surtan efecto puede ser necesario reiniciar BCU. Almacenar en caché los resultados del escaneo de certificados de aplicación Almacenar en caché la información faltante recopilada Limpiar cachés Almacenamiento en la caché ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/CacheSettings.fr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 La mise en cache peut beaucoup réduire le temps de recherche, mais si une application est modifiée, BCU pourrait ne pas noter le changement (ex. la taille). NOTE : pour prendre effet, ces paramètres peuvent requérir le redémarrage de BCU. Mettre en cache les résultats de scan de certificat d'application Mettre en cache l'information manquante collectée Effacer les caches Mise en cache ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/CacheSettings.hu.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 A gyorsítótárazással nagymértékben csökkenthető a keresési idő, de ha egy alkalmazás módosul, a BCU nem feltétlenül veszi észre a változásokat. (pl. méret) MEGJEGYZÉS: Ahhoz, hogy ezek a beállítások érvénybe lépjenek, a BCU újraindítása szükséges lehet. Az alkalmazástanúsítvány vizsgálat eredményeinek gyorsítótárazása Az összegyűjtött hiányzó információk gyorsítótárazása Gyorsítótár törlése Gyorsítótározás ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/CacheSettings.it.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Il caching può ridurre notevolmente il tempo di ricerca, ma se una applicazione viene modificata BCU potrebbe non accorgersi del cambiamento (ad es. la dimensione). NOTA: per attivare queste opzioni potrebbe essere necessario riavviare BCU. Risultati controllo certificato della cache applicazione La cache ha raccolto informazioni mancanti Svuota cache Caching ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/CacheSettings.ja.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 キャッシュは検索時間を大幅に短縮できますが、アプリケーションが変更された場合、BCUが変更に気づかないことがあります。(例: サイズ) 注:これらの設定を反映するには、BCUの再起動が必要な場合があります。 アプリケーション証明書のスキャン結果をキャッシュする 収集された不足情報をキャッシュする キャッシュをクリア キャッシュ ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/CacheSettings.nl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Caching kan zoektijden aanzienlijk reduceren, maar als een programma is gewijzigd, heeft BCU de wijziging(en) mogelijk niet opgemerkt (bijv. de grootte). Opm.: voordat deze instellingen effect hebben, moet BCU mogelijk herstart worden. Cache programma certifcaat scan resultaten Ontbrekende door cache verzamelde informatie Wissen caches Caching ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/CacheSettings.pl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Buforowanie może znacznie skrócić czas wyszukiwania, ale w przypadku modyfikacji aplikacji BCU może nie zauważyć zmian (np. zmiany rozmiaru). UWAGA: Aby zastosować te ustawienia może być konieczne ponowne uruchomienie BCU. Buforuj zebrane informacje o certyfikatach Buforuj zebrane informacje o aplikacjach Wyczyść bufory Buforowanie ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/CacheSettings.pt-BR.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Cache pode reduzir significamente o tempo de busca, mas se uma aplicação é modificada BCU pode não reconhecer as mudaças.(Ex: Tamanho) NOTA: Para as mudaças terem efeito é necessário a reinicialização do BCU. Resultados da verificação de cache do certificado da aplicação Cache das informações ausentes coletadas Limpar Cache Caches ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/CacheSettings.pt.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 A cache pode reduzir em muito os tempos de pesquisa, mas se um aplicativo for modificado, a BCU pode não notar as alterações (como, por exemplo, o tamanho). NOTA: Para que surta efeito, essas configurações podem exigir a reiniciação do BCU. Resultados da verificação do certificado de aplicativo da cache Informação em falta na cache recolhida Limpar a cache Cache em processamento ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/CacheSettings.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Top, Left, Right True True 4, 0 4, 0, 4, 0 0, 0, 0, 4 552, 49 0 Caching can greatly reduce searching times, but if an application is modified BCU might not notice the changes. (e.g. size) NOTE: To take effect these settings might require BCU to restart. label1 System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel1 0 0, 49 0, 0, 0, 0 0, 0 3 panel1 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel1 1 True 4, 53 4, 4, 4, 4 240, 19 1 Cache application certificate scan results checkBoxCerts System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel1 2 True 4, 80 4, 4, 4, 4 220, 19 2 Cache collected missing information checkBoxInfo System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel1 3 4, 107 4, 4, 4, 4 144, 34 3 Clear caches button1 System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel1 4 TopDown 6, 16 4, 4, 4, 4 602, 145 0 False flowLayoutPanel1 System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBox1 0 True GrowAndShrink Top 0, 0 4, 4, 4, 4 6, 4, 6, 0 612, 181 0 Caching groupBox1 System.Windows.Forms.GroupBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 0 True 7, 15 4, 4, 4, 4 612, 272 CacheSettings System.Windows.Forms.UserControl, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/CacheSettings.ru.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Кэширование может значительно сократить время поиска, но, если приложение изменено, BCU может не заметить изменений. (например, размер) ПРИМЕЧАНИЕ: Для вступления в силу этих параметров может потребоваться перезапуск BCU. Кэш результатов сканирования сертификатов приложений Кэш сбора недостающей информации Очистить кэш Кэширование ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/CacheSettings.sl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Medpomnjenje lahko izjemno skrajša čas iskanja toda, če je aplikacija spremenjena, BCU morda ne bodo opazili sprememb. (npr. velikost) OPOMBA: Za uveljavitev teh nastavitev bo morda potrebno BCU ponovno zagnati. Rezultati pregleda certifikata aplikacije za medpomnjenje Manjkajoče informacije zbranega medpomnilnika Počisti medpomnilnike Medpomnjenje ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/CacheSettings.sv.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Cachning kan kraftigt minska söktiderna, men om en applikation ändras kanske inte BCU upptäcker förändringarna. (t.ex. storlek). OBS: För att träda i kraft kan dessa inställningar kräva att BCU startas om. Cacha resultat från applikationscertifikatskanning Cacha samlad saknad information Rensa cache Cachning ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/CacheSettings.tr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Önbelleğe alma, arama sürelerini büyük ölçüde azaltabilir, ancak bir uygulama değiştirilirse BCU, değişiklikleri fark etmeyebilir. (ör. boyut) NOT: Bu ayarların yürürlüğe girmesi için BCU'nun yeniden başlatılması gerekebilir. Önbellek uygulama sertifikası tarama sonuçları Önbellek eksik bilgi topladı Önbelleği temizle Önbelleğe alınıyor ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/CacheSettings.vi.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Bộ nhớ đệm có thể giảm đáng kể thời gian tìm kiếm nhưng BCU có thể không biết những thay đổi đối với ứng dụng của bạn. Lưu ý: Bạn có thể cần phải khởi động lại BCU để các cài đặt này có hiệu lực. Lưu trữ tạm thời các kết quả quét chứng chỉ ứng dụng Lưu trữ tạm thời thông tin bị thiếu được thu thập Xoá bộ nhớ đệm Bộ nhớ đệm ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/CacheSettings.zh-Hans.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 缓存可以大大减少搜索时间,但如果修改了应用程序,BCU可能不会注意到更改。 (例如大小) 注意:要使设置生效,可能需要重启BCU。 缓存应用程序证书扫描结果 缓存收集的丢失信息 清除缓存 缓存 ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/CacheSettings.zh-Hant.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 快取可以大大降低搜尋時間,但如果修改應用程式,BCU可能不會注意到變更。(例如大小) 警告:要使設定生效,可能需要重新啟動BCU。 快取應用程式證書掃描結果 快取收集到的遺失資訊 清理快取 快取 ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/PropertiesSidebar.Designer.cs ================================================ using System.ComponentModel; using System.Windows.Forms; using BulkCrapUninstaller.Functions.Tracking; using Klocman.Controls; namespace BulkCrapUninstaller.Controls { partial class PropertiesSidebar { /// /// Required designer variable. /// private IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Component Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { components = new Container(); ComponentResourceManager resources = new ComponentResourceManager(typeof(PropertiesSidebar)); checkBoxOrphans = new CheckBox(); checkBoxInvalidTest = new CheckBox(); checkBoxCertTest = new CheckBox(); groupBox2 = new GroupBox(); flowLayoutPanel2 = new FlowLayoutPanel(); checkBoxListHideMicrosoft = new CheckBox(); checkBoxListSysComp = new CheckBox(); checkBoxListProtected = new CheckBox(); checkBoxTweaks = new CheckBox(); checkBoxShowUpdates = new CheckBox(); checkBoxWinFeature = new CheckBox(); checkBoxShowStoreApps = new CheckBox(); groupBox1 = new GroupBox(); flowLayoutPanel1 = new FlowLayoutPanel(); checkBoxViewCheckboxes = new CheckBox(); checkBoxViewGroups = new CheckBox(); checkBoxHighlightSpecial = new CheckBox(); toolTip1 = new ToolTip(components); usageTracker1 = new UsageTracker(); groupBox2.SuspendLayout(); flowLayoutPanel2.SuspendLayout(); groupBox1.SuspendLayout(); flowLayoutPanel1.SuspendLayout(); SuspendLayout(); // // checkBoxOrphans // resources.ApplyResources(checkBoxOrphans, "checkBoxOrphans"); checkBoxOrphans.Name = "checkBoxOrphans"; toolTip1.SetToolTip(checkBoxOrphans, resources.GetString("checkBoxOrphans.ToolTip")); checkBoxOrphans.UseVisualStyleBackColor = true; // // checkBoxInvalidTest // resources.ApplyResources(checkBoxInvalidTest, "checkBoxInvalidTest"); checkBoxInvalidTest.Name = "checkBoxInvalidTest"; toolTip1.SetToolTip(checkBoxInvalidTest, resources.GetString("checkBoxInvalidTest.ToolTip")); checkBoxInvalidTest.UseVisualStyleBackColor = true; // // checkBoxCertTest // resources.ApplyResources(checkBoxCertTest, "checkBoxCertTest"); checkBoxCertTest.Name = "checkBoxCertTest"; toolTip1.SetToolTip(checkBoxCertTest, resources.GetString("checkBoxCertTest.ToolTip")); checkBoxCertTest.UseVisualStyleBackColor = true; // // groupBox2 // resources.ApplyResources(groupBox2, "groupBox2"); groupBox2.Controls.Add(flowLayoutPanel2); groupBox2.Name = "groupBox2"; groupBox2.TabStop = false; // // flowLayoutPanel2 // resources.ApplyResources(flowLayoutPanel2, "flowLayoutPanel2"); flowLayoutPanel2.Controls.Add(checkBoxListHideMicrosoft); flowLayoutPanel2.Controls.Add(checkBoxOrphans); flowLayoutPanel2.Controls.Add(checkBoxListSysComp); flowLayoutPanel2.Controls.Add(checkBoxListProtected); flowLayoutPanel2.Controls.Add(checkBoxTweaks); flowLayoutPanel2.Controls.Add(checkBoxShowUpdates); flowLayoutPanel2.Controls.Add(checkBoxWinFeature); flowLayoutPanel2.Controls.Add(checkBoxShowStoreApps); flowLayoutPanel2.Name = "flowLayoutPanel2"; // // checkBoxListHideMicrosoft // resources.ApplyResources(checkBoxListHideMicrosoft, "checkBoxListHideMicrosoft"); checkBoxListHideMicrosoft.Name = "checkBoxListHideMicrosoft"; toolTip1.SetToolTip(checkBoxListHideMicrosoft, resources.GetString("checkBoxListHideMicrosoft.ToolTip")); checkBoxListHideMicrosoft.UseVisualStyleBackColor = true; // // checkBoxListSysComp // resources.ApplyResources(checkBoxListSysComp, "checkBoxListSysComp"); checkBoxListSysComp.Name = "checkBoxListSysComp"; toolTip1.SetToolTip(checkBoxListSysComp, resources.GetString("checkBoxListSysComp.ToolTip")); checkBoxListSysComp.UseVisualStyleBackColor = true; // // checkBoxListProtected // resources.ApplyResources(checkBoxListProtected, "checkBoxListProtected"); checkBoxListProtected.Name = "checkBoxListProtected"; toolTip1.SetToolTip(checkBoxListProtected, resources.GetString("checkBoxListProtected.ToolTip")); checkBoxListProtected.UseVisualStyleBackColor = true; // // checkBoxTweaks // resources.ApplyResources(checkBoxTweaks, "checkBoxTweaks"); checkBoxTweaks.Name = "checkBoxTweaks"; checkBoxTweaks.UseVisualStyleBackColor = true; // // checkBoxShowUpdates // resources.ApplyResources(checkBoxShowUpdates, "checkBoxShowUpdates"); checkBoxShowUpdates.Name = "checkBoxShowUpdates"; toolTip1.SetToolTip(checkBoxShowUpdates, resources.GetString("checkBoxShowUpdates.ToolTip")); checkBoxShowUpdates.UseVisualStyleBackColor = true; // // checkBoxWinFeature // resources.ApplyResources(checkBoxWinFeature, "checkBoxWinFeature"); checkBoxWinFeature.Name = "checkBoxWinFeature"; checkBoxWinFeature.UseVisualStyleBackColor = true; // // checkBoxShowStoreApps // resources.ApplyResources(checkBoxShowStoreApps, "checkBoxShowStoreApps"); checkBoxShowStoreApps.Name = "checkBoxShowStoreApps"; checkBoxShowStoreApps.UseVisualStyleBackColor = true; // // groupBox1 // resources.ApplyResources(groupBox1, "groupBox1"); groupBox1.Controls.Add(flowLayoutPanel1); groupBox1.Name = "groupBox1"; groupBox1.TabStop = false; // // flowLayoutPanel1 // resources.ApplyResources(flowLayoutPanel1, "flowLayoutPanel1"); flowLayoutPanel1.Controls.Add(checkBoxViewCheckboxes); flowLayoutPanel1.Controls.Add(checkBoxViewGroups); flowLayoutPanel1.Controls.Add(checkBoxCertTest); flowLayoutPanel1.Controls.Add(checkBoxInvalidTest); flowLayoutPanel1.Controls.Add(checkBoxHighlightSpecial); flowLayoutPanel1.Name = "flowLayoutPanel1"; // // checkBoxViewCheckboxes // resources.ApplyResources(checkBoxViewCheckboxes, "checkBoxViewCheckboxes"); checkBoxViewCheckboxes.Name = "checkBoxViewCheckboxes"; toolTip1.SetToolTip(checkBoxViewCheckboxes, resources.GetString("checkBoxViewCheckboxes.ToolTip")); checkBoxViewCheckboxes.UseVisualStyleBackColor = true; // // checkBoxViewGroups // resources.ApplyResources(checkBoxViewGroups, "checkBoxViewGroups"); checkBoxViewGroups.Name = "checkBoxViewGroups"; toolTip1.SetToolTip(checkBoxViewGroups, resources.GetString("checkBoxViewGroups.ToolTip")); checkBoxViewGroups.UseVisualStyleBackColor = true; // // checkBoxHighlightSpecial // resources.ApplyResources(checkBoxHighlightSpecial, "checkBoxHighlightSpecial"); checkBoxHighlightSpecial.Name = "checkBoxHighlightSpecial"; toolTip1.SetToolTip(checkBoxHighlightSpecial, resources.GetString("checkBoxHighlightSpecial.ToolTip")); checkBoxHighlightSpecial.UseVisualStyleBackColor = true; // // usageTracker1 // usageTracker1.ContainerControl = this; // // PropertiesSidebar // resources.ApplyResources(this, "$this"); AutoScaleMode = AutoScaleMode.Font; Controls.Add(groupBox1); Controls.Add(groupBox2); Name = "PropertiesSidebar"; groupBox2.ResumeLayout(false); groupBox2.PerformLayout(); flowLayoutPanel2.ResumeLayout(false); flowLayoutPanel2.PerformLayout(); groupBox1.ResumeLayout(false); groupBox1.PerformLayout(); flowLayoutPanel1.ResumeLayout(false); flowLayoutPanel1.PerformLayout(); ResumeLayout(false); PerformLayout(); } #endregion private GroupBox groupBox2; private FlowLayoutPanel flowLayoutPanel2; private CheckBox checkBoxListHideMicrosoft; private CheckBox checkBoxShowUpdates; private CheckBox checkBoxListSysComp; private CheckBox checkBoxListProtected; private GroupBox groupBox1; private FlowLayoutPanel flowLayoutPanel1; private CheckBox checkBoxViewCheckboxes; private CheckBox checkBoxViewGroups; private ToolTip toolTip1; private UsageTracker usageTracker1; private CheckBox checkBoxCertTest; private CheckBox checkBoxInvalidTest; private CheckBox checkBoxOrphans; private CheckBox checkBoxShowStoreApps; private CheckBox checkBoxWinFeature; private CheckBox checkBoxHighlightSpecial; private CheckBox checkBoxTweaks; } } ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/PropertiesSidebar.ar.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 تمييز المثبتات المعتمدة اظهار مكونات النظام عرض التطبيقات التي ليس لديها اي من المثبتات المسجلة. وهي غير مرئية في معظم مديري الالغاء ولكن لا تزال تاخذ مساحة. يتم تمييز العناصر غير المسجلة بلون احمر. تحذير: فحص مزدوج قبل ازاله هذه التطبيقات ، فانها قد لا تزال ضرورية! تحديد استخدام مربعات الاختيار استخدام الالوان للتعرف على المثبتات المعتمدة. اذا تم التحقق من الشهادة بنجاح استخدام اللون الاخضر ، والا استخدم اللون الازرق. تحذير: يمكن ان يستغرق التحقق وقتا طويلا للاكتمال. اظهار التحديثات اظهار المواد المحمية تغيير نمط التحديد للقائمة الى خانات الاختيار. وهي اكثر امانا لان نقره واحده لا يمكن الغاء كل شيء. يمكنك التحقق من مواد متعددة من خلال تمييزها والضغط على مفتاح المسافة. تحديثات التطبيقات الاخرى. وعاده ما يتم الغاء تثبيتها مع التطبيق الاصلي ، بحيث يمكن تجاهلها. اظهار التطبيقات الغير مسجلة عرض تطبيقات مخزن وندوز فلترة كل ما نشر من مايكروسوفت. انها بهذه البساطة استخدم اللون الرمادي لتعريف التثبيتات التالفة او المفقودة. اظهار المواد في مجموعات اظهار ميزات الوندوز يمكن وضع علامة على بعض الغير مثبتات باسم "مكونات النظام" لاخفاءها من قائمه اضافه/ازاله البرامج. غالبا ما يتم وضع علامة على برامج التشغيل بهذه العلامة. اعدادات عرض القائمة اخفاء ما نشرتها مايكروسوفت تمييز المثبتات المفقودة تجميع المواد وفقا للعمود يتم فرز القائمة حسب. يستخدم تجميع معظم الاعمده الفلترة الذكية. الفلترة يتم وضع علامة على المواد المحمية بعلامة "عدم الازاله" ، مما يعني ان الناشر لا يريد منك ازالتها. ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/PropertiesSidebar.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System.ComponentModel; using System.Linq; using System.Reflection; using System.Windows.Forms; using Klocman.Binding.Settings; namespace BulkCrapUninstaller.Controls { public partial class PropertiesSidebar : UserControl { private readonly SettingBinder _settings = Properties.Settings.Default.SettingBinder; public PropertiesSidebar() { InitializeComponent(); } protected override void OnLoad(System.EventArgs e) { base.OnLoad(e); if (DesignMode) return; _settings.BindControl(checkBoxViewCheckboxes, x => x.UninstallerListUseCheckboxes, this); _settings.BindControl(checkBoxViewGroups, x => x.UninstallerListUseGroups, this); _settings.BindControl(checkBoxListHideMicrosoft, x => x.FilterHideMicrosoft, this); _settings.BindControl(checkBoxShowUpdates, x => x.FilterShowUpdates, this); _settings.BindControl(checkBoxListSysComp, x => x.FilterShowSystemComponents, this); _settings.BindControl(checkBoxListProtected, x => x.FilterShowProtected, this); _settings.BindControl(checkBoxShowStoreApps, x => x.FilterShowStoreApps, this); _settings.BindControl(checkBoxWinFeature, x => x.FilterShowWinFeatures, this); _settings.BindControl(checkBoxTweaks, x => x.FilterShowTweaks, this); _settings.BindControl(checkBoxInvalidTest, x => x.AdvancedTestInvalid, this); _settings.BindControl(checkBoxCertTest, x => x.AdvancedTestCertificates, this); _settings.BindControl(checkBoxOrphans, x => x.AdvancedDisplayOrphans, this); _settings.BindControl(checkBoxHighlightSpecial, x => x.AdvancedHighlightSpecial, this); _settings.SendUpdates(this); Disposed += (x, y) => _settings.RemoveHandlers(this); } [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public int GetSuggestedWidth() { var maxWidth = typeof(PropertiesSidebar) .GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) .Where(x => x.FieldType == typeof(CheckBox)) .Select(x => x.GetValue(this)) .Cast() .Max(c => c.Width); return maxWidth + (groupBox1.Width - groupBox1.DisplayRectangle.Width) + Padding.Left + Padding.Right; } [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool SysCompEnabled { get { return checkBoxListSysComp.Enabled; } set { checkBoxListSysComp.Enabled = value; checkBoxListSysComp.Visible = value; } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool ProtectedEnabled { get { return checkBoxListProtected.Enabled; } set { checkBoxListProtected.Enabled = value; checkBoxListProtected.Visible = value; } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool UpdatesEnabled { get { return checkBoxShowUpdates.Enabled; } set { checkBoxShowUpdates.Enabled = value; checkBoxShowUpdates.Visible = value; } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool OrphansEnabled { get { return checkBoxOrphans.Enabled; } set { checkBoxOrphans.Enabled = value; checkBoxOrphans.Visible = value; } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool StoreAppsEnabled { get { return checkBoxShowStoreApps.Enabled; } set { checkBoxShowStoreApps.Enabled = value; checkBoxShowStoreApps.Visible = value; } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool InvalidEnabled { get { return checkBoxInvalidTest.Enabled; } set { checkBoxInvalidTest.Enabled = value; checkBoxInvalidTest.Visible = value; } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool WinFeaturesEnabled { get { return checkBoxWinFeature.Enabled; } set { checkBoxWinFeature.Enabled = value; checkBoxWinFeature.Visible = value; } } [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool ShowTweaksEnabled { get { return checkBoxTweaks.Enabled; } set { checkBoxTweaks.Enabled = value; checkBoxTweaks.Visible = value; } } } } ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/PropertiesSidebar.cs.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Zobrazit systémové součásti Vyberte pomocí zaškrtávacích políček Zobrazit aktualizace Zobrazit chráněné položky Zvýraznit neplatné odinstalátory Aktualizace dalších aplikací. Obvykle jsou odinstalován spolu s jejich mateřskou aplikací, takže mohou být ignorovány. Skrýt publikováné společností Microsoft Zobrazení neregistrovaných aplikací Odfiltrovat vše, co byla vydána společností Microsoft. Je to tak snadné. Změní výběru stylu seznamu na zaškrtávacích políčkách. Jsou bezpečnější, protože jedním kliknutím nelze zrušit výběr všech. Můžete zkontrolovat více položek zvýraznít je stiskem mezerníku. Použít šedou barvu pro identifikaci odinstalátorů, které jsou poškozeny nebo chybí. Zobrazit položky ve skupinách Některé odinstalátory mohou být označeny jako "součásti systému" skrýt z Přidat / Odebrat software. Ovladače jsou často označeny touto značkou. Použít barvy k identifikaci certifikovaných odinstalátorů. V případě, že certifikát byl úspěšně ověřen použít zelenou barvu, jinak používat modrou barvu. Upozornění: Dokončení ověření může trvat delší dobu. Nastavení zobrazení seznamu Zobrazené aplikace, které nemají žádné registrované odinstalátory. Tyto nejsou viditelné v mnoha odinstalačních manažerech, ale stále zabírají místo. Neregistrované položky jsou označeny červenou barvou. Upozornění: Dvojtá kontrola před vyjmutím těchto aplikací, mohli by být stále nezbytné! Skupina položek podle sloupce seznamu je seřazen podle. Seskupení většiny sloupců používá inteligentní filtrování. Filtrování Zvýraznit ověřené odinstalátory Chráněné položek jsou označeny "NoRemove" značkou, což znamená, že vydavatel nechce jejich odstranění. Zobrazit Windows Store aplikace Zobrazit funkce systému Windows True 17, 17 pl 109, 17 ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/PropertiesSidebar.de.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Ungültige Uninstaller hervorheben Graue Farbe kennzeichnet beschädigte oder fehlende Uninstaller Zertifizierte Uninstaller hervorheben Farben verwenden, um zertifizierte Uninstaller zu identifizieren. Erfolgreich geprüfte Zertifikate erscheinen in grüner, andernfalls in blauer Farbe. Achtung: Die Überprüfung kann einige Zeit in Anspruch nehmen. Microsoft Komponenten ausblenden Alles ausblenden, was von Microsoft veröffentlicht wurde. Systemkomponenten anzeigen Einige Uninstaller können als "Systemkomponente" markiert sein, um sie in der Systemsteuerung-Software-Liste zu verstecken. Treiber sind oft so gekennzeichnet Geschützte Elemente anzeigen Geschützte Elemente werden mit "NoRemove" gekennzeichnet, was bedeutet, dass der Hersteller nicht will, dass sie entfernt werden. Updates anzeigen Updates für andere Anwendungen. In der Regel werden sie zusammen mit ihrer übergeordneten Anwendung deinstalliert, sie können daher ignoriert werden. Filtern Auswahl mit Checkboxen Auswahl per Markierungsfeld (Checkbox). Das ist sicherer, damit ein einzelner Klick nicht alles deaktivieren kann. Sie können mehrere Elemente aktivieren, indem Sie sie markieren und die Leertaste drücken. Elemente gruppieren Gruppierung von Elementen entsprechend der Spalte nach der die Liste sortiert ist. 'Smartes' Filtern findet bei den meisten Spalten Verwendung. Ansicht der Einstellungen Nicht registrierte Anwendungen anzeigen Anzeige von Anwendungen, die über keine registrierten Uninstaller verfügen. Sie bleiben den meisten Uninstall-Programmen verborgen, benötigen aber dennoch Plattenplatz. Nicht registrierte Elemente werden rot dargestellt. Achtung: Vor dem Entfernen dieser Anwendungen bitte genau überprüfen, ob sie nicht doch noch beötigt werden. Zeige Windows Eigenschaften Zeige Windows Store Programme Hervorheben spezieller Uninstaller Benutze Farben für spezielle Programme wie z.B. Windows Store Programme oder Eigenschaften. Änderungen anzeigen ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/PropertiesSidebar.es.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Mostrar aplicaciones no registradas Mostrar aplicaciones sin ningún desinstalador registrado. No son visibles en la mayoría de desinstaladores, pero aún ocupan espacio. Los no registrados aparecen de color rojo. ADVERTENCIA: Asegúrese antes de eliminar estas aplicaciones, puede que aún sean necesarias! Resaltar los desinstaladores que faltan Utilizar el color gris para identificar desinstaladores ausentes o dañados. Resaltar desinstaladores certificados Utilizar colores para identificar desinstaladores certificados. Si el certificado se ha verificado correctamente utilizar el color verde, si no utilizar el color azul. Advertencia: La verificación puede tardar mucho tiempo. Ocultar lo publicado por Microsoft Filtrar todo lo que fue publicado por Microsoft. Es así de simple. Mostrar componentes del sistema Algunos desinstaladores pueden marcarse como "componentes del sistema" para ocultarlos de la opción Agregar/Quitar lista de software. Los drivers son a menudo marcados con esta etiqueta. Mostrar elementos protegidos Los elementos protegidos están marcados con la etiqueta "No Eliminar", lo que significa que el editor no quiere que los elimine. Mostrar actualizaciones Actualizaciones de otras aplicaciones. Por lo general, se desinstalan junto con su aplicación principal, por lo que se pueden ignorar. Mostrar características de Windows Mostrar apps de Windows Store Filtrado Seleccionar usando checkboxes Cambia el estilo de selección de la lista a casillas de verificación. Son más seguros porque un solo click no puede anular la selección de todo. Puede comprobar varios elementos resaltándolos y presionando la barra espaciadora. Mostrar elementos en grupos Agrupar elementos por la columna de la lista por la que está ordenada. Agrupar la mayoría de las columnas usa filtrado inteligente. Configuración de la vista de lista Mostrar retoques Destacar los desinstaladores especiales Utilizar colores para diferencias las aplicaciones especiales, por ejemplo, Aplicaciones de la Tienda y Características de Windows. ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/PropertiesSidebar.fr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Afficher les applications non enregistrées Afficher les applications n'ayant pas de désinstalleur enregistré. Elles sont invisibles dans la plupart des gestionnaires de désinstallation, mais prennent quand même de la place. Les éléments non enregistrés sont marqués avec une couleur rouge. Attention : vérifiez à deux fois avant de supprimer ces applications, elles pourraient être encore nécessaires ! Surligner les désinstalleurs invalides Utiliser la couleur grise pour identifier les désinstalleurs corrompus ou manquants. Surligner les désinstalleurs certifiés Utiliser des couleurs pour identifier les désinstalleurs certifiés. Si le certificat a été vérifié avec succès utiliser la couleur verte, autrement utiliser la couleur bleue. Attention : la vérification peut mettre longtemps à se terminer. Cacher si publié par Microsoft Filtrer tout ce qui a été publié par Microsoft. C'est aussi simple que cela. Afficher les composants système Quelques désinstalleurs peuvent être marqués comme "composants système" pour les masquer dans la liste Ajout/Suppression de programmes. Les pilotes sont souvent marqués avec cette balise. Afficher les éléments protégés Les éléments protégés sont marqués avec la balise "NoRemove", signifiant que l'éditeur ne veut pas que vous les enleviez. Afficher les mises à jour Mises à jour d'autres applications. En général elles sont désinstallées ensemble avec leur application parente, ainsi elles peuvent être ignorées. Filtrage Sélectionnner par cases à cocher Change le style de sélection de la liste en cases à cocher. Elles sont plus fiables car un simple clic ne peut désélectionner tout. Vous pouvez cocher de multiples éléments en les surlignant et en pressant la barre d'espace. Afficher les éléments en groupes Grouper les éléments en fonction de la colonne utilisée pour les trier. Le groupage de la plupart des colonnes utilise un tri intelligent. Réglages de la vue liste Afficher les applis du Windows Store Afficher les fonctionnalités Windows Surligner les désinstalleurs spéciaux Utiliser des couleurs pour différencier les applications spéciales, par exemple les applis du Store et les Fonctionnalités Windows. Afficher les perfectionnements ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/PropertiesSidebar.hu.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Hitelesítettek megjelölése Rendszerelemek mutatása Kijelölés jelölőnégyzetekkel Színek alkalmazása a hitelesített eltávolítókhoz. Ha a tanúsítvány sikeresen ellenőrzésre került akkor zöld szín, egyébként a kék szín kerül alkalmazásra. Figyelmeztetés: Az ellenőrzés hosszabb ideig is eltarthat. Frissítések mutatása Védett elemek mutatása Hiányzók megjelölése Lista kijelölési stílusának módosítása a jelölőnégyzetekkel. Ez biztonságos mivel egy kattintással nem vonhatja vissza mindet. Több elemet is kijelölhet a kiemelés és a szóköz billentyű lenyomásával. Egyéb alkalmazások frissítései. Általában ezek eltávolításra kerülnek a kapcsolódó alkalmazással együtt, így kihagyhatók a listából. Nem regisztrált alkalmazás mutatása Áruházbeli alk. mutatása Ezzel egyszerűen kiszűrheti a Microsoft által közzétett alkalmazásokat. Szürke szín alkalmazása a sérült, vagy hiányzó eltávolítók azonosításához. Elemek csoportosítása Windows-szolg. mutatása Néhány eltávolító "rendszerelemként" kerülhet megjelölésre, ezeket elrejtheti a programok listájában. Általában az illesztőprogramok vannak ezzel a címkével jelölve. Listanézet beállításai Microsoft kiadások elrejtése Azoknak az alkalmazásoknak a megjelenítése, amelyek nem rendelkeznek szabályos eltávolítóval. Ezek nem láthatók az eltávolítás kezelők számára, azonban sok helyet foglalhatnak. Az nem regisztrált elemek piros színnel kerülnek megjelölésre. Figyelem: Az eltávolításuk előtt ellenőrizze ezeket az alkalmazásokat mert lehet, hogy még mindig szükség van rájuk! Elemek csoportosítása a lista oszlopainak elrendezése alapján. A leggyakrabban használt oszlopok csoportosítása intelligens szűréssel. Szűrés Védett elemek, amelyek "NoRemove" címkével vannak ellátva. Ebben az esetben a kiadó nem akarja, hogy eltávolítsa ezeket. Javítások mutatása Különleges eltávolítók kiemelése Színek alkalmazása a speciális alkalmazások (Store alkalmazások, Windows szolgáltatások) megkülönböztetésére. ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/PropertiesSidebar.it.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Evidenza disinstallatori certificati Visualizza componenti di sistema Seleziona con casella di controllo Usa i colori per identificare i disinstallatori certificati. Se il certificato è stato verificato correttamente usa il colore verde, altrimenti usa il colore blu. Attenzione: la verifica potrebbe durare a lungo. Visualizza aggiornamenti Visualizza elementi protetti Evidenzia disinstallatori mancanti Modifica stile di selezione dell'elenco da marcare con casella di controllo. È più sicuro perché un clic singolo non deseleziona nulla. Puoi selezionare più elementi selezionandoli e premendo la barra spazio. Aggiornamenti di altre applicazioni. Normalmente sono disinstallate con le applicazioni da cui dipendono, possono quindi essere ignorate. Visualizza applicazioni non registrate Visualizza app di Windows Store Filtra tutto quanto prodotto da Microsoft. Usa il colore grigio per identificare i disinstallatori corrotti o mancanti. Visualizza elementi in gruppo Visualizza funzionalità di Windows Alcuni disinstallatori possono essere marcati come "componenti di sistema" per nasconderli nell'elenco Aggiungi/Rimuovi programmi. I driver sono spesso marcati con questo attributo. Impostazioni vista elenco Nascondi quelli prodotti da Microsoft Visualizza le applicazioni che non hanno nessun disinstallatore registrato. Non sono visibili alla maggior parte dei gestori di disinstallazione ma possono ancora occupare spazio. Gli elementi non registrati sono marcati con colore rosso. Attenzione: verifica attentamente prima di rimuovere queste applicazioni, potrebbero essere necessarie! Raggruppa gli elementi secondo la colonna per cui la'elenco è stata ordinato. Il raggruppamento della maggior parte delle colonne usa un filtro intelligente. Filtro Gli elementi protetti sono marcati con l'attributo "NoRemove" che indica che il produttore non vuole che vengano rimossi. Visualizza trucchi Evidenzia disinstallatori speciali Usa i colori per distinguere applicazioni speciali, ad esempio App dell Store e funzionalità di Windows. ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/PropertiesSidebar.ja.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 未登録のアプリを表示 登録されたアンインストーラーがないアプリケーションを表示します。これらは多くのアンインストールマネージャーで表示されませんが、依然としてディスク容量を使用しています。未登録のアイテムはレッドで表示されます。 警告: これらのアプリケーションを削除する前に、必ず再確認してください。まだ必要である可能性があります。 欠落しているアンインストーラーを強調表示 破損または欠落しているアンインストーラーをグレーで表示します。 認証済みのアンインストーラーを強調表示 認証済みのアンインストーラーを色で識別します。証明書が正常に確認された場合はグリーン、確認に失敗した場合はブルーで表示します。 警告:証明書の確認には時間がかかる場合があります。 Microsoft社製のものを非表示 Microsoft社が公開したすべてのアイテムをフィルタリングして非表示にします。非常にシンプルです。 システムコンポーネントを表示 一部のアンインストーラーは「システムコンポーネント」としてマークされ、ソフトウェアの追加/削除リストから隠されます。ドライバーにはこのタグが付けられることが多いです。 保護されたアイテムを表示 「NoRemove」タグが付けられた保護されたアイテムは、パブリッシャーが削除を推奨していないことを示しています。 tweaksを表示する アップデートを表示 他のアプリケーションの更新プログラムです。通常、親アプリケーションと一緒にアンインストールされるため、無視しても問題ありません。 Windows機能を表示 Windowsストアアプリを表示 フィルタリング チェックボックスで選択 リストの選択スタイルをチェックボックスに変更します。これにより、1回のクリックで全ての選択を解除できなくなるため、安全性が向上します。 複数のアイテムをハイライトして、スペースキーを押すことで選択が可能です。 アイテムをグループで表示 リストの並べ替え基準に基づいてアイテムをグループ化します。多くの列でのグループ化はスマートフィルタリングを使用します。 特別なアンインストーラーを強調表示 WindowsストアアプリやWindows機能などの特別なアプリケーションを色分けして区別します。 リストビューの設定 ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/PropertiesSidebar.nl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Systeem componenten tonen Keuze met checkboxen Kleuren gebruiken om gecertificeerde de-installer te identificeren. Succesvol gecontroleerde certificaten verschijnen in het groen, andere in het blauw gekleurd. Let op: de verificatie kan enige tijd duren. Updates tonen Beveiligde onderdelen tonen Keuze met een markeringsveld (Checkbox). Dit is veiliger, omdat een enkele klik niet alles kan deactiveren. U kunt meerdere onderdelen activeren, wanneer u deze markeert en op de spatiebalk drukt. Updates voor andere programma's. In de regel worden zij tezamen met hun 'ouder' programma gede-installeerd. Daarom kunnen zij worden genegeerd. Niet geregistreerde programma's tonen Alles verbergen wat door Microsoft werd uitgebracht. De grijze kleur betekende beschadigde of ontbrekende de-installers. Toon onderdelen in groepen Enkele de-installers kunnen als systeem componenten zijn aangeduid, om deze te verbergen in de Toevoegen/Verwijderen software lijst. Stuurprogramma's zijn vaak gemarkeerd met dit label. Weergave instellingen Microsoft componenten verbergen Ongeldige de-installers accentueren Groepering van onderdelen overeenkomstig de kolom volgens welke de lijst is gesorteerd. Slim filteren is op de meeste kolommen van toepassing Filteren Beveiligde onderdelen worden met het "NietVerwijderen" label aangeduid hetgeen betekent, dat de uitgever niet wil, dat deze worden verwijderd. Gecertificeerde de-installers accentueren Weergave van programma's, die geen enkele gecertificeerde de-installer hebben. Deze blijven in de meeste de-installer programma's verborgen, maar nemen evenwel schijfruimte in. Niet geregistreerde onderdelen worden rood weergegeven. Waarschuwing: controleer alvorens deze programma's te verwijderen of deze niet nodig zijn! Windows Store apps tonen Windows onderdelen tonen Tweaks tonen Markeer speciale de-installers Gebruik kleuren om speciale applicaties te onderscheiden, bijvoorbeeld Store Apps en Windows functies. ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/PropertiesSidebar.pl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Wyświetlaj niezarejestrowane Pokaż aplikacje które nie mają żadnych zarejestrowanych dezinstalatorów. Nie są one widoczne w większości menedżerów aplikacji, ale wciąż zajmują miejsce. Niezarejestrowane elementy są oznaczone kolorem czerwonym. Uwaga: Przed usunięciem tych aplikacji sprawdź dwukrotnie czy nie są jeszcze potrzebne! Zaznacz uszkodzone Użyj szarego tła do identyfikacji uszkodzonych lub brakujących dezinstalatorów. Zaznacz certyfikowane Użyj kolorów do identyfikacji certyfikowanych programów odinstalowujących. Jeśli certyfikat został pomyślnie zweryfikowany użyj zielonego tła, w innym przypadku użyj niebieskiego tła. Uwaga: Weryfikacja może zająć dużo czasu. Ukryj pozycje Microsoftu Odfiltruj wszystko co zostało opublikowane przez firmę Microsoft. Pokaż elementy systemowe Niektóre dezinstalatory mogą być oznaczone jako "składniki systemu", aby ukryć je z listy Dodaj / Usuń programy. Sterowniki są często oznaczone tym tagiem. Pokaż zabezpieczone Chronione elementy są oznaczone tagiem "NoRemove", co oznacza, że wydawca nie chce abyś je usunął. Pokaż uaktualnienia Aktualizacje innych zainstalowanych aplikacji. Zazwyczaj są usuwane razem z ich nadrzędną aplikacją, więc nie wymagają uwagi. Filtrowanie Zaznaczaj polami wyboru Zmienia styl zaznaczenia na liście do pól wyboru. Są one bezpieczniejsze, ponieważ pojedyncze kliknięcie nie może odznaczyć wszystkiego. Możesz zaznaczyć kilka pozycji podświetlając je i naciskając spację. Grupuj podobne pozycje Grupuj elementy według kolumny którą posortowana jest lista. Grupowanie większości kolumn używa inteligentnych filtrów. Ustawienia listy Pokaż Store Apps Pokaż funkcje systemu Zaznacz specjalne Użyj kolorów do rozróżniania specjalnych aplikacji, na przykład aplikacji ze sklepu Windows i Funkcji systemu Windows. Pokaż usprawnienia ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/PropertiesSidebar.pt-BR.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Destacar os desinstaladores certificados Mostrar os componentes do sistema Exibir aplicativos que não possuem nenhum desinstalador registrado. Eles não são visíveis na maioria dos gerenciadores de desinstalação, mas ainda ocupam espaço. Os itens não registrados estão marcados com uma cor vermelha. Aviso: Verifique antes de remover esses aplicativos, eles ainda podem ser necessários! Selecione usando caixas de seleção Use cores para identificar desinstaladores certificados. Se o certificado foi verificado com sucesso use cor verde, caso contrário use cor azul. Aviso: a verificação pode demorar muito para ser concluída. Exibir atualizações Exibir itens protegidos Muda o estilo de seleção da lista para caixas de seleção. Eles são mais seguros porque um único clique não pode desmarcar tudo. Você pode verificar vários itens, destacando-os e pressionando a barra de espaço. Atualizações de outros aplicativos. Normalmente, eles são desinstalados junto com seu aplicativo pai, para que possam ser ignorados. Exibir aplicativos não registrados Exibir Apps da Windows Store Filtre tudo o que foi publicado pela Microsoft. É simples assim. Use cor cinza para identificar desinstaladores corrompidos ou ausente Exibir itens em grupos Exibir os recursos do Windows Alguns desinstaladores podem ser marcados como "componentes do sistema" para ocultá-los da lista Adicionar/Remover. Os drivers são frequentemente marcados com esta etiqueta. Configurações de exibição de lista Ocultar os publicados pela Microsoft Destacar os desinstaladores inválidos Agrupar itens de acordo com a coluna pela qual a lista foi classificada. O agrupamento da maioria das colunas usa filtragem inteligente. Filtragem Os itens protegidos são marcados com a tag "NoRemove", o que significa que o editor não deseja que você os remova. Mostrar modificações Destacar desinstaladores especiais Usa cores para diferenciar aplicações especiais, como por exemplo Window Store e Recursos do Windows ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/PropertiesSidebar.pt.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Mostrar aplicações não registada na lista. Exibe aplicações sem desinstaladores registados. São invisíveis na maioria dos gestores de desinstalação, mas ainda ocupam espaço. Itens não registrada são marcados a cor vermelha. Aviso: Pense duas vezes antes de remover esses aplicativos pois poderão ainda ser necessários! Destacar os desinstaladores inválidos Use a cor cinzenta para identificar desinstaladores corrompidos ou ausentes. Destacar os desinstaladores certificados Use cores para identificar os desinstaladores certificados. Se o certificado foi verificado com êxito, utilize a cor cinzenta, caso contrário use a cor azul. Atenção: O processo de verificação pode demorar muito tempo. Ocultar se publicado pela Microsoft Filtra tudo o que foi publicado pela Microsoft. Tão simples como isso. Mostrar os componentes do sistema Alguns desinstaladores podem ser designados como "componentes do sistema" para os esconder na lista Adicionar/Remover Programas. Os drivers são muitas vezes rotulados com essa designação. Mostrar itens protegidos Itens protegidos assinalados com a denominação "NoRemove (NãoRemover)" significa que o editor não quer que você os remova. Mostrar actualizações Actualizações de outras aplicações. Normalmente, elas são desinstaladas em conjunto com aplicações semelhantes, para que possam ser ignoradas. Mostrar os recursos do Windows Mostrar as app do Windows Store Filtrando Seleccione usando as caixas de selecção. Mudar o tipo de selecção da lista de caixas de opção. São mais seguros porque um único clique não consegue desmarcar tudo. Você pode verificar vários itens, destacando-os e carregando na barra de espaço. Mostrar os itens em grupos Agrupar itens com base na coluna usada para as ordenar. O agrupamento da maior parte das colunas utiliza uma triagem inteligente. Configurações da lista de exibição ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/PropertiesSidebar.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 True NoControl 4, 28 4, 3, 4, 3 191, 19 1 Show unregistered applications 202, 17 Display applications that do not have any registered uninstallers. They are not visible in most uninstall managers but still take up space. Unregistered items are marked with a red color. Warning: Double check before removing these applications, they might still be necessary! checkBoxOrphans System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel2 1 True NoControl 4, 78 4, 3, 4, 3 183, 19 3 Highlight missing uninstallers Use grey color to identify uninstallers that are corrupted or missing. checkBoxInvalidTest System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel1 3 True NoControl 4, 53 4, 3, 4, 3 185, 19 2 Highlight certified uninstallers Use colors to identify certified uninstallers. If the certificate was successfully verified use green color, otherwise use blue color. Warning: Verification can take a long time to complete. checkBoxCertTest System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel1 2 True GrowAndShrink True GrowAndShrink True NoControl 4, 3 4, 3, 4, 3 176, 19 0 Hide published by Microsoft Filter out everything that was published by Microsoft. It's that simple. checkBoxListHideMicrosoft System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel2 0 True NoControl 4, 53 4, 3, 4, 3 165, 19 2 Show system components Some uninstallers can be marked as "system components" to hide them from the Add/Remove software list. Drivers are often marked with this tag. checkBoxListSysComp System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel2 2 True NoControl 4, 78 4, 3, 4, 3 141, 19 3 Show protected items Protected items are marked with the "NoRemove" tag, which means that the publisher doesn't want you to remove them. checkBoxListProtected System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel2 3 True NoControl 4, 103 4, 3, 4, 3 94, 19 4 Show tweaks checkBoxTweaks System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel2 4 True NoControl 4, 128 4, 3, 4, 3 100, 19 5 Show updates Updates of other applications. Usually they are uninstalled together with their parent application, so they can be ignored. checkBoxShowUpdates System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel2 5 True NoControl 4, 153 4, 3, 4, 3 152, 19 6 Show Windows features checkBoxWinFeature System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel2 6 True NoControl 4, 178 4, 3, 4, 3 165, 19 7 Show Windows Store apps checkBoxShowStoreApps System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel2 7 Fill TopDown 6, 19 4, 3, 4, 3 105, 200 1 flowLayoutPanel2 System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBox2 0 Top 0, 0 4, 3, 4, 3 6, 3, 6, 3 117, 222 0 Filtering groupBox2 System.Windows.Forms.GroupBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 1 True GrowAndShrink True GrowAndShrink True NoControl 4, 3 4, 3, 4, 3 154, 19 0 Select using checkboxes Changes selection style of the list to checkboxes. They are safer because a single click can't deselect everything. You can check multiple items by highlighting them and pressing spacebar. checkBoxViewCheckboxes System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel1 0 True NoControl 4, 28 4, 3, 4, 3 140, 19 1 Show items in groups Group items according to the column the list is sorted by. Grouping of most of the columns uses smart filtering. checkBoxViewGroups System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel1 1 True NoControl 4, 103 4, 3, 4, 3 178, 19 4 Highlight special uninstallers Use colors to differentiate special applications, for example Store Apps and Windows Features. checkBoxHighlightSpecial System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel1 4 Fill TopDown 6, 19 4, 3, 4, 3 105, 125 0 flowLayoutPanel1 System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBox1 0 Top 0, 222 4, 3, 4, 12 6, 3, 6, 3 117, 147 1 List view settings groupBox1 System.Windows.Forms.GroupBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 0 299, 17 True 7, 15 True GrowAndShrink 4, 3, 4, 3 117, 115 117, 369 toolTip1 System.Windows.Forms.ToolTip, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 usageTracker1 BulkCrapUninstaller.Functions.Tracking.UsageTracker, BCUninstaller, Culture=neutral, PublicKeyToken=null PropertiesSidebar System.Windows.Forms.UserControl, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/PropertiesSidebar.ru.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Незарегистрированные Показывать приложения, которые не имеют зарегистрированных деинсталляторов. Они не видны в большинстве менеджеров удаления, но всё равно занимают место. Незарегистрированные элементы отмечены красным цветом. Внимание: Проверьте приложения перед их удалением, они могут быть необходимы! Нет деинсталлятора Выделять серым цветом деинсталляторы, которые повреждены или отсутствуют. Подписанные деинсталляторы Использовать цвета для идентификации сертифицированных деинсталляторов. Если сертификат проверен - зелёный цвет, не проверен - синий цвет. Внимание: Проверка может занять длительное время. Фильтрация Скрыть приложения Microsoft Скрыть всё, что подписано Майкрософт. Отобразить системные приложения Некоторые деинсталляторы могут быть помечены как "системные", можете скрыть эти программы из списка. Драйвера часто помечены этим тегом. Отобразить защищённые Защищённые элементы имеют пометку "NoRemove", это означает, что разработчик не хочет, чтобы их удаляли. Отобразить обновления Обновления для других приложений. Обычно они удаляются вместе с родительским приложением, поэтому ими можно пренебречь. Отобразить приложения Windows Store Вид списка Выбирать, используя флажки Изменяет способ выбора элементов, используя флажки. Пользование ими безопасней, так как одним щелчком нельзя отменить всё. Вы можете отметить несколько элементов, выделив их и нажав пробел. Группировать элементы Группировка элементов "абзацами" согласно колонке, по которой сортируется список. Группировка большинства колонок использует смарт-фильтрацию. Функции Windows Отобразить твики Выделить особые деинсталляторы Использовать цвета для различения особых приложений, например, приложений магазина и функций Windows. 202, 17 299, 17 True ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/PropertiesSidebar.sl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Prikaži sistemske sestavine Prikaz aplikacij, ki nimajo nobene registrirane odstranjevalce. Ti niso vidni v večini upraviteljev odstranjevanja toda še vedno zasedejo prostor. Neregistrirani vnosi so označeni z rdečo barvo. Opozorilo: Dvakrat preverite pred odstranjevanjem teh aplikacij, ki so morda še vedno potrebne! Filtriranje Izberi s potrditvenimi polji Prikaži posodobitve Prikaži zaščitene vnose Posodobitve drugih aplikacij. Ponavadi so te odstranjene skupaj z nadrejeno aplikacijo, tako da jih je mogoče prezreti. Prikaži neregistrirane aplikacije Nekateri odstranjevalci so lahko označeni kot "sestavine sistema". Za njihovo skrivanje s seznama Dodaj/odstrani program. Gonilnikii so pogosto označeni s to oznako. Spremeni izbor sloga seznama potrditvenih polj. Varnejše je, ker en klik ne more počistiti vsega. Lahko označite več vnosov tako, da jih označite in pritisnete na preslednico. Izloči iz filtra vse, kar je objavil Microsoft. To je preprosto. Uporabi sivo barvo za identifikacijo odstranjevalcev, ki so poškodovani ali manjkajo. Prikaži vnose v skupinah Uporabi barve za označevanje potrjenih odstranjevalcev. Če je bilo digitalno potrdilo uspešno preverjeno, uporabi zeleno barvo, sicer uporabi modro barvo. Opozorilo: Konec preverjanja lahko traja dolgo časa. Nastavitve pogleda seznama Skrij objavljeno od Microsofta Označi neveljavne odstranjevalce Seznam je razvrščen v skupine vnosov glede na stolpec. Združevanje v skupine uporablja pametno filtriranje. Označi overjene odstranjevalce Zaščiteni vnosi so označeni z oznako "NeOdstrani", kar pomeni, da izdajatelj ne želi, da jih odstranite. Prikaži Windows Store aplikacije Prikaži Windows funkcije Prikaži izboljšave Označi posebne odstranjevalce Uporabi barve zarazlikovanje posebnih aplikacij, kot so npr. Store Apps in funkcije Windows. True 202, 17 pl 299, 17 ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/PropertiesSidebar.sv.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Visa oregistrerade appar Visa appar som inte har några registrerade avinstallationsprogram. De är inte synliga i de flesta avinstallationshanterare men tar fortfarande upp plats. Oregistrerade objekt markeras med en röd färg. Varning: Dubbelkolla innan du tar bort dessa applikationer, de kan fortfarande vara nödvändiga! Markera saknade avinstallationsprogram Använd grå färg för att identifiera avinstallationsprogram som är korrupta eller saknas. Markera certifierade avinstallationsprogram Använd färger för att identifiera certifierade avinstallationsprogram. Om certifikatet verifierades framgångsrikt, använd grönt, annars använd blått. Varning: Verifiering kan ta lång tid att slutföra. Dölj publicerade av Microsoft Filtrera bort allt som publicerades av Microsoft. Så enkelt är det. Visa systemkomponenter Vissa avinstallationsprogram kan markeras som "systemkomponenter" för att dölja dem från Lägg till/Ta bort listan av appar. Drivrutiner markeras ofta med denna tagg. Visa skyddade objekt Skyddade objekt är märkta med taggen "NoRemove", vilket innebär att utgivaren inte vill att du tar bort dem. Visa justeringar Visa uppdateringar Uppdateringar av andra appar. Vanligtvis avinstalleras de tillsammans med sin huvudapp, så de kan ignoreras. Visa Windows-funktioner Visa Windows Store-appar Filtrering Välj med hjälp av kryssrutor Ändrar urvalsstilen för listan till kryssrutor. De är säkrare eftersom enstaka klick inte kan avmarkera allt. Du kan markera flera objekt genom att markera dem och trycka på mellanslag. Visa objekt i grupper "Gruppera objekt enligt kolumnen som listan är sorterad efter. Gruppering av de flesta kolumnerna använder smart filtrering. Markera speciella avinstallationsprogram Använd färger för att särskilja speciella appar, till exempel Microsoft Store-appar och Windows-funktioner. Inställningar för listvy ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/PropertiesSidebar.tr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Kayıtsız uygulamaları göster Kayıtlı kaldırıcılar içermeyen uygulamaları görüntüleyin. Çoğu kaldırma yöneticisinde görünmezler ancak yine de yer kaplarlar. Kayıtlı olmayan öğeler kırmızı renkle işaretlenir. Uyarı: Bu uygulamaları kaldırmadan önce iki kez kontrol edin, yine de gerekli olabilir! Eksik kaldırıcıları vurgula Bozulmuş veya eksik olan kaldırıcıları tanımlamak için gri renk kullanın. Sertifikalı kaldırıcıları vurgulayın Sertifikalı kaldırıcıları tanımlamak için renkleri kullanın. Sertifika başarıyla doğrulandıysa yeşil renk kullanın, aksi halde mavi renk kullanın. Uyarı: Doğrulamanın tamamlanması uzun sürebilir. Yayıncısı Microsoft olanları gizle Microsoft tarafından yayınlanan her şeyi filtreleyin. Bu kadar basit. Sistem bileşenlerini göster Bazı kaldırıcılar, Ekle / Kaldır yazılım listesinden gizlemek için "sistem bileşenleri" olarak işaretlenebilir. Sürücüler genellikle bu etiketle işaretlenir. Korunan öğeleri göster Korunan öğeler "NoRemove" etiketi ile işaretlenir, yani yayıncı bunları kaldırmanızı istemez. İnce ayarları göster Güncellemeleri göster Diğer uygulamaların güncellemeleri. Genellikle ebeveyn uygulamaları ile birlikte kaldırılırlar, böylece göz ardı edilebilirler. Pencere özelliklerini göster Windows Mağazası uygulamalarını göster Süz Onay kutularını kullanarak seçin Listenin seçim stilini onay kutularına değiştirir. Onlar daha güvenli çünkü tek tıklama, her şeyin seçimini kaldıramaz. Birden fazla öğeyi vurgulayarak ve boşluk tuşuna basarak kontrol edebilirsiniz. Öğeleri gruplarda göster Listeye göre grup öğeleri gruplarına göre sıralanır. Sütunların çoğunun gruplanması akıllı filtreleme kullanır. Özel kaldırıcıları vurgulayın Özel uygulamaları ayırt etmek için renkleri kullanın, örneğin Mağaza Uygulamaları ve Windows Özellikleri. Liste görünümü ayarları ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/PropertiesSidebar.vi.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Hiển thị các ứng dụng chưa đăng ký Hiển thị các ứng dụng chưa có bất kỳ trình gỡ cài đặt được đăng ký nào. Chúng không hiển thị trong hầu hết các trình quản lý gỡ cài đặt nhưng vẫn chiếm dung lượng. Các mục chưa đăng ký được đánh dấu bằng màu đỏ. Cảnh báo: Hãy kiểm tra kỹ trước khi xóa các ứng dụng này, chúng có thể vẫn cần thiết! Đánh dấu các mục thiếu trình gỡ cài đặt Dùng màu xám để xác định trình gỡ cài đặt bị hỏng hoặc bị thiếu. Đánh dấu trình gỡ cài đặt đã đạt chứng chỉ Sử dụng màu sắc để xác định trình gỡ cài đặt đã đạt chứng chỉ. Màu xanh lục nếu chứng chỉ đã được xác minh thành công, ngược lại là màu xanh lam. Cảnh báo: Quá trình xác minh có thể mất nhiều thời gian để hoàn tất. Ẩn mọi thứ do Microsoft phát hành Lọc bỏ mọi thứ do Microsoft phát hành. Chỉ thế thôi. Hiển thị các thành phần hệ thống Một số trình gỡ cài đặt có thể được đánh dấu là "thành phần hệ thống" và bị ẩn khỏi danh sách Thêm/Xóa phần mềm. Các "Driver" thường được đánh dấu bằng thẻ này. Hiển thị các mục được bảo vệ Các mục được bảo vệ được đánh dấu bằng thẻ "NoRemove", có nghĩa là nhà phát hành không muốn bạn xóa chúng. Hiển thị các tinh chỉnh Hiển thị các ứng dụng cập nhật Các ứng dụng dùng để cập nhật các ứng dụng khác. Chúng thường được gỡ cài đặt cùng với ứng dụng gốc nên có thể yên tâm bỏ qua. Hiển thị Windows features Hiển thị ứng dụng từ Windows Store Bộ lọc Chọn bằng cách tích vào hộp kiểm Thay đổi kiểu lựa chọn của danh sách thành bằng cách tích các hộp kiểm. Chúng an toàn hơn vì không thể bỏ chọn mọi thứ bằng một cú nhấp chuột. Bạn có thể kiểm tra nhiều mục bằng cách tích chúng và nhấn phím cách. Hiển thị các mục theo nhóm Nhóm các mục trong danh sách theo các cột được sắp xếp. Việc nhóm hầu hết các cột sử dụng bộ lọc thông minh. Đánh dấu các trình gỡ cài đặt đặc biệt Dùng màu sắc để phân biệt các ứng dụng đặc biệt, ví dụ như Store Apps và Windows Features. Cài đặt chế độ xem ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/PropertiesSidebar.zh-Hans.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 显示未注册的应用程序 显示没有任何已注册卸载程序的应用程序。它们在大多数卸载管理器中不可见,但仍会占用空间。未注册的项目用红色标记。 警告:在删除这些应用程序之前,请仔细检查,它们可能仍然是必需的! 突出显示丢失的卸载程序 使用灰色标记已损坏或丢失的卸载程序。 突出显示已认证卸载程序 使用颜色标识已认证的卸载程序。 如果证书验证成功,使用绿色,否则使用蓝色。 警告:验证可能需要很长时间才能完成。 隐藏由Microsoft发布的内容 筛选掉Microsoft发布的所有内容。就这么简单。 显示系统组件 一些卸载程序可能被标记为"系统组件",以从添加/删除软件列表中隐藏它们。 驱动程序经常被标上这个标签。 显示受保护项目 受保护项目被标记为"不要删除"标签,表示发布者不希望你删除它们。 显示调整 显示更新 其他应用程序的更新。通常它们与父应用程序一起卸载,因此可以忽略它们。 显示Windows功能 显示Windows商店应用 筛选器 使用复选框选择 将列表的选择样式更改为复选框。这样更安全,因为单击不能取消选择所有内容。 你可以通过突出显示多个项目并按空格键来选中它们。 按组显示项目 根据列表排序的列对项目进行分组。 大多数列的分组使用智能筛选。 突出显示特殊的卸载程序 使用颜色区分特殊应用程序,例如商店应用程序和Windows功能。 列表视图设置 ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/PropertiesSidebar.zh-Hant.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 顯示未註冊的應用程式 顯示應用程式沒有任何已註冊的解除安裝軟體。它們不會出現在大多數的解除安裝管理程式內,但仍會佔用空間。未註冊的項目會用紅色來做標示。 警告:在刪除這些應用程式之前,請仔細檢查,它們可能是必須的! 提高顯示遺失的應用程式解除軟體 用灰色顯示應用程式解除軟體遺失或損壞。 提高顯示已認證的應用程式解除軟體 使用顏色標示已認證的應用程式解除軟體。如果憑證驗證成功,用綠色標示,否則為藍色。 警告:驗證可能會花一段時間才能完成。 隱藏由Microsoft發布的內容 搜尋由Microsoft發布的所有內容 顯示系統目錄 有些軟體解除安裝程式可能會被標示為系統目錄。從新增/移除軟體清單來隱藏它們。驅動程式常常會被標上這個標籤。 顯示保護項目 保護項目已被標記為"不要刪除",表示發布人員不希望你移除它們。 顯示調整軟體 顯示更新 其他應用程式的更新。通常它們與主程式一起解除,因此可以忽略他們 顯示Windows 功能 顯示Windows商店應用程式 過濾選項 使用複選框選擇 將列表的選擇樣式改為複選。這樣更安全,因為不能透過點擊來取消選擇所有內容 你可以透過提高顯示多個項目並按空白鍵來選擇它們。 以群組顯示項目 根據列表的排序對項目進行分組。大多數列的分組能夠自動篩選。 提高顯示特殊的移除程式 用顏色區分應用程式,例如商店應用程式和Windows 功能。 以清單顯示設定 ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/UninstallationSettings.Designer.cs ================================================ namespace BulkCrapUninstaller.Controls { partial class UninstallationSettings { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Component Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { components = new System.ComponentModel.Container(); System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(UninstallationSettings)); groupBox3 = new System.Windows.Forms.GroupBox(); checkBoxManualNoCollisionProtection = new System.Windows.Forms.CheckBox(); checkBoxConcurrentOneLoud = new System.Windows.Forms.CheckBox(); checkBoxConcurrent = new System.Windows.Forms.CheckBox(); numericUpDownMaxConcurrent = new System.Windows.Forms.NumericUpDown(); label2 = new System.Windows.Forms.Label(); groupBox2 = new System.Windows.Forms.GroupBox(); flowLayoutPanel4 = new System.Windows.Forms.FlowLayoutPanel(); checkBoxShutdown = new System.Windows.Forms.CheckBox(); checkBoxRestorePoint = new System.Windows.Forms.CheckBox(); checkBoxBatchSortQuiet = new System.Windows.Forms.CheckBox(); checkBoxDiisableProtection = new System.Windows.Forms.CheckBox(); checkBoxSimulate = new System.Windows.Forms.CheckBox(); groupBox1 = new System.Windows.Forms.GroupBox(); flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); checkBoxAutoKillQuiet = new System.Windows.Forms.CheckBox(); checkBoxRetryQuiet = new System.Windows.Forms.CheckBox(); checkBoxGenerate = new System.Windows.Forms.CheckBox(); checkBoxGenerateStuck = new System.Windows.Forms.CheckBox(); checkBoxAutoDaemon = new System.Windows.Forms.CheckBox(); toolTip1 = new System.Windows.Forms.ToolTip(components); groupBox3.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)numericUpDownMaxConcurrent).BeginInit(); groupBox2.SuspendLayout(); flowLayoutPanel4.SuspendLayout(); groupBox1.SuspendLayout(); flowLayoutPanel1.SuspendLayout(); SuspendLayout(); // // groupBox3 // resources.ApplyResources(groupBox3, "groupBox3"); groupBox3.Controls.Add(checkBoxManualNoCollisionProtection); groupBox3.Controls.Add(checkBoxConcurrentOneLoud); groupBox3.Controls.Add(checkBoxConcurrent); groupBox3.Controls.Add(numericUpDownMaxConcurrent); groupBox3.Controls.Add(label2); groupBox3.Name = "groupBox3"; groupBox3.TabStop = false; // // checkBoxManualNoCollisionProtection // resources.ApplyResources(checkBoxManualNoCollisionProtection, "checkBoxManualNoCollisionProtection"); checkBoxManualNoCollisionProtection.Name = "checkBoxManualNoCollisionProtection"; checkBoxManualNoCollisionProtection.UseVisualStyleBackColor = true; // // checkBoxConcurrentOneLoud // resources.ApplyResources(checkBoxConcurrentOneLoud, "checkBoxConcurrentOneLoud"); checkBoxConcurrentOneLoud.Name = "checkBoxConcurrentOneLoud"; checkBoxConcurrentOneLoud.UseVisualStyleBackColor = true; // // checkBoxConcurrent // resources.ApplyResources(checkBoxConcurrent, "checkBoxConcurrent"); checkBoxConcurrent.Name = "checkBoxConcurrent"; checkBoxConcurrent.UseVisualStyleBackColor = true; // // numericUpDownMaxConcurrent // resources.ApplyResources(numericUpDownMaxConcurrent, "numericUpDownMaxConcurrent"); numericUpDownMaxConcurrent.Maximum = new decimal(new int[] { 10, 0, 0, 0 }); numericUpDownMaxConcurrent.Minimum = new decimal(new int[] { 2, 0, 0, 0 }); numericUpDownMaxConcurrent.Name = "numericUpDownMaxConcurrent"; numericUpDownMaxConcurrent.Value = new decimal(new int[] { 2, 0, 0, 0 }); // // label2 // label2.AccessibleRole = System.Windows.Forms.AccessibleRole.StaticText; resources.ApplyResources(label2, "label2"); label2.Name = "label2"; // // groupBox2 // resources.ApplyResources(groupBox2, "groupBox2"); groupBox2.Controls.Add(flowLayoutPanel4); groupBox2.Name = "groupBox2"; groupBox2.TabStop = false; // // flowLayoutPanel4 // resources.ApplyResources(flowLayoutPanel4, "flowLayoutPanel4"); flowLayoutPanel4.Controls.Add(checkBoxShutdown); flowLayoutPanel4.Controls.Add(checkBoxRestorePoint); flowLayoutPanel4.Controls.Add(checkBoxBatchSortQuiet); flowLayoutPanel4.Controls.Add(checkBoxDiisableProtection); flowLayoutPanel4.Controls.Add(checkBoxSimulate); flowLayoutPanel4.Name = "flowLayoutPanel4"; // // checkBoxShutdown // resources.ApplyResources(checkBoxShutdown, "checkBoxShutdown"); checkBoxShutdown.Name = "checkBoxShutdown"; checkBoxShutdown.UseVisualStyleBackColor = true; // // checkBoxRestorePoint // resources.ApplyResources(checkBoxRestorePoint, "checkBoxRestorePoint"); checkBoxRestorePoint.Name = "checkBoxRestorePoint"; toolTip1.SetToolTip(checkBoxRestorePoint, resources.GetString("checkBoxRestorePoint.ToolTip")); checkBoxRestorePoint.UseVisualStyleBackColor = true; // // checkBoxBatchSortQuiet // resources.ApplyResources(checkBoxBatchSortQuiet, "checkBoxBatchSortQuiet"); checkBoxBatchSortQuiet.Name = "checkBoxBatchSortQuiet"; checkBoxBatchSortQuiet.UseVisualStyleBackColor = true; // // checkBoxDiisableProtection // resources.ApplyResources(checkBoxDiisableProtection, "checkBoxDiisableProtection"); checkBoxDiisableProtection.Name = "checkBoxDiisableProtection"; checkBoxDiisableProtection.UseVisualStyleBackColor = true; // // checkBoxSimulate // resources.ApplyResources(checkBoxSimulate, "checkBoxSimulate"); checkBoxSimulate.Name = "checkBoxSimulate"; checkBoxSimulate.UseVisualStyleBackColor = true; // // groupBox1 // resources.ApplyResources(groupBox1, "groupBox1"); groupBox1.Controls.Add(flowLayoutPanel1); groupBox1.Name = "groupBox1"; groupBox1.TabStop = false; // // flowLayoutPanel1 // resources.ApplyResources(flowLayoutPanel1, "flowLayoutPanel1"); flowLayoutPanel1.Controls.Add(checkBoxAutoKillQuiet); flowLayoutPanel1.Controls.Add(checkBoxRetryQuiet); flowLayoutPanel1.Controls.Add(checkBoxGenerate); flowLayoutPanel1.Controls.Add(checkBoxGenerateStuck); flowLayoutPanel1.Controls.Add(checkBoxAutoDaemon); flowLayoutPanel1.Name = "flowLayoutPanel1"; // // checkBoxAutoKillQuiet // resources.ApplyResources(checkBoxAutoKillQuiet, "checkBoxAutoKillQuiet"); checkBoxAutoKillQuiet.Name = "checkBoxAutoKillQuiet"; checkBoxAutoKillQuiet.UseVisualStyleBackColor = true; // // checkBoxRetryQuiet // resources.ApplyResources(checkBoxRetryQuiet, "checkBoxRetryQuiet"); checkBoxRetryQuiet.Name = "checkBoxRetryQuiet"; checkBoxRetryQuiet.UseVisualStyleBackColor = true; // // checkBoxGenerate // resources.ApplyResources(checkBoxGenerate, "checkBoxGenerate"); checkBoxGenerate.Name = "checkBoxGenerate"; checkBoxGenerate.UseVisualStyleBackColor = true; // // checkBoxGenerateStuck // resources.ApplyResources(checkBoxGenerateStuck, "checkBoxGenerateStuck"); checkBoxGenerateStuck.Name = "checkBoxGenerateStuck"; checkBoxGenerateStuck.UseVisualStyleBackColor = true; // // checkBoxAutoDaemon // resources.ApplyResources(checkBoxAutoDaemon, "checkBoxAutoDaemon"); checkBoxAutoDaemon.Name = "checkBoxAutoDaemon"; checkBoxAutoDaemon.UseVisualStyleBackColor = true; // // UninstallationSettings // resources.ApplyResources(this, "$this"); AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; Controls.Add(groupBox3); Controls.Add(groupBox1); Controls.Add(groupBox2); Name = "UninstallationSettings"; groupBox3.ResumeLayout(false); groupBox3.PerformLayout(); ((System.ComponentModel.ISupportInitialize)numericUpDownMaxConcurrent).EndInit(); groupBox2.ResumeLayout(false); groupBox2.PerformLayout(); flowLayoutPanel4.ResumeLayout(false); flowLayoutPanel4.PerformLayout(); groupBox1.ResumeLayout(false); groupBox1.PerformLayout(); flowLayoutPanel1.ResumeLayout(false); flowLayoutPanel1.PerformLayout(); ResumeLayout(false); PerformLayout(); } #endregion private System.Windows.Forms.GroupBox groupBox3; private System.Windows.Forms.CheckBox checkBoxConcurrentOneLoud; private System.Windows.Forms.CheckBox checkBoxConcurrent; private System.Windows.Forms.NumericUpDown numericUpDownMaxConcurrent; private System.Windows.Forms.Label label2; private System.Windows.Forms.GroupBox groupBox2; private System.Windows.Forms.CheckBox checkBoxShutdown; private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel4; private System.Windows.Forms.CheckBox checkBoxBatchSortQuiet; private System.Windows.Forms.CheckBox checkBoxDiisableProtection; private System.Windows.Forms.CheckBox checkBoxSimulate; private System.Windows.Forms.GroupBox groupBox1; private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1; private System.Windows.Forms.CheckBox checkBoxAutoKillQuiet; private System.Windows.Forms.CheckBox checkBoxRetryQuiet; private System.Windows.Forms.CheckBox checkBoxGenerate; private System.Windows.Forms.CheckBox checkBoxGenerateStuck; private System.Windows.Forms.CheckBox checkBoxManualNoCollisionProtection; private System.Windows.Forms.CheckBox checkBoxAutoDaemon; private System.Windows.Forms.CheckBox checkBoxRestorePoint; private System.Windows.Forms.ToolTip toolTip1; } } ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/UninstallationSettings.ar.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 تعطيل منع الاصطدام عند تشغيل الغاء التثبيت يدويا الغاء تثبيت واحد فقط بصوت عال كل مرة (تشغيل التثبيت تلقائيا بشكل متزامن (اذا كان ذلك ممكنا الحد الاقصى لعدد المثبتات التي قيد التشغيل: الغاء تثبيت متزامن منع ايقاف/اعاده تشغيل النظام فرز ذكي الغاء التثبيت تعطيل الحماية محاكاة الغاء التثبيت الاعدادات العامة قتل المثبتات العالقة تلقائيا بهدوء فشل اعاده محاولة التثبيت بهدوء مره انشاء المثبتات المفقودة بهدوء اذا كان ذلك ممكنا قتل تلقائيا اذا كان العالق في انتظار ادخال المستخدم الغاء التثبيت بهدوء انشاء نقطه استعاده قبل الغاء التثبيت يمكنك انشاء نقطه استعاده النظام الى تسجيل النسخ الاحتياطي ، وبعض الاعدادات والملفات. من المستحسن انشاء نقطه استعاده قبل ازاله برامج التشغيل وتطبيقات النظام الهامه. ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/UninstallationSettings.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Drawing; using System.Windows.Forms; using Klocman; using Klocman.Binding.Settings; using Klocman.IO; namespace BulkCrapUninstaller.Controls { public partial class UninstallationSettings : UserControl { public UninstallationSettings() { InitializeComponent(); } protected override void OnLoad(EventArgs e) { base.OnLoad(e); if (DesignMode) return; var sb = Properties.Settings.Default.SettingBinder; // Shutdown blocking not available below Windows Vista if (Environment.OSVersion.Version < new Version(6, 0)) checkBoxShutdown.Enabled = false; else sb.BindControl(checkBoxShutdown, settings => settings.UninstallPreventShutdown, this); checkBoxRestorePoint.Enabled = SysRestore.SysRestoreAvailable(); sb.Bind(x => checkBoxRestorePoint.Checked = x != YesNoAsk.No, () => checkBoxRestorePoint.Checked && sb.Settings.MessagesRestorePoints != YesNoAsk.No ? sb.Settings.MessagesRestorePoints : checkBoxRestorePoint.Checked ? YesNoAsk.Ask : YesNoAsk.No, eh => checkBoxRestorePoint.CheckedChanged += eh, eh => checkBoxRestorePoint.CheckedChanged -= eh, settings => settings.MessagesRestorePoints, this); sb.BindControl(checkBoxConcurrent, settings => settings.UninstallConcurrency, this); sb.BindControl(checkBoxConcurrentOneLoud, settings => settings.UninstallConcurrentOneLoud, this); sb.BindControl(checkBoxManualNoCollisionProtection, settings => settings.UninstallConcurrentDisableManualCollisionProtection, this); sb.Subscribe(OnMaxCountChanged, settings => settings.UninstallConcurrentMaxCount, this); numericUpDownMaxConcurrent.ValueChanged += NumericUpDownMaxConcurrentOnValueChanged; sb.BindControl(checkBoxBatchSortQuiet, x => x.AdvancedIntelligentUninstallerSorting, this); sb.BindControl(checkBoxDiisableProtection, x => x.AdvancedDisableProtection, this); sb.BindControl(checkBoxSimulate, x => x.AdvancedSimulate, this); sb.BindControl(checkBoxAutoKillQuiet, x => x.QuietAutoKillStuck, this); sb.BindControl(checkBoxRetryQuiet, x => x.QuietRetryFailedOnce, this); sb.BindControl(checkBoxGenerate, x => x.QuietAutomatization, this); sb.BindControl(checkBoxGenerateStuck, x => x.QuietAutomatizationKillStuck, this); sb.BindControl(checkBoxAutoDaemon, x => x.QuietUseDaemon, this); sb.Subscribe((sender, args) => checkBoxGenerateStuck.Enabled = args.NewValue, settings => settings.QuietAutomatization, this); sb.Subscribe( (x, y) => checkBoxSimulate.ForeColor = y.NewValue ? Color.OrangeRed : SystemColors.ControlText, x => x.AdvancedSimulate, this); sb.SendUpdates(this); Disposed += (x, y) => sb.RemoveHandlers(this); } private void NumericUpDownMaxConcurrentOnValueChanged(object sender, EventArgs eventArgs) { Properties.Settings.Default.UninstallConcurrentMaxCount = (int)numericUpDownMaxConcurrent.Value; } private void OnMaxCountChanged(object sender, SettingChangedEventArgs args) { numericUpDownMaxConcurrent.Value = Math.Clamp(args.NewValue, numericUpDownMaxConcurrent.Minimum, numericUpDownMaxConcurrent.Maximum); } } } ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/UninstallationSettings.cs.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Simulace odinstalace Zakázat ochranu Inteligentní třídění odinstalace Zakázat prevenci kolizí, při spuštění Odinstalovat ručně Pouze jedno spuštění odinstalace Automaticky spustit souběžné odinstalace (pokud je to možné) Maximální počet spuštění odinstalačních programů: Souběžná odinstalace Zabránit vypnutí/restartu systému Obecná nastavení Automaticky ukončit zablokované tiché odinstalace Opakovat ještě jednou selhané tiché odinstalace Pokud je to možné vytvořit tiché odinstalace Automaticky ukončit pokud zablokované čekání vyžaduje příkaz uživatele Tichá odinstalace True pl Před odinstalováním vytvořte bod obnovení Můžete vytvořit bod obnovení systému, zálohu registru, některá nastavení a soubory. Doporučujeme vytvořit bod obnovení před odebráním ovladačů a důležitých systémových aplikací. ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/UninstallationSettings.de.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Deinstallation simulieren Schutz deaktivieren Intelligente Sortierung Allgemeine Einstellungen Ausschalten der Kollisionsverhütung beim manuellen Deinstallieren Nur eine Instanz erlauben Automatisch Uninstaller gleichzeitig benutzen (wenn möglich) Maximale Anzahl der laufenden Uninstaller Gleichzeitiges deinstallieren Verhinderung des Neustarts/Beenden Automatisches Abbrechen hängender leiser Uninstaller Einmaliger Versuch leise Deinstaller neu zu starten Erzeugen von fehlenden stillen Uninstaller wenn möglich Automatisches Beenden eines Uninstallers wenn auf Benutzereingabe gewartet wird Überwachung "stiller" Uninstaller nach Popups oder andere Hinweise zu automatisierung (Start automatisierter Daemon) Stille Deinstallation True pl Wiederherstellungspunkt vor dem Deinstallieren erzeugen Sie können einen Systemwiederherstellungspunkt für die Backup-Registrierung, einigen Einstellungen und Dateien erstellen. Es wird empfohlen, vor dem Entfernen von Treibern und wichtigen Systemanwendungen einen Wiederherstellungspunkt zu erstellen. ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/UninstallationSettings.es.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Desactivar la prevención de colisiones cuando se ejecutan desinstaladores manualmente Sólo un desinstalador fuerte a la vez Ejecutar desinstaladores simultáneamente (si es posible) Número máximo de desinstaladores en ejecución: Desinstalación simultánea Prevenir sistema de apagado/reinicio Clasificación de desinstalación inteligente Desactivar protección Simular desinstalación Configuración general Eliminar automáticamente los desinstaladores bloqueados Reintentar los desinstaladores silenciosos fallidos una vez Generar posibles desinstaladores silenciosos si es posible Matar si está atascado esperando la entrada del usuario Desinstalación silenciosa Crear un punto de restauración antes de desinstalar Puede crear un punto de restauración del sistema para hacer una copia de seguridad del registro, algunas configuraciones y archivos. Se recomienda crear un punto de restauración antes de eliminar los controladores y las aplicaciones importantes del sistema. Monitorear los desinstaladores "silenciosos" en busca de ventanas emergentes u otros atascos y automatizarlos (ejecutar daemon automatizador) ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/UninstallationSettings.fr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Simuler la désinstallation Désactiver la protection Tri intelligent des désinstalleurs Lancer automatiquement les désinstalleurs de concert (si possible) Nombre max de désinstalleurs lancés : Seulement un désinstalleur causant à la fois Désactiver la prévention de collision en lançant manuellement les désinstalleurs Réglages généraux Désinstallation de concert Empêcher l'arrêt/redémarrage du système Tuer automatiquement les désinstalleurs silencieux bloqués Retenter une fois les désinstalleurs silencieux échoués Générer si possible les désinstalleurs silencieux manquants Tuer automatiquement si bloqués attendant la saisie utilisateur Désinstallation silencieuse Surveiller les popups des désinstalleurs "silencieux" et autres attentes et les automatiser (lancer un démon automatiseur) Créer un point de restauration avant désinstallation Vous pouvez créer un point de restauration système pour sauvegarder le registre, certains paramètres et fichiers. Il est recommandé de créer un point de restauration avant de supprimer des pilotes et des applications système importantes. Si ce paramètre est grisé, les Points de Restauration sont désactivés ou indisponibles. Dans ce cas, aucun point de restauration ne sera créé ! True pl ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/UninstallationSettings.hu.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Ütközéselhárító kikapcsolása, amikor kézzel indítja az eltávolítót Egyidejűleg csak egy beavatkozást kérő fusson Eltávolítók egyidejű autom. futtatása (ha lehetséges) Max. futtatható eltávolítók száma: Egyidejű eltávolítás Rendszer leállítás/újraindítás megakadályozása Intelligens eltávolító kiválasztás Védelem kikapcsolása Szimulált eltávolítás Általános beállítások Automatikus folytatás a beragadt eltávolításkor Egyszer ismételje meg a sikertelen eltávolítást Hiányzó eltávolító létrehozása, ha lehetséges Folytatás beragadt beavatkozási várakozás esetén Csendes eltávolítás Visszaállítási pont létrehozása az eltávolítás előtt Létrehozhat egy rendszer-visszaállítási pontot a beállításjegyzék, egyes beállítások és fájlok biztonsági mentéséhez. Ajánlott visszaállítási pontot létrehozni az illesztőprogramok és fontos rendszeralkalmazások eltávolítása előtt. „Csendes” eltávolítók figyelése és automatizálása felugró ablakok vagy egyéb akadozások esetén (automatizáló szolgáltatás futtatása) ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/UninstallationSettings.it.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Disabilita la prevenzione di collisione quando si eseguono manualmente i disinstallatori Solo un disinstallatore guidato per volta Esegue automaticamente e simultaneamente (se possibile) i disinstallatori Numero massimo disinstallatori eseguibili: Disinstallazione simultanea Previene lo spegnimento/riavvio del sistema Ordinamento intelligente disinstallatore Disabilita protezione Simula disinstallazione Impostazioni generali Termina automaticamente disinstallatori silenziosi bloccati Esegui nuovamente disinstallatori silenziosi non andati a buon fine Genera se possibile disinstallatori silenziosi mancanti Termina automaticamente se bloccato in attesa di comandi dell'utente Disinstallazione silenziosa Controlla i popup o le fasi di stallo dei disinstallatori "silenziosi" e rendili automatici (esegui demone che li automatizza) Crea un punto di ripristino prima della disinstallazione È possibile creare un punto di ripristino del sistema per salvare il registro, alcune configurazioni e file. Ti raccomandiamo prima della rimozione di creare un punto di ripristino. ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/UninstallationSettings.ja.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 手動でアンインストーラーを実行する際の衝突防止を無効化 騒音アンインストーラーは1度に1つだけ 可能であればアンインストーラーを自動的に並行実行 同時に実行できるアンインストーラーの最大数: 並行アンインストール システムのシャットダウン/再起動を防止 アンインストール前に復元ポイントを作成 レジストリ、一部の設定やファイルをバックアップするためにシステム復元ポイントを作成できます。ドライバや重要なシステムアプリケーションを削除する前に、復元ポイントを作成することを推奨します。 アンインストーラーを賢く並べ替え 保護を無効化 アンインストールをシミュレーション 一般設定 フリーズした無音アンインストーラーを自動的に強制終了 失敗した無音アンインストーラーを1度再試行 可能であれば不足している無音アンインストーラーを生成 ユーザー入力待機でフリーズした場合、自動的に強制終了 ポップアップやその他の停止状態を監視し、それらを自動化する(自動化デーモンを実行) 無音アンインストール ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/UninstallationSettings.nl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Intelligente de-installer sortering Beveiliging deactiveren De-installatie simuleren Schakel conflict preventie uit als de-installers handmatig worden uitgevoerd Slechts één de-installatie per keer Automatisch gelijktijdig uitvoeren van de-installers (indien mogelijk) Max. aantal lopende de-installers Gelijktijdige de-installatie Voorkom afsluiten/herstarten van het systeem Algemene instellingen Automatisch beëindigen van vastgelopen stille de-installers Probeer falende stille de-installers eenmaal opnieuw Genereer ontbrekende stille de-installers, indien mogelijk Automatisch beëindigen, als een vastgelopen de-installer wacht op gebruikers invoer Onzichtbare de-installatie Monitor "stille" de-installers voor pop-ups of andere vertragingen en automatiseer deze (start automatiseer daemon) Maak een herstelpunt alvorens te de-installeren Het is mogelijk om een systeem herstelpunt maken voor een back-up van het register, sommige instellingen en bestanden. Het wordt aanbevolen om een herstelpunt te maken voor het verwijderen van stuurprogramma's en belangrijke systeem programma's. ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/UninstallationSettings.pl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Wyłącz zapobiegania kolizji podczas uruchamiania dezinstalatorów ręcznie Tylko jeden głośny dezinstalator na raz Automatycznie uruchom dezinstalatory równolegle Maks. liczba działających dezinstalatorów: Równoległa deinstalacja Zapobiegaj restartowaniu systemu Inteligentne sortowanie Wyłącz zabezpieczenie Symuluj dezinstalację Ustawienia ogólne Automatycznie zatrzymuj zawieszone ciche dezinstalatory Ponów raz próbę niepowiedzonej cichej dezinstalacji Wygeneruj brakujące ciche dezinstalatory jeśli to możliwe Automatycznie zakończ jeśli czeka na interwencję użytkownika Cicha dezinstalacja Monitoruj "ciche" deinstalatory I zautomatyzuj nieprzewidziane wyskakujące okiena Utwórz punkt przywracania przed odinstalowaniem Możesz utworzyć systemowy punkt przywracania systemu (zachowuje rejestr, niektóre ustawienia i pliki). Zaleca się utworzenie punktu przywracania przed usunięciem sterowników i ważnych aplikacji systemowych. ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/UninstallationSettings.pt-BR.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Desativar a prevenção de colisão ao executar desinstaladores manualmente Só um desinstalador de primeiro plano por vez Execute automaticamente os desinstaladores de forma simultânea (se possível) Número máximo de desinstaladores em execução: Desinstalação simultânea Impedir o desligamento/reinício do sistema Classificação inteligente dos desinstaladores Desativar proteção Simular desinstalação Configurações Gerais Finalizar automaticamente os instaladores silenciosos travados Tentar novamente os desinstaladores silenciosos que falharam Gerar desinstaladores silenciosos em falta, se possível Finalizar automaticamente se travar aguardando entrada do usuário Desinstalação silenciosa Criar um ponto de restauração antes de desinstalar Você pode criar um ponto de restaução do sistema para o backup do registro, algumas configurações e arquivos. É recomendado criar um ponto de restauração antes de remover drivers e aplicações de sistema importantes. Monitorar desinstaladores "silenciosos" para popups e outros travamentos e automatizá-los (Executar daemon de automatização) ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/UninstallationSettings.pt.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Desactivar a função anticonflito quando se correr manualmente os desinstaladores Só um desinstalador de primeiro plano de cada vez Correr automaticamente desinstaladores em simultâneo (se possível) Número máximo de desisnataldores em função: Desinstalação simultânea Impedir o fecho/reinício do sistema Ordenação inteligente do desinstalador Descativar a protecção Simulate uninstallation Configurações gerais Eliminar automaticamente os desinstaladores de segunto plano bloqueados Tentar de novo os desinstaladores de segundo plano fracassados Criar os desinstaladores de segundo plano em falta, se possível Eliminar automaticamente se bloqueado à espera da intervenção do utilizador Desinstalação em segundo plano True Criar um ponto de restauro antes de desinstalar Pode criar um ponto de restauro do sistema para o registo de backup, de algumas configurações e de arquivos. Recomenda-se criar um ponto de restauro antes de remover drivers e aplicativos importantes do sistema. ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/UninstallationSettings.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 True GrowAndShrink True False NoControl 9, 95 4, 3, 4, 3 251, 34 4 Disable collision prevention when running uninstallers manually False checkBoxManualNoCollisionProtection System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBox3 0 True NoControl 24, 69 4, 3, 4, 3 208, 19 3 Only one loud uninstaller at a time checkBoxConcurrentOneLoud System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBox3 1 True NoControl 9, 22 4, 3, 4, 3 318, 19 0 Automatically run uninstallers concurrently (if possible) checkBoxConcurrent System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBox3 2 Top, Right 258, 45 4, 3, 4, 3 80, 23 2 numericUpDownMaxConcurrent System.Windows.Forms.NumericUpDown, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBox3 3 True NoControl 21, 47 4, 0, 4, 0 200, 15 1 Max number of running uninstallers: label2 System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBox3 4 Top 0, 309 4, 3, 4, 3 6, 3, 6, 3 348, 151 2 Concurrent uninstallation groupBox3 System.Windows.Forms.GroupBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 0 True True True NoControl 4, 3 4, 3, 4, 3 200, 19 0 Prevent system shutdown/restart checkBoxShutdown System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel4 0 True NoControl 4, 28 4, 3, 4, 3 241, 19 4 Create a restore point before uninstalling 17, 17 You can create a system restore point to backup registry, some settings and files. It's recommended to create a restore point before removing drivers and important system applications. If this setting is grayed out, Restore Points are disabled or unavailable. In this case no restore point will be created! checkBoxRestorePoint System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel4 1 True NoControl 4, 53 4, 3, 4, 3 177, 19 1 Intelligent uninstaller sorting checkBoxBatchSortQuiet System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel4 2 True NoControl 4, 78 4, 3, 4, 3 122, 19 2 Disable protection checkBoxDiisableProtection System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel4 3 True NoControl 4, 103 4, 3, 4, 3 147, 19 3 Simulate uninstallation checkBoxSimulate System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel4 4 Top TopDown 6, 19 4, 3, 4, 3 336, 125 0 False flowLayoutPanel4 System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBox2 0 Top 0, 0 4, 3, 4, 3 6, 3, 6, 3 348, 147 0 General settings groupBox2 System.Windows.Forms.GroupBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 2 True True True NoControl 4, 3 4, 3, 4, 3 242, 19 0 Automatically kill stuck quiet uninstallers checkBoxAutoKillQuiet System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel1 0 True NoControl 4, 28 4, 3, 4, 3 207, 19 1 Retry failed quiet uninstallers once checkBoxRetryQuiet System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel1 1 True NoControl 4, 53 4, 3, 4, 3 266, 19 2 Generate missing quiet uninstallers if possible checkBoxGenerate System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel1 2 True NoControl 4, 78 4, 3, 4, 3 15, 0, 0, 0 290, 19 3 Automatically kill if stuck waiting for user input checkBoxGenerateStuck System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel1 3 True NoControl 4, 103 4, 3, 4, 3 308, 34 4 Monitor "silent" uninstallers for popups or other stalls and automatize them (run automatizer daemon) checkBoxAutoDaemon System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel1 4 Top TopDown 6, 19 4, 3, 4, 3 336, 140 0 False flowLayoutPanel1 System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBox1 0 Top 0, 147 4, 3, 4, 3 6, 3, 6, 3 348, 162 1 Quiet uninstallation groupBox1 System.Windows.Forms.GroupBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 1 True 7, 15 4, 3, 4, 3 348, 478 toolTip1 System.Windows.Forms.ToolTip, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 UninstallationSettings System.Windows.Forms.UserControl, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/UninstallationSettings.ru.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Отключить предупреждения о конфликтах при ручном удалении Только одно шумное удаление за раз Автозапуск деинсталляторов одновременно (если возможно) Максимум запущенных деинсталляторов: Одновременное удаление Запрет выключения/перезагрузки системы Умная сортировка деинсталляторов Отключить защиту Имитировать деинсталляцию Общие настройки Автоматически убивать зависшие тихие деинсталляторы Повторить один раз попытку тихой деинсталляции Генерировать тихую деинсталляцию, если возможно Автоубитие застрявших в ожидании ручного ввода Тихое удаление Создание точки восстановления перед удалением Вы можете создать точку восстановления системы, чтобы сделать резервную копию реестра, некоторых настроек и файлов. Рекомендуется создавать точки восстановления перед удалением драйверов и важных системных приложений. Мониторить "тихие" деинсталляторы на наличие поп-апов или других внезапностей и автоматизировать их (запускать демона-автоматизатора) True ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/UninstallationSettings.sl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Simuliraj odstranitev Onemogoči zaščito Inteligentno razvrščanje odstranjevalca Onemogoči preprečevanje sporov, ko se izvajajo ročna odstranjevanja. Samo en glasnen odstranjevalec naenkrat Samodejno zaženi hkratne odstranjevalce (če je mogoče) Največje število zagnanih odstranjevalcev: Hkratno odstranjevanje Prepreči ustavitev/ponovni zagon sistema Splošne nastavitve Samodejno uniči obtičale tihe odstranjevalce Enkrat ponovi spodletele tihe odstranjevalce Če je mogoče, ustvari manjkajoče tihe odstranjevalce Samodejno uniči, če obtičalo čakanje zahteva vnos uporabnika Tiho odstranjevanje Nadziraj pojavna okna "tihih" odstranjevalcev ali druge stojnice in jih avtomatiziraj (zaženi demona za avtomatizacijo) True pl Preden odstranite program, ustvarite obnovitveno točko Ustvarite lahko obnovitveno točko sistema za varnostni kopirni register, nekatere nastavitve in datoteke. Pred odstranjevanjem gonilnikov in pomembnih sistemskih aplikacij priporočamo, da ustvarite obnovitveno točko. ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/UninstallationSettings.sv.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Inaktivera kollisionsförebyggning när du kör avinstallationsprogram manuellt. Endast en synlig avinstallationsprocess åt gången Automatisk samtidig körning av avinstallationsprogram (om möjligt) Max antal pågående avinstallationsprogram: Samtidig avinstallation Förhindra systemavstängning/omstart Skapa en återställningspunkt innan avinstallation Du kan skapa en systemåterställningspunkt för att säkerhetskopiera register, vissa inställningar och filer. Det rekommenderas att skapa en återställningspunkt innan du tar bort drivrutiner och viktiga systemapplikationer. Intelligent sortering av avinstallationsprogram Inaktivera skydd Simulera avinstallation Allmänna inställningar Automatisk stängning a frysta tysta avinstallationsprogram Försök starta om misslyckade tysta avinstallationsprogram en gång Generera saknade tysta avinstallationsprogram om möjligt Automatisk avslutning vid väntan på användarindata Automatisera tysta popup-fönster för avinstallation via daemon. Tyst avinstallation ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/UninstallationSettings.tr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Kaldırıcıları el ile çalıştırırken çakışma önleme özelliğini devre dışı bırak Tek seferde sadece bir kaldırma Kaldırıcıları otomatik olarak eşzamanlı olarak çalıştırın (eğer mümkünse) Maksimum sayıda çalışan kaldırıcı: Eşzamanlı kaldırma Sistem kapatmayı / yeniden başlatmayı engelle Akıllı kaldırıcı sıralama Korumayı devre dışı bırak Kaldırma simülasyonu Genel ayarlar Kilitlenmiş sessiz kaldırıcıları otomatik olarak sonlandır Sessiz kaldırma girişimini bir kez daha tekrarlayın Mümkünse sessiz kaldırma oluştur Kullanıcı girişi için beklemede kaldığında otomatik olarak sonlandır Pop-up veya diğer tezgahlar için "sessiz" kaldırıcılar izleyin ve onları otomatikleştirin (otomatikleştirici daemon çalıştır) Sessiz kaldırma Kaldırmadan önce bir geri yükleme noktası oluşturun Kayıt defterini, bazı ayarları ve dosyaları yedeklemek için bir sistem geri yükleme noktası oluşturabilirsiniz. Sürücüleri ve önemli sistem uygulamalarını kaldırmadan önce bir geri yükleme noktası oluşturmanız önerilir. ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/UninstallationSettings.vi.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Tắt tính năng chống xung đột khi chạy trình gỡ cài đặt theo cách thủ công Mỗi lần chỉ chạy một trình gỡ cài đặt Tự động chạy đồng thời các trình gỡ cài đặt (nếu có thể) Số trình gỡ cài đặt tối đa chạy đồng thời: Gỡ cài đặt đồng thời Ngăn chặn việc tắt/khởi động lại hệ thống Tạo điểm khôi phục trước khi gỡ cài đặt Bạn có thể sao lưu registry, một số cài đặt và tệp bằng cách tạo điểm khôi phục hệ thống. Bạn nên tạo điểm khôi phục trước khi xóa driver và các ứng dụng hệ thống quan trọng. Sắp xếp trình gỡ cài đặt một cách thông minh Vô hiệu hóa bảo vệ Mô phỏng quá trình gỡ cài đặt Cài đặt chung Tự động huỷ các trình gỡ cài đặt âm thầm bị lỗi Thử lại các trình gỡ cài đặt âm thầm không thành công một lần nữa Tạo trình gỡ cài đặt âm thầm bị thiếu nếu có thể Tự động huỷ trình gỡ cài đặt nếu nó bị kẹt khi chờ thao tác của người dùng Giám sát các trình gỡ cài đặt "im lặng" bật lên cửa sổ không mong muốn hoặc treo máy, và tự động hóa chúng (chạy trình nền tự động) Gỡ cài đặt âm thầm ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/UninstallationSettings.zh-Hans.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 手动运行卸载程序时禁用冲突保护 一次一个交互卸载程序 自动同时运行卸载程序(如果可能) 同时运行的卸载程序最大数量: 同时卸载 防止系统关机/重启 卸载前创建还原点 你可以创建一个系统还原点来备份注册表、一些设置和文件。建议在删除驱动程序和重要的系统应用程序之前创建一个还原点。 智能卸载程序排序 禁用保护 模拟卸载 常规设置 自动终止卡死的静默卸载程序 重试一次失败的静默卸载程序 如果可能,生成丢失的静默卸载程序 如果在等待用户输入时卡住自动终止 监视“静默”卸载程序的弹出窗口或其他停滞并使其自动化(运行自动化程序守护进程) 静默卸载 ================================================ FILE: source/BulkCrapUninstaller/Controls/Settings/UninstallationSettings.zh-Hant.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 手動執行移除軟體時禁止衝突保護 一次一種交互移除軟體 自動運行移除軟體(如果可以) 同時執行移除軟體的最大數量: 同時移除 防止系統關機/重啟 移除前建立系統還原點 你可以建立一個系統還原點來備份機碼、一些設定和文件。建議在刪除驅動程式和重要的系統應用程式之前創一個還原點。 智慧排序移除軟體 關閉保護 模擬移除 一般設定 自動結束沒有回應的最小化移除軟體 重新執行失敗的最小化移除軟體 如果可以,產生遺失最小化移除軟體 自動結束卡在等待使用者輸入的程式 監看"最小化"移除軟體的彈出視窗或其他程序並執行自動化(執行自動化程式保護服務) 最小化移除 ================================================ FILE: source/BulkCrapUninstaller/Controls/TabControlWithoutHeader.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Windows.Forms; namespace BulkCrapUninstaller.Controls { public class TabControlWithoutHeader : TabControl { public TabControlWithoutHeader() { if (!DesignMode) Multiline = true; } protected override void WndProc(ref Message m) { if (m.Msg == 0x1328 && !DesignMode) m.Result = new IntPtr(1); else base.WndProc(ref m); } } } ================================================ FILE: source/BulkCrapUninstaller/Controls/UninstallConfirmation.Designer.cs ================================================ namespace BulkCrapUninstaller.Forms { partial class UninstallConfirmation { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(UninstallConfirmation)); objectListView1 = new BrightIdeasSoftware.ObjectListView(); olvColumnName = new BrightIdeasSoftware.OLVColumn(); olvColumnEnabled = new BrightIdeasSoftware.OLVColumn(); olvColumnQuiet = new BrightIdeasSoftware.OLVColumn(); olvColumnInstallLocation = new BrightIdeasSoftware.OLVColumn(); panel1 = new System.Windows.Forms.Panel(); buttonSmartSort = new System.Windows.Forms.Button(); flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); labelInfo = new System.Windows.Forms.Label(); labelInfo2 = new System.Windows.Forms.Label(); pictureBox1 = new System.Windows.Forms.PictureBox(); ((System.ComponentModel.ISupportInitialize)objectListView1).BeginInit(); panel1.SuspendLayout(); flowLayoutPanel1.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)pictureBox1).BeginInit(); SuspendLayout(); // // objectListView1 // objectListView1.AllColumns.Add(olvColumnName); objectListView1.AllColumns.Add(olvColumnEnabled); objectListView1.AllColumns.Add(olvColumnQuiet); objectListView1.AllColumns.Add(olvColumnInstallLocation); objectListView1.CellEditUseWholeCell = false; objectListView1.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { olvColumnName, olvColumnEnabled, olvColumnQuiet, olvColumnInstallLocation }); resources.ApplyResources(objectListView1, "objectListView1"); objectListView1.FullRowSelect = true; objectListView1.GridLines = true; objectListView1.Name = "objectListView1"; objectListView1.ShowGroups = false; objectListView1.ShowItemToolTips = true; objectListView1.UseCompatibleStateImageBehavior = false; objectListView1.View = System.Windows.Forms.View.Details; // // olvColumnName // resources.ApplyResources(olvColumnName, "olvColumnName"); // // olvColumnEnabled // olvColumnEnabled.CheckBoxes = true; olvColumnEnabled.Hideable = false; resources.ApplyResources(olvColumnEnabled, "olvColumnEnabled"); // // olvColumnQuiet // olvColumnQuiet.CheckBoxes = true; resources.ApplyResources(olvColumnQuiet, "olvColumnQuiet"); // // olvColumnInstallLocation // olvColumnInstallLocation.FillsFreeSpace = true; resources.ApplyResources(olvColumnInstallLocation, "olvColumnInstallLocation"); // // panel1 // panel1.Controls.Add(buttonSmartSort); resources.ApplyResources(panel1, "panel1"); panel1.Name = "panel1"; // // buttonSmartSort // resources.ApplyResources(buttonSmartSort, "buttonSmartSort"); buttonSmartSort.Name = "buttonSmartSort"; buttonSmartSort.UseVisualStyleBackColor = true; buttonSmartSort.Click += buttonSort_Click; // // flowLayoutPanel1 // resources.ApplyResources(flowLayoutPanel1, "flowLayoutPanel1"); flowLayoutPanel1.Controls.Add(labelInfo); flowLayoutPanel1.Controls.Add(labelInfo2); flowLayoutPanel1.Name = "flowLayoutPanel1"; // // labelInfo // resources.ApplyResources(labelInfo, "labelInfo"); labelInfo.Name = "labelInfo"; // // labelInfo2 // resources.ApplyResources(labelInfo2, "labelInfo2"); labelInfo2.Name = "labelInfo2"; // // pictureBox1 // resources.ApplyResources(pictureBox1, "pictureBox1"); pictureBox1.Image = Properties.Resources.list_reorder; pictureBox1.Name = "pictureBox1"; pictureBox1.TabStop = false; // // UninstallConfirmation // resources.ApplyResources(this, "$this"); AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; Controls.Add(pictureBox1); Controls.Add(objectListView1); Controls.Add(flowLayoutPanel1); Controls.Add(panel1); Name = "UninstallConfirmation"; ((System.ComponentModel.ISupportInitialize)objectListView1).EndInit(); panel1.ResumeLayout(false); panel1.PerformLayout(); flowLayoutPanel1.ResumeLayout(false); flowLayoutPanel1.PerformLayout(); ((System.ComponentModel.ISupportInitialize)pictureBox1).EndInit(); ResumeLayout(false); PerformLayout(); } #endregion private BrightIdeasSoftware.ObjectListView objectListView1; private System.Windows.Forms.Panel panel1; private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1; private System.Windows.Forms.Label labelInfo; private BrightIdeasSoftware.OLVColumn olvColumnEnabled; private BrightIdeasSoftware.OLVColumn olvColumnQuiet; private BrightIdeasSoftware.OLVColumn olvColumnName; private BrightIdeasSoftware.OLVColumn olvColumnInstallLocation; private System.Windows.Forms.Button buttonSmartSort; private System.Windows.Forms.PictureBox pictureBox1; private System.Windows.Forms.Label labelInfo2; } } ================================================ FILE: source/BulkCrapUninstaller/Controls/UninstallConfirmation.ar.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 تغيير الترتيب اذا تم تمكين الغاء التثبيت المتزامن.BCU يعتمد الترتيب الاولي على اعدادات الغاء التثبيت ، ولكن يمكن تغييره عن طريق سحب المادة. ملاحظه: يمكن ل هذه هي قائمه من التطبيقات التي سيتم الغاء تثبيتها ، من اجل من اعلى الى اسفل. اذا قمت بالغاء تحديد الحقل "الغاء التثبيت" ، لن يتم الغاء تثبيت التطبيق. اذا لم يكن التثبيت بهدوء متوفرا لمادة ، فلا يمكن التحقق منه فرز ذكي موقع التثبيت بهدوء الغاء التثبيت اسم الغاء التثبيت ================================================ FILE: source/BulkCrapUninstaller/Controls/UninstallConfirmation.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; using BrightIdeasSoftware; using BulkCrapUninstaller.Functions; using UninstallTools.Uninstaller; namespace BulkCrapUninstaller.Forms { public partial class UninstallConfirmation : UserControl { public UninstallConfirmation() { InitializeComponent(); olvColumnEnabled.AspectGetter = rowObject => ((ConfirmationEntry) rowObject).Enabled; olvColumnEnabled.AspectPutter = (rowObject, value) => ((ConfirmationEntry) rowObject).Enabled = (bool) value; olvColumnQuiet.AspectGetter = rowObject => ((ConfirmationEntry) rowObject).Entry.IsSilentPossible; olvColumnQuiet.AspectPutter = (rowObject, value) => { var entry = ((ConfirmationEntry) rowObject).Entry; entry.IsSilentPossible = (bool) value && entry.UninstallerEntry.QuietUninstallPossible; }; olvColumnInstallLocation.AspectGetter = rowObject => ((ConfirmationEntry) rowObject).Entry.UninstallerEntry.InstallLocation; olvColumnName.AspectGetter = rowObject => ((ConfirmationEntry) rowObject).Entry.UninstallerEntry.DisplayName; objectListView1.DragSource = new SimpleDragSource(); var rearrangingDropSink = new RearrangingDropSink(false); objectListView1.DropSink = rearrangingDropSink; rearrangingDropSink.Dropped += (sender, args) => { objectListView1.PrimarySortColumn = null; objectListView1.Sort(); }; // Bug - sorting by column doesn't change the actual order, and disabling sorting doesn't do anything objectListView1.HeaderStyle = ColumnHeaderStyle.Nonclickable; } private IEnumerable Entries => (objectListView1.Objects ?? Enumerable.Empty()).Cast(); private void buttonSort_Click(object sender, EventArgs e) { objectListView1.PrimarySortColumn = null; var results = AppUninstaller.SortIntelligently(Entries, entry => entry.Entry); objectListView1.SetObjects(results.ToList()); } public IEnumerable GetResults() { return Entries.Where(x => x.Enabled).Select(x => x.Entry); } public void SetRelatedApps(IEnumerable items) { var entries = items.Select(x => new ConfirmationEntry(x)); objectListView1.SetObjects(entries.ToList()); } private sealed class ConfirmationEntry { public ConfirmationEntry(BulkUninstallEntry entry) { Entry = entry; Enabled = true; } public bool Enabled { get; set; } public BulkUninstallEntry Entry { get; } } } } ================================================ FILE: source/BulkCrapUninstaller/Controls/UninstallConfirmation.cs.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Pořadí závisí na Vašem nastavení odinstalace, ale lze jej změnit přetažením položky. Poznámka: BCU můžete změnit pořadí, pokud je povolena souběžná odinstalace. Seznam aplikací, které budou odinstalovány, a to shora dolů. Pokud zrušíte výběr "Odinstalovat", aplikace nebude odinstalována. Není-li k dispozici tichá odinstalace pro položku, nelze ji zkontrolovat Inteligentní třídění Místo instalace Potichu Odinstalovat Název odinstalátoru ================================================ FILE: source/BulkCrapUninstaller/Controls/UninstallConfirmation.de.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Die erste Sortierung beruht auf deinen Uninstall Optionen, kann aber durch Ziehen der Items angepasst werden. Bemerkung: BCU kann die Reihenfolge ändern wenn gleichzeitiges Deinstallieren angeklickt ist. Dies ist eine Liste der Programme, welche deinstalliert werden in der Reihenfolge von oben nach unten. Wenn das Uninstall Feld nicht angeklickt ist, wird das betreffende Programm nicht deinstalliert. Wenn eine stille Deinstallierung für ein Programm nicht möglich ist, kann dieses nicht überprüft werden. Intelligentes Sortieren Ort der Installierung Still Uninstall Names des Uninstallers ================================================ FILE: source/BulkCrapUninstaller/Controls/UninstallConfirmation.es.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 El orden inicial depende de la configuración de desinstalación, pero se puede cambiar arrastrando los elementos. Nota: BCU puede cambiar el orden si la desinstalación simultánea está habilitada. Esta es una lista de aplicaciones que se desinstalarán, en orden de arriba a abajo. Si anula la selección del campo "Desinstalar", la aplicación no se desinstalará. Si la desinstalación silenciosa no está disponible para un elemento, no se puede comprobar Clasificación inteligente Ubicación de la instalación Silencioso Desinstalar Nombre del desinstalador ================================================ FILE: source/BulkCrapUninstaller/Controls/UninstallConfirmation.fr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 L'ordre initial dépends de vos réglages de désinstallation, mais il peut être changé en faisant glisser les éléments. Note : BCU peut changer l'ordre si la désinstallation concurrente est activée. Ceci est une liste d'applications qui seront désinstallées dans l'ordre, de haut en bas. Si vous désélectionnez le champ "Désinstaller", l'application ne sera pas désinstallée. Si l'installation silencieuse n'est pas disponible pour un élément, elle ne peut pas ête cochée. jp translator: I don't know the difference between Quiet Uninstall and Silent Uninstall. Can I translate them to mean the same meaning? At this stage, we are trying to separate the two, but Quiet Uninstall is not very familiar to Japanese people. Tri intelligent Emplacement d'installation Silencieux Désinstaller Nom de désinstalleur ================================================ FILE: source/BulkCrapUninstaller/Controls/UninstallConfirmation.hu.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 A kezdeti sorrend az eltávolítási beállításoktól függ, de az elemek áthúzásával megváltoztatható. Megjegyzés: A BCU megváltoztathatja a sorrendet, ha az egyidejű eltávolítás engedélyezve van. Ez az eltávolítandó alkalmazások listája, felülről lefelé haladva. Ha az „Eltávolítás” mezőt nem jelöli be, az alkalmazás nem lesz eltávolítva. Ha egy elemhez nem áll rendelkezésre a csendes eltávolítás, az nem jelölhető be jp translator: I don't know the difference between Quiet Uninstall and Silent Uninstall. Can I translate them to mean the same meaning? At this stage, we are trying to separate the two, but Quiet Uninstall is not very familiar to Japanese people. Intelligens rendezés Telepítés helye Csendes Eltávolítás Eltávolító neve ================================================ FILE: source/BulkCrapUninstaller/Controls/UninstallConfirmation.it.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 L'ordine iniziale dipende dalla configurazione di disinstallazione, ma può essere modificato trascinando gli elementi. Nota: se è abilitata la disinstallazione simultanea BC può cambiare l'ordine di disinstallazione. Questa è una elenco di applicazioni che saranno disinstallate, ordinatamente dall'inizio alla fine. Se deselezioni l'opzione "Disinstalla" l'applicazione non sarà disinstallata. Se la disinstallazione silenziosa non è disponibile per un elemento non potrà essere selezionata. Ordinamento intelligente Cartella installazione Silenzioso Disinstalla Nome disinstallatore ================================================ FILE: source/BulkCrapUninstaller/Controls/UninstallConfirmation.ja.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 初期の順序はアンインストール設定に依存しますが、項目をドラッグすることで変更できます。注意:同時アンインストールが有効な場合、BCUが順序を変更することがあります。 これは、上から下に向かってアンインストールされるアプリケーションのリストです。「アンインストール」フィールドの選択を外すと、そのアプリケーションはアンインストールされません。アイテムに対して静かなアンインストールが利用できない場合、そのチェックは入れられません。 jp translator: I don't know the difference between Quiet Uninstall and Silent Uninstall. Can I translate them to mean the same meaning? At this stage, we are trying to separate the two, but Quiet Uninstall is not very familiar to Japanese people. インテリジェント選択 インストール場所 静かなアンインストール アンインストール アンインストーラー名 ================================================ FILE: source/BulkCrapUninstaller/Controls/UninstallConfirmation.nl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 De-installer naam De-installeer Stil Installatie locatie Intelligent sorteren Dit is een lijst met programma's die zullen worden gede-installeerd, volgordelijk van boven naar beneden. Wanneer u het "De-installeer" veld deselecteerd, wordt het programma niet gede-installeerd. Als stille de-installatie niet beschikbaar is voor een onderdeel, kan dit niet worden aangevinkt. De initiële volgorde hangt af van uw de-installatie instellingen, maar dit kan worden gewijzigd door de onderdelen te verslepen. Opm.: BCU kan de volgorde wijzigen als gelijktijdige de-installatie is ingeschakeld. ================================================ FILE: source/BulkCrapUninstaller/Controls/UninstallConfirmation.pl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Początkowa kolejność zależy od ustawień odinstalowywania, ale można ją zmienić przeciągając elementy. Uwaga: BCU może zmienić kolejność jeśli jest włączona równoczesna dezinstalacja. Poniżej znajduje się lista aplikacji, które zostaną odinstalowane, w kolejności od góry do dołu. Jeśli odznaczysz pole „Odinstaluj”, aplikacja nie zostanie odinstalowana. Jeśli cicha dezinstalacja nie jest dostępna, nie można jej zaznaczyć. Inteligentne sortowanie Miejsce zainstalowania Cicho Odinstaluj Nazwa dezinstalatora ================================================ FILE: source/BulkCrapUninstaller/Controls/UninstallConfirmation.pt-BR.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 A ordem inicial depende das configurações de desinstalação, mas pode ser alterada arrastando os itens. Nota: O BCU pode alterar a ordem se a desinstalação simultânea estiver ativada. Esta é uma lista de aplicativos que serão desinstalados, ordenados do início ao fim. Se o campo "Desinstalar" for desmarcado, o aplicativo não será desinstalado. Se a desinstalação silenciosa não estiver disponível para um item, ela não poderá ser selecionada Classificação inteligente Local de desinstalação Silencioso Desinstalar Nome do desinstalador ================================================ FILE: source/BulkCrapUninstaller/Controls/UninstallConfirmation.pt.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 A ordem inicial depende das configurações de desinstalação, mas pode ser alterada arrastando os itens. Nota: O BCU pode alterar a ordem se a desinstalação simultânea estiver activada. Esta é uma lista de aplicativos que serão desinstalados, do princípio ao fim. Se desmarcar o campo "Desinstalar", o aplicativo não será desinstalado. Se a desinstalação em segundo plano não estiver disponível para um item, não poderá ser verificada Classificação inteligente Local de desinstalação Silencioso Desinstalar Nome do desinstalador ================================================ FILE: source/BulkCrapUninstaller/Controls/UninstallConfirmation.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Uninstaller name 250 Uninstall Center Quiet Center Install location 246 Fill 7, 79 4, 3, 4, 3 722, 217 1 objectListView1 BrightIdeasSoftware.ObjectListView, ObjectListView, Culture=neutral, PublicKeyToken=null $this 1 True Right 614, 7 4, 3, 4, 3 108, 30 0 Intelligent sort buttonSmartSort System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel1 0 Bottom 7, 296 4, 3, 4, 3 0, 7, 0, 0 722, 37 2 panel1 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 3 True True 4, 0 4, 0, 4, 0 58, 0, 0, 5 694, 35 0 This is a list of applications that will be uninstalled, in order from top to bottom. If you deselect the "Uninstall" field, the application will not be uninstalled. If quiet uninstallation is not available for an item, it can't be checked on labelInfo System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel1 0 True 4, 35 4, 0, 4, 0 58, 0, 0, 0 699, 30 0 The initial order depends on your uninstall settings, but it can be changed by dragging the items. Note: BCU can change the order if concurrent uninstallation is enabled. labelInfo2 System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel1 1 Top TopDown 7, 7 4, 3, 4, 3 0, 58 0, 0, 0, 7 722, 72 0 False flowLayoutPanel1 System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 2 Center NoControl 8, 3 4, 3, 4, 3 58, 58 11 pictureBox1 System.Windows.Forms.PictureBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 0 True 7, 15 4, 3, 4, 3 7, 7, 7, 7 736, 340 olvColumnName BrightIdeasSoftware.OLVColumn, ObjectListView, Culture=neutral, PublicKeyToken=null olvColumnEnabled BrightIdeasSoftware.OLVColumn, ObjectListView, Culture=neutral, PublicKeyToken=null olvColumnQuiet BrightIdeasSoftware.OLVColumn, ObjectListView, Culture=neutral, PublicKeyToken=null olvColumnInstallLocation BrightIdeasSoftware.OLVColumn, ObjectListView, Culture=neutral, PublicKeyToken=null UninstallConfirmation System.Windows.Forms.UserControl, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 ================================================ FILE: source/BulkCrapUninstaller/Controls/UninstallConfirmation.ru.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Первоначальный порядок зависит от настроек удаления, но его можно изменить, перетаскивая элементы. Примечание: BCU может изменить порядок, если включена одновременная деинсталляция. Это список приложений, которые будут удалены в порядке сверху вниз. Если Вы отмените выбор в поле "Деинсталляция", приложение не будет удалено. Если тихая деинсталляция недоступна для элемента, его нельзя выбрать. Интеллектуальная сортировка Место установки Тихо Деинсталляция Имя деинсталлятора ================================================ FILE: source/BulkCrapUninstaller/Controls/UninstallConfirmation.sl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Začetno zaporedje je odvisno od vaših nastavitev za odstranitev, vendar ga lahko spremenite tako, da povlečete vnose. Opomba: BCU lahko spremeni vrstni red, če je omogočeno sočasno odstranjevanje. To je seznam aplikacij, ki bodo odstranjene, v zaporedju od zgoraj navzdol. Če počistite polje »Odstrani«, aplikacija ne bo odstranjena. Če za vnos ni na voljo tiho odstranjevanje, ga ni mogoče vklopiti Inteligentno razvrsti Mesto namestitve Tiho Odstrani Ime odstranjevalca ================================================ FILE: source/BulkCrapUninstaller/Controls/UninstallConfirmation.sv.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Den initiala ordningen beror på dina avinstallationsinställningar, men den kan ändras genom att dra objekten. OBS: BCU kan ändra ordningen om samtidig avinstallation är aktiverad. Detta är en lista över appar som kommer att avinstalleras, i ordning från topp till botten. Om du avmarkerar fältet "Avinstallera" kommer applikationen inte att avinstalleras. Om tyst avinstallation inte är tillgängligt för ett objekt, går det inte att markera. jp translator: I don't know the difference between Quiet Uninstall and Silent Uninstall. Can I translate them to mean the same meaning? At this stage, we are trying to separate the two, but Quiet Uninstall is not very familiar to Japanese people. Intelligent sortering Installationsmapp Tyst Avinstallera Avinstallationsnamn ================================================ FILE: source/BulkCrapUninstaller/Controls/UninstallConfirmation.tr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 İlk işlem, kaldırma ayarlarınıza bağlıdır, ancak öğeleri sürükleyerek değiştirilebilir. Not: Eşzamanlı kaldırma etkinse BCU işlemi değiştirebilir. Bu, yukarıdan aşağıya doğru sırayla kaldırılacak uygulamaların bir listesidir. "Kaldır" alanının seçimini kaldırırsanız, uygulama kaldırılmayacaktır. Bir öğe için sessiz kaldırma mevcut değilse, kontrol edilemez Akıllı sıralama Kurulum yeri Sessiz Kaldır Kaldırıcı adı ================================================ FILE: source/BulkCrapUninstaller/Controls/UninstallConfirmation.vi.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Thứ tự sắp xếp ban đầu tùy thuộc vào tuỳ chọn gỡ cài đặt của bạn nhưng có thể thay đổi bằng cách kéo các mục. Lưu ý: BCU có thể thay đổi thứ tự nếu bật tính năng gỡ cài đặt đồng thời. Đây là danh sách các ứng dụng sẽ được gỡ cài đặt, theo thứ tự từ trên xuống dưới. Nếu bạn bỏ tích trường "Gỡ cài đặt", ứng dụng sẽ không được gỡ cài đặt. Nếu tính năng "Gỡ cài đặt âm thầm" không khả dụng cho một ứng dụng thì bạn không thể tích vào trường này. jp translator: I don't know the difference between Quiet Uninstall and Silent Uninstall. Can I translate them to mean the same meaning? At this stage, we are trying to separate the two, but Quiet Uninstall is not very familiar to Japanese people. Sắp xếp thông minh Vị trí cài đặt Gỡ cài đặt âm thầm Gỡ cài đặt Tên trình gỡ cài đặt ================================================ FILE: source/BulkCrapUninstaller/Controls/UninstallConfirmation.zh-Hans.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 初始顺序取决于你的卸载设置,但可以通过拖动项目来更改。注意:如果启用同时卸载,BCU可能更改顺序。 这是将卸载的应用程序列表,从上到下。如果取消选择“卸载”字段,则不会卸载应用程序。如果某个项目不能静默卸载,则不能选择 智能排序 安装位置 静默 卸载 卸载程序名称 ================================================ FILE: source/BulkCrapUninstaller/Controls/UninstallConfirmation.zh-Hant.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 這是將移除的應用程式列表,從上到下。如果取消選擇"移除"字段,則不會移除應用程式。如果某個項目不能最小化移除,則不能選擇 智慧排序 安裝位置 安靜 解除安裝 移除程式名稱 初始移除順序取決於你的解除安裝設定,但可以透過拖曳項目來變更。請注意:如果啟用同時解除安裝時,BCU 可以變更順序。 ================================================ FILE: source/BulkCrapUninstaller/CultureConfigurator.cs ================================================ using BulkCrapUninstaller.Properties; using Klocman.Extensions; using Klocman.Tools; using System; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; using System.Threading; namespace BulkCrapUninstaller { public static class CultureConfigurator { private static IEnumerable _supportedLanguages; private static CultureInfo _enUsCulture; private static CultureInfo EnUsCulture => _enUsCulture ??= CultureInfo.GetCultureInfo("en-US"); public static IEnumerable SupportedLanguages => _supportedLanguages ??= GetSupportedLanguages(); private static IEnumerable GetSupportedLanguages() { // Check what translations are available in program dir var translationDirectories = Program.AssemblyLocation.GetDirectories() .Where(x => { if (x.Name.Length < 2) return false; try { return x.GetFiles("BCUninstaller.resources.dll", SearchOption.TopDirectoryOnly).Any(); } catch (SystemException e) { Console.WriteLine(e); return false; } }) .Select(x => x.Name.Substring(0, 2).ToLower()) .ToList(); var supportedCultures = new[] { // en - English //("en-US"), "en-AU", "en-BZ", "en-CA", "en-IE", "en-JM", "en-NZ", "en-PH", "en-ZA", "en-TT", "en-GB", "en-ZW", // ar - Arabic "ar-DZ", "ar-BH", "ar-EG", "ar-IQ", "ar-JO", "ar-KW", "ar-LB", "ar-LY", "ar-MA", "ar-OM", "ar-QA", "ar-SA", "ar-SY", "ar-TN", "ar-AE", "ar-YE", // Czech "cs-CZ", // de - German "de-AT", "de-DE", "de-LI", "de-LU", "de-CH", // es - Spanish "es-AR", "es-BO", "es-CL", "es-CO", "es-CR", "es-DO", "es-EC", "es-SV", "es-GT", "es-HN", "es-MX", "es-NI", "es-PA", "es-PY", "es-PE", "es-PR", "es-ES", "es-UY", "es-VE", // fr - French "fr-BE", "fr-CA", "fr-FR", "fr-LU", "fr-MC", "fr-CH", // Hungarian "hu-HU", // it - Italian "it-IT", "it-CH", // ja - Japanese "ja-JP", // nl - Dutch "nl-NL", "nl-BE", // Polish "pl-PL", // pt - Portuguese "pt-PT", "pt-BR", // Russian "ru-RU", // Slovenian "sl-SI", // Swedish "sv-AX", "sv-FI", "sv-SE", // Turkish "tr-CY", "tr-TR", // Vietnamese "vi-VN", // Simplified Chinese "zh-Hans", // Traditional Chinese "zh-Hant" }.Attempt(CultureInfo.GetCultureInfo).ToList(); supportedCultures.Add(EnUsCulture); //Debug.Assert(translationDirectories.All(x => supportedCultures.Select(c => c.Name.Substring(0, 2)).Contains(x, StringComparison.OrdinalIgnoreCase)), // "Translation is not added to supported cultures - " + translationDirectories.FirstOrDefault(x => !supportedCultures.Select(c => c.Name.Substring(0, 2)).Contains(x, StringComparison.OrdinalIgnoreCase))); return supportedCultures.Where(x => { var code = x.Name.Substring(0, 2).ToLower(); return code.Equals("en", StringComparison.Ordinal) || translationDirectories.Contains(code, StringComparison.Ordinal); }).OrderBy(x => x.DisplayName).ToList().AsEnumerable(); } public static void SetupCulture() { var currentCulture = CultureInfo.CurrentCulture; var targetLocale = Settings.Default.Language; if (targetLocale.IsNotEmpty()) { try { currentCulture = SupportedLanguages.First(x => x.Name.Equals(targetLocale)); } catch { Settings.Default.Language = string.Empty; } } if (!currentCulture.Name.ContainsAny(SupportedLanguages.Select(x => x.Parent.Name), StringComparison.OrdinalIgnoreCase)) currentCulture = EnUsCulture; ProcessTools.SetDefaultCulture(currentCulture); var thread = Thread.CurrentThread; thread.CurrentCulture = currentCulture; thread.CurrentUICulture = currentCulture; } } } ================================================ FILE: source/BulkCrapUninstaller/EntryPoint.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Diagnostics; using System.Drawing; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.InteropServices; using System.Threading; using System.Windows.Forms; using BulkCrapUninstaller.Forms; using Klocman; using Klocman.Extensions; using Klocman.Forms; using Klocman.Forms.Tools; using UninstallTools.Dialogs; namespace BulkCrapUninstaller { internal static class EntryPoint { public static bool IsRestarting { get; internal set; } private const string MUTEX_NAME = @"Global\BCU-singleinstance"; private static Mutex _mutex; [STAThread] public static void Main(string[] args) { NBugConfigurator.SetupNBug(); using (LogWriter.StartLogging()) { try { Directory.SetCurrentDirectory(Program.AssemblyLocation.FullName); } catch (Exception ex) { Console.WriteLine(ex); } try { Application.SetCompatibleTextRenderingDefault(false); Application.EnableVisualStyles(); _mutex = new Mutex(true, MUTEX_NAME, out var createdNew); if (!createdNew) { _mutex.Dispose(); HandleBeingSecondInstance(); return; } SetupDependancies(); if(Properties.Settings.Default.WindowDpiAware) Application.SetHighDpiMode(HighDpiMode.PerMonitorV2); var startupMgr = args.Contains("/startupmanager", StringComparison.OrdinalIgnoreCase) || args.Contains("/sm", StringComparison.OrdinalIgnoreCase); if (startupMgr) Application.Run(StartupManagerWindow.ShowManagerWindow()); else Application.Run(new MainWindow()); } finally { ProcessShutdown(); } } } private static void ProcessShutdown() { if (!IsRestarting && !_mutex.SafeWaitHandle.IsClosed) _mutex.ReleaseMutex(); _mutex.Dispose(); // If running as portable, delete any leftovers from the system if (!IsRestarting && !Program.IsInstalled && !Program.EnableDebug) Program.StartLogCleaner(); } public static void Restart() { try { IsRestarting = true; _mutex.ReleaseMutex(); Application.Restart(); } catch (Exception ex) { PremadeDialogs.GenericError(ex); IsRestarting = false; } } private static void HandleBeingSecondInstance() { try { var location = Assembly.GetAssembly(typeof(EntryPoint))!.Location; if (location.EndsWith(".dll")) location = location.Substring(0, location.Length - 3) + "exe"; var otherBcu = Process.GetProcesses().FirstOrDefault(x => { try { return string.Equals(x.MainModule!.FileName, location, StringComparison.OrdinalIgnoreCase); } catch { return false; } }); var mainWind = otherBcu?.MainWindowHandle; if (mainWind != null) { try { NativeMethods.SetForegroundWindow(otherBcu.MainWindowHandle.ToInt32()); } catch (Exception ex) { PremadeDialogs.GenericError(ex); } } else { CustomMessageBox.ShowDialog(null, new CmbBasicSettings("BCUninstaller is already running", "BCUninstaller is already running", "You can start only one instance of BCUninstaller. Close previous instances and try again. If you don't see the BCUninstaller window or it's not responding, try closing it with Task Manager.", Icon.ExtractAssociatedIcon(location), "OK")); } } catch (Exception ex) { Console.WriteLine(ex); } } private static class NativeMethods { [DllImport("user32.dll")] public static extern int SetForegroundWindow(int hwnd); } private static void SetupDependancies() { // Order is semi-important, prepare settings should go first. Program.PrepareSettings(); CultureConfigurator.SetupCulture(); //try //{ // UpdateSystem.ProcessPendingUpdates(); //} //catch (Exception ex) //{ // PremadeDialogs.GenericError(ex); //} } } } ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/AdvancedClipboardCopyWindow.Designer.cs ================================================ namespace BulkCrapUninstaller.Forms { partial class AdvancedClipboardCopyWindow { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AdvancedClipboardCopyWindow)); panel1 = new System.Windows.Forms.Panel(); buttonClose = new System.Windows.Forms.Button(); buttonCopyAll = new System.Windows.Forms.Button(); advancedClipboardCopy1 = new BulkCrapUninstaller.Controls.AdvancedClipboardCopy(); panel1.SuspendLayout(); SuspendLayout(); // // panel1 // panel1.Controls.Add(buttonClose); panel1.Controls.Add(buttonCopyAll); resources.ApplyResources(panel1, "panel1"); panel1.Name = "panel1"; // // buttonClose // resources.ApplyResources(buttonClose, "buttonClose"); buttonClose.DialogResult = System.Windows.Forms.DialogResult.Cancel; buttonClose.Name = "buttonClose"; buttonClose.UseVisualStyleBackColor = true; buttonClose.Click += button2_Click; // // buttonCopyAll // resources.ApplyResources(buttonCopyAll, "buttonCopyAll"); buttonCopyAll.Name = "buttonCopyAll"; buttonCopyAll.UseVisualStyleBackColor = true; buttonCopyAll.Click += button1_Click; // // advancedClipboardCopy1 // resources.ApplyResources(advancedClipboardCopy1, "advancedClipboardCopy1"); advancedClipboardCopy1.Name = "advancedClipboardCopy1"; // // AdvancedClipboardCopyWindow // AcceptButton = buttonCopyAll; resources.ApplyResources(this, "$this"); AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; CancelButton = buttonClose; Controls.Add(advancedClipboardCopy1); Controls.Add(panel1); Name = "AdvancedClipboardCopyWindow"; Shown += AdvancedClipboardCopyWindow_Shown; panel1.ResumeLayout(false); ResumeLayout(false); } #endregion private Controls.AdvancedClipboardCopy advancedClipboardCopy1; private System.Windows.Forms.Panel panel1; private System.Windows.Forms.Button buttonClose; private System.Windows.Forms.Button buttonCopyAll; } } ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/AdvancedClipboardCopyWindow.ar.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 اغلاق نسخ الكل نسخ المعلومات الى الحافظة ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/AdvancedClipboardCopyWindow.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Windows.Forms; using BulkCrapUninstaller.Functions; using Klocman.Forms.Tools; using UninstallTools; namespace BulkCrapUninstaller.Forms { public partial class AdvancedClipboardCopyWindow : Form { private AdvancedClipboardCopyWindow() { InitializeComponent(); } public static void ShowDialog(Form parent, IEnumerable targets) { if (parent == null) throw new ArgumentNullException(nameof(parent)); if (targets == null) throw new ArgumentNullException(nameof(targets)); using (var window = new AdvancedClipboardCopyWindow()) { window.advancedClipboardCopy1.Targets = targets; window.Icon = parent.Icon; window.ShowDialog(parent); } } private void AdvancedClipboardCopyWindow_Shown(object sender, EventArgs e) { advancedClipboardCopy1.PatternText = "{" + nameof(ApplicationUninstallerEntry.DisplayName) + "} - {" + nameof(ApplicationUninstallerEntry.UninstallString) + "}"; } private void button1_Click(object sender, EventArgs e) { if (string.IsNullOrEmpty(advancedClipboardCopy1.Result)) { MessageBoxes.NothingToCopy(); } else { try { Clipboard.SetText(advancedClipboardCopy1.Result); } catch (Exception ex) { PremadeDialogs.GenericError(ex); } } } private void button2_Click(object sender, EventArgs e) { Close(); } } } ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/AdvancedClipboardCopyWindow.cs.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Zavřít Kopírovat vše Kopírování informací do schránky ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/AdvancedClipboardCopyWindow.de.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Schließen Kopiere alles Kopiere Information in die Zwischenablage ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/AdvancedClipboardCopyWindow.es.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Copiar información al portapapeles Cerrar Copiar todo ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/AdvancedClipboardCopyWindow.fr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Copier l'information dans le presse-papiers Fermer Tout copier True pl ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/AdvancedClipboardCopyWindow.hu.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Információk másolása a Vágólapra Bezárás Mindent másol ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/AdvancedClipboardCopyWindow.it.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Copia informazioni negli Appunti Chiudi Copia tutto ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/AdvancedClipboardCopyWindow.ja.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 閉じる 全てコピー 情報をクリップボードにコピー ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/AdvancedClipboardCopyWindow.nl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Sluiten Kopieer alles Kopieer informatie naar het klembord ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/AdvancedClipboardCopyWindow.pl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Zamknij Kopiuj wszystko Kopiowanie informacji do schowka ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/AdvancedClipboardCopyWindow.pt-BR.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Fechar Copiar tudo Copiar informação para a Área de Transferência ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/AdvancedClipboardCopyWindow.pt.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Copiar a informação para a Área de Transferência Fechar Copiar tudo True pl ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/AdvancedClipboardCopyWindow.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Top, Right 528, 7 4, 3, 4, 3 88, 27 0 Close buttonClose System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel1 0 Top, Right 387, 7 4, 3, 4, 3 134, 27 0 Copy all buttonCopyAll System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel1 1 Bottom 0, 351 4, 3, 4, 3 623, 42 1 panel1 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 1 Fill 0, 0 5, 3, 5, 3 7, 7, 7, 3 623, 351 0 advancedClipboardCopy1 BulkCrapUninstaller.Controls.AdvancedClipboardCopy, BCUninstaller, Culture=neutral, PublicKeyToken=null $this 0 True 7, 15 623, 393 4, 3, 4, 3 CenterParent Copy information to clipboard AdvancedClipboardCopyWindow System.Windows.Forms.Form, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/AdvancedClipboardCopyWindow.ru.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Копировать информацию в буфер Закрыть Копировать всё True pl ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/AdvancedClipboardCopyWindow.sl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Kopiraj informacijo v odložišče Zapri Kopiraj vse True pl ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/AdvancedClipboardCopyWindow.sv.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Stäng Kopiera alla Kopiera information till urklipp ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/AdvancedClipboardCopyWindow.tr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Kapat Tümünü kopyala Bilgileri panoya kopyala ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/AdvancedClipboardCopyWindow.vi.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Đóng Sao chép tất cả Sao chép vào bảng nhớ tạm ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/AdvancedClipboardCopyWindow.zh-Hans.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 关闭 复制全部 复制信息到剪贴板 ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/AdvancedClipboardCopyWindow.zh-Hant.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 關閉 複製全部 複製資訊到剪貼簿 ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/DebugWindow.Designer.cs ================================================ using System.ComponentModel; using System.Windows.Forms; namespace BulkCrapUninstaller.Forms { partial class DebugWindow { /// /// Required designer variable. /// private IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { groupBox1 = new GroupBox(); checkBox1 = new CheckBox(); button2 = new Button(); button1 = new Button(); button5 = new Button(); groupBox3 = new GroupBox(); panel1 = new Panel(); panel2 = new Panel(); buttonGoMessages = new Button(); numericUpDownMessages = new NumericUpDown(); textBoxMessages = new TextBox(); comboBoxMessages = new ComboBox(); groupBox4 = new GroupBox(); labelVersion = new Label(); button3 = new Button(); button4 = new Button(); groupBox5 = new GroupBox(); checkBoxDebug = new CheckBox(); checkBox2 = new CheckBox(); groupBox6 = new GroupBox(); flowLayoutPanel1 = new FlowLayoutPanel(); button10 = new Button(); button11 = new Button(); button12 = new Button(); button13 = new Button(); button6 = new Button(); button7 = new Button(); button8 = new Button(); button9 = new Button(); button14 = new Button(); checkBoxSysRestoreAvail = new CheckBox(); button15 = new Button(); button16 = new Button(); button17 = new Button(); button18 = new Button(); groupBox1.SuspendLayout(); groupBox3.SuspendLayout(); panel1.SuspendLayout(); panel2.SuspendLayout(); ((ISupportInitialize)numericUpDownMessages).BeginInit(); groupBox4.SuspendLayout(); groupBox5.SuspendLayout(); groupBox6.SuspendLayout(); flowLayoutPanel1.SuspendLayout(); SuspendLayout(); // // groupBox1 // groupBox1.Controls.Add(checkBox1); groupBox1.Controls.Add(button2); groupBox1.Controls.Add(button1); groupBox1.Controls.Add(button5); groupBox1.Dock = DockStyle.Bottom; groupBox1.Location = new System.Drawing.Point(8, 403); groupBox1.Margin = new Padding(4, 3, 4, 3); groupBox1.Name = "groupBox1"; groupBox1.Padding = new Padding(7); groupBox1.Size = new System.Drawing.Size(571, 58); groupBox1.TabIndex = 1; groupBox1.TabStop = false; groupBox1.Text = "Settings"; // // checkBox1 // checkBox1.AutoSize = true; checkBox1.Dock = DockStyle.Left; checkBox1.Location = new System.Drawing.Point(383, 23); checkBox1.Margin = new Padding(4, 3, 4, 3); checkBox1.Name = "checkBox1"; checkBox1.Size = new System.Drawing.Size(129, 28); checkBox1.TabIndex = 1; checkBox1.Text = "Test setting binding"; checkBox1.UseVisualStyleBackColor = true; // // button2 // button2.AutoSize = true; button2.Dock = DockStyle.Left; button2.Location = new System.Drawing.Point(265, 23); button2.Margin = new Padding(4, 3, 4, 3); button2.Name = "button2"; button2.Size = new System.Drawing.Size(118, 28); button2.TabIndex = 0; button2.Text = "External change"; button2.UseVisualStyleBackColor = true; button2.Click += button2_Click; // // button1 // button1.AutoSize = true; button1.Dock = DockStyle.Left; button1.Location = new System.Drawing.Point(165, 23); button1.Margin = new Padding(4, 3, 4, 3); button1.Name = "button1"; button1.Size = new System.Drawing.Size(100, 28); button1.TabIndex = 2; button1.Text = "Force update"; button1.UseVisualStyleBackColor = true; button1.Click += button1_Click_1; // // button5 // button5.AutoSize = true; button5.Dock = DockStyle.Left; button5.Location = new System.Drawing.Point(7, 23); button5.Margin = new Padding(4, 3, 4, 3); button5.Name = "button5"; button5.Size = new System.Drawing.Size(158, 28); button5.TabIndex = 3; button5.Text = "Open settings window"; button5.UseVisualStyleBackColor = true; button5.Click += button5_Click; // // groupBox3 // groupBox3.Controls.Add(panel1); groupBox3.Controls.Add(comboBoxMessages); groupBox3.Dock = DockStyle.Fill; groupBox3.Location = new System.Drawing.Point(8, 168); groupBox3.Margin = new Padding(4, 3, 4, 3); groupBox3.Name = "groupBox3"; groupBox3.Padding = new Padding(7); groupBox3.Size = new System.Drawing.Size(571, 177); groupBox3.TabIndex = 3; groupBox3.TabStop = false; groupBox3.Text = "Test message boxes"; // // panel1 // panel1.Controls.Add(panel2); panel1.Controls.Add(textBoxMessages); panel1.Dock = DockStyle.Fill; panel1.Location = new System.Drawing.Point(7, 46); panel1.Margin = new Padding(4, 3, 4, 3); panel1.Name = "panel1"; panel1.Padding = new Padding(0, 7, 0, 0); panel1.Size = new System.Drawing.Size(557, 124); panel1.TabIndex = 1; // // panel2 // panel2.Controls.Add(buttonGoMessages); panel2.Controls.Add(numericUpDownMessages); panel2.Dock = DockStyle.Fill; panel2.Location = new System.Drawing.Point(462, 7); panel2.Margin = new Padding(4, 3, 4, 3); panel2.Name = "panel2"; panel2.Padding = new Padding(7, 0, 0, 0); panel2.Size = new System.Drawing.Size(95, 117); panel2.TabIndex = 3; // // buttonGoMessages // buttonGoMessages.Dock = DockStyle.Fill; buttonGoMessages.Location = new System.Drawing.Point(7, 23); buttonGoMessages.Margin = new Padding(4, 3, 4, 3); buttonGoMessages.Name = "buttonGoMessages"; buttonGoMessages.Size = new System.Drawing.Size(88, 94); buttonGoMessages.TabIndex = 1; buttonGoMessages.Text = "Open messagebox"; buttonGoMessages.UseVisualStyleBackColor = true; buttonGoMessages.Click += buttonGoMessages_Click; // // numericUpDownMessages // numericUpDownMessages.Dock = DockStyle.Top; numericUpDownMessages.Location = new System.Drawing.Point(7, 0); numericUpDownMessages.Margin = new Padding(4, 3, 4, 3); numericUpDownMessages.Name = "numericUpDownMessages"; numericUpDownMessages.Size = new System.Drawing.Size(88, 23); numericUpDownMessages.TabIndex = 3; // // textBoxMessages // textBoxMessages.Dock = DockStyle.Left; textBoxMessages.Location = new System.Drawing.Point(0, 7); textBoxMessages.Margin = new Padding(4, 3, 4, 3); textBoxMessages.Multiline = true; textBoxMessages.Name = "textBoxMessages"; textBoxMessages.Size = new System.Drawing.Size(462, 117); textBoxMessages.TabIndex = 2; textBoxMessages.Text = "Text to send to the messagebox\r\nSecond line if the box takes multiple lines\r\nIf messagebox needs a number it takes it from the number box on right"; // // comboBoxMessages // comboBoxMessages.AutoCompleteMode = AutoCompleteMode.SuggestAppend; comboBoxMessages.AutoCompleteSource = AutoCompleteSource.ListItems; comboBoxMessages.Dock = DockStyle.Top; comboBoxMessages.FormattingEnabled = true; comboBoxMessages.Location = new System.Drawing.Point(7, 23); comboBoxMessages.Margin = new Padding(4, 3, 4, 3); comboBoxMessages.Name = "comboBoxMessages"; comboBoxMessages.Size = new System.Drawing.Size(557, 23); comboBoxMessages.TabIndex = 0; // // groupBox4 // groupBox4.Controls.Add(labelVersion); groupBox4.Controls.Add(button3); groupBox4.Controls.Add(button4); groupBox4.Dock = DockStyle.Bottom; groupBox4.Location = new System.Drawing.Point(8, 345); groupBox4.Margin = new Padding(4, 3, 4, 3); groupBox4.Name = "groupBox4"; groupBox4.Padding = new Padding(7); groupBox4.Size = new System.Drawing.Size(571, 58); groupBox4.TabIndex = 4; groupBox4.TabStop = false; groupBox4.Text = "Update system"; // // labelVersion // labelVersion.Dock = DockStyle.Fill; labelVersion.Location = new System.Drawing.Point(227, 23); labelVersion.Margin = new Padding(4, 0, 4, 0); labelVersion.Name = "labelVersion"; labelVersion.Size = new System.Drawing.Size(337, 28); labelVersion.TabIndex = 3; labelVersion.Text = "remote version"; labelVersion.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; // // button3 // button3.AutoSize = true; button3.Dock = DockStyle.Left; button3.Location = new System.Drawing.Point(139, 23); button3.Margin = new Padding(4, 3, 4, 3); button3.Name = "button3"; button3.Size = new System.Drawing.Size(88, 28); button3.TabIndex = 2; button3.Text = "Download"; button3.UseVisualStyleBackColor = true; button3.Click += button3_Click; // // button4 // button4.AutoSize = true; button4.Dock = DockStyle.Left; button4.Location = new System.Drawing.Point(7, 23); button4.Margin = new Padding(4, 3, 4, 3); button4.Name = "button4"; button4.Size = new System.Drawing.Size(132, 28); button4.TabIndex = 0; button4.Text = "Check for updates"; button4.UseVisualStyleBackColor = true; button4.Click += button4_Click; // // groupBox5 // groupBox5.Controls.Add(checkBoxDebug); groupBox5.Controls.Add(checkBox2); groupBox5.Dock = DockStyle.Bottom; groupBox5.Location = new System.Drawing.Point(8, 461); groupBox5.Margin = new Padding(4, 3, 4, 3); groupBox5.Name = "groupBox5"; groupBox5.Padding = new Padding(7); groupBox5.Size = new System.Drawing.Size(571, 58); groupBox5.TabIndex = 5; groupBox5.TabStop = false; groupBox5.Text = "Misc"; // // checkBoxDebug // checkBoxDebug.AutoSize = true; checkBoxDebug.Dock = DockStyle.Left; checkBoxDebug.Location = new System.Drawing.Point(162, 23); checkBoxDebug.Margin = new Padding(4, 3, 4, 3); checkBoxDebug.Name = "checkBoxDebug"; checkBoxDebug.Size = new System.Drawing.Size(132, 28); checkBoxDebug.TabIndex = 1; checkBoxDebug.Text = "Enable debug mode"; checkBoxDebug.UseVisualStyleBackColor = true; // // checkBox2 // checkBox2.AutoSize = true; checkBox2.Dock = DockStyle.Left; checkBox2.Location = new System.Drawing.Point(7, 23); checkBox2.Margin = new Padding(4, 3, 4, 3); checkBox2.Name = "checkBox2"; checkBox2.Size = new System.Drawing.Size(155, 28); checkBox2.TabIndex = 0; checkBox2.Text = "Override BCU is installed"; checkBox2.UseVisualStyleBackColor = true; checkBox2.CheckedChanged += checkBox2_CheckedChanged; // // groupBox6 // groupBox6.Controls.Add(flowLayoutPanel1); groupBox6.Dock = DockStyle.Top; groupBox6.Location = new System.Drawing.Point(8, 8); groupBox6.Margin = new Padding(4, 3, 4, 3); groupBox6.Name = "groupBox6"; groupBox6.Padding = new Padding(7); groupBox6.Size = new System.Drawing.Size(571, 160); groupBox6.TabIndex = 6; groupBox6.TabStop = false; groupBox6.Text = "Test methods"; // // flowLayoutPanel1 // flowLayoutPanel1.AutoSize = true; flowLayoutPanel1.Controls.Add(button10); flowLayoutPanel1.Controls.Add(button11); flowLayoutPanel1.Controls.Add(button12); flowLayoutPanel1.Controls.Add(button13); flowLayoutPanel1.Controls.Add(button6); flowLayoutPanel1.Controls.Add(button7); flowLayoutPanel1.Controls.Add(button8); flowLayoutPanel1.Controls.Add(button9); flowLayoutPanel1.Controls.Add(button14); flowLayoutPanel1.Controls.Add(checkBoxSysRestoreAvail); flowLayoutPanel1.Controls.Add(button15); flowLayoutPanel1.Controls.Add(button16); flowLayoutPanel1.Controls.Add(button17); flowLayoutPanel1.Controls.Add(button18); flowLayoutPanel1.Dock = DockStyle.Fill; flowLayoutPanel1.Location = new System.Drawing.Point(7, 23); flowLayoutPanel1.Margin = new Padding(4, 3, 4, 3); flowLayoutPanel1.Name = "flowLayoutPanel1"; flowLayoutPanel1.Size = new System.Drawing.Size(557, 130); flowLayoutPanel1.TabIndex = 1; // // button10 // button10.AutoSize = true; button10.AutoSizeMode = AutoSizeMode.GrowAndShrink; button10.Location = new System.Drawing.Point(4, 3); button10.Margin = new Padding(4, 3, 4, 3); button10.Name = "button10"; button10.Size = new System.Drawing.Size(110, 25); button10.TabIndex = 7; button10.Text = "Test junk searcher"; button10.UseVisualStyleBackColor = true; button10.Click += TestJunkSearcher; // // button11 // button11.AutoSize = true; button11.AutoSizeMode = AutoSizeMode.GrowAndShrink; button11.Location = new System.Drawing.Point(122, 3); button11.Margin = new Padding(4, 3, 4, 3); button11.Name = "button11"; button11.Size = new System.Drawing.Size(151, 25); button11.TabIndex = 6; button11.Text = "Crash background thread"; button11.UseVisualStyleBackColor = true; button11.Click += TestCrashBackgroundThread; // // button12 // button12.AutoSize = true; button12.AutoSizeMode = AutoSizeMode.GrowAndShrink; button12.Location = new System.Drawing.Point(281, 3); button12.Margin = new Padding(4, 3, 4, 3); button12.Name = "button12"; button12.Size = new System.Drawing.Size(97, 25); button12.TabIndex = 5; button12.Text = "Crash ui thread"; button12.UseVisualStyleBackColor = true; button12.Click += TestCrashUiThread; // // button13 // button13.AutoSize = true; button13.AutoSizeMode = AutoSizeMode.GrowAndShrink; button13.Location = new System.Drawing.Point(386, 3); button13.Margin = new Padding(4, 3, 4, 3); button13.Name = "button13"; button13.Size = new System.Drawing.Size(130, 25); button13.TabIndex = 4; button13.Text = "Finish collecting stats"; button13.UseVisualStyleBackColor = true; button13.Click += button13_Click; // // button6 // button6.AutoSize = true; button6.AutoSizeMode = AutoSizeMode.GrowAndShrink; button6.Location = new System.Drawing.Point(4, 34); button6.Margin = new Padding(4, 3, 4, 3); button6.Name = "button6"; button6.Size = new System.Drawing.Size(70, 25); button6.TabIndex = 8; button6.Text = "Send stats"; button6.UseVisualStyleBackColor = true; button6.Click += button6_Click; // // button7 // button7.AutoSize = true; button7.AutoSizeMode = AutoSizeMode.GrowAndShrink; button7.Location = new System.Drawing.Point(82, 34); button7.Margin = new Padding(4, 3, 4, 3); button7.Name = "button7"; button7.Size = new System.Drawing.Size(76, 25); button7.TabIndex = 9; button7.Text = "Restart app"; button7.UseVisualStyleBackColor = true; button7.Click += button7_Click; // // button8 // button8.AutoSize = true; button8.AutoSizeMode = AutoSizeMode.GrowAndShrink; button8.Location = new System.Drawing.Point(166, 34); button8.Margin = new Padding(4, 3, 4, 3); button8.Name = "button8"; button8.Size = new System.Drawing.Size(92, 25); button8.TabIndex = 10; button8.Text = "Get hotkey list"; button8.UseVisualStyleBackColor = true; button8.Click += button8_Click; // // button9 // button9.AutoSize = true; button9.AutoSizeMode = AutoSizeMode.GrowAndShrink; button9.Location = new System.Drawing.Point(266, 34); button9.Margin = new Padding(4, 3, 4, 3); button9.Name = "button9"; button9.Size = new System.Drawing.Size(69, 25); button9.TabIndex = 11; button9.Text = "Soft crash"; button9.UseVisualStyleBackColor = true; button9.Click += SoftCrash; // // button14 // button14.AutoSize = true; button14.AutoSizeMode = AutoSizeMode.GrowAndShrink; flowLayoutPanel1.SetFlowBreak(button14, true); button14.Location = new System.Drawing.Point(343, 34); button14.Margin = new Padding(4, 3, 4, 3); button14.Name = "button14"; button14.Size = new System.Drawing.Size(90, 25); button14.TabIndex = 12; button14.Text = "Feedback box"; button14.UseVisualStyleBackColor = true; button14.Click += button14_Click; // // checkBoxSysRestoreAvail // checkBoxSysRestoreAvail.AutoSize = true; checkBoxSysRestoreAvail.Dock = DockStyle.Left; checkBoxSysRestoreAvail.Enabled = false; checkBoxSysRestoreAvail.Location = new System.Drawing.Point(4, 65); checkBoxSysRestoreAvail.Margin = new Padding(4, 3, 4, 3); checkBoxSysRestoreAvail.Name = "checkBoxSysRestoreAvail"; checkBoxSysRestoreAvail.Size = new System.Drawing.Size(131, 25); checkBoxSysRestoreAvail.TabIndex = 16; checkBoxSysRestoreAvail.Text = "SysRestore available"; checkBoxSysRestoreAvail.UseVisualStyleBackColor = true; // // button15 // button15.AutoSize = true; button15.AutoSizeMode = AutoSizeMode.GrowAndShrink; button15.Location = new System.Drawing.Point(143, 65); button15.Margin = new Padding(4, 3, 4, 3); button15.Name = "button15"; button15.Size = new System.Drawing.Size(157, 25); button15.TabIndex = 13; button15.Text = "Start restore point creation"; button15.UseVisualStyleBackColor = true; button15.Click += button15_Click; // // button16 // button16.AutoSize = true; button16.AutoSizeMode = AutoSizeMode.GrowAndShrink; button16.Location = new System.Drawing.Point(308, 65); button16.Margin = new Padding(4, 3, 4, 3); button16.Name = "button16"; button16.Size = new System.Drawing.Size(76, 25); button16.TabIndex = 14; button16.Text = "EndRestore"; button16.UseVisualStyleBackColor = true; button16.Click += button16_Click; // // button17 // button17.AutoSize = true; button17.AutoSizeMode = AutoSizeMode.GrowAndShrink; button17.Location = new System.Drawing.Point(392, 65); button17.Margin = new Padding(4, 3, 4, 3); button17.Name = "button17"; button17.Size = new System.Drawing.Size(92, 25); button17.TabIndex = 15; button17.Text = "CancelRestore"; button17.UseVisualStyleBackColor = true; button17.Click += button17_Click; // // button18 // button18.AutoSize = true; button18.AutoSizeMode = AutoSizeMode.GrowAndShrink; button18.Location = new System.Drawing.Point(4, 96); button18.Margin = new Padding(4, 3, 4, 3); button18.Name = "button18"; button18.Size = new System.Drawing.Size(134, 25); button18.TabIndex = 17; button18.Text = "Simulate outdated W7"; button18.UseVisualStyleBackColor = true; button18.Click += button18_Click; // // DebugWindow // AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); AutoScaleMode = AutoScaleMode.Font; ClientSize = new System.Drawing.Size(587, 527); Controls.Add(groupBox3); Controls.Add(groupBox4); Controls.Add(groupBox1); Controls.Add(groupBox6); Controls.Add(groupBox5); Margin = new Padding(4, 3, 4, 3); Name = "DebugWindow"; Padding = new Padding(8); Text = "DebugWindow (here be dragons)"; groupBox1.ResumeLayout(false); groupBox1.PerformLayout(); groupBox3.ResumeLayout(false); panel1.ResumeLayout(false); panel1.PerformLayout(); panel2.ResumeLayout(false); ((ISupportInitialize)numericUpDownMessages).EndInit(); groupBox4.ResumeLayout(false); groupBox4.PerformLayout(); groupBox5.ResumeLayout(false); groupBox5.PerformLayout(); groupBox6.ResumeLayout(false); groupBox6.PerformLayout(); flowLayoutPanel1.ResumeLayout(false); flowLayoutPanel1.PerformLayout(); ResumeLayout(false); } #endregion private GroupBox groupBox1; private CheckBox checkBox1; private Button button2; private Button button1; private GroupBox groupBox3; private TextBox textBoxMessages; private Button buttonGoMessages; private ComboBox comboBoxMessages; private NumericUpDown numericUpDownMessages; private GroupBox groupBox4; private Label labelVersion; private Button button3; private Button button4; private Button button5; private GroupBox groupBox5; private CheckBox checkBox2; private GroupBox groupBox6; private Panel panel1; private Panel panel2; private CheckBox checkBoxDebug; private FlowLayoutPanel flowLayoutPanel1; private Button button10; private Button button11; private Button button12; private Button button13; private Button button6; private Button button7; private Button button8; private Button button9; private Button button14; private Button button15; private Button button16; private Button button17; private CheckBox checkBoxSysRestoreAvail; private Button button18; } } ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/DebugWindow.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.IO; using System.Linq; using System.Reflection; using System.Threading; using System.Windows.Forms; using BulkCrapUninstaller.Functions; using BulkCrapUninstaller.Functions.ApplicationList; using BulkCrapUninstaller.Functions.Tracking; using BulkCrapUninstaller.Properties; using Klocman.Binding.Settings; using Klocman.Forms.Tools; using Klocman.IO; namespace BulkCrapUninstaller.Forms { public partial class DebugWindow : Form { private readonly UninstallerListViewUpdater _listView; private readonly MainWindow _reference; private readonly SettingBinder _settings = Settings.Default.SettingBinder; private readonly AppUninstaller _appUninstaller; internal DebugWindow(MainWindow reference, UninstallerListViewUpdater listview, AppUninstaller appUninstaller) { _reference = reference; _listView = listview; _appUninstaller = appUninstaller; InitializeComponent(); if (DesignMode) return; _settings.Subscribe(TestHandler, x => x.FilterHideMicrosoft, this); _settings.BindControl(checkBox1, x => x.FilterHideMicrosoft, this); _settings.BindControl(checkBoxDebug, x => x.Debug, this); checkBoxDebug.Checked = Settings.Default.Debug; var messageboxes = typeof(MessageBoxes) .GetMethods(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public); foreach (var x in messageboxes) { var wr = new ComboBoxWrapper(x, y => { var name = y.ToString(); return name!.Substring(name.IndexOf(' ') + 1); }); comboBoxMessages.Items.Add(wr); } checkBox2.Checked = Program.IsInstalled; checkBoxSysRestoreAvail.Checked = SysRestore.SysRestoreAvailable(); } private void button13_Click(object sender, EventArgs e) { UsageManager.FinishCollectingData(); } private void button1_Click_1(object sender, EventArgs e) { _settings.SendUpdates(this); } private void button2_Click(object sender, EventArgs e) { Settings.Default.FilterHideMicrosoft = !Settings.Default.FilterHideMicrosoft; } private void button3_Click(object sender, EventArgs e) { //UpdateSystem.BeginUpdate(); } private void button4_Click(object sender, EventArgs e) { //MessageBox.Show(UpdateSystem.CheckForUpdates().ToString()); //if (UpdateSystem.LastError != null) // MessageBox.Show(UpdateSystem.LastError.Message); // //if (UpdateSystem.LatestReply != null) //{ // MessageBox.Show(UpdateSystem.LatestReply.FullReply.ToString()); // labelVersion.Text = UpdateSystem.LatestReply.GetUpdateVersion().ToString(); //} } private void button5_Click(object sender, EventArgs e) { using (var settingsW = new SettingsWindow()) { settingsW.ShowDialog(); } } private void button6_Click(object sender, EventArgs e) { UsageManager.SendUsageData(); } private void button7_Click(object sender, EventArgs e) { EntryPoint.Restart(); } private void buttonGoMessages_Click(object sender, EventArgs e) { try { var wrapper = comboBoxMessages.SelectedItem as ComboBoxWrapper; if (wrapper?.WrappedObject == null) return; var methodInfo = wrapper.WrappedObject; var parameters = methodInfo.GetParameters(); if (parameters.Length == 0) methodInfo.Invoke(null, Array.Empty()); else { var first = parameters.First(); if (first.ParameterType.IsArray) { methodInfo.Invoke(null, new object[] { textBoxMessages.Lines }); } else if (first.ParameterType == typeof(int)) { methodInfo.Invoke(null, new object[] { (int)numericUpDownMessages.Value }); } else if (first.ParameterType == typeof(Form)) { methodInfo.Invoke(null, new object[] { _reference }); } else if (first.ParameterType == typeof(Exception)) { #pragma warning disable CA2201 // Do not raise reserved exception types methodInfo.Invoke(null, new object[] { new Exception(textBoxMessages.Text) }); #pragma warning restore CA2201 // Do not raise reserved exception types } else { methodInfo.Invoke(null, new object[] { textBoxMessages.Text }); } } } catch (Exception exception) { MessageBox.Show(exception.Message); } } private void checkBox2_CheckedChanged(object sender, EventArgs e) { Program.IsInstalled = checkBox2.Checked; } private void TestCrashBackgroundThread(object sender, EventArgs e) { NBug.Settings.ReleaseMode = false; new Thread(() => throw new ArgumentException("TestCrashBackgroundThread", new IOException("Inner exception"))).Start(); } private void TestCrashUiThread(object sender, EventArgs e) { NBug.Settings.ReleaseMode = false; throw new ArgumentException("TestCrashUiThread", new IOException("Inner exception")); } private void TestHandler(object sender, SettingChangedEventArgs args) { button2.Text = args.NewValue.ToString(); } private void TestJunkSearcher(object sender, EventArgs e) { _appUninstaller.AdvancedUninstall(_listView.SelectedUninstallers, _listView.AllUninstallers.Except(_listView.SelectedUninstallers)); } private void button8_Click(object sender, EventArgs e) { MessageBox.Show(string.Join(Environment.NewLine, _reference.globalHotkeys1.GetHotkeyList().Select(x => x.ToString()).ToArray())); } private void SoftCrash(object sender, EventArgs e) { try { throw new ArithmeticException("Soft crash test", new ArgumentException("Yer a bit bored, eh?")); } catch (Exception ex) { PremadeDialogs.GenericError(ex); } } private void button14_Click(object sender, EventArgs e) { FeedbackBox.ShowFeedbackBox(this, true); } private static long _currentRestoreId; private void button15_Click(object sender, EventArgs e) { SysRestore.StartRestore("BCU RESTORE POINT TEST " + DateTime.Now.ToShortTimeString(), out _currentRestoreId); } private void button16_Click(object sender, EventArgs e) { SysRestore.EndRestore(_currentRestoreId); } private void button17_Click(object sender, EventArgs e) { SysRestore.CancelRestore(_currentRestoreId); } private void button18_Click(object sender, EventArgs e) { throw new DllNotFoundException(@"Unable to load DLL 'api-ms-win-core-com-l1-1-0.dll' or one of its dependencies: The specified module could not be found. (0x8007007E)"); } } } ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/DebugWindow.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/FeedbackBox.Designer.cs ================================================ namespace BulkCrapUninstaller.Forms { partial class FeedbackBox { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FeedbackBox)); this.flowLayoutPanel5 = new System.Windows.Forms.FlowLayoutPanel(); this.p1welcomeHeading = new System.Windows.Forms.Label(); this.p1welcomeSubheading = new System.Windows.Forms.Label(); this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); this.buttonSendFeedback2 = new System.Windows.Forms.Button(); this.buttonRate = new System.Windows.Forms.Button(); this.buttonTwitter = new System.Windows.Forms.Button(); this.p1FeedbackHeading = new System.Windows.Forms.Label(); this.p1FeedbackDesc = new System.Windows.Forms.Label(); this.flowLayoutPanel2 = new System.Windows.Forms.FlowLayoutPanel(); this.buttonSubmitGithub = new System.Windows.Forms.Button(); this.buttonSendFeedback = new System.Windows.Forms.Button(); this.p1HelpHeading = new System.Windows.Forms.Label(); this.p1HelpDesc = new System.Windows.Forms.Label(); this.flowLayoutPanel3 = new System.Windows.Forms.FlowLayoutPanel(); this.buttonDonate = new System.Windows.Forms.Label(); this.buttonTranslate = new System.Windows.Forms.Button(); this.buttonIssues = new System.Windows.Forms.Button(); this.panel1 = new System.Windows.Forms.Panel(); this.checkBoxNeverShow = new System.Windows.Forms.CheckBox(); this.buttonClose = new System.Windows.Forms.Button(); this.flowLayoutPanel5.SuspendLayout(); this.flowLayoutPanel1.SuspendLayout(); this.flowLayoutPanel2.SuspendLayout(); this.flowLayoutPanel3.SuspendLayout(); this.panel1.SuspendLayout(); this.SuspendLayout(); // // flowLayoutPanel5 // resources.ApplyResources(this.flowLayoutPanel5, "flowLayoutPanel5"); this.flowLayoutPanel5.BackColor = System.Drawing.SystemColors.ControlLightLight; this.flowLayoutPanel5.Controls.Add(this.p1welcomeHeading); this.flowLayoutPanel5.Controls.Add(this.p1welcomeSubheading); this.flowLayoutPanel5.Controls.Add(this.flowLayoutPanel1); this.flowLayoutPanel5.Controls.Add(this.p1FeedbackHeading); this.flowLayoutPanel5.Controls.Add(this.p1FeedbackDesc); this.flowLayoutPanel5.Controls.Add(this.flowLayoutPanel2); this.flowLayoutPanel5.Controls.Add(this.p1HelpHeading); this.flowLayoutPanel5.Controls.Add(this.p1HelpDesc); this.flowLayoutPanel5.Controls.Add(this.flowLayoutPanel3); this.flowLayoutPanel5.Name = "flowLayoutPanel5"; // // p1welcomeHeading // resources.ApplyResources(this.p1welcomeHeading, "p1welcomeHeading"); this.flowLayoutPanel5.SetFlowBreak(this.p1welcomeHeading, true); this.p1welcomeHeading.Name = "p1welcomeHeading"; // // p1welcomeSubheading // resources.ApplyResources(this.p1welcomeSubheading, "p1welcomeSubheading"); this.p1welcomeSubheading.Name = "p1welcomeSubheading"; // // flowLayoutPanel1 // resources.ApplyResources(this.flowLayoutPanel1, "flowLayoutPanel1"); this.flowLayoutPanel1.Controls.Add(this.buttonSendFeedback2); this.flowLayoutPanel1.Controls.Add(this.buttonRate); this.flowLayoutPanel1.Controls.Add(this.buttonTwitter); this.flowLayoutPanel5.SetFlowBreak(this.flowLayoutPanel1, true); this.flowLayoutPanel1.Name = "flowLayoutPanel1"; // // buttonSendFeedback2 // resources.ApplyResources(this.buttonSendFeedback2, "buttonSendFeedback2"); this.buttonSendFeedback2.Name = "buttonSendFeedback2"; this.buttonSendFeedback2.UseVisualStyleBackColor = true; this.buttonSendFeedback2.Click += new System.EventHandler(this.buttonSendFeedback2_Click); // // buttonRate // resources.ApplyResources(this.buttonRate, "buttonRate"); this.buttonRate.Name = "buttonRate"; this.buttonRate.UseVisualStyleBackColor = true; this.buttonRate.Click += new System.EventHandler(this.buttonRate_Click); // // buttonTwitter // resources.ApplyResources(this.buttonTwitter, "buttonTwitter"); this.buttonTwitter.Name = "buttonTwitter"; this.buttonTwitter.UseVisualStyleBackColor = true; this.buttonTwitter.Click += new System.EventHandler(this.buttonTwitter_Click); // // p1FeedbackHeading // resources.ApplyResources(this.p1FeedbackHeading, "p1FeedbackHeading"); this.flowLayoutPanel5.SetFlowBreak(this.p1FeedbackHeading, true); this.p1FeedbackHeading.Name = "p1FeedbackHeading"; // // p1FeedbackDesc // resources.ApplyResources(this.p1FeedbackDesc, "p1FeedbackDesc"); this.p1FeedbackDesc.Name = "p1FeedbackDesc"; // // flowLayoutPanel2 // resources.ApplyResources(this.flowLayoutPanel2, "flowLayoutPanel2"); this.flowLayoutPanel2.Controls.Add(this.buttonSubmitGithub); this.flowLayoutPanel2.Controls.Add(this.buttonSendFeedback); this.flowLayoutPanel5.SetFlowBreak(this.flowLayoutPanel2, true); this.flowLayoutPanel2.Name = "flowLayoutPanel2"; // // buttonSubmitGithub // resources.ApplyResources(this.buttonSubmitGithub, "buttonSubmitGithub"); this.buttonSubmitGithub.Name = "buttonSubmitGithub"; this.buttonSubmitGithub.UseVisualStyleBackColor = true; this.buttonSubmitGithub.Click += new System.EventHandler(this.buttonSubmitGithub_Click); // // buttonSendFeedback // resources.ApplyResources(this.buttonSendFeedback, "buttonSendFeedback"); this.buttonSendFeedback.Name = "buttonSendFeedback"; this.buttonSendFeedback.UseVisualStyleBackColor = true; this.buttonSendFeedback.Click += new System.EventHandler(this.buttonSendFeedback2_Click); // // p1HelpHeading // resources.ApplyResources(this.p1HelpHeading, "p1HelpHeading"); this.flowLayoutPanel5.SetFlowBreak(this.p1HelpHeading, true); this.p1HelpHeading.Name = "p1HelpHeading"; // // p1HelpDesc // resources.ApplyResources(this.p1HelpDesc, "p1HelpDesc"); this.p1HelpDesc.Name = "p1HelpDesc"; // // flowLayoutPanel3 // resources.ApplyResources(this.flowLayoutPanel3, "flowLayoutPanel3"); this.flowLayoutPanel3.Controls.Add(this.buttonDonate); this.flowLayoutPanel3.Controls.Add(this.buttonTranslate); this.flowLayoutPanel3.Controls.Add(this.buttonIssues); this.flowLayoutPanel5.SetFlowBreak(this.flowLayoutPanel3, true); this.flowLayoutPanel3.Name = "flowLayoutPanel3"; // // buttonDonate // this.buttonDonate.Image = global::BulkCrapUninstaller.Properties.Resources.donate_button; resources.ApplyResources(this.buttonDonate, "buttonDonate"); this.buttonDonate.Name = "buttonDonate"; this.buttonDonate.Click += new System.EventHandler(this.buttonDonate_Click); // // buttonTranslate // resources.ApplyResources(this.buttonTranslate, "buttonTranslate"); this.buttonTranslate.Name = "buttonTranslate"; this.buttonTranslate.UseVisualStyleBackColor = true; this.buttonTranslate.Click += new System.EventHandler(this.buttonTranslate_Click); // // buttonIssues // resources.ApplyResources(this.buttonIssues, "buttonIssues"); this.buttonIssues.Name = "buttonIssues"; this.buttonIssues.UseVisualStyleBackColor = true; this.buttonIssues.Click += new System.EventHandler(this.buttonIssues_Click); // // panel1 // resources.ApplyResources(this.panel1, "panel1"); this.panel1.Controls.Add(this.checkBoxNeverShow); this.panel1.Controls.Add(this.buttonClose); this.panel1.Name = "panel1"; // // checkBoxNeverShow // resources.ApplyResources(this.checkBoxNeverShow, "checkBoxNeverShow"); this.checkBoxNeverShow.Name = "checkBoxNeverShow"; this.checkBoxNeverShow.UseVisualStyleBackColor = true; // // buttonClose // this.buttonClose.DialogResult = System.Windows.Forms.DialogResult.Cancel; resources.ApplyResources(this.buttonClose, "buttonClose"); this.buttonClose.Name = "buttonClose"; this.buttonClose.UseVisualStyleBackColor = true; // // FeedbackBox // this.AcceptButton = this.buttonClose; resources.ApplyResources(this, "$this"); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.CancelButton = this.buttonClose; this.Controls.Add(this.panel1); this.Controls.Add(this.flowLayoutPanel5); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "FeedbackBox"; this.flowLayoutPanel5.ResumeLayout(false); this.flowLayoutPanel5.PerformLayout(); this.flowLayoutPanel1.ResumeLayout(false); this.flowLayoutPanel1.PerformLayout(); this.flowLayoutPanel2.ResumeLayout(false); this.flowLayoutPanel2.PerformLayout(); this.flowLayoutPanel3.ResumeLayout(false); this.flowLayoutPanel3.PerformLayout(); this.panel1.ResumeLayout(false); this.panel1.PerformLayout(); this.ResumeLayout(false); this.PerformLayout(); } #endregion private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel5; private System.Windows.Forms.Label p1welcomeHeading; private System.Windows.Forms.Label p1welcomeSubheading; private System.Windows.Forms.Label p1FeedbackHeading; private System.Windows.Forms.Label p1FeedbackDesc; private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1; private System.Windows.Forms.Button buttonSendFeedback2; private System.Windows.Forms.Button buttonRate; private System.Windows.Forms.Button buttonTwitter; private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel2; private System.Windows.Forms.Button buttonSubmitGithub; private System.Windows.Forms.Button buttonSendFeedback; private System.Windows.Forms.Label p1HelpHeading; private System.Windows.Forms.Label p1HelpDesc; private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel3; private System.Windows.Forms.Button buttonIssues; private System.Windows.Forms.Button buttonTranslate; private System.Windows.Forms.Label buttonDonate; private System.Windows.Forms.Panel panel1; private System.Windows.Forms.CheckBox checkBoxNeverShow; private System.Windows.Forms.Button buttonClose; } } ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/FeedbackBox.ar.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 فتحي الداودية يشكركم على استخدام المثبت! اذا وجدت هذه الحرة مفتوحة المصدر اداه مفيده ، يرجى النظر في قضاء دقيقه للمساعدة! اخبر اصدقائك عن ذلك ، وتقاسمها على وسائل الاعلام الاجتماعية ، واعطاء ردود الفعل--كل شيء يحسب قليلا! ارسال الملاحظات السعر (في أسفل الصفحة) شاركنا على تويتر اي مشاكل او الميزات المفقودة ؟ او اذا كنت ترغب في اقتراح ميزه جديده ، يرجى التحقق من هذه الروابط BCU،اذا كان لديك اي مشاكل مع: (تحتاج الى حساب) GitHub تقدم على ارسال الملاحظات هل تريد المساعدة ؟ الى لغتك الاصليه. كل مساعده هو موضع تقدير كبير ، مهما كانت صغيره BCU ليس عليك ان تكون مبرمجا للمساعدة! يمكنك التبرع لتسريع التحديثات ، او ترجمه BCU ترجمه GitHub المسائل المتعلقة بـ لا تظهر هذه النافذة في وقت مضى مره اخرى ، من اي وقت مضي اغلاق ارسال الملاحظات ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/FeedbackBox.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Windows.Forms; using BulkCrapUninstaller.Properties; namespace BulkCrapUninstaller.Forms { public partial class FeedbackBox : Form { public static void ShowFeedbackBox(Form parent, bool showDisableCheckbox) { if (parent == null) throw new ArgumentNullException(nameof(parent)); using (var f = new FeedbackBox()) { f.checkBoxNeverShow.Visible = showDisableCheckbox; f.checkBoxNeverShow.Enabled = showDisableCheckbox; f.Icon = parent.Icon; f.Owner = parent; f.StartPosition = FormStartPosition.CenterParent; f.ShowDialog(parent); } } private FeedbackBox() { InitializeComponent(); if (DesignMode) return; Settings.Default.SettingBinder.BindControl(checkBoxNeverShow, x => x.MiscFeedbackNagNeverShow, this); Settings.Default.SettingBinder.SendUpdates(this); } private void buttonSendFeedback2_Click(object sender, EventArgs e) { MainWindow.OpenUrls(new[] { new Uri(Resources.SubmitFeedbackLink) }); } private void buttonRate_Click(object sender, EventArgs e) { MainWindow.OpenUrls(new[] { new Uri(Resources.ReviewLink) }); } private void buttonTwitter_Click(object sender, EventArgs e) { MainWindow.OpenUrls(new[] { new Uri(Resources.TwitterLink) }); } private void buttonSubmitGithub_Click(object sender, EventArgs e) { MainWindow.OpenUrls(new[] { new Uri(Resources.GithubNewIssueLink) }); } private void buttonIssues_Click(object sender, EventArgs e) { MainWindow.OpenUrls(new[] { new Uri(Resources.GithubIssuesLink) }); } private void buttonTranslate_Click(object sender, EventArgs e) { MainWindow.OpenUrls(new[] { new Uri(Resources.TranslateLink) }); } private void buttonDonate_Click(object sender, EventArgs e) { MainWindow.OpenUrls(new[] { new Uri(Resources.DonateLink) }); } } } ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/FeedbackBox.cs.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Děkujeme vám za použití BCUninstaller! Pokud je tento bezplatný open-source nástroj pro Vás užitečný, prosím zvažte svoji pomoc! Řekněte svým přátelům, sdílet na sociálních sítích, poskytněte zpětnou vazbu - vše se počítá! Poslat zpětnou vazbu Poměr (v dolní části stránky) Podělte se na Twitteru Jakékoli problémy nebo chybějící funkce? Pokud byste měli nějaké problémy s BCU, nebo chcete-li navrhnout novou funkci, viz tento odkaz: Předložení návrhu na GitHub (Potřebujete účet) Poslat zpětnou vazbu Chcete pomoci? Nemusíte být programátor, aby jste pomohly! Můžete darovat k urychlení aktualizace nebo překládat BCU do Vašeho jazyka. Jakákoli pomoc je velmi ceněna, bez ohledu na to, jak malá je! Přeložit BCU Problémy na GitHub Nikdy nezobrazovat toto okno znovu Zavřít Poslat zpětnou vazbu ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/FeedbackBox.de.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Danke für die Benutzung von BCUninstaller! Wenn du dieses Open Source Tool nutzvoll findest, erzähle deinen Freunden davon, teile es auf den Sozialen Medien. Jedes bißchen Hilfe zählt. Feedback senden Bewertung am unteren Rand der Seite Auf Twitter teilen Probleme oder fehlende Funktionen? Wenn Sie irgendwelche Probleme mit BCU hatten oder eine Verbesserung haben nutzen sie diese Links: An GitHub senden (Account benötigt) Feedback senden Möchtest du helfen? Du brauchst kein Programmierer zu sein um zu helfen. Du kannst Spenden oder in deine Sprache übersetzen. Jede Hilfe ist sehr willkommen, egal wie wenig. BCU übersetzen Probleme mit GitHub Niemals mehr dieses Fenster zeigen Schließen Feedback senden ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/FeedbackBox.es.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ¡Gracias por utilizar BCUninstaller! Si has encontrado útil esta herramienta gratuita de código abierto, ¡por favor considera dedicar un minuto a ayudar! Díselo a tus amigos, compártela en las redes sociales, envía comentarios - ¡cualquier cosa pequeña cuenta! Enviar comentario Tarifa (parte inferior de la página) Compartir en Twitter ¿Problemas o características que faltan? Si tuviste algún problema con BCU, o si quieres sugerir una nueva característica, consulte estos enlaces: Enviar a GitHub (Necesita una cuenta) Enviar comentario ¿Quieres ayudar? ¡No tienes que ser un programador para ayudar! Puedes donar para acelerar las actualizaciones o traducir BCU en tu lengua materna. Toda ayuda es muy apreciada ¡no importa si es pequeña! Traducir BCU Problemas en GitHub No volver a mostrar esta ventana Cerrar Enviar comentario ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/FeedbackBox.fr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Merci d'utiliser BCUninstaller ! Si vous trouvez cet outil open-source gratuit utile, merci de prendre une minute pour aider ! Parlez-en à vos amis, partagez-le sur les réseaux sociaux, donnez un retour - chaque petit geste compte ! Envoyer un retour Évaluer (en bas de la page) Partager sur Twitter Des problèmes ou des fonctions manquantes ? Si vous avez des problèmes avec BCU ou si vous souhaitez suggérer une nouvelle fonction, merci de vérifier ces liens : Soumettre sur GitHub (Nécessite un compte) Envoyer un retour Voulez-vous aider ? Vous n'avez pas à être un programmeur pour aider ! Vous pouvez faire un don pour accélérer les mises à jour, ou traduire BCU dans votre langue maternelle. Toute aide est grandement appréciée, même petite ! Traduire BCU Problèmes sur GitHub Ne plus jamais montrer cette fenêtre, jamais Fermer Envoyer un retour ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/FeedbackBox.hu.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Köszönjük, hogy a BCUninstaller-t használja! Ha ezt az ingyenes nyílt forráskódú eszközt hasznosnak találta, szánjon egy percet az elterjesztésére! Ajánlja a barátainak a közösségi médiákban. A legkisebb segítség is sokat jelent nekünk! Hibát talált, vagy hiányzik valamilyen funkció? Hibát talált, vagy javaslata van? Kérem, használja ezeket a lehetőségeket: Szeretne segíteni nekünk? Nem kell programozónak lennie, hogy segítsen! Hozzájárulhat a frissítések felgyorsításához, vagy lefordíthatja a BCU-t a saját nyelvére. Bármilyen kicsi segítséget is szívesen veszünk! Visszajelzés Ár (az oldal alján) Twitter megosztás GitHub visszajelzés (fiók szükséges) Visszajelzés BCU lefordítása GitHub kérdés Ne jelenjen meg ez az oldal többé Bezárás Visszajelzés ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/FeedbackBox.it.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Grazie per l'uso di BCUninstaller! Se questo programma free ed open source ti è stato utile ti invito a spendere un minuto per aiutarci! Parlane ai tuoi amici, condividilo sui social media, scrivici le tue impressioni - ogni piccolo contributo è utile! Hai avuto problemi o mancano delle funzionalità? Se hai avuto problemi con BCU o se desideri suggerire una nuova funzionalità ti invitiamo a dare uno sguardo a questi collegamenti: Vuoi aiutarci? Per aiutarci non devi essere un programmatore! Potresti donare una piccola somma per accelerare lo sviluppo degli aggiornamenti, o tradurre BCU nella tua lingua. Qualunque aiuto, seppur piccolo, sarà molto apprezzato! Invia feedback Vota (in fondo alla pagina) Condividi su Twitter Invia su GitHub (richiesto account GitHub) Invia feedback Traduci BCU Segnalazioni su GitHub Non visualizzare più questa finestra Chiudi Invia feedback ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/FeedbackBox.ja.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 BCUninstallerをご利用いただきありがとうございます! この無料のオープンソースツールが役立った場合は、ぜひ1分だけお手伝いをお願いいたします!友人に教えたり、SNSで共有したり、フィードバックを送ったり、どんな小さなことでも大歓迎です! フィードバックを送る 評価する(ページの一番下にあります) Twitterで共有 問題や不足している機能はありますか? BCUに関して問題があった場合や、新しい機能を提案したい場合は、これらのリンクをご確認ください: GitHubで提出する(アカウントが必要です) フィードバックを送信 お手伝いをしていただけますか? プログラマーでなくてもお手伝いいただけます!更新を早めるために寄付することや、BCUを母国語に翻訳することができます。どんな小さなお手伝いも大変感謝いたします! BCUを翻訳 GitHubの問題 このウィンドウを二度と表示しない 閉じる フィードバックを送信 ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/FeedbackBox.nl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Bedankt dat u BCUninstaller gebruikt! Feedback sturen Delen op Twitter Problemen of ontbrekende mogelijkheden? Heeft u problemen met BCU of suggesties voor nieuwe mogelijkheden, controleer dan deze links: Aanmelden op GitHub (Acccount vereist) Feedback sturen Wilt u ons helpen? U hoeft geen programmeur te zijn om ons te helpen! U kunt een donatie doen om updates sneller uit te brengen, of BCU in uw taal te vertalen. Alle hulp wordt op prijs gesteld, ongeacht de wijze waarop! Vertaal BCU Problemen op GitHub Toon dit venster nooit meer Sluiten Stuur feedback Als u deze vrije open-source tool handig vindt, overweeg dan even om de helpfunctie te raadplegen! Vertel uw vrienden hierover, deel het op social media, stuur feedback - alle kleine beetjes helpen! Tarief (onderaan de pagina) ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/FeedbackBox.pl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Dziękujemy za korzystanie z BCUninstaller! Jeśli to darmowe i otwarte narzędzie było tobie przydatne, pomyśl o pomocy temu projektowi! Powiedz znajomym o BCU, podziel się nim w portalach społecznościowych, zostaw opinię - wszystko się liczy! Wyślij opinię Oceń (na dole strony) Twittuj o BCU Jakieś problemy lub brakujące funkcje? Sprawdź te linki aby zasugerować nową funkcję, lub zgłosić błąd w aplikacji: Pomóż na GitHub Prześlij opinię Chcesz pomóc? Nie trzeba być programistą aby pomóc! Można przekazać darowiznę aby przyśpieszyć rozwój, lub przetłumaczyć BCU do swojego ojczystego języka. Każda pomoc jest mile widziana, nie ważne jak mała! Przetłumacz BCU Problemy na GitHub Nigdy nie pokazuj ponownie tego okna Zamknij Wyślij opinię ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/FeedbackBox.pt-BR.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Obrigado por usar o BCUninstaller! Se você achou útil esta ferramenta gratuita de código aberto, considere gastar um minuto para ajudar! Fale com os seus amigos sobre isso, compartilhe nas mídias sociais, dê uma resposta - um pouco vale muito! Enviar comentários Avaliar (na parte inferior) Compartilhe no Twitter Algum problema ou recursos faltando? Se você teve algum problema com o BCU, ou se quiser sugerir um novo recurso, verifique esses links: Envie para GitHub (Necessita de uma conta) Enviar comentário. Você quer ajudar? Você não precisa ser um programador para ajudar! Você pode fazer uma doação para acelerar as atualizações ou traduzir BCU para a sua língua nativa. Toda a ajuda é muito apreciada, não importa quão pequena! Traduzir o BCU Problemas no GitHub Nunca mais mostrar esta janela. Fechar Enviar comentário. ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/FeedbackBox.pt.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Obrigado por usar o BCUninstaller! Se achou útil esta ferramenta gratuita de código aberto, por favor pondere arranjar um minuto para ajudar! Diga aos seus amigos, compartilhe-o nas redes sociais, envie comentários – tudo conta! Enviar comentário. Taxa (na parte inferior) Partilhe no Twitter Problemas ou características em falta? 105/5000 Se teve um problema com o BCU, ou se quiser sugerir um novo recurso, consulte estes links: Envie para GitHub (Necessita de uma conta) Enviar comentário. Quer ajudar? Não tem de ser um programador para ajudar! Pode doar para acelerar as actualizações ou traduzir o BCU para o seu idioma pátrio. Toda a ajuda é bem-vinda, por mais pequena que seja! Traduzir o BCU Problemas com o GitHub Nunca mais mostrar esta janela. Fechar Enviar comentário. ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/FeedbackBox.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 True GrowAndShrink True Arial Black, 12pt, style=Bold NoControl 11, 4 0, 8, 0, 3 315, 34 0 Thank you for using BCUninstaller! p1welcomeHeading System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel5 0 True NoControl 11, 38 0, 0, 0, 4 322, 43 1 If you found this free open-source tool useful, please consider spending a minute to help out! Tell your friends about it, share it on social media, give feedback - everything little bit counts! p1welcomeSubheading System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel5 1 True True GrowAndShrink 3, 3 90, 23 0 Send feedback buttonSendFeedback2 System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel1 0 True GrowAndShrink 99, 3 168, 23 1 Rate (at the bottom of the page) buttonRate System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel1 1 True GrowAndShrink 3, 32 95, 23 2 Share on Twitter buttonTwitter System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel1 2 11, 84 270, 58 2 flowLayoutPanel1 System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel5 2 True Arial Black, 12pt, style=Bold NoControl 11, 145 0, 8, 0, 3 315, 34 3 Any problems or missing features? p1FeedbackHeading System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel5 3 True NoControl 11, 179 0, 0, 0, 4 309, 30 4 If you had any issues with BCU, or if you want to suggest a new feature, please check these links: p1FeedbackDesc System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel5 4 True True GrowAndShrink 3, 3 192, 23 0 Submit on GitHub (Need an account) buttonSubmitGithub System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel2 0 True GrowAndShrink 201, 3 90, 23 1 Send feedback buttonSendFeedback System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel2 1 11, 212 294, 29 5 flowLayoutPanel2 System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel5 5 True Arial Black, 12pt, style=Bold NoControl 11, 244 0, 8, 0, 3 195, 34 6 Do you want to help? p1HelpHeading System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel5 6 True NoControl 11, 278 0, 0, 0, 4 337, 43 7 You don't have to be a programmer to help! You can donate to speed up the updates, or translate BCU to your native language. All help is greatly appreciated, no matter how small! p1HelpDesc System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel5 7 True TopLeft 3, 0 0, 2, 0, 0 76, 29 2 buttonDonate System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel3 0 True GrowAndShrink 85, 3 86, 23 1 Translate BCU buttonTranslate System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel3 1 True GrowAndShrink 177, 3 98, 23 0 Issues on GitHub buttonIssues System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel3 2 11, 324 278, 29 8 flowLayoutPanel3 System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel5 8 Top 0, 0 8, 4, 8, 8 359, 364 0 flowLayoutPanel5 System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 1 GrowAndShrink True Left 8, 8 9999, 23 0, 23 217, 23 0 Don't ever show this window again, ever checkBoxNeverShow System.Windows.Forms.CheckBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel1 0 Right 276, 8 9999, 23 0, 23 75, 23 1 Close buttonClose System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel1 1 Top 0, 364 8, 8, 8, 8 359, 39 1 panel1 System.Windows.Forms.Panel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 0 6, 13 True GrowAndShrink 359, 490 375, 9999999 375, 39 Send feedback FeedbackBox System.Windows.Forms.Form, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 True ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/FeedbackBox.ru.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Благодарим вас за использование BCUninstaller! Если Вы нашли это бесплатное ПО полезным, пожалуйста, подумайте о том, как потратить минуту на то, чтобы помочь его развитию! Расскажите о нём друзьям, поделитесь им в социальных сетях, отправьте отзыв — любая малость значительна! Отправить отзыв Оценить (внизу страницы) Поделиться в Twitter Нашли ошибку или нужна функция? Если у Вас возникли проблемы с BCU или Вы хотите предложить новую функцию, посетите эти ссылки: Отзыв на GitHub (нужна учетная запись) Отправить отзыв Хотите помочь? Вам не обязательно быть программистом, чтобы помочь! Вы можете сделать пожертвование для ускорения выхода обновлений или перевести BCU на ваш родной язык. Любая помощь приветствуется, независимо от её размера! Перевести BCU Проблемы на GitHub Никогда не показывать это окно снова Закрыть Отправить отзыв ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/FeedbackBox.sl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Hvala, ker uporabljate BCUninstaller! Če menite, da je to brezplačno, odprtokodno orodje uporabno za vas, razmislite kakšno minutko o majhni pomoči! Povejte svojim prijateljem o tem, delite svoje mnenje na družbenih omrežjih, pošljite jim vaše povratne informacije - vse, kar je potrebno, malo, šteje! Kakršne koli težave ali manjkajoče funkcije? Če ste imeli kakršne koli težave z BCU ali pa, če bi radi predlagali novo funkcijo, si oglejte te povezave: Ali želite pomagati? Saj ni treba biti programer, da boste lahko pomagali! Lahko prispevate darilo, da pospešite posodabljanje ali prevedete BCU v svoj materni jezik. Vsa pomoč je zelo cenjena, ne glede na to, kako majhna bo! Pošlji povratno informacijo Deli na Twitterju Pošlji na GitHub (Potreben je račun) Pošlji povratne informacije Prevedite BCU Zadeve na GitHub Tega okna ne prikazuj nikoli več Zapri Pošlji povratne informacije Ocena (na dnu strani) ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/FeedbackBox.sv.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Tack för att du använder BCUninstaller! Om du har haft nytta av den här kostnadsfria öppen källkodsverktyget, överväg att lägga några minuter på att hjälpa till! Berätta för dina vänner om det, dela det i sociala medier, ge feedback - varje litet bidrag räknas! Skicka feedback Betygsätt (längst ner på sidan) Dela på Twitter Några problem eller saknade funktioner? Om du hade några problem med BCU, eller om du vill föreslå en ny funktion, vänligen se dessa länkar: Skicka in på GitHub (konto krävs) Skicka feedback Vill du hjälpa till? Du behöver inte vara en programmerare för att hjälpa till! Du kan donera för att påskynda uppdateringarna, eller översätta BCU till ditt modersmål. All hjälp uppskattas mycket, oavsett hur liten! Översätt BCU Ärenden på GitHub Visa aldrig det här fönstret igen, någonsin Stäng Skicka feedback ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/FeedbackBox.tr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 BCUninstaller'ı kullandığınız için teşekkür ederiz! Bu ücretsiz açık kaynak aracını yararlı bulduysanız, lütfen yardım için bir dakikanızı ayırmayı düşünün! Arkadaşlarınıza bunu anlatın, sosyal medyada paylaşın, geri bildirim verin - her şey küçük sayılır! Geribildirim yolla Oran (sayfanın en altında) Twitter'da paylaş Herhangi bir sorun veya eksik özellik var mı? BCU ile ilgili herhangi bir sorun yaşarsanız veya yeni bir özellik önermek istiyorsanız, lütfen şu bağlantıları kontrol edin: GitHub'da Gönder (Bir hesaba ihtiyacınız var) Geribildirim yolla Yardım ister misiniz? Yardımcı olmak için bir programcı olmanıza gerek yok! Güncellemeleri hızlandırmak veya BCU'yu kendi dilinize çevirmek için bağışta bulunabilirsiniz. Ne kadar küçük olursa olsun tüm yardımlar çok takdir edilir! BCU'yu Çevir GitHub ile ilgili sorunlar Bu pencereyi bir daha asla gösterme Kapat Geribildirim yolla ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/FeedbackBox.vi.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Cảm ơn bạn đã sử dụng BCUninstaller! Bạn đã thấy công cụ mã nguồn mở miễn phí này hữu ích chứ? Nếu có, hãy dành một phút để giúp chúng tôi nhé! Hãy giới thiệu nó với bạn bè của bạn, chia sẻ nó lên mạng xã hội, hay cung cấp phản hồi - mọi đóng góp nhỏ đều có giá trị! Gửi phản hồi Đánh giá (ở cuối trang) Chia sẻ lên Twitter Có bất kỳ trục trặc gì hay thiếu tính năng nào không? Nếu bạn gặp phải bất kỳ sự cố nào với BCU hoặc muốn đề xuất tính năng mới, vui lòng kiểm tra các liên kết này: Gửi lên GitHub (Cần có tài khoản) Gửi phản hồi Bạn có muốn góp sức không? Bạn không cần phải là lập trình viên để góp sức! Bạn có thể quyên góp để đẩy nhanh quá trình cập nhật hoặc dịch BCU sang tiếng mẹ đẻ của bạn. Mọi sự giúp đỡ đều được trân trọng, dù là nhỏ nhất! Dịch BCU Báo cáo lỗi trên GitHub Không bao giờ hiển thị lại cửa sổ này nữa Đóng Gửi phản hồi ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/FeedbackBox.zh-Hans.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 感谢你使用BCUninstaller! 如果你觉得这个免费的开源工具有用,请考虑花一分钟帮忙!告诉你的朋友,在社交媒体上分享,给予反馈——一切都很重要! 发送反馈 评分(在页面底部) 在Twitter上分享 有什么问题或功能缺失吗? 如果你对BCU有任何问题,或者你想建议新功能,请查看以下链接: 在GitHub上提交(需要帐户) 发送反馈 你想帮忙吗? 不是程序员也可以帮忙!你可以捐款来加速更新,或者把BCU翻译成你的母语。非常感谢所有的帮助,不管有多小! 翻译BCU Github上的Issue 不再显示这个窗口 关闭 发送反馈 ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/FeedbackBox.zh-Hant.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 感謝你使用BCUnintstaller! 如果你覺得這個免費的開源工具有用,請考慮花一分鐘幫忙!告訴你的朋友,在社交媒體上分享,給予回饋——一切都很重要! 傳送回饋 評分(在頁面底部) 在Twitter上分享 有甚麼問題或沒有的功能嗎? 如果你對BCU有任何問題,或者你想建議新功能,請查看以下連結: 你也想幫忙嗎? 不是程式設計師也可以幫忙!你可以捐款來加速更新,或者把BCU翻譯成你的母語。非常感謝所有的幫助,不管有多小! 翻譯BCU GitHub上的Issues 不再顯示這個視窗 關閉 傳送回饋 在GitHub上提交(需要GitHub帳號) 傳送回饋 ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/FeedbackWindow.Designer.cs ================================================ namespace BulkCrapUninstaller.Forms { partial class FeedbackWindow { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FeedbackWindow)); webBrowser = new System.Windows.Forms.WebBrowser(); loadingLabel = new System.Windows.Forms.Label(); SuspendLayout(); // // webBrowser // webBrowser.AllowWebBrowserDrop = false; resources.ApplyResources(webBrowser, "webBrowser"); webBrowser.IsWebBrowserContextMenuEnabled = false; webBrowser.Name = "webBrowser"; // // loadingLabel // resources.ApplyResources(loadingLabel, "loadingLabel"); loadingLabel.Name = "loadingLabel"; loadingLabel.UseWaitCursor = true; // // FeedbackWindow // resources.ApplyResources(this, "$this"); AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; Controls.Add(loadingLabel); Controls.Add(webBrowser); FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; MaximizeBox = false; MinimizeBox = false; Name = "FeedbackWindow"; Shown += FeedbackWindow_Shown; ResumeLayout(false); } #endregion private System.Windows.Forms.WebBrowser webBrowser; private System.Windows.Forms.Label loadingLabel; } } ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/FeedbackWindow.ar.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 التحميل ، الرجاء الانتظار... ارسال الملاحظات ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/FeedbackWindow.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Windows.Forms; namespace BulkCrapUninstaller.Forms { internal partial class FeedbackWindow : Form { public FeedbackWindow() { InitializeComponent(); webBrowser.DocumentCompleted += webBrowser_DocumentCompleted; webBrowser.ScrollBarsEnabled = false; //webBrowser.Visible = false; } public static void ShowFeedbackDialog() { using (var fw = new FeedbackWindow()) { fw.ShowDialog(); } } private void webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) { webBrowser.DocumentCompleted -= webBrowser_DocumentCompleted; try { var container = webBrowser.Document!.GetElementById("container"); container!.InnerHtml = webBrowser.Document.GetElementById("content")!.InnerHtml; container.Style = "width:422px; margin:10px auto; padding:10px; align:center;"; webBrowser.Document.Body!.Style = "padding:0px;"; } catch { //Error while parsing, probably couldn't connect. Let the browser show the error. } loadingLabel.Visible = false; webBrowser.Visible = true; } private void FeedbackWindow_Shown(object sender, EventArgs e) { webBrowser.Navigate(new Uri(@"http://klocmansoftware.weebly.com/feedback--contact.html")); } } } ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/FeedbackWindow.cs.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Načítání prosím počkejte ... Odeslat zpětnou vazbu True fr ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/FeedbackWindow.de.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Wird geladen, bitte warten... Feedback senden True fr ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/FeedbackWindow.es.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Cargando, por favor espere... Enviar comentario ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/FeedbackWindow.fr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 4, 3, 4, 3 23, 23 562, 672 4, 0, 4, 0 562, 672 Chargement, veuillez patienter... 7, 15 562, 672 4, 3, 4, 3 Soumettre un retour ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/FeedbackWindow.hu.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Betöltés, kérem várjon... Visszajelzés ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/FeedbackWindow.it.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Caricamento... Invia feedback ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/FeedbackWindow.ja.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 読み込み中です。しばらくお待ちください… フィードバックを送信 ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/FeedbackWindow.nl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Wordt geladen, even geduld a.u.b... Feedback sturen ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/FeedbackWindow.pl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Wczytywanie, proszę czekać... Wyślij opinię ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/FeedbackWindow.pt-BR.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Carregando, por favor aguarde... Enviar comentário ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/FeedbackWindow.pt.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 A carregar, por favor espere... Enviar comentário True fr ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/FeedbackWindow.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Fill 0, 0 4, 3, 4, 3 23, 23 562, 672 0 False webBrowser System.Windows.Forms.WebBrowser, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 1 Fill Microsoft Sans Serif, 14pt 0, 0 4, 0, 4, 0 562, 672 1 Loading, please wait... MiddleCenter loadingLabel System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 0 True 7, 15 562, 672 5, 3, 5, 3 CenterParent Submit feedback FeedbackWindow System.Windows.Forms.Form, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/FeedbackWindow.ru.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Загрузка, ожидайте... Отправить отзыв True fr ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/FeedbackWindow.sl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Nalagam. Počakajte, prosim... Pošlji povratne informacije True fr ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/FeedbackWindow.sv.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Laddar, vänligen vänta... Skicka feedback ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/FeedbackWindow.tr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Yükleniyor lütfen bekleyin... Geri bildirim gönder ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/FeedbackWindow.vi.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Đang nạp, vui lòng đợi... Gửi phản hồi ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/FeedbackWindow.zh-Hans.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 加载中,请等待... 提交反馈 ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/FeedbackWindow.zh-Hant.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 載入中,請稍待... 提交回饋 ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/ListLegendWindow.Designer.cs ================================================ namespace BulkCrapUninstaller.Forms { partial class ListLegendWindow { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { components = new System.ComponentModel.Container(); opacityResetTimer = new System.Windows.Forms.Timer(components); listLegend1 = new BulkCrapUninstaller.Controls.ListLegend(); SuspendLayout(); // // opacityResetTimer // opacityResetTimer.Interval = 25; opacityResetTimer.Tick += opacityResetTimer_Tick; // // listLegend1 // listLegend1.AutoSize = true; listLegend1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; listLegend1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; listLegend1.Cursor = System.Windows.Forms.Cursors.Hand; listLegend1.Location = new System.Drawing.Point(0, 0); listLegend1.Margin = new System.Windows.Forms.Padding(5, 3, 5, 3); listLegend1.MinimumSize = new System.Drawing.Size(184, 2); listLegend1.Name = "listLegend1"; listLegend1.Size = new System.Drawing.Size(184, 163); listLegend1.TabIndex = 0; // // ListLegendWindow // AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; AutoSize = true; AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; BackColor = System.Drawing.Color.Fuchsia; ClientSize = new System.Drawing.Size(350, 346); ControlBox = false; Controls.Add(listLegend1); FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); MaximizeBox = false; MinimizeBox = false; Name = "ListLegendWindow"; ShowIcon = false; ShowInTaskbar = false; SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; StartPosition = System.Windows.Forms.FormStartPosition.Manual; Text = "ListLegendWindow"; TransparencyKey = System.Drawing.Color.Fuchsia; EnabledChanged += ListLegendWindow_EnabledChanged; VisibleChanged += ListLegendWindow_VisibleChanged; ResumeLayout(false); PerformLayout(); } #endregion private Controls.ListLegend listLegend1; private System.Windows.Forms.Timer opacityResetTimer; } } ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/ListLegendWindow.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.ComponentModel; using System.Drawing; using System.Windows.Forms; using BulkCrapUninstaller.Controls; using Klocman.Extensions; namespace BulkCrapUninstaller.Forms { public partial class ListLegendWindow : Form { private const double OpacityChangeAmount = .12; public ListLegendWindow() { InitializeComponent(); listLegend1.CloseRequested += (sender, args) => { Visible = false; Owner.Focus(); }; foreach (var control in this.GetAllChildren()) { control.MouseLeave += ControlOnMouseEvent; control.MouseEnter += ControlOnMouseEvent; } } public void UpdatePosition(Control owner) { if (owner == null) throw new ArgumentNullException(nameof(owner)); if (!owner.Visible || owner.IsDisposed || owner.Disposing) return; var local = new Point(owner.Width - Width - 30, owner.Height - Height - 30); var global = owner.PointToScreen(local); Location = global; } public ListLegend ListLegend => listLegend1; private void ListLegendWindow_VisibleChanged(object sender, EventArgs e) { if (Opacity < .9) opacityResetTimer.Start(); } private void ListLegendWindow_EnabledChanged(object sender, EventArgs e) { if (Opacity < .9) opacityResetTimer.Start(); } private void opacityResetTimer_Tick(object sender, EventArgs e) { if (CheckMouseHover()) { if (Math.Abs(Opacity - .3) < .03) opacityResetTimer.Stop(); else try { Opacity = OpacityLerp(.3); } catch (Win32Exception) { } } else { if (Math.Abs(Opacity - 1) < .03) opacityResetTimer.Stop(); else try { Opacity = OpacityLerp(1); } catch (Win32Exception) { } } } private double OpacityLerp(double target) { return Opacity > target ? Math.Max(target, Opacity - OpacityChangeAmount) : Math.Min(target, Opacity + OpacityChangeAmount); } private void ControlOnMouseEvent(object sender, EventArgs eventArgs) { opacityResetTimer.Start(); } private bool CheckMouseHover() { var pt = PointToClient(Cursor.Position); return ClientRectangle.Contains(pt); } } } ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/ListLegendWindow.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 17, 17 ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/NewsPopup.Designer.cs ================================================ namespace BulkCrapUninstaller.Forms { partial class NewsPopup { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(NewsPopup)); labelTitle = new System.Windows.Forms.Label(); label3 = new System.Windows.Forms.Label(); linkLabel1 = new System.Windows.Forms.LinkLabel(); linkLabel2 = new System.Windows.Forms.LinkLabel(); linkLabel3 = new System.Windows.Forms.LinkLabel(); linkLabel4 = new System.Windows.Forms.LinkLabel(); linkLabel5 = new System.Windows.Forms.LinkLabel(); linkLabel6 = new System.Windows.Forms.LinkLabel(); linkLabel7 = new System.Windows.Forms.LinkLabel(); label1 = new System.Windows.Forms.Label(); checkBoxNeverShow = new System.Windows.Forms.CheckBox(); tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); tableLayoutPanel1.SuspendLayout(); SuspendLayout(); // // labelTitle // resources.ApplyResources(labelTitle, "labelTitle"); labelTitle.Name = "labelTitle"; labelTitle.Click += Close; // // label3 // resources.ApplyResources(label3, "label3"); label3.Name = "label3"; label3.Click += Close; // // linkLabel1 // resources.ApplyResources(linkLabel1, "linkLabel1"); linkLabel1.Name = "linkLabel1"; linkLabel1.TabStop = true; linkLabel1.LinkClicked += linkLabel1_LinkClicked; // // linkLabel2 // resources.ApplyResources(linkLabel2, "linkLabel2"); linkLabel2.Name = "linkLabel2"; linkLabel2.TabStop = true; linkLabel2.LinkClicked += linkLabel2_LinkClicked; // // linkLabel3 // resources.ApplyResources(linkLabel3, "linkLabel3"); linkLabel3.Name = "linkLabel3"; linkLabel3.TabStop = true; linkLabel3.LinkClicked += linkLabel3_LinkClicked; // // linkLabel4 // resources.ApplyResources(linkLabel4, "linkLabel4"); linkLabel4.Name = "linkLabel4"; linkLabel4.TabStop = true; linkLabel4.LinkClicked += linkLabel4_LinkClicked; // // linkLabel5 // resources.ApplyResources(linkLabel5, "linkLabel5"); linkLabel5.Name = "linkLabel5"; linkLabel5.TabStop = true; linkLabel5.LinkClicked += linkLabel5_LinkClicked; // // linkLabel6 // resources.ApplyResources(linkLabel6, "linkLabel6"); linkLabel6.Name = "linkLabel6"; linkLabel6.TabStop = true; linkLabel6.LinkClicked += linkLabel6_LinkClicked; // // linkLabel7 // resources.ApplyResources(linkLabel7, "linkLabel7"); linkLabel7.Name = "linkLabel7"; linkLabel7.TabStop = true; linkLabel7.LinkClicked += linkLabel7_LinkClicked; // // label1 // resources.ApplyResources(label1, "label1"); label1.Name = "label1"; label1.Click += Close; // // checkBoxNeverShow // resources.ApplyResources(checkBoxNeverShow, "checkBoxNeverShow"); checkBoxNeverShow.Name = "checkBoxNeverShow"; checkBoxNeverShow.UseVisualStyleBackColor = true; // // tableLayoutPanel1 // resources.ApplyResources(tableLayoutPanel1, "tableLayoutPanel1"); tableLayoutPanel1.Controls.Add(label1, 0, 0); tableLayoutPanel1.Controls.Add(checkBoxNeverShow, 1, 0); tableLayoutPanel1.Name = "tableLayoutPanel1"; // // NewsPopup // resources.ApplyResources(this, "$this"); AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; BackColor = System.Drawing.Color.White; Controls.Add(tableLayoutPanel1); Controls.Add(label3); Controls.Add(linkLabel7); Controls.Add(linkLabel4); Controls.Add(linkLabel3); Controls.Add(linkLabel2); Controls.Add(linkLabel6); Controls.Add(linkLabel5); Controls.Add(linkLabel1); Controls.Add(labelTitle); ForeColor = System.Drawing.Color.Black; FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; MaximizeBox = false; MinimizeBox = false; Name = "NewsPopup"; ShowIcon = false; ShowInTaskbar = false; SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; Click += Close; tableLayoutPanel1.ResumeLayout(false); tableLayoutPanel1.PerformLayout(); ResumeLayout(false); PerformLayout(); } #endregion private System.Windows.Forms.Label labelTitle; private System.Windows.Forms.Label label3; private System.Windows.Forms.LinkLabel linkLabel1; private System.Windows.Forms.LinkLabel linkLabel2; private System.Windows.Forms.LinkLabel linkLabel3; private System.Windows.Forms.LinkLabel linkLabel4; private System.Windows.Forms.LinkLabel linkLabel5; private System.Windows.Forms.LinkLabel linkLabel6; private System.Windows.Forms.LinkLabel linkLabel7; private System.Windows.Forms.Label label1; private System.Windows.Forms.CheckBox checkBoxNeverShow; private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; } } ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/NewsPopup.ar.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 لا تظهر هذه النافذة في وقت مضى مره اخرى ، من اي وقت مضي ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/NewsPopup.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Windows.Forms; using BulkCrapUninstaller.Functions; using BulkCrapUninstaller.Properties; namespace BulkCrapUninstaller.Forms { public partial class NewsPopup : Form { private NewsPopup() { InitializeComponent(); if (DesignMode) return; var version = Program.AssemblyVersion; labelTitle.Text = string.Format(Program.IsAfterUpgrade ? Localisable.NewsPopup_UpdatedTitle : Localisable.NewsPopup_FirstStartTitle, version.Major + "." + version.Minor + (version.Build > 0 ? "." + version.Build : string.Empty)); Settings.Default.SettingBinder.BindControl(checkBoxNeverShow, settings => settings.MiscFeedbackNagNeverShow, this); Settings.Default.SettingBinder.SendUpdates(this); } public static void ShowPopup(Form owner) { if (Settings.Default.MiscFeedbackNagNeverShow) return; using (var news = new NewsPopup()) { news.StartPosition = FormStartPosition.CenterParent; news.ShowDialog(owner); } } private void Close(object sender, EventArgs e) { Close(); } private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { MainWindow.OpenUrls(new[] { new Uri(Resources.GithubReleasesLink) }); } private void linkLabel5_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { MessageBoxes.DisplayHelp(); } private void linkLabel6_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { FeedbackBox.ShowFeedbackBox(this, false); } private void linkLabel2_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { MainWindow.OpenUrls(new[] { new Uri(Resources.GithubLink) }); } private void linkLabel3_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { MessageBoxes.DisplayLicense(); } private void linkLabel4_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { MessageBoxes.DisplayPrivacyPolicy(); } private void linkLabel7_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { MainWindow.OpenUrls(new[] { new Uri(Resources.DonateLink) }); } } } ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/NewsPopup.cs.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Nikdy nezobrazovat toto okno znovu ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/NewsPopup.de.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Um den Dialog zu schließen, klicke in diesem Fenster irgendwo hin Spende (PayPal, Bitcoin, Steam Geschenke) Sende Feedback / Kontakt zum Entwickler Hilfe lesen Datenschutzrichtlinie Lizenzbestimmungen Zeige oder ändere den Source Code Versionshinweise und Änderungen Spenden helfen bei der Weiterentwicklung dieses Projektes wie z.B. Zertifikate, Hosting und andere Keinigkeiten Niemals mehr dieses Fenster zeigen ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/NewsPopup.es.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 (Clic en cualquier lugar para cerrar este cuadro de diálogo) Donar en (PayPal, Bitcoin, Steam gifts) Enviar comentarios/contactar al desarrollador Leer el archivo de ayuda Leer la política de privacidad Leer la licencia Ver el código fuente o contribuir Ver notas de la versión y registro de cambios Las donaciones ayudan a mantenerme interesado en este proyecto, así como a pagar certificados de firma de código, hosting y otras necesidades. No volver a mostrar esta ventana ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/NewsPopup.fr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 (Cliquez n'importe où pour fermer cette fenêtre) Donner (Paypal, Bitcoin, cadeaux Steam) Envoyez un retour / Contacter le développeur Lire le fichier d'aide Lire la politique de confidentialité Lire la licence Voir le code source ou contribuer Voir les notes de mise à jour et le journal de modifications Les dons me permettent de rester intéressé par ce projet et de financer les certificats de signature de code, l'hébergement et autres dépenses nécessaires. Ne plus jamais montrer cette fenêtre. ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/NewsPopup.hu.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Ne jelenjen meg ez az oldal többé Adományok segítségével tudom fenntartani érdeklődésemet a projekt iránt, valamint fedezni tudom a kódaláírási tanúsítványokat, a tárhelyszolgáltatásokat és egyéb szükséges költségeket. Kiadási megjegyzések és változásnapló megtekintése Forráskód megtekintése és közreműködés Licensz elolvasása Adatvédelmi nyilatkozat elolvasása Sugófájl elolvasása Visszajelzés küldése / Kapcsolatfelvétel a fejlesztővel Adományozás (PayPal, Bitcoin, Steam Ajándékkártyák) (Kattintson bárhová az ablak bezárásához) ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/NewsPopup.it.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 (per chiudere questo messaggio fai clic in qualunque punto) Dona (via PayPal, Bitcoin, Steam gift) Invia feedback/contatta lo sviluppatore Consulta il file della guida in linea Leggi la politica della privacy Leggi la licenza visualizza il codice sorgente o contribuisci Leggi le note della versione e i cambiamenti Le donazioni aiutano a finanziare il progetto e a pagare i certificati per la firma del codice sorgente, l'hosting e altre necessità. Non visualizzare più questa finestra ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/NewsPopup.ja.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 寄付はこのプロジェクトへの関心を保ち、コード署名証明書、ホスティング、その他の必要経費を賄うのに役立ちます。 リリースノートと変更履歴を見る ソースコードを閲覧または貢献する ライセンスを読む プライバシーポリシーを読む ヘルプファイルを読む フィードバックを送信 / 開発者に連絡 寄付する(PayPal、Bitcoin、Steamギフト) (このダイアログを閉じるには、画面のどこかをクリックしてください) このウィンドウを二度と表示しない ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/NewsPopup.nl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Donaties helpen mij om mijn interesse te bewaren in dit project. Evenals betalingen voor code ondertekening van certificaten, hosting en andere benodigdheden. Bekijk de release notities en het wijzigingen logboek Bekijk de broncode of draag daaraan bij Lees de licentie Lees de privacyverklaring Lees het helpbestand Stuur feedback / Neem contact op met de ontwikkelaar Doneer (PayPal, Bitcoin, Steam giften) (Klik ergens om dit dialoogvenster te sluiten) Toon dit venster nooit meer ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/NewsPopup.pl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 (Kliknij w dowolnym miejscu aby zamknąć to okno) Darowizna (PayPal, Bitcoin, prezenty Steam) Wyślij Feedback / Kontakt z deweloperem Przeczytaj plik pomocy Przeczytaj politykę prywatności Przeczytaj licencje Sprawdź kod źródłowy Zobacz informacje o wersji i dziennik zmian Darowizny pomagają mi zainteresować się tym projektem, a także płacić za certyfikaty podpisywania kodu, hosting i inne potrzebne rzeczy. Nigdy nie pokazuj ponownie tego okna ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/NewsPopup.pt-br.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Nunca mais mostrar esta janela. Doações me ajudam a manter interesse nesse projeto e também por assinatura de certificados para o código, hospedagem e outras necessidades. Ver notas de lançamento e registro de alterações Ver o código-fonte ou contribuir Ler a licença Ler política de privacidade Ler arquivo de ajuda Enviar feedback / Contatar o desenvolvedor Doar (Paypal, Bitcoin, Steam gifts) (Clique em qualquer lugar para fechar o diálogo) ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/NewsPopup.pt.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Nunca mais mostrar esta janela. ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/NewsPopup.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 True Top Microsoft Sans Serif, 18pt, style=Bold 7, 7 4, 0, 4, 0 572, 0 0, 35 0, 0, 0, 23 0, 52 0 TopCenter labelTitle System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 9 True Top Microsoft Sans Serif, 8.25pt 7, 282 4, 0, 4, 0 572, 0 7, 0, 0, 23 541, 49 3 Donations help keep me interested in this project, as well as pay for code signing certificates, hosting, and other necessities. label3 System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 1 True Top Microsoft Sans Serif, 9.75pt, style=Bold 7, 59 4, 0, 4, 0 7, 0, 0, 12 253, 28 4 View release notes and changelog linkLabel1 System.Windows.Forms.LinkLabel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 8 True Top Microsoft Sans Serif, 9.75pt NoControl 7, 154 4, 0, 4, 0 7, 0, 0, 23 218, 39 5 View the source code or contribute linkLabel2 System.Windows.Forms.LinkLabel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 5 True Top Microsoft Sans Serif, 9.75pt NoControl 7, 193 4, 0, 4, 0 7, 0, 0, 12 115, 28 6 Read the licence linkLabel3 System.Windows.Forms.LinkLabel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 4 True Top Microsoft Sans Serif, 9.75pt NoControl 7, 221 4, 0, 4, 0 7, 0, 0, 23 155, 39 7 Read the privacy policy linkLabel4 System.Windows.Forms.LinkLabel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 3 True Top Microsoft Sans Serif, 9.75pt, style=Bold NoControl 7, 87 4, 0, 4, 0 7, 0, 0, 23 136, 39 8 Read the help file linkLabel5 System.Windows.Forms.LinkLabel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 7 True Top Microsoft Sans Serif, 9.75pt NoControl 7, 126 4, 0, 4, 0 7, 0, 0, 12 247, 28 9 Send feedback / Contact the developer linkLabel6 System.Windows.Forms.LinkLabel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 6 True Top Microsoft Sans Serif, 9.75pt, style=Bold NoControl 7, 260 4, 0, 4, 0 7, 0, 0, 6 268, 22 10 Donate (PayPal, Bitcoin, Steam gifts) linkLabel7 System.Windows.Forms.LinkLabel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 2 True Top Microsoft Sans Serif, 9.75pt NoControl 4, 0 4, 0, 4, 0 572, 0 7, 2, 0, 0 226, 18 11 (Click anywhere to close this dialog) label1 System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tableLayoutPanel1 0 True Right 383, 3 4, 3, 4, 3 187, 19 12 Never show this window again checkBoxNeverShow System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tableLayoutPanel1 1 True Top 7, 331 574, 25 0 tableLayoutPanel1 System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 0 <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="label1" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="checkBoxNeverShow" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /></Controls><Columns Styles="AutoSize,0,AutoSize,0" /><Rows Styles="AutoSize,0" /></TableLayoutSettings> True 7, 15 True GrowAndShrink 588, 464 4, 3, 4, 3 604, 102557 604, 39 7, 7, 7, 20 NewsPopup System.Windows.Forms.Form, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/NewsPopup.ru.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Никогда не показывать это окно снова Пожертвования позволяют мне не терять интерес к этому проекту, а также — оплачивать подписные сертификаты кода, хостинг и другую важную деятельность. Посмотреть примечания к релизу и историю изменений Посмотреть исходный код или внести свой вклад Лицензию Политика конфиденциальности Справка Отправить отзыв / Связаться с разработчиком Пожертвовать (PayPal, Bitcoin, Steam gifts) (Кликните в любом месте, чтобы закрыть) ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/NewsPopup.sl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 (Kliknite kjerkoli, da zaprete to pogovorno okno) Darujte (PayPal, Bitcoin, darila Steam) Pošljite povratne informacije/obrnite se na razvijalca Preberite datoteko pomoči Preberite pravilnik o zasebnosti Preberite licenco Ogled izvorne kodo ali prispevkov Ogled opomb o izdaji in dnevnika sprememb Darila mi pomagajo, da ohranim zanimanje za ta projekt, pa tudi kot plačailo potrebnih digitalnih potrdil kode, gostovanja in drugih potreb. Tega okna ne prikazuj nikoli več ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/NewsPopup.sv.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Donationer hjälper mig att fortsätta intressera mig för detta projekt, samt att betala för kodsigneringscertifikat, webbhotell och andra nödvändigheter. Visa versionsnoteringar och ändringslogg Visa källkoden eller bidra Läs licensen Läs integritetspolicyn Läs hjälpfilen Skicka feedback / Kontakta utvecklaren Donera (PayPal, Bitcoin, Steam gifts) (Klicka var som helst för att stänga denna dialog) Visa aldrig detta fönstret igen ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/NewsPopup.tr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 (Bu iletişim kutusunu kapatmak için herhangi bir yere tıklayın) Bağış (PayPal, Bitcoin, Steam hediyeleri) Geri bildirim gönder / Geliştiriciye başvurun Yardım dosyasını okuyun Gizlilik politikasını okuyun Lisansı oku Kaynak kodunu görüntüleyin veya katkıda bulunun Sürüm notlarını ve changelog'u görüntüle Bağışlar, bu projeyle ilgilenmeme yardımcı olurken, kod imzalama sertifikaları, barındırma ve diğer gereksinimler için de ödeme yapmanıza yardımcı olur. Bu pencereyi bir daha asla gösterme ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/NewsPopup.vi.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Các khoản tài trợ giúp tôi duy trì sự hứng thú với dự án này, đồng thời cũng để thanh toán chi phí cho chứng chỉ ký code, lưu trữ và các nhu cầu cần thiết khác. Xem các bản ghi chú phát hành và nhật ký thay đổi Xem mã nguồn hoặc đóng góp Đọc giấy phép Đọc chính sách bảo mật Đọc tệp tin trợ giúp Gửi phản hồi / Liên hệ với nhà phát triển Quyên góp (PayPal, Bitcoin, Steam gifts) (Nhấp chuột vào bất cứ đâu để đóng hộp thoại này) Không bao giờ hiển thị lại cửa sổ này nữa ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/NewsPopup.zh-Hans.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 捐款帮助我保持对这个项目的兴趣,以及支付代码签名证书,托管和其他必需的费用。 查看发行说明和更新日志 查看源代码或贡献 查看许可证 查看隐私政策 查看帮助文件 发送反馈/联系开发者 捐款(PayPal,Bitcoin,Steam礼物) (单击任意位置关闭此对话框) 不再显示此窗口 ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/NewsPopup.zh-Hant.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 捐款幫助我保持對這個項目的興趣,以及支付程式碼簽名證書,主機和其他必需的費用。 查看發行說明和更新日誌 查看程式碼或貢獻 查看許可證 查看隱私政策 查看幫助文件 傳送回饋/聯絡開發者 捐款(PayPal,BitCoin,Steam 禮物) (點擊任何位置關閉此視窗 不再顯示此視窗 ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/PropertiesWindow.Designer.cs ================================================ using System.ComponentModel; using System.Windows.Forms; namespace BulkCrapUninstaller.Forms { partial class PropertiesWindow { /// /// Required designer variable. /// private IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { components = new Container(); ComponentResourceManager resources = new ComponentResourceManager(typeof(PropertiesWindow)); contextMenuStrip1 = new ContextMenuStrip(components); copyToClipboardToolStripMenuItem = new ToolStripMenuItem(); saveToFileToolStripMenuItem = new ToolStripMenuItem(); saveFileDialog1 = new SaveFileDialog(); tabControl1 = new TabControl(); tabPage1 = new TabPage(); tabPage2 = new TabPage(); dataGridView1 = new DataGridView(); tabControl2 = new TabControl(); tabPageOverview = new TabPage(); tabPageFileInfo = new TabPage(); tabPageRegistry = new TabPage(); tabPageCertificate = new TabPage(); contextMenuStrip1.SuspendLayout(); tabControl1.SuspendLayout(); ((ISupportInitialize)dataGridView1).BeginInit(); tabControl2.SuspendLayout(); SuspendLayout(); // // contextMenuStrip1 // contextMenuStrip1.Items.AddRange(new ToolStripItem[] { copyToClipboardToolStripMenuItem, saveToFileToolStripMenuItem }); contextMenuStrip1.Name = "contextMenuStrip1"; resources.ApplyResources(contextMenuStrip1, "contextMenuStrip1"); contextMenuStrip1.Opening += contextMenuStrip1_Opening; // // copyToClipboardToolStripMenuItem // copyToClipboardToolStripMenuItem.Image = Properties.Resources.pagecopy; copyToClipboardToolStripMenuItem.Name = "copyToClipboardToolStripMenuItem"; resources.ApplyResources(copyToClipboardToolStripMenuItem, "copyToClipboardToolStripMenuItem"); copyToClipboardToolStripMenuItem.Click += copyToClipboardToolStripMenuItem_Click; // // saveToFileToolStripMenuItem // saveToFileToolStripMenuItem.Image = Properties.Resources.save; saveToFileToolStripMenuItem.Name = "saveToFileToolStripMenuItem"; resources.ApplyResources(saveToFileToolStripMenuItem, "saveToFileToolStripMenuItem"); saveToFileToolStripMenuItem.Click += saveToFileToolStripMenuItem_Click; // // saveFileDialog1 // saveFileDialog1.DefaultExt = "txt"; resources.ApplyResources(saveFileDialog1, "saveFileDialog1"); saveFileDialog1.FileOk += saveFileDialog1_FileOk; // // tabControl1 // tabControl1.Controls.Add(tabPage1); tabControl1.Controls.Add(tabPage2); resources.ApplyResources(tabControl1, "tabControl1"); tabControl1.Name = "tabControl1"; tabControl1.SelectedIndex = 0; tabControl1.SelectedIndexChanged += OnSelectedTabChanged; // // tabPage1 // resources.ApplyResources(tabPage1, "tabPage1"); tabPage1.Name = "tabPage1"; tabPage1.UseVisualStyleBackColor = true; // // tabPage2 // resources.ApplyResources(tabPage2, "tabPage2"); tabPage2.Name = "tabPage2"; tabPage2.UseVisualStyleBackColor = true; // // dataGridView1 // dataGridView1.AllowUserToAddRows = false; dataGridView1.AllowUserToDeleteRows = false; dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill; dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells; dataGridView1.BorderStyle = BorderStyle.Fixed3D; dataGridView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize; dataGridView1.ContextMenuStrip = contextMenuStrip1; resources.ApplyResources(dataGridView1, "dataGridView1"); dataGridView1.Name = "dataGridView1"; dataGridView1.ReadOnly = true; dataGridView1.RowHeadersVisible = false; dataGridView1.ShowEditingIcon = false; dataGridView1.KeyUp += dataGridView1_KeyUp; // // tabControl2 // tabControl2.Controls.Add(tabPageOverview); tabControl2.Controls.Add(tabPageFileInfo); tabControl2.Controls.Add(tabPageRegistry); tabControl2.Controls.Add(tabPageCertificate); resources.ApplyResources(tabControl2, "tabControl2"); tabControl2.Name = "tabControl2"; tabControl2.SelectedIndex = 0; tabControl2.SelectedIndexChanged += OnSelectedTabChanged; // // tabPageOverview // resources.ApplyResources(tabPageOverview, "tabPageOverview"); tabPageOverview.Name = "tabPageOverview"; tabPageOverview.UseVisualStyleBackColor = true; // // tabPageFileInfo // resources.ApplyResources(tabPageFileInfo, "tabPageFileInfo"); tabPageFileInfo.Name = "tabPageFileInfo"; tabPageFileInfo.UseVisualStyleBackColor = true; // // tabPageRegistry // resources.ApplyResources(tabPageRegistry, "tabPageRegistry"); tabPageRegistry.Name = "tabPageRegistry"; tabPageRegistry.UseVisualStyleBackColor = true; // // tabPageCertificate // resources.ApplyResources(tabPageCertificate, "tabPageCertificate"); tabPageCertificate.Name = "tabPageCertificate"; tabPageCertificate.UseVisualStyleBackColor = true; // // PropertiesWindow // resources.ApplyResources(this, "$this"); AutoScaleMode = AutoScaleMode.Font; Controls.Add(dataGridView1); Controls.Add(tabControl2); Controls.Add(tabControl1); KeyPreview = true; Name = "PropertiesWindow"; KeyDown += PropertiesWindow_KeyDown; contextMenuStrip1.ResumeLayout(false); tabControl1.ResumeLayout(false); ((ISupportInitialize)dataGridView1).EndInit(); tabControl2.ResumeLayout(false); ResumeLayout(false); } #endregion private ContextMenuStrip contextMenuStrip1; private ToolStripMenuItem copyToClipboardToolStripMenuItem; private ToolStripMenuItem saveToFileToolStripMenuItem; private SaveFileDialog saveFileDialog1; private TabControl tabControl1; private TabPage tabPage1; private TabPage tabPage2; private DataGridView dataGridView1; private TabControl tabControl2; private TabPage tabPageOverview; private TabPage tabPageFileInfo; private TabPage tabPageRegistry; private TabPage tabPageCertificate; } } ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/PropertiesWindow.ar.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 نسخ الى الحافظة حفظ الى ملف... Text files|*.txt keep the |*.txt حفظ البيانات الى ملف نظرة عامة معلومات الغاء التثبيت مكتب التسجيل شهادة الخصائص ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/PropertiesWindow.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.IO; using System.Linq; using System.Windows.Forms; using BulkCrapUninstaller.Functions; using BulkCrapUninstaller.Properties; using Klocman.Extensions; using Klocman.Forms.Tools; using UninstallTools; namespace BulkCrapUninstaller.Forms { sealed partial class PropertiesWindow : Form { private readonly string _titleBeginning; public PropertiesWindow() { InitializeComponent(); Icon = Resources.Icon_Logo; _titleBeginning = Text; } private InfoType CurrentlyVisiblePage { get { switch (tabControl2.SelectedIndex) { case 0: return InfoType.Overview; case 1: return InfoType.FileInfo; case 2: return InfoType.Registry; case 3: return InfoType.Certificate; default: return InfoType.Invalid; } } } public void ShowPropertiesDialog(IEnumerable targets) { var applicationUninstallerEntries = targets as IList ?? targets.ToList(); if (applicationUninstallerEntries.Count <= 0) return; UseWaitCursor = true; tabControl1.Visible = applicationUninstallerEntries.Count > 1; tabControl1.TabPages.Clear(); applicationUninstallerEntries.OrderBy(x => x.DisplayName) .ForEach(x => tabControl1.TabPages.Add(new TabPage(x.DisplayName) {Tag = x})); OnSelectedTabChanged(this, EventArgs.Empty); StartPosition = FormStartPosition.CenterParent; ShowDialog(); } private void contextMenuStrip1_Opening(object sender, CancelEventArgs e) { if (dataGridView1.SelectedCells.Count < 0) e.Cancel = true; } private void copyToClipboardToolStripMenuItem_Click(object sender, EventArgs e) { try { var content = dataGridView1.GetClipboardContent(); if (content != null) Clipboard.SetDataObject(content, true); } catch (Exception ex) { PremadeDialogs.GenericError(ex); } } private void dataGridView1_KeyUp(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.Apps) { if (dataGridView1.SelectedCells.Count > 0) contextMenuStrip1.Show(dataGridView1.PointToScreen(Point.Empty)); e.Handled = true; } } private void OnSelectedTabChanged(object sender, EventArgs e) { if (tabControl1.SelectedTab == null) return; UseWaitCursor = true; Application.DoEvents(); dataGridView1.DataSource = AppPropertiesGatherer.GetInfo(tabControl1.SelectedTab.Tag as ApplicationUninstallerEntry, CurrentlyVisiblePage); // Make first column shorter, since it contains much less text. Default FillWeight is around 34 var firstColumn = dataGridView1.Columns.GetFirstColumn(new DataGridViewElementStates()); if (firstColumn != null) { firstColumn.FillWeight = 35f; dataGridView1.Sort(firstColumn, ListSortDirection.Ascending); } Text = _titleBeginning + tabControl1.SelectedTab.Text; UseWaitCursor = false; } private void PropertiesWindow_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.Escape) { if (contextMenuStrip1.Visible) contextMenuStrip1.Hide(); else Hide(); e.Handled = true; } } private void saveFileDialog1_FileOk(object sender, CancelEventArgs e) { var content = dataGridView1.GetClipboardContent(); if (content != null) { try { File.WriteAllText(saveFileDialog1.FileName, content.GetText()); } catch (Exception ex) { MessageBoxes.ExportFailed(ex.Message, this); } } } private void saveToFileToolStripMenuItem_Click(object sender, EventArgs e) { saveFileDialog1.ShowDialog(); } } } ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/PropertiesWindow.cs.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Zkopírovat do schránky Uložit do souboru ... Textové soubory|*.txt keep the |*.txt Uložit data do souboru Přehled Informace o odinstalátoru Registry Certifikát Vlastnosti 17, 17 162, 17 True ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/PropertiesWindow.de.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 In die Zwischenablage kopieren Datei speichern... Textdateien|*.txt keep the |*.txt Daten in Datei speichern Übersicht Uninstaller Information Zertifikat Eigenschaften Registry ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/PropertiesWindow.es.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Copiar al portapapeles Guardar al archivo... Archivos de texto|*.txt keep the |*.txt Guardar información al archivo Información del desinstalador Registro Certificados Propiedades Visión general ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/PropertiesWindow.fr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Copier dans le presse-papiers Sauver dans un fichier... Fichiers texte|*.txt keep the |*.txt Sauver les données dans un fichier Aperçu Information du désinstalleur Registre Certificat Propriétés ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/PropertiesWindow.hu.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Másolás a Vágólapra Mentés fájlba... Szövegfájlok|*.txt keep the |*.txt Adatmentés egy fájlba Áttekintés Eltávolítási információ Beállításjegyzék Tanúsítvány Tulajdonságok ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/PropertiesWindow.it.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Copia negli Appunti Salva nel file... File testo|*.txt keep the |*.txt Salva informazioni in un file Panoramica Informazioni sul disinstallatore Registro Certificato Proprietà ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/PropertiesWindow.ja.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 クリップボードにコピー ファイルに保存... テキストファイル|*.txt keep the |*.txt データをファイルに保存 概要 アンインストーラー情報 レジストリ 証明書 プロパティ ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/PropertiesWindow.nl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Kopieer naar klembord Bestand opslaan... Tekst bestanden|*.txt keep the |*.txt Gegevens in een bestand opslaan Overzicht De-installer informatie Register Certificaat Eigenschappen ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/PropertiesWindow.pl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Kopiuj do schowka Zapisz do pliku... Ogólne Informacje o dezinstalatorze Rejestr Właściwości Pliki tekstowe|*.txt keep the |*.txt Zapisz dane do pliku Certyfikat ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/PropertiesWindow.pt-BR.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Copiar para a Área de Transferência Salvar num Arquivo... Arquivos texto|*.txt keep the |*.txt Salvar dados no arquivo Visão geral Informação do desinstalador Registro Certificado Propriedades ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/PropertiesWindow.pt.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Copiar para a Área de Transferência Salvar num ficheiro... Ficheiros de texto|*.txt keep the |*.txt Salvar os dados num ficheiro Visão geral Informação do desinstalador Registo Certificado Propriedades 17, 17 162, 17 True ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/PropertiesWindow.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 17, 17 169, 22 Copy to clipboard 169, 22 Save to file... 170, 48 contextMenuStrip1 System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 162, 17 Text files|*.txt Save data to file 4, 24 4, 3, 4, 3 4, 3, 4, 3 683, 0 0 tabPage1 System.Windows.Forms.TabPage, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tabControl1 0 4, 24 4, 3, 4, 3 4, 3, 4, 3 683, 0 1 tabPage2 System.Windows.Forms.TabPage, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tabControl1 1 Top 0, 0 4, 3, 4, 3 1166667, 28 0, 24 691, 24 1 tabControl1 System.Windows.Forms.TabControl, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 3 Fill 0, 52 4, 3, 4, 3 691, 377 0 dataGridView1 System.Windows.Forms.DataGridView, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 1 4, 24 4, 3, 4, 3 683, 0 0 Overview tabPageOverview System.Windows.Forms.TabPage, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tabControl2 0 4, 24 4, 3, 4, 3 683, 0 1 Uninstaller information tabPageFileInfo System.Windows.Forms.TabPage, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tabControl2 1 4, 24 4, 3, 4, 3 683, 0 2 Registry tabPageRegistry System.Windows.Forms.TabPage, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tabControl2 2 4, 24 4, 3, 4, 3 683, 0 3 Certificate tabPageCertificate System.Windows.Forms.TabPage, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tabControl2 3 Top 0, 24 4, 3, 4, 3 1166667, 28 0, 28 691, 28 2 tabControl2 System.Windows.Forms.TabControl, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 2 True 7, 15 691, 429 4, 3, 4, 3 Properties copyToClipboardToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 saveToFileToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 saveFileDialog1 System.Windows.Forms.SaveFileDialog, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 PropertiesWindow System.Windows.Forms.Form, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/PropertiesWindow.ru.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Копировать в буфер Сохранить в файл... Текстовый|*.txt keep the |*.txt Сохранить данные в файл Обзор Информация о деинсталляторе Реестр Сертификат Свойства 17, 17 162, 17 True ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/PropertiesWindow.sl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Kopiraj v odložišče Shrani v datoteko... Besedilne datoteke|*.txt keep the |*.txt Shrani podatke v datoteko Pregled Informacije odstranjevalca Register Digitalno potrdilo Lastnosti 17, 17 162, 17 True ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/PropertiesWindow.sv.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Kopiera till urklipp Spara till fil... Text filer|*.txt keep the |*.txt Spara data till fil Översikt Avinstallationsinformation Register Certifikat Egenskaper ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/PropertiesWindow.tr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Panoya kopyala Dosya olarak kaydet... Text dosyası|*.txt keep the |*.txt Verileri dosyaya kaydet Genel bakış Kaldırıcı bilgisi Kayıt defteri Sertifika Özellikler ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/PropertiesWindow.vi.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Sao chép vào bảng nhớ tạm Lưu vào tệp tin... Tệp văn bản|*.txt keep the |*.txt Lưu dữ liệu vào tệp tin... Tổng quan Thông tin trình gỡ cài đặt Registry Giấy chứng chỉ Thông tin chi tiết ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/PropertiesWindow.zh-Hans.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 复制到剪贴板 保存到文件... 文本文件|*.txt keep the |*.txt 保存数据到文件 概述 卸载程序信息 注册表 证书 属性 ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/PropertiesWindow.zh-Hant.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 複製到剪貼簿 儲存到文件... 文字文件|*.txt keep the |*.txt 儲存資料到文件 概述 移除程式資訊 登錄表 憑證 內容 ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/RatingPopup.Designer.cs ================================================ namespace BulkCrapUninstaller.Forms { partial class RatingPopup { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(RatingPopup)); buttonGood = new System.Windows.Forms.Button(); buttonBad = new System.Windows.Forms.Button(); buttonCancel = new System.Windows.Forms.Button(); groupBox1 = new System.Windows.Forms.GroupBox(); buttonNormal = new System.Windows.Forms.Button(); panel1 = new System.Windows.Forms.Panel(); groupBox1.SuspendLayout(); panel1.SuspendLayout(); SuspendLayout(); // // buttonGood // buttonGood.BackColor = System.Drawing.Color.FromArgb(192, 255, 192); resources.ApplyResources(buttonGood, "buttonGood"); buttonGood.ForeColor = System.Drawing.Color.Black; buttonGood.Name = "buttonGood"; buttonGood.UseVisualStyleBackColor = false; buttonGood.Click += buttonGood_Click; // // buttonBad // buttonBad.BackColor = System.Drawing.Color.FromArgb(255, 192, 192); resources.ApplyResources(buttonBad, "buttonBad"); buttonBad.ForeColor = System.Drawing.Color.Black; buttonBad.Name = "buttonBad"; buttonBad.UseVisualStyleBackColor = false; buttonBad.Click += buttonBad_Click; // // buttonCancel // resources.ApplyResources(buttonCancel, "buttonCancel"); buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; buttonCancel.Name = "buttonCancel"; buttonCancel.UseVisualStyleBackColor = true; // // groupBox1 // groupBox1.Controls.Add(buttonBad); groupBox1.Controls.Add(buttonNormal); groupBox1.Controls.Add(buttonGood); resources.ApplyResources(groupBox1, "groupBox1"); groupBox1.Name = "groupBox1"; groupBox1.TabStop = false; // // buttonNormal // buttonNormal.BackColor = System.Drawing.Color.FromArgb(255, 255, 192); resources.ApplyResources(buttonNormal, "buttonNormal"); buttonNormal.ForeColor = System.Drawing.Color.Black; buttonNormal.Name = "buttonNormal"; buttonNormal.UseVisualStyleBackColor = false; buttonNormal.Click += buttonNormal_Click; // // panel1 // panel1.Controls.Add(buttonCancel); resources.ApplyResources(panel1, "panel1"); panel1.Name = "panel1"; // // RatingPopup // resources.ApplyResources(this, "$this"); AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; CancelButton = buttonCancel; Controls.Add(groupBox1); Controls.Add(panel1); FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; Name = "RatingPopup"; ShowIcon = false; ShowInTaskbar = false; groupBox1.ResumeLayout(false); panel1.ResumeLayout(false); ResumeLayout(false); } #endregion private System.Windows.Forms.Button buttonGood; private System.Windows.Forms.Button buttonBad; private System.Windows.Forms.Button buttonCancel; private System.Windows.Forms.GroupBox groupBox1; private System.Windows.Forms.Button buttonNormal; private System.Windows.Forms.Panel panel1; } } ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/RatingPopup.ar.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 الغاء الامر مفيده | نوعيه جيده مشكوك فيها | نوعيه سيئه معدل خردة | يحتمل ان تكون خطره مشاركه تقييمك مع مستخدمين اخرين ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/RatingPopup.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Drawing; using System.Windows.Forms; using BulkCrapUninstaller.Functions.Ratings; namespace BulkCrapUninstaller.Forms { public partial class RatingPopup : Form { private UninstallerRating _result = UninstallerRating.Unknown; private RatingPopup() { InitializeComponent(); } public static UninstallerRating ShowRateDialog(Form owner, string applicationName) { return ShowRateDialog(owner, applicationName, Point.Empty); } public static UninstallerRating ShowRateDialog(Form owner, string applicationName, Point mouseLocation) { if (owner == null) throw new ArgumentNullException(nameof(owner)); using (var window = new RatingPopup()) { window.Text += " " + applicationName; window.Icon = owner.Icon; if (mouseLocation.IsEmpty) window.StartPosition = FormStartPosition.CenterParent; else window.Location = new Point(mouseLocation.X - window.Size.Width/2, mouseLocation.Y - window.Size.Height/2); window.ShowDialog(owner); return window._result; } } private void buttonGood_Click(object sender, EventArgs e) { _result = UninstallerRating.Good; Close(); } private void buttonNormal_Click(object sender, EventArgs e) { _result = UninstallerRating.Neutral; Close(); } private void buttonBad_Click(object sender, EventArgs e) { _result = UninstallerRating.Bad; Close(); } } } ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/RatingPopup.cs.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Užitečné | Dobrá jakost Nevyžádané | Potenciálně nebezpečný Zrušit Sporná | Špatná kvalita Podělte se o své hodnocení Hodnotit True ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/RatingPopup.de.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Nützliche | Gute Qualität Junk | Potentiell gefährliche Abbrechen Fragwürdige | Schlechte Qualität Sagen Sie Ihre Bewertung Rezension True ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/RatingPopup.es.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Cancelar Útil | Buena calidad Cuestionable | Mala calidad Calificar Compartir calificaciones con otros usuarios Basura | Potencialmente peligroso ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/RatingPopup.fr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Utile | Bonne qualité Déchet | Potentiellement dangereux Annuler Douteux | Mauvaise qualité Partager votre note avec d'autres utilisateurs Noter True ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/RatingPopup.hu.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Mégse Hasznos | Jó minőségű Kétes | Rossz minőségű Minősítés Felesleges | Potenciálisan veszélyes Értékelés megosztása más felhasználókkal ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/RatingPopup.it.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Annulla Utile | Buona qualità Discutibile | Cattiva qualità Valutazione Residuo | Potenzialmente dannoso Condividi la tua valutazione con altri utenti ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/RatingPopup.ja.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 キャンセル 役立つ | 良質 微妙 | 悪質 評価 ゴミ | 潜在的に危険 他のユーザーと評価を共有 ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/RatingPopup.nl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Annuleren Bruikbaar | Goede kwaliteit Twijfelachtig | Slechte kwaliteit Waardering Rommel | Potentieel gevaarlijk Deel uw waardering met andere gebruikers ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/RatingPopup.pl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Przydatny | Dobrej jakości Śmieć | Potencjalnie niebezpieczny Anuluj Wątpliwy | Kiepskiej jakości Podziel się swoją oceną Oceń ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/RatingPopup.pt-BR.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Cancelar Útil | Boa qualidade Duvidoso | Má qualidade Classificar Lixo | Potencialmente perigoso Compartilhe sua classificação com outros usuários ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/RatingPopup.pt.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Cancelar Útil | Boa qualidade Duvidoso | Má qualidade Classificar Lixo | Potentialmente perigosos Partilhe a sua classificação com outros utilizadores True ru ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/RatingPopup.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Top 9, 25 4, 3, 4, 3 272, 30 0 Useful | Good quality buttonGood System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBox1 2 Top 9, 85 4, 3, 4, 3 272, 30 2 Junk | Potentially dangerous buttonBad System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBox1 0 Bottom, Right 196, 7 4, 3, 4, 3 88, 27 0 Cancel buttonCancel System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel1 0 Top 9, 55 4, 3, 4, 3 272, 30 1 Questionable | Bad quality buttonNormal System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBox1 1 Fill 9, 9 4, 3, 4, 3 9, 9, 9, 9 290, 124 0 Share your rating with other users groupBox1 System.Windows.Forms.GroupBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 0 Bottom 9, 133 4, 3, 4, 3 290, 33 1 panel1 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 1 True 7, 15 308, 175 5, 3, 5, 3 9, 9, 9, 9 Manual Rate RatingPopup System.Windows.Forms.Form, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/RatingPopup.ru.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 9, 25 4, 3, 4, 3 272, 30 Полезное | Хорошее качество 9, 85 4, 3, 4, 3 272, 30 Мусорное | Потенциально опасное 196, 7 4, 3, 4, 3 88, 27 Отмена 9, 9 4, 3, 4, 3 9, 9, 9, 9 290, 124 Поделитесь своей оценкой с другими пользователями 9, 55 4, 3, 4, 3 272, 30 Сомнительное | Плохое качество 9, 133 4, 3, 4, 3 290, 33 7, 15 308, 175 4, 3, 4, 3 9, 9, 9, 9 Рейтинг ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/RatingPopup.sl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Prekliči Uporabna | Dobra kakovost Vprašljiva | Slaba kakovost Ocena Neuporabna | Potencialno nevarna Delite vaše ocene z drugimi uporabniki True pl ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/RatingPopup.sv.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Avbryt Användbar | God kvalitet Tveksam | Dålig kvalitet Betygsätt Skräp | Potentiellt farligt Dela din bedömning med andra användare ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/RatingPopup.tr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Vazgeç Faydalı | İyi kalite Şüpheli | Kötü kalite Oran Önemsiz | Potansiyel olarak tehlikeli Değerlendirmenizi diğer kullanıcılarla paylaşın ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/RatingPopup.vi.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Huỷ Hữu ích | Chất lượng tốt Có vấn đề | Chất lượng kém Đánh giá Rác | Nguy hiểm tiềm tàng Chia sẻ đánh giá của bạn với người dùng khác ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/RatingPopup.zh-Hans.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 取消 实用 | 好品质 有问题 | 坏品质 评分 垃圾 | 潜在危险 与其他用户分享评分 ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/RatingPopup.zh-Hant.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 取消 實用 | 好品質 有問題 | 壞品質 評分 垃圾 | 潛在危險 與其他使用者分享評分 ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/TargetWindow.Designer.cs ================================================ namespace BulkCrapUninstaller.Forms { partial class TargetWindow { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(TargetWindow)); groupBox1 = new System.Windows.Forms.GroupBox(); windowTargeter1 = new Klocman.Controls.WindowTargeter(); groupBox2 = new System.Windows.Forms.GroupBox(); fileTargeter1 = new BulkCrapUninstaller.Controls.FileTargeter(); flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); label1 = new System.Windows.Forms.Label(); flowLayoutPanel2 = new System.Windows.Forms.FlowLayoutPanel(); label2 = new System.Windows.Forms.Label(); panel1 = new System.Windows.Forms.Panel(); panel2 = new System.Windows.Forms.Panel(); groupBox1.SuspendLayout(); groupBox2.SuspendLayout(); flowLayoutPanel1.SuspendLayout(); flowLayoutPanel2.SuspendLayout(); SuspendLayout(); // // groupBox1 // resources.ApplyResources(groupBox1, "groupBox1"); groupBox1.Controls.Add(windowTargeter1); groupBox1.Name = "groupBox1"; groupBox1.TabStop = false; // // windowTargeter1 // resources.ApplyResources(windowTargeter1, "windowTargeter1"); windowTargeter1.Name = "windowTargeter1"; // // groupBox2 // groupBox2.Controls.Add(fileTargeter1); resources.ApplyResources(groupBox2, "groupBox2"); groupBox2.Name = "groupBox2"; groupBox2.TabStop = false; // // fileTargeter1 // fileTargeter1.AllowDrop = true; resources.ApplyResources(fileTargeter1, "fileTargeter1"); fileTargeter1.Name = "fileTargeter1"; // // flowLayoutPanel1 // resources.ApplyResources(flowLayoutPanel1, "flowLayoutPanel1"); flowLayoutPanel1.Controls.Add(label1); flowLayoutPanel1.Name = "flowLayoutPanel1"; // // label1 // resources.ApplyResources(label1, "label1"); label1.Name = "label1"; // // flowLayoutPanel2 // resources.ApplyResources(flowLayoutPanel2, "flowLayoutPanel2"); flowLayoutPanel2.Controls.Add(label2); flowLayoutPanel2.Name = "flowLayoutPanel2"; // // label2 // resources.ApplyResources(label2, "label2"); label2.Name = "label2"; // // panel1 // resources.ApplyResources(panel1, "panel1"); panel1.Name = "panel1"; // // panel2 // resources.ApplyResources(panel2, "panel2"); panel2.Name = "panel2"; // // TargetWindow // AllowDrop = true; resources.ApplyResources(this, "$this"); AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; Controls.Add(panel1); Controls.Add(flowLayoutPanel2); Controls.Add(groupBox2); Controls.Add(panel2); Controls.Add(groupBox1); Controls.Add(flowLayoutPanel1); FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; MaximizeBox = false; MinimizeBox = false; Name = "TargetWindow"; ShowIcon = false; ShowInTaskbar = false; SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; groupBox1.ResumeLayout(false); groupBox2.ResumeLayout(false); flowLayoutPanel1.ResumeLayout(false); flowLayoutPanel1.PerformLayout(); flowLayoutPanel2.ResumeLayout(false); flowLayoutPanel2.PerformLayout(); ResumeLayout(false); PerformLayout(); } #endregion private System.Windows.Forms.GroupBox groupBox1; private Klocman.Controls.WindowTargeter windowTargeter1; private System.Windows.Forms.GroupBox groupBox2; private Controls.FileTargeter fileTargeter1; private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1; private System.Windows.Forms.Label label1; private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel2; private System.Windows.Forms.Label label2; private System.Windows.Forms.Panel panel1; private System.Windows.Forms.Panel panel2; } } ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/TargetWindow.ar.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 البحث عن تطبيق والغاء تثبيته استنادا الى احد الاطارات الخاصة به او الاختصارات او موقع التثبيت او ملفات .تنفيذية. Target تطبيق تحديد باستخدام اطار تحديد استخدام مجلد التثبيت او ملفات البرنامج ملاحظه: تاكد من ان اي ملفات تقوم بتحديدها موجودة داخل دليل تثبيت التطبيق. يمكنك تحديد دليل يحتوي على تطبيقات متعددة لالغاء تثبيتها جميعا. ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/TargetWindow.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using BulkCrapUninstaller.Controls; using BulkCrapUninstaller.Properties; using Klocman.Extensions; using Klocman.Forms.Tools; using Klocman.Tools; using System; using System.Collections.Generic; using System.Drawing; using System.IO; using System.Linq; using System.Windows.Forms; namespace BulkCrapUninstaller.Forms { public partial class TargetWindow : Form { private Action _setMainWindowVisible; public event EventHandler DirectoriesSelected; public TargetWindow() { InitializeComponent(); fileTargeter1.DirectoriesSelected += DirectoryTargeterDirectoriesSelected; windowTargeter1.PickingStarted += WindowTargeter1OnPickingStarted; windowTargeter1.WindowSelected += WindowTargeterWindowSelected; } private void DirectoryTargeterDirectoriesSelected(object sender, DirectoriesSelectedEventArgs e) { if (e.SelectedFiles.Count == 0) { MessageBox.Show( Localisable.TargetWindow_NoFilesSelected_Message, Localisable.TargetWindow_NoFilesSelected_Title, MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } OnDirectoriesSelected(e); } protected virtual void OnDirectoriesSelected(DirectoriesSelectedEventArgs e) { DialogResult = DialogResult.OK; Close(); DirectoriesSelected?.Invoke(this, e); } private void WindowTargeter1OnPickingStarted(object sender, EventArgs e) { _setMainWindowVisible(false); } private void WindowTargeterWindowSelected(object sender, Klocman.Subsystems.WindowHoverEventArgs e) { _setMainWindowVisible(true); try { var fileName = e.TargetWindow.GetRunningProcess().MainModule?.FileName; if (fileName == null) throw new InvalidOperationException("Process has no MainModule"); var parentDirectory = new FileInfo(fileName).Directory; if (parentDirectory == null) throw new InvalidOperationException("Failed to get MainModule Directory"); // Ignore targeting BCU itself if (PathTools.SubPathIsInsideBasePath(Program.AssemblyLocation.FullName, fileName, true, true)) return; OnDirectoriesSelected(new DirectoriesSelectedEventArgs(parentDirectory.ToEnumerable().ToList())); } catch (Exception exception) { Console.WriteLine(exception); PremadeDialogs.GenericError(exception); } } public static ICollection ShowDialog(IWin32Window owner, Action setMainWindowVisible) { using (var window = new TargetWindow()) { window._setMainWindowVisible = setMainWindowVisible ?? throw new ArgumentNullException(nameof(setMainWindowVisible)); window.StartPosition = FormStartPosition.Manual; var targeterHalf = window.windowTargeter1.Height / 2; var offsetx = targeterHalf + 10; var offsety = targeterHalf + 30; window.Location = new Point(Cursor.Position.X - offsetx, Cursor.Position.Y - offsety); ICollection results = null; window.DirectoriesSelected += (sender, args) => results = args.SelectedFiles; if (window.ShowDialog() != DialogResult.OK) return null; return results; } } } } ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/TargetWindow.cs.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Najít a odstranit aplikace prostřednictvím údaj o jejich umístění, zástupci nebo jejím umístění nebo .exe soubory instalace. Target aplikace Vybrat okno Vyberte pomocí instalační složky nebo program files Poznámka: Ujistěte se, že vybrané soubory jsou uvnitř instalačního adresáře aplikace. ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/TargetWindow.de.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Wähle ein Fenster aus Wähle einen Installationsordner oder Programmdateien aus Finde und deinstalliere ein Programm auf Grund seiner Fenster, seiner Shortcuts, seines Installierungsordners oder seiner .exe Datei Bemerkung: Stelle sicher, dass sich alle ausgewählten Dateien im Installationsverzeichnis der Anwendung befinden. Du kannst ein Verzeichnis auswählen, das mehrere Anwendungen enthält, um alle zu deinstallieren. Beende ein Programm ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/TargetWindow.es.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Buscar y desinstalar una aplicación basada en una de sus ventanas, accesos directos, o su ubicación de instalación o archivos .exe. Destruir una aplicación Seleccionar usando una ventana Seleccionar mediante carpeta de instalación o archivos de programa Nota: Asegúrese de que los archivos que seleccione están dentro del directorio de instalación de la aplicación. Puede seleccionar un directorio que contenga varias aplicaciones para desinstalarlas todas. ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/TargetWindow.fr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Trouver et désinstaller une application sur la base d'une de ses fenêtres, raccourcis, son emplacement d'installation ou ses fichiers .exe. Sélectionner en utilisant une fenêtre Sélectionner en utilisant le dossier d'installation ou les fichiers de programmes Note : assurez-vous que tous les fichiers sélectionnés sont dans le dossier d'installation de l'application. Vous pouvez sélectionner un dossier qui contient de multiples applications pour les désinstaller toutes. Cibler une application ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/TargetWindow.hu.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Kiválasztás egy ablak segítségével Kiválasztás mappa vagy fájl segítségével Alkalmazások keresése és eltávolítása ablakok, parancsikonok, telepítési hely vagy .exe fájlok alapján. Megjegyzés: Győződjön meg róla, hogy a kiválasztott fájlok az alkalmazás telepítési mappájában vannak. Több alkalmazást tartalmazó mappát is kiválaszthat az összes mappában lévő alkalmazás eltávolításához. Alkalmazás kiválasztása ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/TargetWindow.it.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Seleziona usando una finestra Seleziona usando la cartella di installazione o del programma Cerca e disinstalla una applicazione basata su una delle sue finestre, collegamenti o la sua ubicazione di installazione o file .exe Nota: assicurati che tutti i file selezionati siano presenti nella cartella di installazione dell'applicazione. Puoi selezionare una cartella che contiene varie applicazioni per disinstallarle tutte. Obiettivo un'applicazione ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/TargetWindow.ja.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ウィンドウを使って選択 インストールフォルダーまたはプログラムファイルを使って選択 ウィンドウ、ショートカット、またはインストール場所や.exeファイルのいずれかに基づいてアプリケーションを見つけてアンインストールします。 注意: 選択するファイルがアプリケーションのインストールディレクトリ内にあることを確認してください。 複数のアプリケーションをアンインストールするために、複数のアプリケーションを含むディレクトリを選択することができます。 アプリケーションを対象にする ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/TargetWindow.nl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Zoek en de-installeer een programma op basis van een van zijn vensters, snelkoppelingen, of zijn installatie locatie of .exe bestand(en). Misleid een programma Selecteer door een venster te gebruiken Selecteer door gebruik te maken van de installatie map of programma bestanden Opm.: overtuig u er van dat de door u geselecteerde bestanden zich bevinden in de installatie map. U kunt een map selecteren die meerdere programma's bevat om deze te de-installeren. ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/TargetWindow.pl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Wybierz okno Wybierz miejsce zainstalowania lub pliki programu Znajdź i odinstaluj aplikacje poprzez wskazanie ich miejsca zainstalowania, skrótów, plików, lub otwartych okien. Uwaga: upewnij się że wybrane pliki znajdują się wewnątrz katalogu instalacyjnego aplikacji. Można wybrać katalog który zawiera wiele aplikacji aby je wszystkie odinstalować. Zniszcz aplikację ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/TargetWindow.pt-BR.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Selecione usando uma janela Pasta de instalação ou arquivos Encontre e desinstale um aplicativo com base em uma das suas janelas, atalhos, seu local instalação ou arquivos .exe. Nota: Certifique-se de que todos os arquivos selecionados estejam dentro do diretório de instalação do aplicativo. Você pode selecionar um diretório que contenha vários aplicativos para desinstalá-los todos de uma vez. Caçar aplicação ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/TargetWindow.pt.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Encontrar e desinstalar uma aplicação existente na base de uma das janelas, atalhos, o seu local de instalação ou arquivos .exe Destruir uma aplicação Seleccione usando uma janela Selecionar usando a pasta de instalação ou os arquivos de programa Nota: Certifique-se de que todos os arquivos seleccionados estão na pasta de instalação do aplicativo. Pode seleccionar uma pasta que contenha vários aplicativos para os desinstalar a todos. ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/TargetWindow.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 GrowAndShrink Top 4, 19 5, 3, 5, 3 11666666, 74 0, 74 354, 74 0 windowTargeter1 Klocman.Controls.WindowTargeter, KlocTools, Culture=neutral, PublicKeyToken=null groupBox1 0 Top 5, 40 4, 3, 4, 3 4, 3, 4, 3 362, 96 0 Select using a window groupBox1 System.Windows.Forms.GroupBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 4 Fill 4, 19 5, 3, 5, 3 2, 2, 2, 2 354, 63 0 fileTargeter1 BulkCrapUninstaller.Controls.FileTargeter, BCUninstaller, Culture=neutral, PublicKeyToken=null groupBox2 0 Top 5, 141 4, 3, 4, 3 4, 3, 4, 3 362, 85 1 Select using install folder or program files groupBox2 System.Windows.Forms.GroupBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 2 True True 4, 0 4, 0, 4, 0 338, 30 0 Find and uninstall an application based on one of its windows, shortcuts, or its install location or .exe files. label1 System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel1 0 Top 5, 5 4, 3, 4, 3 0, 0, 0, 5 362, 35 2 flowLayoutPanel1 System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 5 True True 4, 5 4, 0, 4, 0 344, 75 0 Note: Make sure that any files you select are inside of the application's installation directory. You can select a directory that contains multiple applications to uninstall them all. label2 System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel2 0 Top 5, 226 4, 3, 4, 3 0, 5, 0, 0 362, 80 3 flowLayoutPanel2 System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 1 Top 5, 306 4, 3, 4, 3 362, 2 4 panel1 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 0 Top 5, 136 4, 3, 4, 3 362, 5 6 panel2 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 3 True 7, 15 True GrowAndShrink 372, 339 4, 3, 4, 3 347, 39 5, 5, 5, 5 Target an application TargetWindow System.Windows.Forms.Form, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/TargetWindow.ru.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Найти и удалить приложение по одному из его окон, ярлыку, местоположению установки или файлу .exe. Уничтожить приложение Найти по окну Найти по папке или файлам программы Примечание: Убедитесь, что выбранные файлы находятся внутри каталога установки приложения. Вы можете выбрать каталог, содержащий несколько приложений, для их удаления. ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/TargetWindow.sl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Poiščite in odstranite aplikacijo na podlagi enega od njunih oken, bližnjic, mesta njune namestitve ali datoteke .exe. Uniči aplikacijo Izberi z oknom Izberi s pomočjo namestitvene mape ali programskimi datotekami Opomba: Prepričajte se, da so vse izbrane datoteke znotraj mape nameščene aplikacije. Izberete lahko mapo, ki vsebuje več aplikacij, da jih vse odstranite. ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/TargetWindow.sv.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Välj med hjälp av ett fönster Välj med hjälp av installationsmappen eller programfiler Hitta och avinstallera en app baserat på ett av dess fönster, genvägar, dess installationsplats eller .exe-filer. OBS: Säkerställ att alla filer du väljer finns inom appens installationsmapp. Du kan välja en mapp som innehåller flera appar för att avinstallera dem alla. Välj en app ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/TargetWindow.tr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Bir pencere seç Yükleme klasörünü veya program dosyalarını kullanarak seçin Bir uygulamayı pencere, kısayol, yükleme konumu veya .exe dosyasının biriyle bulun ve kaldırın. Not: Seçtiğiniz dosyaların uygulamanın kurulum dizininde olduğundan emin olun. Hepsini kaldırmak için birden çok uygulama içeren bir dizin seçebilirsiniz. Uygulamayı yok et ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/TargetWindow.vi.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Chọn một cửa sổ Chọn thư mục cài đặt hoặc tệp tin ứng dụng Tìm và gỡ cài đặt một ứng dụng dựa vào một trong các thông tin sau: cửa sổ, lối tắt hoặc vị trí cài đặt hoặc tệp .exe của ứng dụng đó. Lưu ý: Hãy đảm bảo bất kỳ tệp bạn chọn phải nằm trong thư mục cài đặt ứng dụng. Bạn có thể chọn một thư mục chứa nhiều ứng dụng để gỡ cài đặt tất cả chúng cùng một lúc. Nhắm mục tiêu ứng dụng ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/TargetWindow.zh-Hans.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 使用窗口选择 使用安装文件夹或程序文件选择 根据某个应用程序的窗口、快捷方式、安装位置或.exe文件查找并卸载该应用程序。 注意:确保你选择的所有文件都在应用程序的安装目录中。 你可以选择一个包含多个应用程序的目录来卸载它们。 强制删除应用程序 ================================================ FILE: source/BulkCrapUninstaller/Forms/Helpers/TargetWindow.zh-Hant.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 選擇使用視窗 選擇安裝資料夾或程式文件 根據某個應用程式視窗、捷徑、安裝位置或執行檔文件尋找並移除該應用程式 注意:確保你 所選的文件都有在應用程式的安裝目錄中。 你可以選擇一個包含多個應用程式的目錄來移除它們。 強制刪除應用程式 ================================================ FILE: source/BulkCrapUninstaller/Forms/UninstallerListDoubleClickAction.cs ================================================ using BulkCrapUninstaller.Properties; using Klocman.Localising; namespace BulkCrapUninstaller.Forms; public enum UninstallerListDoubleClickAction { [LocalisedName(typeof (Localisable), nameof(Localisable.UninstallerListDoubleClickAction_DoNothing))] DoNothing = 0, [LocalisedName(typeof (Localisable),nameof(Localisable.UninstallerListDoubleClickAction_Properties))] OpenProperties, [LocalisedName(typeof (Localisable), nameof(Localisable.UninstallerListDoubleClickAction_Uninstall))] Uninstall } ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/AboutBox.Designer.cs ================================================ using System.ComponentModel; using System.Windows.Forms; using BulkCrapUninstaller.Functions.Tracking; namespace BulkCrapUninstaller.Forms { partial class AboutBox { /// /// Required designer variable. /// private IContainer components = null; /// /// Clean up any resources being used. /// protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { ComponentResourceManager resources = new ComponentResourceManager(typeof(AboutBox)); labelName = new Label(); labelVersion = new Label(); labelCopyright = new Label(); labelCompanyName = new Label(); groupBox1 = new GroupBox(); panel1 = new Panel(); labelis64 = new Label(); labelPortable = new Label(); panel4 = new Panel(); labelArchitecture = new Label(); groupBox2 = new GroupBox(); panel5 = new Panel(); flowLayoutPanel1 = new FlowLayoutPanel(); linkLabel6 = new LinkLabel(); linkLabel9 = new LinkLabel(); linkLabel3 = new LinkLabel(); linkLabel1 = new LinkLabel(); linkLabel5 = new LinkLabel(); linkLabel2 = new LinkLabel(); linkLabel7 = new LinkLabel(); linkLabel8 = new LinkLabel(); button1 = new Button(); linkLabel4 = new LinkLabel(); groupBox3 = new GroupBox(); panel3 = new Panel(); imageBox = new Label(); panel2 = new Panel(); groupBox4 = new GroupBox(); flowLayoutPanel2 = new FlowLayoutPanel(); usageTracker1 = new UsageTracker(); groupBox1.SuspendLayout(); panel1.SuspendLayout(); panel4.SuspendLayout(); groupBox2.SuspendLayout(); panel5.SuspendLayout(); flowLayoutPanel1.SuspendLayout(); groupBox3.SuspendLayout(); panel3.SuspendLayout(); panel2.SuspendLayout(); groupBox4.SuspendLayout(); SuspendLayout(); // // labelName // resources.ApplyResources(labelName, "labelName"); labelName.Name = "labelName"; // // labelVersion // resources.ApplyResources(labelVersion, "labelVersion"); labelVersion.Name = "labelVersion"; // // labelCopyright // resources.ApplyResources(labelCopyright, "labelCopyright"); labelCopyright.Name = "labelCopyright"; // // labelCompanyName // resources.ApplyResources(labelCompanyName, "labelCompanyName"); labelCompanyName.Name = "labelCompanyName"; // // groupBox1 // resources.ApplyResources(groupBox1, "groupBox1"); groupBox1.Controls.Add(panel1); groupBox1.Controls.Add(panel4); groupBox1.Controls.Add(labelName); groupBox1.Name = "groupBox1"; groupBox1.TabStop = false; // // panel1 // resources.ApplyResources(panel1, "panel1"); panel1.Controls.Add(labelis64); panel1.Controls.Add(labelPortable); panel1.Name = "panel1"; // // labelis64 // resources.ApplyResources(labelis64, "labelis64"); labelis64.Name = "labelis64"; // // labelPortable // resources.ApplyResources(labelPortable, "labelPortable"); labelPortable.Name = "labelPortable"; // // panel4 // resources.ApplyResources(panel4, "panel4"); panel4.Controls.Add(labelVersion); panel4.Controls.Add(labelArchitecture); panel4.Name = "panel4"; // // labelArchitecture // resources.ApplyResources(labelArchitecture, "labelArchitecture"); labelArchitecture.Name = "labelArchitecture"; // // groupBox2 // groupBox2.Controls.Add(panel5); resources.ApplyResources(groupBox2, "groupBox2"); groupBox2.Name = "groupBox2"; groupBox2.TabStop = false; // // panel5 // panel5.Controls.Add(flowLayoutPanel1); resources.ApplyResources(panel5, "panel5"); panel5.Name = "panel5"; // // flowLayoutPanel1 // resources.ApplyResources(flowLayoutPanel1, "flowLayoutPanel1"); flowLayoutPanel1.Controls.Add(linkLabel6); flowLayoutPanel1.Controls.Add(linkLabel9); flowLayoutPanel1.Controls.Add(linkLabel3); flowLayoutPanel1.Controls.Add(linkLabel1); flowLayoutPanel1.Controls.Add(linkLabel5); flowLayoutPanel1.Controls.Add(linkLabel2); flowLayoutPanel1.Controls.Add(linkLabel7); flowLayoutPanel1.Controls.Add(linkLabel8); flowLayoutPanel1.Name = "flowLayoutPanel1"; // // linkLabel6 // resources.ApplyResources(linkLabel6, "linkLabel6"); linkLabel6.Name = "linkLabel6"; linkLabel6.TabStop = true; linkLabel6.LinkClicked += linkLabel6_LinkClicked; // // linkLabel9 // resources.ApplyResources(linkLabel9, "linkLabel9"); linkLabel9.Name = "linkLabel9"; linkLabel9.TabStop = true; linkLabel9.LinkClicked += linkLabel9_LinkClicked; // // linkLabel3 // resources.ApplyResources(linkLabel3, "linkLabel3"); linkLabel3.Name = "linkLabel3"; linkLabel3.TabStop = true; linkLabel3.LinkClicked += linkLabel3_LinkClicked; // // linkLabel1 // resources.ApplyResources(linkLabel1, "linkLabel1"); linkLabel1.Name = "linkLabel1"; linkLabel1.TabStop = true; linkLabel1.LinkClicked += linkLabel1_LinkClicked; // // linkLabel5 // resources.ApplyResources(linkLabel5, "linkLabel5"); linkLabel5.Name = "linkLabel5"; linkLabel5.TabStop = true; linkLabel5.LinkClicked += linkLabel5_LinkClicked; // // linkLabel2 // resources.ApplyResources(linkLabel2, "linkLabel2"); linkLabel2.Name = "linkLabel2"; linkLabel2.TabStop = true; linkLabel2.LinkClicked += linkLabel2_LinkClicked; // // linkLabel7 // resources.ApplyResources(linkLabel7, "linkLabel7"); linkLabel7.Name = "linkLabel7"; linkLabel7.TabStop = true; linkLabel7.LinkClicked += linkLabel7_LinkClicked; // // linkLabel8 // resources.ApplyResources(linkLabel8, "linkLabel8"); linkLabel8.Name = "linkLabel8"; linkLabel8.TabStop = true; linkLabel8.LinkClicked += linkLabel8_LinkClicked; // // button1 // resources.ApplyResources(button1, "button1"); button1.DialogResult = DialogResult.Cancel; button1.Name = "button1"; button1.UseVisualStyleBackColor = true; button1.Click += button1_Click; // // linkLabel4 // resources.ApplyResources(linkLabel4, "linkLabel4"); linkLabel4.Name = "linkLabel4"; linkLabel4.TabStop = true; linkLabel4.LinkClicked += linkLabel4_LinkClicked; // // groupBox3 // resources.ApplyResources(groupBox3, "groupBox3"); groupBox3.Controls.Add(linkLabel4); groupBox3.Controls.Add(panel3); groupBox3.Name = "groupBox3"; groupBox3.TabStop = false; // // panel3 // resources.ApplyResources(panel3, "panel3"); panel3.Controls.Add(labelCopyright); panel3.Controls.Add(labelCompanyName); panel3.Name = "panel3"; // // imageBox // imageBox.BorderStyle = BorderStyle.Fixed3D; resources.ApplyResources(imageBox, "imageBox"); imageBox.Image = Properties.Resources.bigImage; imageBox.Name = "imageBox"; // // panel2 // panel2.Controls.Add(groupBox4); panel2.Controls.Add(groupBox2); panel2.Controls.Add(button1); panel2.Controls.Add(groupBox3); panel2.Controls.Add(groupBox1); resources.ApplyResources(panel2, "panel2"); panel2.Name = "panel2"; // // groupBox4 // groupBox4.Controls.Add(flowLayoutPanel2); resources.ApplyResources(groupBox4, "groupBox4"); groupBox4.Name = "groupBox4"; groupBox4.TabStop = false; // // flowLayoutPanel2 // resources.ApplyResources(flowLayoutPanel2, "flowLayoutPanel2"); flowLayoutPanel2.Name = "flowLayoutPanel2"; // // usageTracker1 // usageTracker1.ContainerControl = this; // // AboutBox // AcceptButton = button1; resources.ApplyResources(this, "$this"); AutoScaleMode = AutoScaleMode.Font; CancelButton = button1; Controls.Add(panel2); Controls.Add(imageBox); FormBorderStyle = FormBorderStyle.FixedDialog; MaximizeBox = false; MinimizeBox = false; Name = "AboutBox"; ShowIcon = false; ShowInTaskbar = false; groupBox1.ResumeLayout(false); groupBox1.PerformLayout(); panel1.ResumeLayout(false); panel1.PerformLayout(); panel4.ResumeLayout(false); panel4.PerformLayout(); groupBox2.ResumeLayout(false); panel5.ResumeLayout(false); flowLayoutPanel1.ResumeLayout(false); flowLayoutPanel1.PerformLayout(); groupBox3.ResumeLayout(false); groupBox3.PerformLayout(); panel3.ResumeLayout(false); panel3.PerformLayout(); panel2.ResumeLayout(false); panel2.PerformLayout(); groupBox4.ResumeLayout(false); ResumeLayout(false); } #endregion private Label labelName; private Label labelVersion; private Label labelCopyright; private Label labelCompanyName; private GroupBox groupBox1; private GroupBox groupBox2; private LinkLabel linkLabel3; private LinkLabel linkLabel2; private LinkLabel linkLabel1; private LinkLabel linkLabel4; private Button button1; private Label labelArchitecture; private GroupBox groupBox3; private Label labelis64; private LinkLabel linkLabel6; private LinkLabel linkLabel5; private Label labelPortable; private UsageTracker usageTracker1; private Label imageBox; private Panel panel1; private Panel panel3; private Panel panel2; private Panel panel4; private GroupBox groupBox4; private FlowLayoutPanel flowLayoutPanel1; private LinkLabel linkLabel7; private FlowLayoutPanel flowLayoutPanel2; private Panel panel5; private LinkLabel linkLabel8; private LinkLabel linkLabel9; } } ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/AboutBox.ar.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 BCUninstaller (Bulk Crap Uninstaller) الاصدار: حقوق النشر خالق هو 64 بت: مثبت: هيكل: اصدار البرنامج DotNetZip ايقونات واجهه المستخدم الحديثة Si "Modern UI Icons" significa "Iconos de Interfaz de Usuario Moderno" la traducción será "Iconos Modernos de Interface de Usuario" عرض قائمه الكائنات NBug مزود الاعدادات المحمولة برنامج التضمين المدار لبرنامج جدوله المهام ?? If translation wanted: "Pacote de Gestão de Tarefas Agendadas" الاختبار الابيض الاصول المستخدمة اغلاق الصفحة الرسمية معلومات المطور المترجمون BCUninstaller (Bulk Crap Uninstaller) حول ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/AboutBox.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Drawing; using System.Globalization; using System.Linq; using System.Reflection; using System.Windows.Forms; using BulkCrapUninstaller.Properties; using Klocman.Extensions; using Klocman.Forms.Tools; using Klocman.Tools; namespace BulkCrapUninstaller.Forms { sealed partial class AboutBox : Form { public AboutBox() { InitializeComponent(); labelVersion.Text += AssemblyVersion; labelCopyright.Text = AssemblyCopyright; labelCompanyName.Text = AssemblyCompany; labelis64.Text += ProcessTools.Is64BitProcess.ToYesNo(); Assembly.GetExecutingAssembly().Modules.First().GetPEKind(out var pekind, out var ifmachine); string machine; if (Enum.IsDefined(ifmachine)) { machine = Enum.GetName(ifmachine); } else // Work around .NET 6 not having WoA64 definitions in GetPEKind { machine = "ARM64"; } labelArchitecture.Text += machine; labelPortable.Text += Program.IsInstalled.ToYesNo(); var translationCredits = new[] { // en - English new {culture = CultureInfo.GetCultureInfo("en"), translator = "Marcin Szeniak"}, // ar - Arabic new {culture = CultureInfo.GetCultureInfo("ar"), translator = "MFM Dawdeh"}, // Czech new {culture = CultureInfo.GetCultureInfo("cs-CZ"), translator = "Richard Kahl"}, // de - German new {culture = CultureInfo.GetCultureInfo("de"), translator = "Dieter Hummel, Thomas Werk"}, // es - Spanish new {culture = CultureInfo.GetCultureInfo("es"), translator = "MS-PC2, Freddynic159, Emilio J. Grao"}, // fr - French new {culture = CultureInfo.GetCultureInfo("fr"), translator = "Thierry Delaunay, Orphée V."}, // Hungarian new {culture = CultureInfo.GetCultureInfo("hu"), translator = "Phoenix (Döbröntei Sándor)"}, // it - Italian new {culture = CultureInfo.GetCultureInfo("it"), translator = "Luca Carrabba (luca.carrabba@yahoo.com)"}, // ja - Japanese new {culture = CultureInfo.GetCultureInfo("ja"), translator = "KKbion"}, // nl - Dutch new {culture = CultureInfo.GetCultureInfo("nl"), translator = "Jaap Kramer"}, // Polish new {culture = CultureInfo.GetCultureInfo("pl"), translator = "Marcin Szeniak"}, // pt - Portuguese new {culture = CultureInfo.GetCultureInfo("pt-PT"), translator = "Artur Álvaro Pereira"}, new {culture = CultureInfo.GetCultureInfo("pt-BR"), translator = "Silvio Corral"}, // Russian new {culture = CultureInfo.GetCultureInfo("ru"), translator = "wvxwxvw, Kommprog"}, // Slovenian new {culture = CultureInfo.GetCultureInfo("sl"), translator = "Jadran Rudec"}, // Swedish new {culture = CultureInfo.GetCultureInfo("sv"), translator = "@glecas"}, // Turkish new {culture = CultureInfo.GetCultureInfo("tr"), translator = "Harun Güngör, @DogancanYr"}, // Vietnamese new {culture = CultureInfo.GetCultureInfo("vi"), translator = "wanwanvxt / Vũ Xuân Trường"}, // Simplified Chinese new {culture = CultureInfo.GetCultureInfo("zh-Hans"), translator = "cc713"}, // Traditional Chinese new {culture = CultureInfo.GetCultureInfo("zh-Hant"), translator = "Henryliu880922"} }; foreach (var translationCredit in translationCredits .Select(x => new { x.culture.DisplayName, x.translator }) .OrderBy(x => x.DisplayName)) { var l = new Label { Text = translationCredit.DisplayName + " - " + translationCredit.translator, Padding = new Padding(0, 0, 0, 3), AutoSize = true, TextAlign = ContentAlignment.MiddleLeft }; flowLayoutPanel2.Controls.Add(l); } } public static string AssemblyCompany { get { var attributes = Assembly.GetExecutingAssembly() .GetCustomAttributes(typeof(AssemblyCompanyAttribute), false); if (attributes.Length == 0) { return ""; } return ((AssemblyCompanyAttribute)attributes[0]).Company; } } public static string AssemblyCopyright { get { var attributes = Assembly.GetExecutingAssembly() .GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false); if (attributes.Length == 0) { return ""; } return ((AssemblyCopyrightAttribute)attributes[0]).Copyright; } } public static Version AssemblyVersion => Assembly.GetExecutingAssembly().GetName().Version; private void button1_Click(object sender, EventArgs e) { Close(); } private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { PremadeDialogs.StartProcessSafely(@"http://objectlistview.sourceforge.net"); } private void linkLabel2_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { PremadeDialogs.StartProcessSafely( @"http://www.codeproject.com/Articles/20917/Creating-a-Custom-Settings-Provider"); } private void linkLabel3_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { PremadeDialogs.StartProcessSafely(@"https://github.com/Templarian/WindowsIcons/"); } private void linkLabel4_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { PremadeDialogs.StartProcessSafely(Resources.HomepageUrl); } private void linkLabel5_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { PremadeDialogs.StartProcessSafely(@"https://nbug.codeplex.com/"); } private void linkLabel6_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { PremadeDialogs.StartProcessSafely(@"http://dotnetzip.codeplex.com/"); } private void linkLabel7_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { PremadeDialogs.StartProcessSafely(@"http://taskscheduler.codeplex.com/"); } private void linkLabel8_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { PremadeDialogs.StartProcessSafely(@"https://github.com/TestStack/White"); } private void linkLabel9_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { PremadeDialogs.StartProcessSafely(@"https://www.voidtools.com/"); } } } ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/AboutBox.cs.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Verze: Autorská práva Tvůrce Je 64bit: Je nainstalován: Architektura: Verze programu Windows Ikony Si "Modern UI Icons" significa "Iconos de Interfaz de Usuario Moderno" la traducción será "Iconos Modernos de Interface de Usuario" PortableSettingsPoskytovatel CodeChimp Použité položky Zavřit Oficiální webové stránky Vývojář info Překlad O Programu BCUninstaller (Bulk Crap Uninstaller) BCUninstaller (Bulk Crap Uninstaller) DotNetZip ObjectListView NBug od Teoman Soygul Task Scheduler Managed Wrapper ?? If translation wanted: "Pacote de Gestão de Tarefas Agendadas" TestStack.White ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/AboutBox.de.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 BCUninstaller (Bulk Crap Uninstaller) Version: Copyright Urheber 64bit: Installiert: Architektur: Programmversion DotNetZip NBug von Teoman Soygul Moderne UI Icons Si "Modern UI Icons" significa "Iconos de Interfaz de Usuario Moderno" la traducción será "Iconos Modernos de Interface de Usuario" PortableSettingsProvider von CodeChimp ObjectListView Verwendete Quellen Schließen Offizielle Website Hersteller Info Übersetzer Über BCUninstaller (Bulk Crap Uninstaller) Task Scheduler Managed Wrapper ?? If translation wanted: "Pacote de Gestão de Tarefas Agendadas" TestStack.White es.exe (CLI für Everything) Almost all the translations here were in English 116, 17 True ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/AboutBox.es.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 BCUninstaller (Bulk Crap Uninstaller) Versión: Copyright Creador Versión del programa Es 64 bits: Está instalado: Arquitectura: DotNetZip Modern UI Icons Si "Modern UI Icons" significa "Iconos de Interfaz de Usuario Moderno" la traducción será "Iconos Modernos de Interface de Usuario" ObjectListView NBug PortableSettingsProvider Cerrar Sitio web oficial Info. del desarrollador Traductores Acerca de BCUninstaller (Bulk Crap Uninstaller) Task Scheduler Managed Wrapper ?? If translation wanted: "Pacote de Gestão de Tarefas Agendadas" TestStack.White Activos utilizados es.exe (CLI para Everything) ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/AboutBox.fr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Version : Créateur Est 64bits : Est installé : Architecture : Version du programme NBug I have translated it directly in Japanese, but it may not convey the meaning very well. Icônes Modern UI Si "Modern UI Icons" significa "Iconos de Interfaz de Usuario Moderno" la traducción será "Iconos Modernos de Interface de Usuario" PortableSettingsProvider 1 Eléments actifs utilisés Fermer Page web officielle Infos développeur Traducteurs A propos de BCUninstaller (Bulk Crap Uninstaller) Copyright DotNetZip jp translator: what's this? BCUninstaller (Bulk Crap Uninstaller) ObjectListView Task Scheduler Managed Wrapper ?? If translation wanted: "Pacote de Gestão de Tarefas Agendadas" TestStack.White I have translated it directly in Japanese, but it may not convey the meaning very well. es.exe (CLI pour Everything) Almost all the translations here were in English ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/AboutBox.hu.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 BCUninstaller (Bulk Crap Uninstaller) Verzió: Copyright Készítő 64-bites: Telepítve: Architektúra: Programverzió DotNetZip jp translator: what's this? Modern UI ikonok Si "Modern UI Icons" significa "Iconos de Interfaz de Usuario Moderno" la traducción será "Iconos Modernos de Interface de Usuario" ObjectListView NBug by Teoman Soygul I have translated it directly in Japanese, but it may not convey the meaning very well. PortableSettingsProvider by CodeChimp 1 Task Scheduler Managed Wrapper ?? If translation wanted: "Pacote de Gestão de Tarefas Agendadas" TestStack.White I have translated it directly in Japanese, but it may not convey the meaning very well. Használt eszközök Bezárás Hivatalos weboldal Fejlesztői infó Fordítók A BCUninstaller (Bulk Crap Uninstaller) névjegye es.exe (CLI Everything-hez) ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/AboutBox.it.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 BCUninstaller (Bulk Crap Uninstaller) Versione: Copyright Creatore 64 bit: Installato: Architettura: Versione programma DotNetZip Icone Modern UI Si "Modern UI Icons" significa "Iconos de Interfaz de Usuario Moderno" la traducción será "Iconos Modernos de Interface de Usuario" ObjectList View Nbug PortableSettingsProvider 1 Wrapper gestito dall'utilità di pianificazione ?? If translation wanted: "Pacote de Gestão de Tarefas Agendadas" TestStack.White Risorse usate Chiudi Sito web ufficiale Info sviluppatore Traduttori Info su BCUninstaller (Bulk Crap Uninstaller) es.exe (CLI per Everything) ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/AboutBox.ja.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 BCUninstaller(バルク クラップ アンインストーラー) バージョン: 著作権 作成者 64ビットかどうか: インストール済みかどうか: 構成: プログラムバージョン DotNetZip jp translator: what's this? es.exe (Everything用CLI) モダンUIアイコン Si "Modern UI Icons" significa "Iconos de Interfaz de Usuario Moderno" la traducción será "Iconos Modernos de Interface de Usuario" オブジェクトリストビュー Nバグ I have translated it directly in Japanese, but it may not convey the meaning very well. ポータブル設定プロバイダー 1 タスクスケジュールマネージャー ?? If translation wanted: "Pacote de Gestão de Tarefas Agendadas" TestStack.White I have translated it directly in Japanese, but it may not convey the meaning very well. 使用されているアセット 閉じる 公式ウェブページ 開発者情報 翻訳者 BCUninstaller(バルク クラップ アンインストーラー)について ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/AboutBox.nl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 BCUninstaller (BulkCrap Uninstaller) Versie Copyright Gemaakt door 64bit: Geïnstalleerd: Architectuur Programma versie DotNetZip jp translator: what's this? Modern UI Icons Si "Modern UI Icons" significa "Iconos de Interfaz de Usuario Moderno" la traducción será "Iconos Modernos de Interface de Usuario" ObjectListView NBug von Teoman Soygul I have translated it directly in Japanese, but it may not convey the meaning very well. PortableSettingsProvider von CodeChimp 1 Task Scheduler Managed Wrapper ?? If translation wanted: "Pacote de Gestão de Tarefas Agendadas" TestStack.White I have translated it directly in Japanese, but it may not convey the meaning very well. Gebruikte bronnen Sluiten Officiële website Ontwikkelaar info Vertalers Over BCUninstaller (Bulk Crap Uninstaller) es.exe (CLI voor Everything) ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/AboutBox.pl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Wersja: Prawo autorskie Twórca Jest 64bit: Jest zainstalowany: Architektura: Wersja programu NBug przez Teoman Soygul Modern UI Icons Si "Modern UI Icons" significa "Iconos de Interfaz de Usuario Moderno" la traducción será "Iconos Modernos de Interface de Usuario" PortableSettingsProvider przez CodeChimp Użyte elementy Zamknij Oficjalna strona internetowa Informacje o twórcy Tłumaczenia O programie BCUninstaller (Bulk Crap Uninstaller) BCUninstaller (Bulk Crap Uninstaller) DotNetZip ObjectListView Task Scheduler Managed Wrapper ?? If translation wanted: "Pacote de Gestão de Tarefas Agendadas" TestStack.White ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/AboutBox.pt-BR.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 BCUninstaller (Bulk Crap Uninstaller) Versão: Direitos Autorais Criador 64bit: Está instalado: Arquitetura: Versão do programa DotNetZip Ícones Modernos (IU) Si "Modern UI Icons" significa "Iconos de Interfaz de Usuario Moderno" la traducción será "Iconos Modernos de Interface de Usuario" ObjectListView NBug PortableSettingsProvider Armazenamento Gerenciado pelo Agendador de Tarefas ?? If translation wanted: "Pacote de Gestão de Tarefas Agendadas" TestStack.White Ativos usados Fechar Página da Web Oficial Informação do Desenvolvedor Tradutores Sobre o BCUninstaller (Bulk Crap Uninstaller) ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/AboutBox.pt.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 BCUninstaller (Bulk Crap Uninstaller) Versão: Direitos de Autor Criador Versão do programa É 64bit: Está instalado: Arquitectura: DotNetZip Ícones de Modern UI Si "Modern UI Icons" significa "Iconos de Interfaz de Usuario Moderno" la traducción será "Iconos Modernos de Interface de Usuario" ObjectListView NBug PortableSettingsProvider Pacote de Gestão do Programador de Tarefas ?? If translation wanted: "Pacote de Gestão de Tarefas Agendadas" TestStack.White Elementos activos usados Fechar Página web oficial Informação do Programador Translators Acerca do BCUninstaller (Bulk Crap Uninstaller) 116, 17 True ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/AboutBox.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 True Top NoControl 7, 19 4, 0, 4, 0 0, 0, 0, 3 199, 18 0 BCUninstaller (Bulk Crap Uninstaller) MiddleLeft labelName System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBox1 2 True NoControl 0, 0 4, 0, 4, 0 0, 0, 0, 3 51, 18 0 Version: MiddleLeft labelVersion System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel4 0 True Right NoControl 294, 0 4, 0, 4, 0 0, 0, 0, 3 60, 18 1 Copyright MiddleLeft labelCopyright System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel3 0 True NoControl 0, 0 4, 0, 4, 0 0, 0, 0, 3 46, 18 0 Creator MiddleLeft labelCompanyName System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel3 1 True True True NoControl 0, 0 4, 0, 4, 0 0, 0, 0, 3 50, 18 0 Is 64bit: labelis64 System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel1 0 True Right NoControl 282, 0 4, 0, 4, 0 0, 0, 4, 3 72, 18 1 Is installed: labelPortable System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel1 1 Top 7, 55 4, 3, 4, 3 354, 18 2 panel1 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBox1 0 True True Right NoControl 276, 0 4, 0, 4, 0 0, 0, 0, 3 78, 18 1 Architecture: labelArchitecture System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel4 1 Top 7, 37 4, 3, 4, 3 354, 18 1 panel4 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBox1 1 Top 8, 0 4, 3, 4, 3 7, 3, 4, 5 365, 78 0 Program version groupBox1 System.Windows.Forms.GroupBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel2 4 True GrowAndShrink True NoControl 4, 0 4, 0, 4, 0 0, 0, 0, 3 62, 18 0 DotNetZip linkLabel6 System.Windows.Forms.LinkLabel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel1 0 True NoControl 4, 18 4, 0, 4, 0 0, 0, 0, 3 144, 18 7 es.exe (CLI for Everything) linkLabel9 System.Windows.Forms.LinkLabel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel1 1 True NoControl 4, 36 4, 0, 4, 0 0, 0, 0, 3 94, 18 4 Modern UI Icons linkLabel3 System.Windows.Forms.LinkLabel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel1 2 True NoControl 4, 54 4, 0, 4, 0 0, 0, 0, 3 85, 18 2 ObjectListView linkLabel1 System.Windows.Forms.LinkLabel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel1 3 True NoControl 4, 72 4, 0, 4, 0 0, 0, 0, 3 37, 18 1 NBug linkLabel5 System.Windows.Forms.LinkLabel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel1 4 True NoControl 4, 90 4, 0, 4, 0 0, 0, 0, 3 137, 18 3 PortableSettingsProvider linkLabel2 System.Windows.Forms.LinkLabel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel1 5 True NoControl 4, 108 4, 0, 4, 0 0, 0, 0, 3 185, 18 5 Task Scheduler Managed Wrapper linkLabel7 System.Windows.Forms.LinkLabel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel1 6 True NoControl 4, 126 4, 0, 4, 0 0, 0, 0, 3 89, 18 6 TestStack.White linkLabel8 System.Windows.Forms.LinkLabel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel1 7 Fill TopDown 0, 0 4, 3, 4, 3 354, 74 5 False flowLayoutPanel1 System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel5 0 Fill 7, 19 4, 3, 4, 3 354, 74 5 panel5 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBox2 0 Top 8, 138 4, 3, 4, 3 7, 3, 4, 5 365, 98 2 Assets used groupBox2 System.Windows.Forms.GroupBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel2 1 Bottom, Right NoControl 282, 337 4, 3, 4, 3 88, 27 4 Close button1 System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel2 2 True Top NoControl 7, 37 4, 0, 4, 0 0, 0, 0, 3 96, 18 0 Official webpage linkLabel4 System.Windows.Forms.LinkLabel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBox3 0 True True Top 7, 19 4, 3, 4, 3 354, 18 26 panel3 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBox3 1 Top 8, 78 4, 3, 4, 3 7, 3, 4, 5 365, 60 1 Developer info groupBox3 System.Windows.Forms.GroupBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel2 3 Left NoControl 10, 10 4, 0, 4, 0 191, 367 0 imageBox System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 1 True Fill TopDown 7, 19 4, 3, 4, 3 354, 68 4 False flowLayoutPanel2 System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBox4 0 Top 8, 236 4, 3, 4, 3 7, 3, 4, 5 365, 92 3 Translators groupBox4 System.Windows.Forms.GroupBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel2 0 Fill 201, 10 4, 3, 4, 3 8, 0, 0, 0 373, 367 0 panel2 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 0 116, 17 True 7, 15 584, 387 4, 3, 4, 3 10, 10, 10, 10 CenterParent About BCUninstaller (Bulk Crap Uninstaller) usageTracker1 BulkCrapUninstaller.Functions.Tracking.UsageTracker, BCUninstaller, Culture=neutral, PublicKeyToken=null AboutBox System.Windows.Forms.Form, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/AboutBox.ru.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 BCUninstaller (Bulk Crap Uninstaller) Версия: Copyright Создатель Версия программы Есть 64bit: Инсталлирован: Архитектура: Используемые компоненты DotNetZip Иконки "Метро" Si "Modern UI Icons" significa "Iconos de Interfaz de Usuario Moderno" la traducción será "Iconos Modernos de Interface de Usuario" ObjectListView NBug PortableSettingsProvider Оболочка .NET для планировщика заданий Windows ?? If translation wanted: "Pacote de Gestão de Tarefas Agendadas" Закрыть Официальный сайт Разработчик Переводчики О программе BCUninstaller (Bulk Crap Uninstaller) TestStack.White es.exe (Мгновенный поисковик по файлам) 116, 17 True ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/AboutBox.sl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 BCUninstaller (Bulk Crap Uninstaller) Različica: Avtorske pravice Izdelovalec 64 bitni: Nameščen: Ahitektura: Različica programa DotNetZip Sodobne ikone uporabniškega vmesnika Si "Modern UI Icons" significa "Iconos de Interfaz de Usuario Moderno" la traducción será "Iconos Modernos de Interface de Usuario" ObjectListView NBug od Teoman Soygul PortableSettingsProvider by CodeChimp Wrapper upravljan z urnikom opravil ?? If translation wanted: "Pacote de Gestão de Tarefas Agendadas" Uporabljena sredstva Zapri Uradna spletna stran Podatki o razvijalcu Prevajalci Vizitka BCUninstallerja (Bulk Crap Uninstaller) TestStack.White 116, 17 True ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/AboutBox.sv.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 BCUninstaller (Bulk Crap Uninstaller) Version: Copyright Skapare Är 64-bitars: Är installerad: Arkitektur: Program version DotNetZip jp translator: what's this? es.exe (CLI for Everything) Moderna UI Ikoner Si "Modern UI Icons" significa "Iconos de Interfaz de Usuario Moderno" la traducción será "Iconos Modernos de Interface de Usuario" ObjectListView NBug I have translated it directly in Japanese, but it may not convey the meaning very well. PortableSettingsProvider 1 Managed Wrapper för Schemaläggaren ?? If translation wanted: "Pacote de Gestão de Tarefas Agendadas" TestStack.White I have translated it directly in Japanese, but it may not convey the meaning very well. Använda tillgångar Stäng Officiell webbsida Utvecklarinformation Översättare Om BCUninstaller (Bulk Crap Uninstaller) ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/AboutBox.tr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 BCUninstaller (Toplu Düzeltme Kaldırıcı) Versiyon: Telif Hakkı Üreticisi 64 Bit Yüklü: Mimari: Yazılım Versiyonu DotNetZip Modern UI ikonları Si "Modern UI Icons" significa "Iconos de Interfaz de Usuario Moderno" la traducción será "Iconos Modernos de Interface de Usuario" ObjectListView NBug Taşınabilir Ayarlar Sağlayıcısı Görev Zamanlayıcı Yönetim Kabuğu ?? If translation wanted: "Pacote de Gestão de Tarefas Agendadas" TestStack.White Varlıklar kullanıldı Kapat Resmi web sayfası Geliştirici bilgisi Çevirmenler BCUninstaller Hakkında (Toplu Düzeltme Kaldırıcı) es.exe (Her şey için komut satırı) ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/AboutBox.vi.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 BCUninstaller (Bulk Crap Uninstaller) Phiên bản: Bản quyền Tác giả Phiên bản 64bit: Được cài bằng trình cài đặt: Cấu trúc: Phiên bản ứng dụng DotNetZip jp translator: what's this? es.exe (CLI for Everything) Modern UI Icons Si "Modern UI Icons" significa "Iconos de Interfaz de Usuario Moderno" la traducción será "Iconos Modernos de Interface de Usuario" ObjectListView NBug I have translated it directly in Japanese, but it may not convey the meaning very well. PortableSettingsProvider 1 Task Scheduler Managed Wrapper ?? If translation wanted: "Pacote de Gestão de Tarefas Agendadas" TestStack.White I have translated it directly in Japanese, but it may not convey the meaning very well. Thành phần được sử dụng Đóng Trang web chính thức Thông tin nhà phát triển Các dịch giả Giới thiệu về BCUninstaller (Bulk Crap Uninstaller) ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/AboutBox.zh-Hans.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 BCUninstaller (Bulk Crap Uninstaller) 版本: 版权 创作者 64位: 安装版: 架构: 程序版本 DotNetZip es.exe (CLI for Everything) Modern UI Icons Si "Modern UI Icons" significa "Iconos de Interfaz de Usuario Moderno" la traducción será "Iconos Modernos de Interface de Usuario" ObjectListView NBug PortableSettingsProvider 1 Task Scheduler Managed Wrapper ?? If translation wanted: "Pacote de Gestão de Tarefas Agendadas" TestStack.White 使用素材 关闭 官网 开发者信息 翻译者 关于BCUninstaller (Bulk Crap Uninstaller) ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/AboutBox.zh-Hant.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 BCUninstaller (Bulk Crap Uninstaller) 版本號碼: 版權 創作者 程式是否為64位元: 安裝版或免安裝版: 架構: 程式版本 DotNetZip es.exe (CLI for Everything) Modern UI Icons Si "Modern UI Icons" significa "Iconos de Interfaz de Usuario Moderno" la traducción será "Iconos Modernos de Interface de Usuario" ObjectListView NBug PortableSettingsProvider 1 Task Scheduler Managed Wrapper ?? If translation wanted: "Pacote de Gestão de Tarefas Agendadas" TestStack.White 使用元件 關閉 官網 開發者資訊 翻譯人員 關於BCUninstaller (Bulk Crap Uninstaller) ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/JunkRemoveWindow.Designer.cs ================================================ using System.ComponentModel; using System.Windows.Forms; using BrightIdeasSoftware; using BulkCrapUninstaller.Functions.Tracking; namespace BulkCrapUninstaller.Forms { partial class JunkRemoveWindow { /// /// Required designer variable. /// private IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { components = new Container(); ComponentResourceManager resources = new ComponentResourceManager(typeof(JunkRemoveWindow)); exportDialog = new SaveFileDialog(); buttonCancel = new Button(); buttonAccept = new Button(); buttonExport = new Button(); comboBoxChecker = new ComboBox(); checkBoxHideLowConfidence = new CheckBox(); panel1 = new Panel(); groupBox1 = new GroupBox(); objectListViewMain = new ObjectListView(); olvColumnPath = new OLVColumn(); olvColumnSafety = new OLVColumn(); olvColumnUninstallerName = new OLVColumn(); flowLayoutPanel1 = new FlowLayoutPanel(); headerIntro = new Label(); headerConfTitle = new Label(); headerConfInfo = new Label(); usageTracker1 = new UsageTracker(); listViewContextMenuStrip = new ContextMenuStrip(components); openToolStripMenuItem = new ToolStripMenuItem(); toolStripSeparator1 = new ToolStripSeparator(); copyToClipboardToolStripMenuItem = new ToolStripMenuItem(); detailsToolStripMenuItem = new ToolStripMenuItem(); panel1.SuspendLayout(); groupBox1.SuspendLayout(); ((ISupportInitialize)objectListViewMain).BeginInit(); flowLayoutPanel1.SuspendLayout(); listViewContextMenuStrip.SuspendLayout(); SuspendLayout(); // // exportDialog // exportDialog.DefaultExt = "txt"; exportDialog.FileName = "New BCUninstaller Junk Export"; resources.ApplyResources(exportDialog, "exportDialog"); exportDialog.RestoreDirectory = true; exportDialog.FileOk += exportDialog_FileOk; // // buttonCancel // resources.ApplyResources(buttonCancel, "buttonCancel"); buttonCancel.DialogResult = DialogResult.Cancel; buttonCancel.Name = "buttonCancel"; buttonCancel.UseVisualStyleBackColor = true; // // buttonAccept // resources.ApplyResources(buttonAccept, "buttonAccept"); buttonAccept.Name = "buttonAccept"; buttonAccept.UseVisualStyleBackColor = true; buttonAccept.Click += buttonAccept_Click; // // buttonExport // resources.ApplyResources(buttonExport, "buttonExport"); buttonExport.Name = "buttonExport"; buttonExport.UseVisualStyleBackColor = true; buttonExport.Click += buttonExport_Click; // // comboBoxChecker // comboBoxChecker.DropDownStyle = ComboBoxStyle.DropDownList; comboBoxChecker.FormattingEnabled = true; resources.ApplyResources(comboBoxChecker, "comboBoxChecker"); comboBoxChecker.Name = "comboBoxChecker"; comboBoxChecker.DropDown += comboBoxChecker_DropDown; comboBoxChecker.SelectedIndexChanged += comboBoxChecker_SelectedIndexChanged; comboBoxChecker.DropDownClosed += comboBoxChecker_DropDownClosed; // // checkBoxHideLowConfidence // resources.ApplyResources(checkBoxHideLowConfidence, "checkBoxHideLowConfidence"); checkBoxHideLowConfidence.Checked = true; checkBoxHideLowConfidence.CheckState = CheckState.Checked; checkBoxHideLowConfidence.Name = "checkBoxHideLowConfidence"; checkBoxHideLowConfidence.UseVisualStyleBackColor = true; checkBoxHideLowConfidence.CheckedChanged += checkBoxHideLowConfidence_CheckedChanged; checkBoxHideLowConfidence.Click += checkBoxHideLowConfidence_Click; // // panel1 // panel1.Controls.Add(buttonAccept); panel1.Controls.Add(buttonCancel); panel1.Controls.Add(checkBoxHideLowConfidence); panel1.Controls.Add(comboBoxChecker); panel1.Controls.Add(buttonExport); resources.ApplyResources(panel1, "panel1"); panel1.Name = "panel1"; // // groupBox1 // groupBox1.Controls.Add(objectListViewMain); groupBox1.Controls.Add(flowLayoutPanel1); resources.ApplyResources(groupBox1, "groupBox1"); groupBox1.Name = "groupBox1"; groupBox1.TabStop = false; // // objectListViewMain // objectListViewMain.AllColumns.Add(olvColumnPath); objectListViewMain.AllColumns.Add(olvColumnSafety); objectListViewMain.AllColumns.Add(olvColumnUninstallerName); objectListViewMain.CellEditActivation = ObjectListView.CellEditActivateMode.DoubleClick; objectListViewMain.CellEditUseWholeCell = false; objectListViewMain.CheckBoxes = true; objectListViewMain.Columns.AddRange(new ColumnHeader[] { olvColumnPath, olvColumnSafety, olvColumnUninstallerName }); resources.ApplyResources(objectListViewMain, "objectListViewMain"); objectListViewMain.FullRowSelect = true; objectListViewMain.GridLines = true; objectListViewMain.Name = "objectListViewMain"; objectListViewMain.ShowItemToolTips = true; objectListViewMain.UseCompatibleStateImageBehavior = false; objectListViewMain.View = View.Details; objectListViewMain.CellEditStarting += objectListViewMain_CellEditStarting; objectListViewMain.CellRightClick += objectListViewMain_CellRightClick; // // olvColumnPath // olvColumnPath.AspectName = ""; resources.ApplyResources(olvColumnPath, "olvColumnPath"); // // olvColumnSafety // olvColumnSafety.AspectName = ""; resources.ApplyResources(olvColumnSafety, "olvColumnSafety"); // // olvColumnUninstallerName // olvColumnUninstallerName.AspectName = ""; resources.ApplyResources(olvColumnUninstallerName, "olvColumnUninstallerName"); // // flowLayoutPanel1 // resources.ApplyResources(flowLayoutPanel1, "flowLayoutPanel1"); flowLayoutPanel1.Controls.Add(headerIntro); flowLayoutPanel1.Controls.Add(headerConfTitle); flowLayoutPanel1.Controls.Add(headerConfInfo); flowLayoutPanel1.Name = "flowLayoutPanel1"; // // headerIntro // resources.ApplyResources(headerIntro, "headerIntro"); headerIntro.Name = "headerIntro"; // // headerConfTitle // resources.ApplyResources(headerConfTitle, "headerConfTitle"); headerConfTitle.Name = "headerConfTitle"; // // headerConfInfo // resources.ApplyResources(headerConfInfo, "headerConfInfo"); headerConfInfo.Name = "headerConfInfo"; // // usageTracker1 // usageTracker1.ContainerControl = this; // // listViewContextMenuStrip // listViewContextMenuStrip.Items.AddRange(new ToolStripItem[] { openToolStripMenuItem, toolStripSeparator1, copyToClipboardToolStripMenuItem, detailsToolStripMenuItem }); listViewContextMenuStrip.Name = "listViewContextMenuStrip"; resources.ApplyResources(listViewContextMenuStrip, "listViewContextMenuStrip"); // // openToolStripMenuItem // resources.ApplyResources(openToolStripMenuItem, "openToolStripMenuItem"); openToolStripMenuItem.Image = Properties.Resources.folderopen; openToolStripMenuItem.Name = "openToolStripMenuItem"; openToolStripMenuItem.Click += openToolStripMenuItem_Click; // // toolStripSeparator1 // toolStripSeparator1.Name = "toolStripSeparator1"; resources.ApplyResources(toolStripSeparator1, "toolStripSeparator1"); // // copyToClipboardToolStripMenuItem // copyToClipboardToolStripMenuItem.Image = Properties.Resources.pagecopy; copyToClipboardToolStripMenuItem.Name = "copyToClipboardToolStripMenuItem"; resources.ApplyResources(copyToClipboardToolStripMenuItem, "copyToClipboardToolStripMenuItem"); copyToClipboardToolStripMenuItem.Click += copyToClipboardToolStripMenuItem_Click; // // detailsToolStripMenuItem // detailsToolStripMenuItem.Image = Properties.Resources.magnifybrowse; detailsToolStripMenuItem.Name = "detailsToolStripMenuItem"; resources.ApplyResources(detailsToolStripMenuItem, "detailsToolStripMenuItem"); detailsToolStripMenuItem.Click += detailsToolStripMenuItem_Click; // // JunkRemoveWindow // AcceptButton = buttonAccept; resources.ApplyResources(this, "$this"); AutoScaleMode = AutoScaleMode.Font; CancelButton = buttonCancel; Controls.Add(groupBox1); Controls.Add(panel1); Name = "JunkRemoveWindow"; panel1.ResumeLayout(false); panel1.PerformLayout(); groupBox1.ResumeLayout(false); groupBox1.PerformLayout(); ((ISupportInitialize)objectListViewMain).EndInit(); flowLayoutPanel1.ResumeLayout(false); flowLayoutPanel1.PerformLayout(); listViewContextMenuStrip.ResumeLayout(false); ResumeLayout(false); } #endregion private SaveFileDialog exportDialog; private Button buttonCancel; private Button buttonAccept; private Button buttonExport; private ComboBox comboBoxChecker; private CheckBox checkBoxHideLowConfidence; private Panel panel1; private GroupBox groupBox1; private ObjectListView objectListViewMain; private OLVColumn olvColumnPath; private OLVColumn olvColumnSafety; private OLVColumn olvColumnUninstallerName; private UsageTracker usageTracker1; private FlowLayoutPanel flowLayoutPanel1; private Label headerConfInfo; private Label headerIntro; private Label headerConfTitle; private ContextMenuStrip listViewContextMenuStrip; private ToolStripMenuItem openToolStripMenuItem; private ToolStripSeparator toolStripSeparator1; private ToolStripMenuItem copyToClipboardToolStripMenuItem; private ToolStripMenuItem detailsToolStripMenuItem; } } ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/JunkRemoveWindow.ar.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 &تفاصيل &نسخ الى الحافظة &افتح ازاله البقايا قائمه الملفات و/او مفاتيح التسجيل المتبقية بعد الغاء التثبيت الكشف عن هذه البقايا هو عمليه معقده التي يمكن ان تسبب الاخطاء. وبسبب هذا ، يتم منح كافة المواد تقدير الثقة ويترك القرار النهائي للمستخدم. البنود ذات الثقة الجيدة والجيدة وعاده ما تكون امنه للازاله ، ولكن لا يزال عليك التحقق منها مرتين. تقييم الثقة يبدو ان المواد التالية قد تركت وراءها من قبل المثبتات الخاصة بهم. قد يفشل بعض المثبتين في ازاله اجزاء من التطبيق ، مما يؤدي الى تكلفه سعة المحرك . ومع ذلك ، فان معظم هذه المواد من المرجح ان تكون اعدادات التطبيق ، والتي تاخذ مساحة صغيره وغير مؤذيه. اسم الغاء التثبيت ثقة مسار المادة اخفاء المواد بثقة سيئه تصدير... حذف محدد الغاء الامر تصدير القائمه المتبقية leftover=rimanenti Text files|*.txt keep the |*.txt ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/JunkRemoveWindow.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Globalization; using System.IO; using System.Linq; using System.Windows.Forms; using BrightIdeasSoftware; using BulkCrapUninstaller.Functions; using BulkCrapUninstaller.Properties; using Klocman; using Klocman.Extensions; using Klocman.Forms.Tools; using Klocman.Localising; using Klocman.Resources; using Klocman.Tools; using UninstallTools.Junk.Confidence; using UninstallTools.Junk.Containers; namespace BulkCrapUninstaller.Forms { public partial class JunkRemoveWindow : Form { private static readonly string SelectionBoxText = Localisable.JunkRemove_SelectionBoxText; private static readonly string BackupDateFormat = new CultureInfo("en-US", false).DateTimeFormat.SortableDateTimePattern.Replace(':', '-').Replace('T', '_'); private bool _confirmLowConfidenceMessageShown; private TypedObjectListView _listViewWrapper; public JunkRemoveWindow(IEnumerable junk) { InitializeComponent(); Icon = Resources.Icon_Logo; var junkNodes = junk as IList ?? junk.ToList(); SetupListView(junkNodes); if (junkNodes.All(x => x.Confidence.GetRawConfidence() < 0)) { _confirmLowConfidenceMessageShown = true; checkBoxHideLowConfidence.Checked = true; checkBoxHideLowConfidence.Enabled = false; } else if (junkNodes.All(x => x.Confidence.GetRawConfidence() >= 0)) checkBoxHideLowConfidence.Enabled = false; new[] { ConfidenceLevel.VeryGood, ConfidenceLevel.Good, ConfidenceLevel.Questionable, ConfidenceLevel.Bad } .ForEach(x => comboBoxChecker.Items.Add(new LocalisedEnumWrapper(x))); comboBoxChecker_DropDownClosed(this, EventArgs.Empty); } public IEnumerable SelectedJunk => _listViewWrapper.CheckedObjects; private void buttonAccept_Click(object sender, EventArgs e) { Enabled = false; try { var filters = SelectedJunk.OfType().Select(x => x.Path.FullName).Distinct().ToArray(); if (!AppUninstaller.CheckForRunningProcesses(filters, false, this)) return; if (SelectedJunk.Any(x => !(x is FileSystemJunk))) { if (Settings.Default.BackupLeftovers == YesNoAsk.Ask) { switch (MessageBoxes.BackupRegistryQuestion(this)) { case MessageBoxes.PressedButton.Yes: var path = MessageBoxes.SelectFolder( Localisable.JunkRemoveWindow_SelectBackupDirectoryTitle); if (string.IsNullOrEmpty(path)) return; try { CreateBackup(path); Settings.Default.BackupLeftoversDirectory = path; } catch (OperationCanceledException) { goto case MessageBoxes.PressedButton.Yes; } break; case MessageBoxes.PressedButton.No: break; default: return; } } else if (Settings.Default.BackupLeftovers == YesNoAsk.Yes) { while (true) { if (Directory.Exists(Settings.Default.BackupLeftoversDirectory)) { try { CreateBackup(Settings.Default.BackupLeftoversDirectory); break; } catch (OperationCanceledException) { } } Settings.Default.BackupLeftoversDirectory = MessageBoxes.SelectFolder(Localisable.JunkRemoveWindow_SelectBackupDirectoryTitle); if (string.IsNullOrEmpty(Settings.Default.BackupLeftoversDirectory)) { Settings.Default.BackupLeftoversDirectory = string.Empty; Settings.Default.BackupLeftovers = YesNoAsk.Ask; return; } } } } DialogResult = DialogResult.OK; Close(); } finally { Enabled = true; } } private void CreateBackup(string backupPath) { var dir = Path.Combine(backupPath, GetUniqueBackupName()); if (string.IsNullOrEmpty(backupPath) || !Directory.Exists(backupPath)) { PremadeDialogs.GenericError($"The parent directory does not exist:\n{backupPath}\n\nPlease choose a different backup location."); throw new OperationCanceledException(); } try { Directory.CreateDirectory(dir); } catch (Exception ex) { // https://github.com/dotnet/runtime/issues/24783 if (ex is FileNotFoundException) ex = new UnauthorizedAccessException("You do not have access to this path, choose a different path. If you use controlled folders, try turning them off or adding BCU to exclusions.", ex); PremadeDialogs.GenericError(ex); throw new OperationCanceledException(); } try { FilesystemTools.CompressDirectory(dir, TimeSpan.FromMinutes(2)); } catch { // Ignore, not important } RunBackup(dir); } private void buttonExport_Click(object sender, EventArgs e) { exportDialog.ShowDialog(); } private void checkBoxHideLowConfidence_CheckedChanged(object sender, EventArgs e) { objectListViewMain.UpdateColumnFiltering(); } private void checkBoxHideLowConfidence_Click(object sender, EventArgs e) { if (!checkBoxHideLowConfidence.Checked) { if (_confirmLowConfidenceMessageShown || MessageBoxes.ConfirmLowConfidenceQuestion(this)) _confirmLowConfidenceMessageShown = true; else checkBoxHideLowConfidence.Checked = true; } } private void comboBoxChecker_DropDown(object sender, EventArgs e) { comboBoxChecker.Items.Remove(SelectionBoxText); //comboBoxChecker.ForeColor = SystemColors.WindowText; } private void comboBoxChecker_DropDownClosed(object sender, EventArgs e) { if (comboBoxChecker.SelectedItem is LocalisedEnumWrapper localisedEnumWrapper) { var selectedConfidence = (ConfidenceLevel)localisedEnumWrapper.TargetEnum; if ((selectedConfidence != ConfidenceLevel.Bad && selectedConfidence != ConfidenceLevel.Questionable) || MessageBoxes.ConfirmLowConfidenceQuestion(this)) //Ask if selected low confidence { SelectUpTo(selectedConfidence); } } comboBoxChecker.Items.Add(SelectionBoxText); comboBoxChecker.SelectedItem = SelectionBoxText; //comboBoxChecker.ForeColor = SystemColors.Control; } private void comboBoxChecker_SelectedIndexChanged(object sender, EventArgs e) { objectListViewMain.BuildList(true); } private void copyToClipboardToolStripMenuItem_Click(object sender, EventArgs e) { try { var items = objectListViewMain.SelectedObjects.Cast().Select(x => x.ToLongString()).ToArray(); if (items.Any()) { Clipboard.SetText(string.Join(Environment.NewLine, items)); } } catch (Exception ex) { PremadeDialogs.GenericError(ex); } } private void detailsToolStripMenuItem_Click(object sender, EventArgs e) { if (objectListViewMain.SelectedObject is not IJunkResult item) return; DisplayDetails(item); } private static void DisplayDetails(IJunkResult item) { var groups = item.Confidence.ConfidenceParts.GroupBy(part => part.Change > 0).ToList(); var positives = Localisable.Empty; if (groups.Any(x => x.Key)) { var items = groups.First(x => x.Key) .Where(x => x.Reason.IsNotEmpty()) .Select(x => x.Reason) .ToArray(); if (items.Any()) positives = string.Join("\n", items); } var negatives = Localisable.Empty; if (groups.Any(x => !x.Key)) { var items = groups.First(x => !x.Key) .Where(x => x.Reason.IsNotEmpty()) .Select(x => x.Reason) .ToArray(); if (items.Any()) negatives = string.Join("\n", items); } MessageBox.Show(string.Format(CultureInfo.CurrentCulture, Localisable.JunkRemove_Details_Message, item.Confidence.GetRawConfidence(), positives, negatives), Localisable.JunkRemove_Details_Title, MessageBoxButtons.OK, MessageBoxIcon.Information); } private void exportDialog_FileOk(object sender, CancelEventArgs e) { try { File.WriteAllLines(exportDialog.FileName, objectListViewMain.FilteredObjects.Cast().Select(x => x.ToLongString()).ToArray()); } catch (Exception ex) { MessageBoxes.ExportFailed(ex.Message, this); } } private static string GetUniqueBackupName() { return "BCU Backup " + DateTime.Now.ToString(BackupDateFormat, CultureInfo.InvariantCulture); } private bool JunkListFilter(object obj) { if (obj is not IJunkResult item) return false; if (checkBoxHideLowConfidence.Checked && item.Confidence.GetRawConfidence() < 0) return false; return true; } private void objectListViewMain_CellEditStarting(object sender, CellEditEventArgs e) { e.Cancel = true; if (e.RowObject is not IJunkResult item) return; EnsureSingleSelection(e.ListViewItem); OpenJunkNodePreview(item); } private void objectListViewMain_CellRightClick(object sender, CellRightClickEventArgs e) { if (e.Model == null) return; EnsureSingleSelection(e.Item); e.MenuStrip = listViewContextMenuStrip; } private void EnsureSingleSelection(ListViewItem clickedItem) { if (objectListViewMain.SelectedItems.Count != 1) { objectListViewMain.DeselectAll(); clickedItem.Selected = true; } } private static void OpenJunkNodePreview(IJunkResult item) { try { item.Open(); } catch (Exception ex) { PremadeDialogs.GenericError(ex); } } private void openToolStripMenuItem_Click(object sender, EventArgs e) { if (objectListViewMain.SelectedObject is not IJunkResult item) return; OpenJunkNodePreview(item); } private void RunBackup(string targetdir) { var failed = new List(); foreach (var junkNode in SelectedJunk) { try { junkNode.Backup(targetdir); } catch (Exception ex) { var displayName = junkNode.GetDisplayName(); failed.Add(ex.Message + " - " + displayName); Console.WriteLine($"Backup failed for item {displayName} with exception: {ex}"); } } if (failed.Any()) { failed.Sort(); // Prevent the dialog from getting too large if (failed.Count > 6) failed = failed.Take(5).Concat(new[] { "... (check log for the full list)" }).ToList(); if (MessageBoxes.BackupFailedQuestion(string.Join("\n", failed.ToArray()), this) != MessageBoxes.PressedButton.Yes) { throw new OperationCanceledException(); } } } private void SelectUpTo(ConfidenceLevel selectedConfidenceLevel) { objectListViewMain.BeginControlUpdate(); objectListViewMain.BeginUpdate(); objectListViewMain.DeselectAll(); objectListViewMain.UncheckAll(); objectListViewMain.CheckObjects(objectListViewMain.FilteredObjects.Cast() .Where(x => x.Confidence.GetConfidence() >= selectedConfidenceLevel).ToList()); objectListViewMain.EndUpdate(); objectListViewMain.EndControlUpdate(); } private void SetupListView(IEnumerable junk) { _listViewWrapper = new TypedObjectListView(objectListViewMain); olvColumnSafety.AspectGetter = x => ((x as IJunkResult)?.Confidence?.GetConfidence() ?? ConfidenceLevel.Unknown).GetLocalisedName(); olvColumnPath.GroupKeyGetter = x => (x as IJunkResult)?.Source?.CategoryName ?? CommonStrings.Unknown; olvColumnPath.AspectGetter = rowObject => (rowObject as IJunkResult)?.GetDisplayName(); olvColumnUninstallerName.AspectGetter = rowObject => { if (rowObject is not IJunkResult junkResult) return null; var displayName = junkResult.Application?.DisplayName; if (!string.IsNullOrEmpty(displayName)) return displayName; var categoryName = junkResult.Source?.CategoryName; if (!string.IsNullOrEmpty(categoryName)) return categoryName; return Localisable.NotAvailable; }; objectListViewMain.BeginUpdate(); objectListViewMain.UseFiltering = true; objectListViewMain.AdditionalFilter = new ModelFilter(JunkListFilter); objectListViewMain.PrimarySortColumn = olvColumnUninstallerName; objectListViewMain.PrimarySortOrder = SortOrder.Ascending; objectListViewMain.SetObjects(junk); SelectUpTo(ConfidenceLevel.Good); objectListViewMain.EndUpdate(); } } } ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/JunkRemoveWindow.cs.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 &Detaily &Zkopírovat do schránky &Otevřít Odstranit zbylé soubory Seznam souborů, které zůstaly po odinstalování Detekce těchto zbytků je složitý proces, který může udělat chybu. Z tohoto důvodu jsou všechny položky uvedeny mírou spolehlivosti a konečné rozhodnutí je ponecháno na uživateli. Položky s dobrou a velmi dobrou důvěry jsou obvykle bezpečné odstraněny, ale stále by se měli zkontrolovat. Hodnocení důvěry Následující položky po sobě zanechal jejich odinstalátor. Některé odinstalátory můžou selhat odstraní části aplikace, což má za následek obsazení kapacity disku. Jak již bylo řečeno, většina z těchto položek které by mohly být nastavením aplikace, zabírají málo místa a jsou neškodné. Název odinstalátoru Důveryhodné cesta k položce Skrýt neduvěryhodné položky Export... Smazat vybrané Zrušit Export seznamu pozůstatků leftover=rimanenti Textové soubory|*.txt keep the |*.txt 17, 17 131, 17 330, 17 True 454, 17 ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/JunkRemoveWindow.de.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 &Details In Zwischenablage &kopieren Ö&ffnen Übrig gebliebene Dateien entfernen Liste der Dateien, die nach der Deinstallation übrig blieben Die Erkennung dieser Rückstände ist ein komplexer Prozess, bei dem Fehler auftreten können. Aus diesem Grund gibt es für jedes Element eine Vertrauensbewertung. Die endgültige Entscheidung hat am Ende der Benutzer. Elemente mit hohem oder sehr hohem Vertrauensgrad können gefahrlos entfernt werden, dennoch sollten Sie alles vor dem Löschen sorgfältig überprüfen. Bewertungsdetails können Sie sich nach Doppelklick auf das Element anzeigen lassen. Vertrauensbewertung Folgende Elemente scheinen von ihren Uninstallern zurückgelassen worden zu sein. Mitunter werden nicht alle Programmteile vollständigen entfernt - was auf Kosten der Laufwerkskapazität geht. Jedoch sind die meisten dieser Elemente wahrscheinlich Anwendungseinstellungen, belegen wenig Platz und sind harmlos. Name des Uninstallers Vertrauensgrad Elementpfad Ausblenden von Elementen mit niedrigem Vertrauensgrad Exportieren... Ausgewählte löschen Abbrechen Liste mit Rückständen exportieren leftover=rimanenti Textdateien|*.txt keep the |*.txt ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/JunkRemoveWindow.es.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 &Detalles &Copiar al portapapeles &Abrir Eliminar restos Lista de archivos o claves de registro restantes después de la desinstalación La detección de estos restos es un proceso complejo que puede cometer errores. Por eso, a todos los artículos se les otorga un grado de confianza y la decisión final se deja al usuario. Los artículos con confianza buena y muy buena son generalmente seguros de eliminar, pero todavía se deben verificar dos veces. Grado de confianza Tras desinstalar, han quedado éstos restos. Algunos desinstaladores no puedan eliminar partes de la aplicación, lo que reduce la capacidad de la unidad. La mayoría de estos elementos son probablemente ajustes de aplicación, que ocupan poco espacio y son inofensivos. Nombre del desinstalador Confianza Ruta del elemento Ocultar elementos con mala confianza Exportar... Eliminar seleccionado Cancelar Exportar lista de restos leftover=rimanenti Archivos de texto|*.text keep the |*.txt ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/JunkRemoveWindow.fr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Fichiers texte|*.txt keep the |*.txt Exporter la liste des vestiges leftover=rimanenti Annuler Supprimer la sélection Exporter... Cacher les éléments avec une confiance peu élevée Chemin de l'élément Confiance Nom du désinstalleur Les éléments suivants semblent avoir été laissés en arrière par leurs désinstalleurs. Quelques désinstalleurs peuvent échouer à supprimer des parties de l'application, avec pour résultat un coût en capacité du lecteur. Ceci étant dit, la plupart de ces éléments sont susceptibles d'être des réglages de l'application, qui prennent peu d'espace et sont sans danger. Niveau de confiance La détection de ces vestiges est un processus complexe qui peut commettre des erreurs. Pour cette raison, il est donné un taux de confiance à tous les éléments et la décision finale revient à l'utilisateur. Les éléments avec une bonne ou très bonne confiance sont habituellement bons à supprimer, mais vous devriez tout de même les vérifier deux fois. Liste des fichiers et/ou clés de registre laissés après désinstallation Suppression des vestiges &Ouvrir &Copier dans le presse-papiers &Détails ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/JunkRemoveWindow.hu.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 &Részletek Más&olás a Vágólapra Megnyi&tás Maradvány eltávolítás Eltávolítás után visszamaradt fájlok és beállításkulcsok listája A maradványoknak a beazonosítása egy összetett folyamat, amely néha hibás lehet. Emiatt az összes elem biztonságosságának besorolásában a végső döntést a felhasználónak kell meghoznia. A jó és a nagyon jó besorolású elemek általában biztonsággal eltávolíthatók, de mindig ellenőrizze azokat. Biztonsági besorolás Úgy tűnik, hogy a következő elemeket hátrahagyták az eltávolítóik. Néhány eltávolító nem távolítja el az összes programelemet, és ezek feleslegesen foglalják a területet. A legtöbb itt látható elem általában programbeállításokat tartalmaz, amelyek kis helyen is elférnek és veszélytelenek. Eltávolító neve Biztonságosság Útvonal Nem biztonságos elemek elrejtése Exportálás... Kijelölt törlése Mégse Maradványlista exportálása leftover=rimanenti Szövegfájlok|*.txt keep the |*.txt ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/JunkRemoveWindow.it.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 &Dettagli &Copia nella Appunti &Apri Rimozione oggetti residui Elenco di file e/o chiavi di registro ignorati durante la disinstallazione Il rilevamento degli elementi residui è un processo elaborato che può produrre errori. Per questo motivo a tutti gli oggetti è assegnato un livello di affidabilità e la decisione finale è lasciata all'utente. Gli elementi con un livello di affidabilità alto e molto alto sono normalmente sicuri da rimuovere, ma sarebbe opportuno controllare ancora. Livello affidabilità I seguenti elementi sembrano essere stati ignorati dai loro disinstallatori. Alcuni disinstallatori potrebbero aver fallito nella rimozione di parte dell'applicazione, sprecando spazio su disco. In ogni caso buona parte di questi elementi sono spesso le impostazioni dell'applicazione, che occupano poco spazio e non danno problemi. Nome disinstallatore Affidabilità Percorso elemento Nascondi elementi con pessima affidabilità Esporta... Rimuovi selezionati Annulla Esporta elenco oggetti residui leftover=rimanenti File testo|*.txt keep the |*.txt ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/JunkRemoveWindow.ja.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 &詳細 &クリップボードにコピー &開く 残存物の削除 アンインストール後に残ったファイルおよび/またはレジストリキーのリスト これらの残存物の検出は複雑なプロセスであり、誤りが生じることがあります。そのため、すべての項目に信頼度評価が付けられ、最終的な判断はユーザーに委ねられます。信頼度が良好または非常に良好な項目は通常、安全に削除できますが、再度確認することをお勧めします。 信頼度評価 以下の項目は、アンインストーラーによって残された可能性があります。一部のアンインストーラーはアプリケーションの一部を削除できないことがあり、これによりドライブの容量が無駄になる可能性があります。ただし、これらの項目のほとんどはアプリケーションの設定であり、容量をほとんど消費せず、無害です。 アンインストーラー名 信頼性 項目パス 信頼度が低い項目を非表示にする エクスポート... 選択した項目を削除 キャンセル 残存物リストのエクスポート leftover=rimanenti テキストファイル|*.txt keep the |*.txt ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/JunkRemoveWindow.nl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Tekst bestanden|*.txt keep the |*.txt Lijst met restanten exporteren leftover=rimanenti Annuleren Geselecteerde verwijderen Exporteren... Verbergen van onderdelen die u niet vertrouwd Onderdeel pad Vertrouwen De-installer naam De volgende onderdelen zijn waarschijnlijk door uw de-installer achter gebleven. Sommige de-installers kunnen falen in het verwijderen van programma onderdelen ten koste van opslag capaciteit. Echter de meeste van deze onderdelen zijn waarschijnlijk programma instellingen, die ongevaarlijk zijn en slechts weinig schijfruimte innemen. Vertrouwens waardering Het detecteren van deze restanten is een complex proces dat tot vergissingen kan leiden. Daarom is er voor elk onderdeel een vertrouwens waardering, waarbij de gebruiker de eindbeslissing heeft. Onderdelen met een (zeer) hoge graad van vertrouwen kunnen zonder gevaar worden verwijderd. Desalniettemin moet u alles alvorens te verwijderen zorgvuldig controleren. Waarderings details kunt u na een dubbelklik op het onderdeel weergeven. Lijst met bestanden en/of registersleutels, die na de-installatie zijn achtergebleven. Achtergebleven bestanden verwijderen &Openen &Kopieër naar klembord &Details ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/JunkRemoveWindow.pl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 &Szczegóły &Kopiuj do schowka &Otwórz Usuwanie pozostałości Lista możliwych pozostałości Wykrycie tych resztek jest złożonym procesem, który może popełnić błędy. Wobec tego wszystkie elementy są poddane ocenie zaufania, a ostateczna decyzja należy do użytkownika. Elementy o dobrej i bardzo dobrej ocenie zazwyczaj można bezpiecznie usunąć, jednak mimo to powinny zostać sprawdzone. Możesz kliknąć dwukrotnie na dowolny element, aby zobaczyć szczegóły jego oceny. Ocena zaufania Następujące elementy wydają się być pozostawione przez ich dezinstalatory. Niektóre dezinstalatory mogą nie usunąć części aplikacji, w wyniku czego miejsce na dysku jest tracone. Większość z tych elementów to ustawienia aplikacji, które zajmują mało miejsca i nie są szkodliwe. Nazwa aplikacji Pewność Ścieżka przedmiotu Ukryj pozycje ze słabą pewnością Eksportuj... Usuń zaznaczone Anuluj Eksportuj listę pozostałości leftover=rimanenti Pliki tekstowe|*.txt keep the |*.txt ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/JunkRemoveWindow.pt-BR.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 &Detalhes &Copiar para a Área de Transferência &Abrir Remoção de sobras Lista de arquivos e/ou de chaves de registro deixados após a desinstalação. A detecção desses restos é um processo complexo que pode cometer erros. Por isso, são dados a todos os itens uma avaliação de confiança e a decisão final é deixada ao usuário. Itens com boa e muito boa confiança geralmente são seguros para remover, mas você ainda deve verificar novamente. Nível de confiança Os seguintes itens parecem ter sido deixados para trás por seus desinstaladores. Alguns desinstaladores podem não remover partes do aplicativo, resultando em ocupação de espaço na unidade. Dito isto, a maioria desses itens provavelmente serão configurações de aplicativos, que ocupam pouco espaço e são inofensivas. Nome do desinstalador Confiança Caminho do item Ocultar itens com má confiança Exportar... Excluir selecionado Cancelar Exportar lista de sobras Arquivos texto|*.txt ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/JunkRemoveWindow.pt.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 &Pormenores &Copiar para a Área de Transferência &Abrir Remoção de vestígios residuais Lista de ficheiros e/ou de chaves de registo deixados após a desinstalação. A detecção destes resíduos é um processo complexo que pode provocar erros. Por esse motivo, são dados a todos os itens um nível de confiança e a decisão final fica a cargo do utilizador. Itens com avaliação de confiança bom ou muito bom são, geralmente, seguros para remover mas, ainda assim, verifique-os por duas vezes antes de se decidir. Nível de confiança Os itens seguintes aparentam ter ficado para trás pelos seus desinstaladores. Alguns desinstaladores falham na remoção de partes da aplicação, resultando numa ocupação da capacidade da unidade. Dito isto, a maioria destes itens são susceptíveis de serem configurações do aplicativo que ocupam pouco espaço e são inofensivos. Nome do desinstalador Confiança Percurso do item Ocultar itens duvidosos Exportar... Suprimir a selecção Cancelar Exportar a lista de vestígios residuuais leftover=rimanenti Ficheiros de texto|*.txt keep the |*.txt 17, 17 131, 17 330, 17 True 454, 17 ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/JunkRemoveWindow.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 17, 17 Text files|*.txt Export leftover list Top, Right NoControl 759, 7 4, 3, 4, 3 88, 27 3 Cancel buttonCancel System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel1 1 Top, Right NoControl 615, 7 4, 3, 4, 3 138, 27 2 Delete selected buttonAccept System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel1 0 NoControl 4, 7 4, 3, 4, 3 88, 27 0 Export... buttonExport System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel1 4 98, 9 4, 3, 4, 3 160, 23 1 comboBoxChecker System.Windows.Forms.ComboBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel1 3 True NoControl 266, 12 4, 3, 4, 3 194, 19 2 Hide items with bad confidence checkBoxHideLowConfidence System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel1 2 Bottom 8, 555 4, 3, 4, 3 850, 39 0 panel1 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 2 Item path 412 Confidence 103 Uninstaller Name 163 Fill 9, 109 4, 3, 4, 3 832, 429 0 objectListViewMain BrightIdeasSoftware.ObjectListView, ObjectListView, Culture=neutral, PublicKeyToken=null groupBox1 0 True True NoControl 4, 0 4, 0, 4, 0 0, 0, 0, 7 791, 37 6 Following items seem to have been left behind by their uninstallers. Some uninstallers might fail to remove parts of the application, resulting in drive capacity cost. That being said, most of these items are likely to be application settings, which take up little space and are harmless. headerIntro System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel1 0 True Arial, 8.25pt, style=Bold NoControl 4, 37 4, 0, 4, 0 105, 14 6 Confidence rating headerConfTitle System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel1 1 True NoControl 4, 51 4, 0, 4, 0 2, 0, 0, 7 813, 37 6 Detection of these leftovers is a complex process that can make mistakes. Because of this, all items are given a confidence rating and the final decision is left to the user. Items with good and very good confidence are usually safe to remove, but you still should double check them. headerConfInfo System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel1 2 Top 9, 21 4, 3, 4, 3 832, 88 5 flowLayoutPanel1 System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBox1 1 Fill 8, 8 4, 3, 4, 3 9, 5, 9, 9 850, 547 1 List of files and/or registry keys left after uninstallation groupBox1 System.Windows.Forms.GroupBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 1 330, 17 True 7, 15 866, 602 4, 3, 4, 3 581, 340 8, 8, 8, 8 CenterParent Leftover removal exportDialog System.Windows.Forms.SaveFileDialog, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 olvColumnPath BrightIdeasSoftware.OLVColumn, ObjectListView, Culture=neutral, PublicKeyToken=null olvColumnSafety BrightIdeasSoftware.OLVColumn, ObjectListView, Culture=neutral, PublicKeyToken=null olvColumnUninstallerName BrightIdeasSoftware.OLVColumn, ObjectListView, Culture=neutral, PublicKeyToken=null usageTracker1 BulkCrapUninstaller.Functions.Tracking.UsageTracker, BCUninstaller, Culture=neutral, PublicKeyToken=null openToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripSeparator1 System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 copyToClipboardToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 detailsToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 JunkRemoveWindow System.Windows.Forms.Form, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 454, 17 Tahoma, 8.25pt, style=Bold 169, 22 &Open 166, 6 169, 22 &Copy to clipboard 169, 22 &Details 170, 76 listViewContextMenuStrip System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/JunkRemoveWindow.ru.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 &Детали Копировать в &буфер &Открыть Удаление остатков Список файлов и/или ключей реестра, оставшихся после удаления Обнаружение остатков — сложный процесс, в котором возможны ошибки. Из-за этого все элементы рейтингуются и окончательное решение остаётся за пользователем. Элементы с хорошим и очень хорошим рейтингом доверия обычно безопасны для удаления, но Вам всё же стоит проверить их. Рейтинг доверия Следующие элементы, как представляется, остались после удаления программ(ы). Некоторые деинсталляторы могут не удалять части своего приложения. Чаще всего эти элементы являются параметрами приложений, которые занимают мало места и безвредны. Имя деинсталлятора Уверенные Путь элемента Скрыть элементы с плохой уверенностью Экспорт... Удалить отмеченное Отмена Экспорт списка оставшегося leftover=rimanenti Текстовый|*.txt keep the |*.txt 17, 17 131, 17 330, 17 True 454, 17 ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/JunkRemoveWindow.sl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Po&drobnosti &Kopiraj v odložišče &Odpri Odstranjevanje ostankov Seznam datotek in/ali, preostalih registrskih ključev, po odstranjevanju Odkrivanje teh ostankov je kompleksen proces, ki lahko povzroči napake. Zaradi tega so vsi vnosi podani glede na oceno zaupanja in končna odločitev je prepuščena vam kot uporabniku. Vnose z dobrim in zelo dobrim zaupanjem je ponavadi varno odstraniti, vendar jih še vedno treba dva krat preveriti. Ocena zaupanja Naslednji vnosi so videti kot, da so ostali z njihovimi odstranjevalci. Nekateri odstranjevalci morda ne odstranijo dele aplikacij in so rezultat cene kapacitete pogona. Kot je rečeno, večina teh vnosov so verjetno nastavitve aplikacij, ki zavzamejo malo prostora in so neškodljive. Ime odstranjevalca Zaupanje Pot vnosa Skrij vnose slabega zaupanja Izvozi... Izbriši izbrano Prekliči Izvoz seznama ostankov leftover=rimanenti Besedilne datoteke|*.txt keep the |*.txt 17, 17 131, 17 330, 17 True 454, 17 ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/JunkRemoveWindow.sv.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 &Detaljer &Kopiera till urklipp &Öppna Borttagning av rester Lista över filer och/eller registerposter kvar efter avinstallation Att upptäcka rester är en komplex process som kan göra misstag. Därför tilldelas alla objekt en tillförlitlighetsgrad och det slutliga beslutet lämnas till användaren. Objekt med bra och mycket bra tillförlitlighet är vanligtvis säkra att ta bort, men du bör ändå dubbelkolla dem. Tillförlitlighetsgrad Följande objekt verkar ha lämnats kvar efter avinstallation. Vissa avinstallationer kan lämna överblivna filer, vilket tar plats och minskar ledigt utrymme. Troligtvis är de flesta av dessa objekt appinställningar, som tar upp lite utrymme och är harmlösa. Avinstallationsprogramnamn Tillförlitlighet Sökväg Dölj objekt med dålig tillförlitlighet Exportera... Ta bort valda Avbryt Exportera lista av rester leftover=rimanenti Text filer|*.txt keep the |*.txt ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/JunkRemoveWindow.tr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 &Detaylar &Panoya kopyala &Aç Arta kalan kaldırma Kaldırma işleminden sonra kalan dosya ve / veya kayıt defteri listesi Bu arta kaların tespiti, hata yapabilen karmaşık bir süreçtir. Bu nedenle, tüm öğelere bir güven derecesi verilir ve nihai karar kullanıcıya bırakılır. İyi ve çok iyi güveni olan öğelerin genellikle kaldırılması güvenlidir, ancak yine de bunları iki kez kontrol etmelisiniz. Güven derecesi Aşağıdaki öğeler kaldırıcıları tarafından geride bırakılar artıklar gibi görünüyor. Bazı kaldırıcılar, uygulama bölümlerini kaldırarak sürücü kapasitesi maliyetine neden olabilir. Bununla birlikte, bu öğelerin çoğunun uygulama alanı olması muhtemeldir, bu da az yer kaplar ve zararsızdır. Kaldırıcı Adı Güvenli Öğe yolu Güvenilmeyen öğeleri gizle Dışa aktar Seçileni sil Vazgeç Arta kalan listesini dışa aktar leftover=rimanenti Text dosyaları|*.txt keep the |*.txt ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/JunkRemoveWindow.vi.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 &Chi tiết &Sao chép vào bảng nhớ tạm &Mở Dọn dẹp những thứ còn sót lại Danh sách các tệp tin và/hoặc mã registry còn lại sau khi gỡ cài đặt Việc phát hiện những mục dư thừa này là một quá trình phức tạp và có thể mắc sai sót. Do đó, tất cả các mục đều được đánh giá mức độ tin cậy và quyết định cuối cùng thuộc về bạn. Những mục có mức độ tin cậy tốt và rất tốt thường an toàn để xóa, nhưng bạn vẫn nên kiểm tra lại chúng. Mức độ tin cậy Các mục sau đây dường như bị trình gỡ cài đặt của chúng bỏ lại. Một số trình gỡ cài đặt có thể không xóa được một số mục, và có thể dẫn đến chiếm dung lượng ổ đĩa. Tuy nhiên, hầu hết các mục này có thể là cài đặt của ứng dụng, thường chiếm rất ít dung lượng và vô hại. Tên trình gỡ cài đặt Độ tin cậy Đường dẫn Ẩn các mục có độ tin cậy thấp Xuất... Xóa các mục đã chọn Huỷ Xuất danh sách các mục còn sót lại leftover=rimanenti Tệp văn bản|*.txt keep the |*.txt ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/JunkRemoveWindow.zh-Hans.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 详细信息 复制到剪贴板 打开 残余卸载 卸载后留下的文件及注册表项列表 检测这些残余是一个复杂的过程,可能会出错。因此,所有项目都会被给予一个置信度等级,最终决定权留给用户。有好和非常好置信度的项目通常可以安全删除,但你仍应仔细检查。 置信度等级 以下项目似乎是由其卸载程序留下的。某些卸载程序可能无法删除应用程序某些部分,从而导致驱动器容量占用增加。也就是说,这些项目大多是应用程序设置,占用空间小,无害。 卸载程序名称 置信度 项目路径 隐藏低置信度项目 导出... 删除选中项 取消 导出残余列表 leftover=rimanenti 文本文件|*.txt keep the |*.txt ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/JunkRemoveWindow.zh-Hant.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 詳細資料 複製到剪貼簿 開啟 剩餘項目移除 解除安裝後剩餘的文件及登錄表 檢測這些剩餘項目是一個複雜的過程,可能會有錯誤。因此所有項目都會被給予一個信任等級,最終選擇權留給使用者。有非常好的信任度項通常可以安全移除,但你仍應該仔細檢查。 信任度等級 下列項目似乎是由某移除程式留下的。某些移除程式可能無法刪除應用程式某些部分,從而導致硬碟空間。也就是說,這些項目大多都是應用程式設定,占用空減小且無害。 移除程式名稱 信任度 項目路徑 隱藏低信任度項目 匯出... 刪除選中項目 取消 匯出剩餘項目 leftover=rimanenti 文字文件|*.txt keep the |*.txt ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/MainWindow.Designer.cs ================================================ using System.ComponentModel; using System.Windows.Forms; using BrightIdeasSoftware; using BulkCrapUninstaller.Controls; using BulkCrapUninstaller.Functions.Tracking; namespace BulkCrapUninstaller.Forms { partial class MainWindow { /// /// Required designer variable. /// private IContainer components = null; #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { components = new Container(); ComponentResourceManager resources = new ComponentResourceManager(typeof(MainWindow)); splitContainer1 = new SplitContainer(); advancedFilters1 = new AdvancedFilters(); splitContainerListAndMap = new SplitContainer(); listViewPanel = new Panel(); uninstallerObjectListView = new ObjectListView(); olvColumnDisplayName = new OLVColumn(); olvColumnPublisher = new OLVColumn(); olvColumnRating = new OLVColumn(); olvColumnDisplayVersion = new OLVColumn(); olvColumnInstallDate = new OLVColumn(); olvColumnSize = new OLVColumn(); olvColumnStartup = new OLVColumn(); olvColumnIs64 = new OLVColumn(); olvColumnUninstallString = new OLVColumn(); olvColumnAbout = new OLVColumn(); olvColumnInstallSource = new OLVColumn(); olvColumnInstallLocation = new OLVColumn(); olvColumnUninstallerKind = new OLVColumn(); olvColumnSystemComponent = new OLVColumn(); olvColumnProtected = new OLVColumn(); olvColumnRegistryKeyName = new OLVColumn(); olvColumnGuid = new OLVColumn(); olvColumnQuietUninstallString = new OLVColumn(); treeMap1 = new SimpleTreeMap.TreeMap(); toolStrip = new ToolStrip(); toolStripButton1 = new ToolStripButton(); toolStripSeparator22 = new ToolStripSeparator(); toolStripButtonSelAll = new ToolStripButton(); toolStripButtonSelNone = new ToolStripButton(); toolStripButtonSelInv = new ToolStripButton(); toolStripSeparator23 = new ToolStripSeparator(); toolStripButtonTarget = new ToolStripButton(); toolStripSeparator21 = new ToolStripSeparator(); toolStripButtonUninstall = new ToolStripButton(); toolStripButton2 = new ToolStripButton(); toolStripButtonModify = new ToolStripButton(); toolStripSeparator4 = new ToolStripSeparator(); toolStripButtonProperties = new ToolStripButton(); toolStripSeparator24 = new ToolStripSeparator(); toolStripButton7 = new ToolStripButton(); toolStripButton8 = new ToolStripButton(); statusStrip1 = new StatusStrip(); toolStripLabelStatus = new ToolStripStatusLabel(); toolStripLabelSize = new ToolStripStatusLabel(); toolStripLabelTotal = new ToolStripStatusLabel(); settingsSidebarPanel = new Panel(); propertiesSidebar = new PropertiesSidebar(); label1 = new Label(); groupBox1 = new GroupBox(); buttonAdvFiltering = new Button(); filterEditor1 = new UninstallTools.Controls.FilterEditor(); uninstallListContextMenuStrip = new ContextMenuStrip(components); uninstallContextMenuStripItem = new ToolStripMenuItem(); quietUninstallContextMenuStripItem = new ToolStripMenuItem(); manualUninstallToolStripMenuItem1 = new ToolStripMenuItem(); uninstallUsingMsiExecContextMenuStripItem = new ToolStripMenuItem(); msiInstallContextMenuStripItem = new ToolStripMenuItem(); msiUninstallContextMenuStripItem = new ToolStripMenuItem(); msiQuietUninstallContextMenuStripItem = new ToolStripMenuItem(); toolStripSeparator3 = new ToolStripSeparator(); excludeToolStripMenuItem = new ToolStripMenuItem(); includeToolStripMenuItem = new ToolStripMenuItem(); toolStripSeparatorFiltering = new ToolStripSeparator(); runToolStripMenuItem = new ToolStripMenuItem(); toolStripSeparator8 = new ToolStripSeparator(); copyToClipboardContextMenuStripItem = new ToolStripMenuItem(); toolStripMenuItem9 = new ToolStripMenuItem(); toolStripSeparator9 = new ToolStripSeparator(); fullInformationCopyContextMenuStripItem = new ToolStripMenuItem(); programNameCopyContextMenuStripItem = new ToolStripMenuItem(); gUIDProductCodeCopyContextMenuStripItem = new ToolStripMenuItem(); fullRegistryPathCopyContextMenuStripItem = new ToolStripMenuItem(); uninstallStringCopyContextMenuStripItem = new ToolStripMenuItem(); deleteRegistryEntryContextMenuStripItem = new ToolStripMenuItem(); renameContextMenuStripItem = new ToolStripMenuItem(); toolStripSeparator6 = new ToolStripSeparator(); openInExplorerContextMenuStripItem = new ToolStripMenuItem(); installLocationOpenInExplorerContextMenuStripItem = new ToolStripMenuItem(); uninstallerLocationOpenInExplorerContextMenuStripItem = new ToolStripMenuItem(); sourceLocationOpenInExplorerContextMenuStripItem = new ToolStripMenuItem(); openWebPageContextMenuStripItem = new ToolStripMenuItem(); lookUpOnlineToolStripMenuItem = new ToolStripMenuItem(); toolStripMenuItem15 = new ToolStripMenuItem(); toolStripMenuItem16 = new ToolStripMenuItem(); slantcoToolStripMenuItem = new ToolStripMenuItem(); toolStripSeparator26 = new ToolStripSeparator(); fossHubcomToolStripMenuItem = new ToolStripMenuItem(); sourceForgecomToolStripMenuItem = new ToolStripMenuItem(); gitHubcomToolStripMenuItem = new ToolStripMenuItem(); fileHippocomToolStripMenuItem = new ToolStripMenuItem(); rateToolStripMenuItem = new ToolStripMenuItem(); toolStripSeparator7 = new ToolStripSeparator(); propertiesContextMenuStripItem = new ToolStripMenuItem(); exportDialog = new SaveFileDialog(); menuStrip = new MenuStrip(); fileToolStripMenuItem = new ToolStripMenuItem(); reloadUninstallersToolStripMenuItem = new ToolStripMenuItem(); toolStripSeparator1 = new ToolStripSeparator(); loadUninstallerListToolStripMenuItem = new ToolStripMenuItem(); toolStripSeparator30 = new ToolStripSeparator(); exportSelectedToolStripMenuItem = new ToolStripMenuItem(); exportToABatchUninstallScriptToolStripMenuItem = new ToolStripMenuItem(); exportStoreAppsToPowerShellRemoveScriptToolStripMenuItem = new ToolStripMenuItem(); toolStripSeparator10 = new ToolStripSeparator(); exitToolStripMenuItem = new ToolStripMenuItem(); viewToolStripMenuItem = new ToolStripMenuItem(); showColorLegendToolStripMenuItem = new ToolStripMenuItem(); displayToolbarToolStripMenuItem = new ToolStripMenuItem(); showTreemapToolStripMenuItem = new ToolStripMenuItem(); displaySettingsToolStripMenuItem = new ToolStripMenuItem(); displayStatusbarToolStripMenuItem = new ToolStripMenuItem(); toolStripSeparator12 = new ToolStripSeparator(); useSystemThemeToolStripMenuItem = new ToolStripMenuItem(); toolStripSeparator33 = new ToolStripSeparator(); autosizeAllColumnsToolStripMenuItem = new ToolStripMenuItem(); filteringToolStripMenuItem = new ToolStripMenuItem(); advancedApplicationsToolStripMenuItem = new ToolStripMenuItem(); basicApplicationsToolStripMenuItem = new ToolStripMenuItem(); systemComponentsToolStripMenuItem = new ToolStripMenuItem(); everythingToolStripMenuItem = new ToolStripMenuItem(); toolStripSeparator20 = new ToolStripSeparator(); automaticallyStartedToolStripMenuItem = new ToolStripMenuItem(); onlyWebBrowsersToolStripMenuItem = new ToolStripMenuItem(); toolStripSeparator31 = new ToolStripSeparator(); viewTweaksToolStripMenuItem = new ToolStripMenuItem(); viewUnregisteredToolStripMenuItem = new ToolStripMenuItem(); viewUpdatesToolStripMenuItem = new ToolStripMenuItem(); viewWindowsFeaturesToolStripMenuItem = new ToolStripMenuItem(); viewWindowsStoreAppsToolStripMenuItem = new ToolStripMenuItem(); toolStripSeparator28 = new ToolStripSeparator(); searchToolStripMenuItem = new ToolStripMenuItem(); basicOperationsToolStripMenuItem = new ToolStripMenuItem(); uninstallToolStripMenuItem = new ToolStripMenuItem(); quietUninstallToolStripMenuItem = new ToolStripMenuItem(); modifyToolStripMenuItem = new ToolStripMenuItem(); toolStripSeparator2 = new ToolStripSeparator(); toolStripMenuItem8 = new ToolStripMenuItem(); advancedClipCopyToolStripMenuItem = new ToolStripMenuItem(); toolStripSeparator11 = new ToolStripSeparator(); copyFullInformationToolStripMenuItem = new ToolStripMenuItem(); toolStripMenuItem10 = new ToolStripMenuItem(); toolStripMenuItem11 = new ToolStripMenuItem(); toolStripMenuItem12 = new ToolStripMenuItem(); toolStripMenuItem13 = new ToolStripMenuItem(); toolStripMenuItem1 = new ToolStripMenuItem(); toolStripMenuItem5 = new ToolStripMenuItem(); toolStripMenuItem6 = new ToolStripMenuItem(); toolStripMenuItem7 = new ToolStripMenuItem(); toolStripMenuItem14 = new ToolStripMenuItem(); onlineSearchToolStripMenuItem = new ToolStripMenuItem(); googleToolStripMenuItem = new ToolStripMenuItem(); alternativeToToolStripMenuItem = new ToolStripMenuItem(); slantcoToolStripMenuItem1 = new ToolStripMenuItem(); toolStripSeparator27 = new ToolStripSeparator(); toolStripMenuItem17 = new ToolStripMenuItem(); toolStripMenuItem18 = new ToolStripMenuItem(); toolStripMenuItem20 = new ToolStripMenuItem(); toolStripMenuItem19 = new ToolStripMenuItem(); rateToolStripMenuItem1 = new ToolStripMenuItem(); toolStripSeparator15 = new ToolStripSeparator(); propertiesToolStripMenuItem = new ToolStripMenuItem(); advancedOperationsToolStripMenuItem = new ToolStripMenuItem(); manualUninstallToolStripMenuItem = new ToolStripMenuItem(); msiUninstalltoolStripMenuItem = new ToolStripMenuItem(); toolStripMenuItem2 = new ToolStripMenuItem(); toolStripMenuItem3 = new ToolStripMenuItem(); toolStripMenuItem4 = new ToolStripMenuItem(); toolStripSeparator14 = new ToolStripSeparator(); renameToolStripMenuItem = new ToolStripMenuItem(); disableAutostartToolStripMenuItem = new ToolStripMenuItem(); deleteToolStripMenuItem = new ToolStripMenuItem(); toolStripSeparator5 = new ToolStripSeparator(); createBackupToolStripMenuItem = new ToolStripMenuItem(); openKeyInRegeditToolStripMenuItem = new ToolStripMenuItem(); toolStripSeparator32 = new ToolStripSeparator(); takeOwnershipToolStripMenuItem = new ToolStripMenuItem(); toolsToolStripMenuItem = new ToolStripMenuItem(); openStartupManagerToolStripMenuItem = new ToolStripMenuItem(); toolStripSeparator25 = new ToolStripSeparator(); cleanUpProgramFilesToolStripMenuItem = new ToolStripMenuItem(); targetMenuItem = new ToolStripMenuItem(); uninstallFromDirectoryToolStripMenuItem = new ToolStripMenuItem(); toolStripSeparator13 = new ToolStripSeparator(); troubleshootUninstallProblemsToolStripMenuItem = new ToolStripMenuItem(); startDiskCleanupToolStripMenuItem = new ToolStripMenuItem(); tryToInstallNETV35ToolStripMenuItem = new ToolStripMenuItem(); createRestorePointToolStripMenuItem = new ToolStripMenuItem(); toolStripSeparator29 = new ToolStripSeparator(); openProgramsAndFeaturesToolStripMenuItem = new ToolStripMenuItem(); openSystemRestoreToolStripMenuItem = new ToolStripMenuItem(); toolStripSeparator19 = new ToolStripSeparator(); settingsToolStripMenuItem = new ToolStripMenuItem(); helpToolStripMenuItem = new ToolStripMenuItem(); openHelpToolStripMenuItem = new ToolStripMenuItem(); startSetupWizardToolStripMenuItem = new ToolStripMenuItem(); toolStripSeparator16 = new ToolStripSeparator(); checkForUpdatesToolStripMenuItem = new ToolStripMenuItem(); submitFeedbackToolStripMenuItem = new ToolStripMenuItem(); toolStripSeparator18 = new ToolStripSeparator(); resetSettingsToolStripMenuItem = new ToolStripMenuItem(); uninstallBCUninstallToolstripMenuItem = new ToolStripMenuItem(); toolStripSeparator17 = new ToolStripSeparator(); aboutToolStripMenuItem = new ToolStripMenuItem(); debugToolStripMenuItem = new ToolStripMenuItem(); createBackupFileDialog = new SaveFileDialog(); globalHotkeys1 = new Klocman.Subsystems.GlobalHotkeys(); splashScreen1 = new Klocman.Forms.SplashScreen(); usageTracker = new UsageTracker(); ((ISupportInitialize)splitContainer1).BeginInit(); splitContainer1.Panel1.SuspendLayout(); splitContainer1.Panel2.SuspendLayout(); splitContainer1.SuspendLayout(); ((ISupportInitialize)splitContainerListAndMap).BeginInit(); splitContainerListAndMap.Panel1.SuspendLayout(); splitContainerListAndMap.Panel2.SuspendLayout(); splitContainerListAndMap.SuspendLayout(); listViewPanel.SuspendLayout(); ((ISupportInitialize)uninstallerObjectListView).BeginInit(); toolStrip.SuspendLayout(); statusStrip1.SuspendLayout(); settingsSidebarPanel.SuspendLayout(); groupBox1.SuspendLayout(); uninstallListContextMenuStrip.SuspendLayout(); menuStrip.SuspendLayout(); SuspendLayout(); // // splitContainer1 // resources.ApplyResources(splitContainer1, "splitContainer1"); splitContainer1.FixedPanel = FixedPanel.Panel1; splitContainer1.Name = "splitContainer1"; // // splitContainer1.Panel1 // splitContainer1.Panel1.Controls.Add(advancedFilters1); resources.ApplyResources(splitContainer1.Panel1, "splitContainer1.Panel1"); // // splitContainer1.Panel2 // splitContainer1.Panel2.Controls.Add(splitContainerListAndMap); splitContainer1.Panel2.Controls.Add(toolStrip); splitContainer1.Panel2.Controls.Add(statusStrip1); // // advancedFilters1 // resources.ApplyResources(advancedFilters1, "advancedFilters1"); advancedFilters1.Name = "advancedFilters1"; // // splitContainerListAndMap // resources.ApplyResources(splitContainerListAndMap, "splitContainerListAndMap"); splitContainerListAndMap.FixedPanel = FixedPanel.Panel2; splitContainerListAndMap.Name = "splitContainerListAndMap"; // // splitContainerListAndMap.Panel1 // splitContainerListAndMap.Panel1.Controls.Add(listViewPanel); // // splitContainerListAndMap.Panel2 // splitContainerListAndMap.Panel2.Controls.Add(treeMap1); // // listViewPanel // listViewPanel.BorderStyle = BorderStyle.FixedSingle; listViewPanel.Controls.Add(uninstallerObjectListView); resources.ApplyResources(listViewPanel, "listViewPanel"); listViewPanel.Name = "listViewPanel"; // // uninstallerObjectListView // uninstallerObjectListView.AllColumns.Add(olvColumnDisplayName); uninstallerObjectListView.AllColumns.Add(olvColumnPublisher); uninstallerObjectListView.AllColumns.Add(olvColumnRating); uninstallerObjectListView.AllColumns.Add(olvColumnDisplayVersion); uninstallerObjectListView.AllColumns.Add(olvColumnInstallDate); uninstallerObjectListView.AllColumns.Add(olvColumnSize); uninstallerObjectListView.AllColumns.Add(olvColumnStartup); uninstallerObjectListView.AllColumns.Add(olvColumnIs64); uninstallerObjectListView.AllColumns.Add(olvColumnUninstallString); uninstallerObjectListView.AllColumns.Add(olvColumnAbout); uninstallerObjectListView.AllColumns.Add(olvColumnInstallSource); uninstallerObjectListView.AllColumns.Add(olvColumnInstallLocation); uninstallerObjectListView.AllColumns.Add(olvColumnUninstallerKind); uninstallerObjectListView.AllColumns.Add(olvColumnSystemComponent); uninstallerObjectListView.AllColumns.Add(olvColumnProtected); uninstallerObjectListView.AllColumns.Add(olvColumnRegistryKeyName); uninstallerObjectListView.AllColumns.Add(olvColumnGuid); uninstallerObjectListView.AllColumns.Add(olvColumnQuietUninstallString); uninstallerObjectListView.AllowColumnReorder = true; uninstallerObjectListView.BorderStyle = BorderStyle.None; uninstallerObjectListView.CellEditActivation = ObjectListView.CellEditActivateMode.DoubleClick; uninstallerObjectListView.CellEditUseWholeCell = false; uninstallerObjectListView.CheckBoxes = true; uninstallerObjectListView.Columns.AddRange(new ColumnHeader[] { olvColumnDisplayName, olvColumnPublisher, olvColumnRating, olvColumnDisplayVersion, olvColumnInstallDate, olvColumnSize, olvColumnStartup, olvColumnIs64, olvColumnUninstallString, olvColumnAbout, olvColumnInstallSource, olvColumnInstallLocation, olvColumnUninstallerKind, olvColumnSystemComponent, olvColumnProtected, olvColumnRegistryKeyName, olvColumnGuid, olvColumnQuietUninstallString }); resources.ApplyResources(uninstallerObjectListView, "uninstallerObjectListView"); uninstallerObjectListView.FullRowSelect = true; uninstallerObjectListView.GridLines = true; uninstallerObjectListView.Name = "uninstallerObjectListView"; uninstallerObjectListView.ShowGroups = false; uninstallerObjectListView.ShowImagesOnSubItems = true; uninstallerObjectListView.ShowItemToolTips = true; uninstallerObjectListView.SortGroupItemsByPrimaryColumn = false; uninstallerObjectListView.UseCompatibleStateImageBehavior = false; uninstallerObjectListView.UseFilterIndicator = true; uninstallerObjectListView.UseHyperlinks = true; uninstallerObjectListView.View = View.Details; uninstallerObjectListView.VirtualMode = true; uninstallerObjectListView.CellEditStarting += uninstallerObjectListView_CellEditStarting; uninstallerObjectListView.CellRightClick += uninstallerObjectListView_CellRightClick; uninstallerObjectListView.ItemsChanged += RefreshStatusbarTotalLabel; uninstallerObjectListView.SelectionChanged += uninstallerObjectListView_SelectedChanged; uninstallerObjectListView.ItemChecked += uninstallerObjectListView_SelectedChanged; uninstallerObjectListView.Click += uninstallerObjectListView_Click; uninstallerObjectListView.KeyDown += uninstallerObjectListView_KeyDown; uninstallerObjectListView.KeyUp += HandleListViewMenuKeystroke; // // olvColumnDisplayName // olvColumnDisplayName.Hideable = false; resources.ApplyResources(olvColumnDisplayName, "olvColumnDisplayName"); // // olvColumnPublisher // resources.ApplyResources(olvColumnPublisher, "olvColumnPublisher"); // // olvColumnRating // olvColumnRating.IsEditable = false; olvColumnRating.MaximumWidth = 160; olvColumnRating.MinimumWidth = 80; olvColumnRating.Searchable = false; resources.ApplyResources(olvColumnRating, "olvColumnRating"); olvColumnRating.UseFiltering = false; // // olvColumnDisplayVersion // resources.ApplyResources(olvColumnDisplayVersion, "olvColumnDisplayVersion"); // // olvColumnInstallDate // olvColumnInstallDate.IsEditable = false; resources.ApplyResources(olvColumnInstallDate, "olvColumnInstallDate"); // // olvColumnSize // olvColumnSize.Searchable = false; resources.ApplyResources(olvColumnSize, "olvColumnSize"); // // olvColumnStartup // olvColumnStartup.AspectName = ""; resources.ApplyResources(olvColumnStartup, "olvColumnStartup"); // // olvColumnIs64 // olvColumnIs64.AspectName = "Is64Bit"; resources.ApplyResources(olvColumnIs64, "olvColumnIs64"); // // olvColumnUninstallString // resources.ApplyResources(olvColumnUninstallString, "olvColumnUninstallString"); // // olvColumnAbout // olvColumnAbout.Hyperlink = true; olvColumnAbout.IsEditable = false; resources.ApplyResources(olvColumnAbout, "olvColumnAbout"); // // olvColumnInstallSource // resources.ApplyResources(olvColumnInstallSource, "olvColumnInstallSource"); // // olvColumnInstallLocation // resources.ApplyResources(olvColumnInstallLocation, "olvColumnInstallLocation"); // // olvColumnUninstallerKind // resources.ApplyResources(olvColumnUninstallerKind, "olvColumnUninstallerKind"); // // olvColumnSystemComponent // resources.ApplyResources(olvColumnSystemComponent, "olvColumnSystemComponent"); // // olvColumnProtected // olvColumnProtected.AspectName = "IsProtected"; resources.ApplyResources(olvColumnProtected, "olvColumnProtected"); // // olvColumnRegistryKeyName // resources.ApplyResources(olvColumnRegistryKeyName, "olvColumnRegistryKeyName"); // // olvColumnGuid // resources.ApplyResources(olvColumnGuid, "olvColumnGuid"); // // olvColumnQuietUninstallString // resources.ApplyResources(olvColumnQuietUninstallString, "olvColumnQuietUninstallString"); // // treeMap1 // resources.ApplyResources(treeMap1, "treeMap1"); treeMap1.Name = "treeMap1"; treeMap1.ShowToolTip = false; treeMap1.UseLogValueScaling = false; // // toolStrip // toolStrip.GripStyle = ToolStripGripStyle.Hidden; toolStrip.ImageScalingSize = new System.Drawing.Size(22, 22); resources.ApplyResources(toolStrip, "toolStrip"); toolStrip.Items.AddRange(new ToolStripItem[] { toolStripButton1, toolStripSeparator22, toolStripButtonSelAll, toolStripButtonSelNone, toolStripButtonSelInv, toolStripSeparator23, toolStripButtonTarget, toolStripSeparator21, toolStripButtonUninstall, toolStripButton2, toolStripButtonModify, toolStripSeparator4, toolStripButtonProperties, toolStripSeparator24, toolStripButton7, toolStripButton8 }); toolStrip.LayoutStyle = ToolStripLayoutStyle.HorizontalStackWithOverflow; toolStrip.Name = "toolStrip"; toolStrip.TabStop = true; // // toolStripButton1 // resources.ApplyResources(toolStripButton1, "toolStripButton1"); toolStripButton1.Name = "toolStripButton1"; toolStripButton1.Click += ReloadUninstallers; // // toolStripSeparator22 // toolStripSeparator22.Name = "toolStripSeparator22"; resources.ApplyResources(toolStripSeparator22, "toolStripSeparator22"); // // toolStripButtonSelAll // toolStripButtonSelAll.DisplayStyle = ToolStripItemDisplayStyle.Image; resources.ApplyResources(toolStripButtonSelAll, "toolStripButtonSelAll"); toolStripButtonSelAll.Name = "toolStripButtonSelAll"; // // toolStripButtonSelNone // toolStripButtonSelNone.DisplayStyle = ToolStripItemDisplayStyle.Image; resources.ApplyResources(toolStripButtonSelNone, "toolStripButtonSelNone"); toolStripButtonSelNone.Name = "toolStripButtonSelNone"; // // toolStripButtonSelInv // toolStripButtonSelInv.DisplayStyle = ToolStripItemDisplayStyle.Image; resources.ApplyResources(toolStripButtonSelInv, "toolStripButtonSelInv"); toolStripButtonSelInv.Name = "toolStripButtonSelInv"; // // toolStripSeparator23 // toolStripSeparator23.Name = "toolStripSeparator23"; resources.ApplyResources(toolStripSeparator23, "toolStripSeparator23"); // // toolStripButtonTarget // toolStripButtonTarget.DisplayStyle = ToolStripItemDisplayStyle.Image; toolStripButtonTarget.Image = Properties.Resources.target; resources.ApplyResources(toolStripButtonTarget, "toolStripButtonTarget"); toolStripButtonTarget.Name = "toolStripButtonTarget"; toolStripButtonTarget.Click += OpenTargetWindow; // // toolStripSeparator21 // toolStripSeparator21.Name = "toolStripSeparator21"; resources.ApplyResources(toolStripSeparator21, "toolStripSeparator21"); // // toolStripButtonUninstall // resources.ApplyResources(toolStripButtonUninstall, "toolStripButtonUninstall"); toolStripButtonUninstall.Name = "toolStripButtonUninstall"; toolStripButtonUninstall.Click += RunLoudUninstall; // // toolStripButton2 // resources.ApplyResources(toolStripButton2, "toolStripButton2"); toolStripButton2.Name = "toolStripButton2"; toolStripButton2.Click += RunQuietUninstall; // // toolStripButtonModify // toolStripButtonModify.DisplayStyle = ToolStripItemDisplayStyle.Image; toolStripButtonModify.Image = Properties.Resources.edit_box; resources.ApplyResources(toolStripButtonModify, "toolStripButtonModify"); toolStripButtonModify.Name = "toolStripButtonModify"; toolStripButtonModify.Click += modifyToolStripMenuItem_Click; // // toolStripSeparator4 // toolStripSeparator4.Name = "toolStripSeparator4"; resources.ApplyResources(toolStripSeparator4, "toolStripSeparator4"); // // toolStripButtonProperties // toolStripButtonProperties.Image = Properties.Resources.properties; resources.ApplyResources(toolStripButtonProperties, "toolStripButtonProperties"); toolStripButtonProperties.Name = "toolStripButtonProperties"; toolStripButtonProperties.Click += OpenProperties; // // toolStripSeparator24 // toolStripSeparator24.Name = "toolStripSeparator24"; resources.ApplyResources(toolStripSeparator24, "toolStripSeparator24"); // // toolStripButton7 // toolStripButton7.DisplayStyle = ToolStripItemDisplayStyle.Image; toolStripButton7.Image = Properties.Resources.settings; resources.ApplyResources(toolStripButton7, "toolStripButton7"); toolStripButton7.Name = "toolStripButton7"; toolStripButton7.Click += settingsToolStripMenuItem_Click; // // toolStripButton8 // toolStripButton8.DisplayStyle = ToolStripItemDisplayStyle.Image; toolStripButton8.Image = Properties.Resources.information_circle; resources.ApplyResources(toolStripButton8, "toolStripButton8"); toolStripButton8.Name = "toolStripButton8"; toolStripButton8.Click += openHelpToolStripMenuItem_Click; // // statusStrip1 // statusStrip1.ImageScalingSize = new System.Drawing.Size(20, 20); statusStrip1.Items.AddRange(new ToolStripItem[] { toolStripLabelStatus, toolStripLabelSize, toolStripLabelTotal }); resources.ApplyResources(statusStrip1, "statusStrip1"); statusStrip1.Name = "statusStrip1"; statusStrip1.RenderMode = ToolStripRenderMode.ManagerRenderMode; // // toolStripLabelStatus // toolStripLabelStatus.BorderSides = ToolStripStatusLabelBorderSides.Left | ToolStripStatusLabelBorderSides.Top | ToolStripStatusLabelBorderSides.Right | ToolStripStatusLabelBorderSides.Bottom; toolStripLabelStatus.BorderStyle = Border3DStyle.Sunken; toolStripLabelStatus.Name = "toolStripLabelStatus"; resources.ApplyResources(toolStripLabelStatus, "toolStripLabelStatus"); toolStripLabelStatus.Spring = true; toolStripLabelStatus.TextChanged += toolStripLabelStatus_TextChanged; // // toolStripLabelSize // resources.ApplyResources(toolStripLabelSize, "toolStripLabelSize"); toolStripLabelSize.BorderSides = ToolStripStatusLabelBorderSides.Left | ToolStripStatusLabelBorderSides.Top | ToolStripStatusLabelBorderSides.Right | ToolStripStatusLabelBorderSides.Bottom; toolStripLabelSize.BorderStyle = Border3DStyle.Sunken; toolStripLabelSize.Name = "toolStripLabelSize"; // // toolStripLabelTotal // resources.ApplyResources(toolStripLabelTotal, "toolStripLabelTotal"); toolStripLabelTotal.BorderSides = ToolStripStatusLabelBorderSides.Left | ToolStripStatusLabelBorderSides.Top | ToolStripStatusLabelBorderSides.Right | ToolStripStatusLabelBorderSides.Bottom; toolStripLabelTotal.BorderStyle = Border3DStyle.Sunken; toolStripLabelTotal.Name = "toolStripLabelTotal"; // // settingsSidebarPanel // resources.ApplyResources(settingsSidebarPanel, "settingsSidebarPanel"); settingsSidebarPanel.Controls.Add(propertiesSidebar); settingsSidebarPanel.Controls.Add(label1); settingsSidebarPanel.Controls.Add(groupBox1); settingsSidebarPanel.Name = "settingsSidebarPanel"; // // propertiesSidebar // resources.ApplyResources(propertiesSidebar, "propertiesSidebar"); propertiesSidebar.Name = "propertiesSidebar"; // // label1 // resources.ApplyResources(label1, "label1"); label1.Name = "label1"; // // groupBox1 // resources.ApplyResources(groupBox1, "groupBox1"); groupBox1.Controls.Add(buttonAdvFiltering); groupBox1.Controls.Add(filterEditor1); groupBox1.Name = "groupBox1"; groupBox1.TabStop = false; // // buttonAdvFiltering // resources.ApplyResources(buttonAdvFiltering, "buttonAdvFiltering"); buttonAdvFiltering.Name = "buttonAdvFiltering"; buttonAdvFiltering.UseVisualStyleBackColor = true; buttonAdvFiltering.Click += buttonAdvFiltering_Click; // // filterEditor1 // resources.ApplyResources(filterEditor1, "filterEditor1"); filterEditor1.Name = "filterEditor1"; filterEditor1.ShowAsSearch = true; filterEditor1.FocusSearchTarget += filterEditor1_FocusSearchTarget; // // uninstallListContextMenuStrip // uninstallListContextMenuStrip.ImageScalingSize = new System.Drawing.Size(20, 20); uninstallListContextMenuStrip.Items.AddRange(new ToolStripItem[] { uninstallContextMenuStripItem, quietUninstallContextMenuStripItem, manualUninstallToolStripMenuItem1, uninstallUsingMsiExecContextMenuStripItem, toolStripSeparator3, excludeToolStripMenuItem, includeToolStripMenuItem, toolStripSeparatorFiltering, runToolStripMenuItem, toolStripSeparator8, copyToClipboardContextMenuStripItem, deleteRegistryEntryContextMenuStripItem, renameContextMenuStripItem, toolStripSeparator6, openInExplorerContextMenuStripItem, openWebPageContextMenuStripItem, lookUpOnlineToolStripMenuItem, rateToolStripMenuItem, toolStripSeparator7, propertiesContextMenuStripItem }); uninstallListContextMenuStrip.Name = "uninstallListContextMenuStrip"; resources.ApplyResources(uninstallListContextMenuStrip, "uninstallListContextMenuStrip"); uninstallListContextMenuStrip.Opening += UpdateUninstallListContextMenuStrip; // // uninstallContextMenuStripItem // resources.ApplyResources(uninstallContextMenuStripItem, "uninstallContextMenuStripItem"); uninstallContextMenuStripItem.Name = "uninstallContextMenuStripItem"; uninstallContextMenuStripItem.Click += RunLoudUninstall; // // quietUninstallContextMenuStripItem // resources.ApplyResources(quietUninstallContextMenuStripItem, "quietUninstallContextMenuStripItem"); quietUninstallContextMenuStripItem.Name = "quietUninstallContextMenuStripItem"; quietUninstallContextMenuStripItem.Click += RunQuietUninstall; // // manualUninstallToolStripMenuItem1 // manualUninstallToolStripMenuItem1.Name = "manualUninstallToolStripMenuItem1"; resources.ApplyResources(manualUninstallToolStripMenuItem1, "manualUninstallToolStripMenuItem1"); manualUninstallToolStripMenuItem1.Click += RunAdvancedUninstall; // // uninstallUsingMsiExecContextMenuStripItem // uninstallUsingMsiExecContextMenuStripItem.DropDownItems.AddRange(new ToolStripItem[] { msiInstallContextMenuStripItem, msiUninstallContextMenuStripItem, msiQuietUninstallContextMenuStripItem }); uninstallUsingMsiExecContextMenuStripItem.Name = "uninstallUsingMsiExecContextMenuStripItem"; resources.ApplyResources(uninstallUsingMsiExecContextMenuStripItem, "uninstallUsingMsiExecContextMenuStripItem"); // // msiInstallContextMenuStripItem // msiInstallContextMenuStripItem.Name = "msiInstallContextMenuStripItem"; resources.ApplyResources(msiInstallContextMenuStripItem, "msiInstallContextMenuStripItem"); msiInstallContextMenuStripItem.Click += msiInstallContextMenuStripItem_Click; // // msiUninstallContextMenuStripItem // msiUninstallContextMenuStripItem.Name = "msiUninstallContextMenuStripItem"; resources.ApplyResources(msiUninstallContextMenuStripItem, "msiUninstallContextMenuStripItem"); msiUninstallContextMenuStripItem.Click += msiUninstallContextMenuStripItem_Click; // // msiQuietUninstallContextMenuStripItem // msiQuietUninstallContextMenuStripItem.Name = "msiQuietUninstallContextMenuStripItem"; resources.ApplyResources(msiQuietUninstallContextMenuStripItem, "msiQuietUninstallContextMenuStripItem"); msiQuietUninstallContextMenuStripItem.Click += msiQuietUninstallContextMenuStripItem_Click; // // toolStripSeparator3 // toolStripSeparator3.Name = "toolStripSeparator3"; resources.ApplyResources(toolStripSeparator3, "toolStripSeparator3"); // // excludeToolStripMenuItem // excludeToolStripMenuItem.Name = "excludeToolStripMenuItem"; resources.ApplyResources(excludeToolStripMenuItem, "excludeToolStripMenuItem"); excludeToolStripMenuItem.Click += excludeToolStripMenuItem_Click; // // includeToolStripMenuItem // includeToolStripMenuItem.Name = "includeToolStripMenuItem"; resources.ApplyResources(includeToolStripMenuItem, "includeToolStripMenuItem"); includeToolStripMenuItem.Click += includeToolStripMenuItem_Click; // // toolStripSeparatorFiltering // toolStripSeparatorFiltering.Name = "toolStripSeparatorFiltering"; resources.ApplyResources(toolStripSeparatorFiltering, "toolStripSeparatorFiltering"); // // runToolStripMenuItem // runToolStripMenuItem.Name = "runToolStripMenuItem"; resources.ApplyResources(runToolStripMenuItem, "runToolStripMenuItem"); runToolStripMenuItem.DropDownItemClicked += runToolStripMenuItem_DropDownItemClicked; // // toolStripSeparator8 // toolStripSeparator8.Name = "toolStripSeparator8"; resources.ApplyResources(toolStripSeparator8, "toolStripSeparator8"); // // copyToClipboardContextMenuStripItem // copyToClipboardContextMenuStripItem.DropDownItems.AddRange(new ToolStripItem[] { toolStripMenuItem9, toolStripSeparator9, fullInformationCopyContextMenuStripItem, programNameCopyContextMenuStripItem, gUIDProductCodeCopyContextMenuStripItem, fullRegistryPathCopyContextMenuStripItem, uninstallStringCopyContextMenuStripItem }); resources.ApplyResources(copyToClipboardContextMenuStripItem, "copyToClipboardContextMenuStripItem"); copyToClipboardContextMenuStripItem.Name = "copyToClipboardContextMenuStripItem"; // // toolStripMenuItem9 // toolStripMenuItem9.Name = "toolStripMenuItem9"; resources.ApplyResources(toolStripMenuItem9, "toolStripMenuItem9"); toolStripMenuItem9.Click += OpenAdvancedClipboardCopy; // // toolStripSeparator9 // toolStripSeparator9.Name = "toolStripSeparator9"; resources.ApplyResources(toolStripSeparator9, "toolStripSeparator9"); // // fullInformationCopyContextMenuStripItem // fullInformationCopyContextMenuStripItem.Name = "fullInformationCopyContextMenuStripItem"; resources.ApplyResources(fullInformationCopyContextMenuStripItem, "fullInformationCopyContextMenuStripItem"); fullInformationCopyContextMenuStripItem.Click += ClipboardCopyFullInformation; // // programNameCopyContextMenuStripItem // programNameCopyContextMenuStripItem.Name = "programNameCopyContextMenuStripItem"; resources.ApplyResources(programNameCopyContextMenuStripItem, "programNameCopyContextMenuStripItem"); programNameCopyContextMenuStripItem.Click += ClipboardCopyProgramName; // // gUIDProductCodeCopyContextMenuStripItem // gUIDProductCodeCopyContextMenuStripItem.Name = "gUIDProductCodeCopyContextMenuStripItem"; resources.ApplyResources(gUIDProductCodeCopyContextMenuStripItem, "gUIDProductCodeCopyContextMenuStripItem"); gUIDProductCodeCopyContextMenuStripItem.Click += ClipboardCopyGuids; // // fullRegistryPathCopyContextMenuStripItem // fullRegistryPathCopyContextMenuStripItem.Name = "fullRegistryPathCopyContextMenuStripItem"; resources.ApplyResources(fullRegistryPathCopyContextMenuStripItem, "fullRegistryPathCopyContextMenuStripItem"); fullRegistryPathCopyContextMenuStripItem.Click += ClipboardCopyRegistryPath; // // uninstallStringCopyContextMenuStripItem // uninstallStringCopyContextMenuStripItem.Name = "uninstallStringCopyContextMenuStripItem"; resources.ApplyResources(uninstallStringCopyContextMenuStripItem, "uninstallStringCopyContextMenuStripItem"); uninstallStringCopyContextMenuStripItem.Click += ClipboardCopyUninstallString; // // deleteRegistryEntryContextMenuStripItem // deleteRegistryEntryContextMenuStripItem.Name = "deleteRegistryEntryContextMenuStripItem"; resources.ApplyResources(deleteRegistryEntryContextMenuStripItem, "deleteRegistryEntryContextMenuStripItem"); deleteRegistryEntryContextMenuStripItem.Click += DeleteRegistryEntries; // // renameContextMenuStripItem // renameContextMenuStripItem.Name = "renameContextMenuStripItem"; resources.ApplyResources(renameContextMenuStripItem, "renameContextMenuStripItem"); renameContextMenuStripItem.Click += RenameEntries; // // toolStripSeparator6 // toolStripSeparator6.Name = "toolStripSeparator6"; resources.ApplyResources(toolStripSeparator6, "toolStripSeparator6"); // // openInExplorerContextMenuStripItem // openInExplorerContextMenuStripItem.DropDownItems.AddRange(new ToolStripItem[] { installLocationOpenInExplorerContextMenuStripItem, uninstallerLocationOpenInExplorerContextMenuStripItem, sourceLocationOpenInExplorerContextMenuStripItem }); resources.ApplyResources(openInExplorerContextMenuStripItem, "openInExplorerContextMenuStripItem"); openInExplorerContextMenuStripItem.Name = "openInExplorerContextMenuStripItem"; // // installLocationOpenInExplorerContextMenuStripItem // installLocationOpenInExplorerContextMenuStripItem.Name = "installLocationOpenInExplorerContextMenuStripItem"; resources.ApplyResources(installLocationOpenInExplorerContextMenuStripItem, "installLocationOpenInExplorerContextMenuStripItem"); installLocationOpenInExplorerContextMenuStripItem.Click += OpenInstallLocation; // // uninstallerLocationOpenInExplorerContextMenuStripItem // uninstallerLocationOpenInExplorerContextMenuStripItem.Name = "uninstallerLocationOpenInExplorerContextMenuStripItem"; resources.ApplyResources(uninstallerLocationOpenInExplorerContextMenuStripItem, "uninstallerLocationOpenInExplorerContextMenuStripItem"); uninstallerLocationOpenInExplorerContextMenuStripItem.Click += OpenUninstallerLocation; // // sourceLocationOpenInExplorerContextMenuStripItem // sourceLocationOpenInExplorerContextMenuStripItem.Name = "sourceLocationOpenInExplorerContextMenuStripItem"; resources.ApplyResources(sourceLocationOpenInExplorerContextMenuStripItem, "sourceLocationOpenInExplorerContextMenuStripItem"); sourceLocationOpenInExplorerContextMenuStripItem.Click += OpenInstallationSource; // // openWebPageContextMenuStripItem // openWebPageContextMenuStripItem.Name = "openWebPageContextMenuStripItem"; resources.ApplyResources(openWebPageContextMenuStripItem, "openWebPageContextMenuStripItem"); openWebPageContextMenuStripItem.Click += OpenAssociatedWebPage; // // lookUpOnlineToolStripMenuItem // lookUpOnlineToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { toolStripMenuItem15, toolStripMenuItem16, slantcoToolStripMenuItem, toolStripSeparator26, fossHubcomToolStripMenuItem, sourceForgecomToolStripMenuItem, gitHubcomToolStripMenuItem, fileHippocomToolStripMenuItem }); resources.ApplyResources(lookUpOnlineToolStripMenuItem, "lookUpOnlineToolStripMenuItem"); lookUpOnlineToolStripMenuItem.Name = "lookUpOnlineToolStripMenuItem"; // // toolStripMenuItem15 // toolStripMenuItem15.Name = "toolStripMenuItem15"; resources.ApplyResources(toolStripMenuItem15, "toolStripMenuItem15"); toolStripMenuItem15.Click += googleToolStripMenuItem_Click; // // toolStripMenuItem16 // toolStripMenuItem16.Name = "toolStripMenuItem16"; resources.ApplyResources(toolStripMenuItem16, "toolStripMenuItem16"); toolStripMenuItem16.Click += alternativeToToolStripMenuItem_Click; // // slantcoToolStripMenuItem // slantcoToolStripMenuItem.Name = "slantcoToolStripMenuItem"; resources.ApplyResources(slantcoToolStripMenuItem, "slantcoToolStripMenuItem"); slantcoToolStripMenuItem.Click += slantcoToolStripMenuItem_Click; // // toolStripSeparator26 // toolStripSeparator26.Name = "toolStripSeparator26"; resources.ApplyResources(toolStripSeparator26, "toolStripSeparator26"); // // fossHubcomToolStripMenuItem // fossHubcomToolStripMenuItem.Name = "fossHubcomToolStripMenuItem"; resources.ApplyResources(fossHubcomToolStripMenuItem, "fossHubcomToolStripMenuItem"); fossHubcomToolStripMenuItem.Click += fossHubcomToolStripMenuItem_Click; // // sourceForgecomToolStripMenuItem // sourceForgecomToolStripMenuItem.Name = "sourceForgecomToolStripMenuItem"; resources.ApplyResources(sourceForgecomToolStripMenuItem, "sourceForgecomToolStripMenuItem"); sourceForgecomToolStripMenuItem.Click += sourceForgecomToolStripMenuItem_Click; // // gitHubcomToolStripMenuItem // gitHubcomToolStripMenuItem.Name = "gitHubcomToolStripMenuItem"; resources.ApplyResources(gitHubcomToolStripMenuItem, "gitHubcomToolStripMenuItem"); gitHubcomToolStripMenuItem.Click += gitHubcomToolStripMenuItem_Click; // // fileHippocomToolStripMenuItem // fileHippocomToolStripMenuItem.Name = "fileHippocomToolStripMenuItem"; resources.ApplyResources(fileHippocomToolStripMenuItem, "fileHippocomToolStripMenuItem"); fileHippocomToolStripMenuItem.Click += fileHippocomToolStripMenuItem_Click; // // rateToolStripMenuItem // rateToolStripMenuItem.Image = Properties.Resources.star; rateToolStripMenuItem.Name = "rateToolStripMenuItem"; resources.ApplyResources(rateToolStripMenuItem, "rateToolStripMenuItem"); rateToolStripMenuItem.Click += rateToolStripMenuItem_Click; // // toolStripSeparator7 // toolStripSeparator7.Name = "toolStripSeparator7"; resources.ApplyResources(toolStripSeparator7, "toolStripSeparator7"); // // propertiesContextMenuStripItem // resources.ApplyResources(propertiesContextMenuStripItem, "propertiesContextMenuStripItem"); propertiesContextMenuStripItem.Image = Properties.Resources.magnifybrowse; propertiesContextMenuStripItem.Name = "propertiesContextMenuStripItem"; propertiesContextMenuStripItem.Click += OpenProperties; // // exportDialog // exportDialog.DefaultExt = "txt"; exportDialog.FileName = "New BCUninstaller Export"; resources.ApplyResources(exportDialog, "exportDialog"); exportDialog.RestoreDirectory = true; exportDialog.FileOk += exportDialog_FileOk; // // menuStrip // menuStrip.ImageScalingSize = new System.Drawing.Size(20, 20); menuStrip.Items.AddRange(new ToolStripItem[] { fileToolStripMenuItem, viewToolStripMenuItem, filteringToolStripMenuItem, basicOperationsToolStripMenuItem, advancedOperationsToolStripMenuItem, toolsToolStripMenuItem, helpToolStripMenuItem, debugToolStripMenuItem }); resources.ApplyResources(menuStrip, "menuStrip"); menuStrip.Name = "menuStrip"; // // fileToolStripMenuItem // fileToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { reloadUninstallersToolStripMenuItem, toolStripSeparator1, loadUninstallerListToolStripMenuItem, toolStripSeparator30, exportSelectedToolStripMenuItem, exportToABatchUninstallScriptToolStripMenuItem, exportStoreAppsToPowerShellRemoveScriptToolStripMenuItem, toolStripSeparator10, exitToolStripMenuItem }); fileToolStripMenuItem.Name = "fileToolStripMenuItem"; resources.ApplyResources(fileToolStripMenuItem, "fileToolStripMenuItem"); fileToolStripMenuItem.DropDownOpening += fileToolStripMenuItem_DropDownOpening; // // reloadUninstallersToolStripMenuItem // resources.ApplyResources(reloadUninstallersToolStripMenuItem, "reloadUninstallersToolStripMenuItem"); reloadUninstallersToolStripMenuItem.Name = "reloadUninstallersToolStripMenuItem"; reloadUninstallersToolStripMenuItem.Click += ReloadUninstallers; // // toolStripSeparator1 // toolStripSeparator1.Name = "toolStripSeparator1"; resources.ApplyResources(toolStripSeparator1, "toolStripSeparator1"); // // loadUninstallerListToolStripMenuItem // resources.ApplyResources(loadUninstallerListToolStripMenuItem, "loadUninstallerListToolStripMenuItem"); loadUninstallerListToolStripMenuItem.Name = "loadUninstallerListToolStripMenuItem"; loadUninstallerListToolStripMenuItem.Click += OpenUninstallLists; // // toolStripSeparator30 // toolStripSeparator30.Name = "toolStripSeparator30"; resources.ApplyResources(toolStripSeparator30, "toolStripSeparator30"); // // exportSelectedToolStripMenuItem // exportSelectedToolStripMenuItem.Name = "exportSelectedToolStripMenuItem"; resources.ApplyResources(exportSelectedToolStripMenuItem, "exportSelectedToolStripMenuItem"); exportSelectedToolStripMenuItem.Click += exportSelectedToolStripMenuItem_Click; // // exportToABatchUninstallScriptToolStripMenuItem // exportToABatchUninstallScriptToolStripMenuItem.Name = "exportToABatchUninstallScriptToolStripMenuItem"; resources.ApplyResources(exportToABatchUninstallScriptToolStripMenuItem, "exportToABatchUninstallScriptToolStripMenuItem"); exportToABatchUninstallScriptToolStripMenuItem.Click += exportToABatchUninstallScriptToolStripMenuItem_Click; // // exportStoreAppsToPowerShellRemoveScriptToolStripMenuItem // exportStoreAppsToPowerShellRemoveScriptToolStripMenuItem.Name = "exportStoreAppsToPowerShellRemoveScriptToolStripMenuItem"; resources.ApplyResources(exportStoreAppsToPowerShellRemoveScriptToolStripMenuItem, "exportStoreAppsToPowerShellRemoveScriptToolStripMenuItem"); exportStoreAppsToPowerShellRemoveScriptToolStripMenuItem.Click += exportStoreAppsToPowerShellRemoveScriptToolStripMenuItem_Click; // // toolStripSeparator10 // toolStripSeparator10.Name = "toolStripSeparator10"; resources.ApplyResources(toolStripSeparator10, "toolStripSeparator10"); // // exitToolStripMenuItem // exitToolStripMenuItem.Name = "exitToolStripMenuItem"; resources.ApplyResources(exitToolStripMenuItem, "exitToolStripMenuItem"); exitToolStripMenuItem.Click += exitToolStripMenuItem_Click; // // viewToolStripMenuItem // viewToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { showColorLegendToolStripMenuItem, displayToolbarToolStripMenuItem, showTreemapToolStripMenuItem, displaySettingsToolStripMenuItem, displayStatusbarToolStripMenuItem, toolStripSeparator12, useSystemThemeToolStripMenuItem, toolStripSeparator33, autosizeAllColumnsToolStripMenuItem }); viewToolStripMenuItem.Name = "viewToolStripMenuItem"; resources.ApplyResources(viewToolStripMenuItem, "viewToolStripMenuItem"); viewToolStripMenuItem.DropDownOpening += viewToolStripMenuItem_DropDownOpening; // // showColorLegendToolStripMenuItem // showColorLegendToolStripMenuItem.Name = "showColorLegendToolStripMenuItem"; resources.ApplyResources(showColorLegendToolStripMenuItem, "showColorLegendToolStripMenuItem"); // // displayToolbarToolStripMenuItem // displayToolbarToolStripMenuItem.Checked = true; displayToolbarToolStripMenuItem.CheckState = CheckState.Checked; displayToolbarToolStripMenuItem.Name = "displayToolbarToolStripMenuItem"; resources.ApplyResources(displayToolbarToolStripMenuItem, "displayToolbarToolStripMenuItem"); // // showTreemapToolStripMenuItem // showTreemapToolStripMenuItem.Name = "showTreemapToolStripMenuItem"; resources.ApplyResources(showTreemapToolStripMenuItem, "showTreemapToolStripMenuItem"); // // displaySettingsToolStripMenuItem // displaySettingsToolStripMenuItem.Checked = true; displaySettingsToolStripMenuItem.CheckState = CheckState.Checked; displaySettingsToolStripMenuItem.Name = "displaySettingsToolStripMenuItem"; resources.ApplyResources(displaySettingsToolStripMenuItem, "displaySettingsToolStripMenuItem"); // // displayStatusbarToolStripMenuItem // displayStatusbarToolStripMenuItem.Checked = true; displayStatusbarToolStripMenuItem.CheckState = CheckState.Checked; displayStatusbarToolStripMenuItem.Name = "displayStatusbarToolStripMenuItem"; resources.ApplyResources(displayStatusbarToolStripMenuItem, "displayStatusbarToolStripMenuItem"); // // toolStripSeparator12 // toolStripSeparator12.Name = "toolStripSeparator12"; resources.ApplyResources(toolStripSeparator12, "toolStripSeparator12"); // // useSystemThemeToolStripMenuItem // useSystemThemeToolStripMenuItem.Checked = true; useSystemThemeToolStripMenuItem.CheckState = CheckState.Checked; useSystemThemeToolStripMenuItem.Name = "useSystemThemeToolStripMenuItem"; resources.ApplyResources(useSystemThemeToolStripMenuItem, "useSystemThemeToolStripMenuItem"); // // toolStripSeparator33 // toolStripSeparator33.Name = "toolStripSeparator33"; resources.ApplyResources(toolStripSeparator33, "toolStripSeparator33"); // // autosizeAllColumnsToolStripMenuItem // autosizeAllColumnsToolStripMenuItem.Name = "autosizeAllColumnsToolStripMenuItem"; resources.ApplyResources(autosizeAllColumnsToolStripMenuItem, "autosizeAllColumnsToolStripMenuItem"); autosizeAllColumnsToolStripMenuItem.Click += autosizeAllColumnsToolStripMenuItem_Click; // // filteringToolStripMenuItem // filteringToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { advancedApplicationsToolStripMenuItem, basicApplicationsToolStripMenuItem, systemComponentsToolStripMenuItem, everythingToolStripMenuItem, toolStripSeparator20, automaticallyStartedToolStripMenuItem, onlyWebBrowsersToolStripMenuItem, toolStripSeparator31, viewTweaksToolStripMenuItem, viewUnregisteredToolStripMenuItem, viewUpdatesToolStripMenuItem, viewWindowsFeaturesToolStripMenuItem, viewWindowsStoreAppsToolStripMenuItem, toolStripSeparator28, searchToolStripMenuItem }); filteringToolStripMenuItem.Name = "filteringToolStripMenuItem"; resources.ApplyResources(filteringToolStripMenuItem, "filteringToolStripMenuItem"); filteringToolStripMenuItem.DropDownOpening += filteringToolStripMenuItem_DropDownOpening; // // advancedApplicationsToolStripMenuItem // advancedApplicationsToolStripMenuItem.Image = Properties.Resources.filter; advancedApplicationsToolStripMenuItem.Name = "advancedApplicationsToolStripMenuItem"; resources.ApplyResources(advancedApplicationsToolStripMenuItem, "advancedApplicationsToolStripMenuItem"); advancedApplicationsToolStripMenuItem.Click += advancedApplicationsToolStripMenuItem_Click; // // basicApplicationsToolStripMenuItem // basicApplicationsToolStripMenuItem.Name = "basicApplicationsToolStripMenuItem"; resources.ApplyResources(basicApplicationsToolStripMenuItem, "basicApplicationsToolStripMenuItem"); basicApplicationsToolStripMenuItem.Click += basicApplicationsToolStripMenuItem_Click; // // systemComponentsToolStripMenuItem // systemComponentsToolStripMenuItem.Name = "systemComponentsToolStripMenuItem"; resources.ApplyResources(systemComponentsToolStripMenuItem, "systemComponentsToolStripMenuItem"); systemComponentsToolStripMenuItem.Click += systemComponentsToolStripMenuItem_Click; // // everythingToolStripMenuItem // everythingToolStripMenuItem.Name = "everythingToolStripMenuItem"; resources.ApplyResources(everythingToolStripMenuItem, "everythingToolStripMenuItem"); everythingToolStripMenuItem.Click += everythingToolStripMenuItem_Click; // // toolStripSeparator20 // toolStripSeparator20.Name = "toolStripSeparator20"; resources.ApplyResources(toolStripSeparator20, "toolStripSeparator20"); // // automaticallyStartedToolStripMenuItem // automaticallyStartedToolStripMenuItem.Image = Properties.Resources.timer; automaticallyStartedToolStripMenuItem.Name = "automaticallyStartedToolStripMenuItem"; resources.ApplyResources(automaticallyStartedToolStripMenuItem, "automaticallyStartedToolStripMenuItem"); automaticallyStartedToolStripMenuItem.Click += automaticallyStartedToolStripMenuItem_Click; // // onlyWebBrowsersToolStripMenuItem // onlyWebBrowsersToolStripMenuItem.Name = "onlyWebBrowsersToolStripMenuItem"; resources.ApplyResources(onlyWebBrowsersToolStripMenuItem, "onlyWebBrowsersToolStripMenuItem"); onlyWebBrowsersToolStripMenuItem.Click += onlyWebBrowsersToolStripMenuItem_Click; // // toolStripSeparator31 // toolStripSeparator31.Name = "toolStripSeparator31"; resources.ApplyResources(toolStripSeparator31, "toolStripSeparator31"); // // viewTweaksToolStripMenuItem // viewTweaksToolStripMenuItem.Name = "viewTweaksToolStripMenuItem"; resources.ApplyResources(viewTweaksToolStripMenuItem, "viewTweaksToolStripMenuItem"); viewTweaksToolStripMenuItem.Click += viewTweaksToolStripMenuItem_Click; // // viewUnregisteredToolStripMenuItem // viewUnregisteredToolStripMenuItem.Name = "viewUnregisteredToolStripMenuItem"; resources.ApplyResources(viewUnregisteredToolStripMenuItem, "viewUnregisteredToolStripMenuItem"); viewUnregisteredToolStripMenuItem.Click += viewUnregisteredToolStripMenuItem_Click; // // viewUpdatesToolStripMenuItem // viewUpdatesToolStripMenuItem.Name = "viewUpdatesToolStripMenuItem"; resources.ApplyResources(viewUpdatesToolStripMenuItem, "viewUpdatesToolStripMenuItem"); viewUpdatesToolStripMenuItem.Click += viewUpdatesToolStripMenuItem_Click; // // viewWindowsFeaturesToolStripMenuItem // viewWindowsFeaturesToolStripMenuItem.Name = "viewWindowsFeaturesToolStripMenuItem"; resources.ApplyResources(viewWindowsFeaturesToolStripMenuItem, "viewWindowsFeaturesToolStripMenuItem"); viewWindowsFeaturesToolStripMenuItem.Click += viewWindowsFeaturesToolStripMenuItem_Click; // // viewWindowsStoreAppsToolStripMenuItem // viewWindowsStoreAppsToolStripMenuItem.Name = "viewWindowsStoreAppsToolStripMenuItem"; resources.ApplyResources(viewWindowsStoreAppsToolStripMenuItem, "viewWindowsStoreAppsToolStripMenuItem"); viewWindowsStoreAppsToolStripMenuItem.Click += viewWindowsStoreAppsToolStripMenuItem_Click; // // toolStripSeparator28 // toolStripSeparator28.Name = "toolStripSeparator28"; resources.ApplyResources(toolStripSeparator28, "toolStripSeparator28"); // // searchToolStripMenuItem // resources.ApplyResources(searchToolStripMenuItem, "searchToolStripMenuItem"); searchToolStripMenuItem.Name = "searchToolStripMenuItem"; searchToolStripMenuItem.Click += searchToolStripMenuItem_Click; // // basicOperationsToolStripMenuItem // basicOperationsToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { uninstallToolStripMenuItem, quietUninstallToolStripMenuItem, modifyToolStripMenuItem, toolStripSeparator2, toolStripMenuItem8, toolStripMenuItem1, toolStripMenuItem14, onlineSearchToolStripMenuItem, rateToolStripMenuItem1, toolStripSeparator15, propertiesToolStripMenuItem }); resources.ApplyResources(basicOperationsToolStripMenuItem, "basicOperationsToolStripMenuItem"); basicOperationsToolStripMenuItem.Name = "basicOperationsToolStripMenuItem"; basicOperationsToolStripMenuItem.DropDownOpening += basicOperationsToolStripMenuItem_DropDownOpening; // // uninstallToolStripMenuItem // resources.ApplyResources(uninstallToolStripMenuItem, "uninstallToolStripMenuItem"); uninstallToolStripMenuItem.Name = "uninstallToolStripMenuItem"; uninstallToolStripMenuItem.Click += RunLoudUninstall; // // quietUninstallToolStripMenuItem // resources.ApplyResources(quietUninstallToolStripMenuItem, "quietUninstallToolStripMenuItem"); quietUninstallToolStripMenuItem.Name = "quietUninstallToolStripMenuItem"; quietUninstallToolStripMenuItem.Click += RunQuietUninstall; // // modifyToolStripMenuItem // modifyToolStripMenuItem.Image = Properties.Resources.edit_box; modifyToolStripMenuItem.Name = "modifyToolStripMenuItem"; resources.ApplyResources(modifyToolStripMenuItem, "modifyToolStripMenuItem"); modifyToolStripMenuItem.Click += modifyToolStripMenuItem_Click; // // toolStripSeparator2 // toolStripSeparator2.Name = "toolStripSeparator2"; resources.ApplyResources(toolStripSeparator2, "toolStripSeparator2"); // // toolStripMenuItem8 // toolStripMenuItem8.DropDownItems.AddRange(new ToolStripItem[] { advancedClipCopyToolStripMenuItem, toolStripSeparator11, copyFullInformationToolStripMenuItem, toolStripMenuItem10, toolStripMenuItem11, toolStripMenuItem12, toolStripMenuItem13 }); resources.ApplyResources(toolStripMenuItem8, "toolStripMenuItem8"); toolStripMenuItem8.Name = "toolStripMenuItem8"; // // advancedClipCopyToolStripMenuItem // advancedClipCopyToolStripMenuItem.Name = "advancedClipCopyToolStripMenuItem"; resources.ApplyResources(advancedClipCopyToolStripMenuItem, "advancedClipCopyToolStripMenuItem"); advancedClipCopyToolStripMenuItem.Click += OpenAdvancedClipboardCopy; // // toolStripSeparator11 // toolStripSeparator11.Name = "toolStripSeparator11"; resources.ApplyResources(toolStripSeparator11, "toolStripSeparator11"); // // copyFullInformationToolStripMenuItem // copyFullInformationToolStripMenuItem.Name = "copyFullInformationToolStripMenuItem"; resources.ApplyResources(copyFullInformationToolStripMenuItem, "copyFullInformationToolStripMenuItem"); copyFullInformationToolStripMenuItem.Click += ClipboardCopyFullInformation; // // toolStripMenuItem10 // toolStripMenuItem10.Name = "toolStripMenuItem10"; resources.ApplyResources(toolStripMenuItem10, "toolStripMenuItem10"); toolStripMenuItem10.Click += ClipboardCopyProgramName; // // toolStripMenuItem11 // toolStripMenuItem11.Name = "toolStripMenuItem11"; resources.ApplyResources(toolStripMenuItem11, "toolStripMenuItem11"); toolStripMenuItem11.Click += ClipboardCopyGuids; // // toolStripMenuItem12 // toolStripMenuItem12.Name = "toolStripMenuItem12"; resources.ApplyResources(toolStripMenuItem12, "toolStripMenuItem12"); toolStripMenuItem12.Click += ClipboardCopyRegistryPath; // // toolStripMenuItem13 // toolStripMenuItem13.Name = "toolStripMenuItem13"; resources.ApplyResources(toolStripMenuItem13, "toolStripMenuItem13"); toolStripMenuItem13.Click += ClipboardCopyUninstallString; // // toolStripMenuItem1 // toolStripMenuItem1.DropDownItems.AddRange(new ToolStripItem[] { toolStripMenuItem5, toolStripMenuItem6, toolStripMenuItem7 }); resources.ApplyResources(toolStripMenuItem1, "toolStripMenuItem1"); toolStripMenuItem1.Name = "toolStripMenuItem1"; // // toolStripMenuItem5 // toolStripMenuItem5.Name = "toolStripMenuItem5"; resources.ApplyResources(toolStripMenuItem5, "toolStripMenuItem5"); toolStripMenuItem5.Click += OpenInstallLocation; // // toolStripMenuItem6 // toolStripMenuItem6.Name = "toolStripMenuItem6"; resources.ApplyResources(toolStripMenuItem6, "toolStripMenuItem6"); toolStripMenuItem6.Click += OpenUninstallerLocation; // // toolStripMenuItem7 // toolStripMenuItem7.Name = "toolStripMenuItem7"; resources.ApplyResources(toolStripMenuItem7, "toolStripMenuItem7"); toolStripMenuItem7.Click += OpenInstallationSource; // // toolStripMenuItem14 // toolStripMenuItem14.Name = "toolStripMenuItem14"; resources.ApplyResources(toolStripMenuItem14, "toolStripMenuItem14"); toolStripMenuItem14.Click += OpenAssociatedWebPage; // // onlineSearchToolStripMenuItem // onlineSearchToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { googleToolStripMenuItem, alternativeToToolStripMenuItem, slantcoToolStripMenuItem1, toolStripSeparator27, toolStripMenuItem17, toolStripMenuItem18, toolStripMenuItem20, toolStripMenuItem19 }); resources.ApplyResources(onlineSearchToolStripMenuItem, "onlineSearchToolStripMenuItem"); onlineSearchToolStripMenuItem.Name = "onlineSearchToolStripMenuItem"; // // googleToolStripMenuItem // googleToolStripMenuItem.Name = "googleToolStripMenuItem"; resources.ApplyResources(googleToolStripMenuItem, "googleToolStripMenuItem"); googleToolStripMenuItem.Click += googleToolStripMenuItem_Click; // // alternativeToToolStripMenuItem // alternativeToToolStripMenuItem.Name = "alternativeToToolStripMenuItem"; resources.ApplyResources(alternativeToToolStripMenuItem, "alternativeToToolStripMenuItem"); alternativeToToolStripMenuItem.Click += alternativeToToolStripMenuItem_Click; // // slantcoToolStripMenuItem1 // slantcoToolStripMenuItem1.Name = "slantcoToolStripMenuItem1"; resources.ApplyResources(slantcoToolStripMenuItem1, "slantcoToolStripMenuItem1"); slantcoToolStripMenuItem1.Click += slantcoToolStripMenuItem_Click; // // toolStripSeparator27 // toolStripSeparator27.Name = "toolStripSeparator27"; resources.ApplyResources(toolStripSeparator27, "toolStripSeparator27"); // // toolStripMenuItem17 // toolStripMenuItem17.Name = "toolStripMenuItem17"; resources.ApplyResources(toolStripMenuItem17, "toolStripMenuItem17"); toolStripMenuItem17.Click += fossHubcomToolStripMenuItem_Click; // // toolStripMenuItem18 // toolStripMenuItem18.Name = "toolStripMenuItem18"; resources.ApplyResources(toolStripMenuItem18, "toolStripMenuItem18"); toolStripMenuItem18.Click += sourceForgecomToolStripMenuItem_Click; // // toolStripMenuItem20 // toolStripMenuItem20.Name = "toolStripMenuItem20"; resources.ApplyResources(toolStripMenuItem20, "toolStripMenuItem20"); toolStripMenuItem20.Click += gitHubcomToolStripMenuItem_Click; // // toolStripMenuItem19 // toolStripMenuItem19.Name = "toolStripMenuItem19"; resources.ApplyResources(toolStripMenuItem19, "toolStripMenuItem19"); toolStripMenuItem19.Click += gitHubcomToolStripMenuItem_Click; // // rateToolStripMenuItem1 // rateToolStripMenuItem1.Image = Properties.Resources.star; rateToolStripMenuItem1.Name = "rateToolStripMenuItem1"; resources.ApplyResources(rateToolStripMenuItem1, "rateToolStripMenuItem1"); rateToolStripMenuItem1.Click += rateToolStripMenuItem_Click; // // toolStripSeparator15 // toolStripSeparator15.Name = "toolStripSeparator15"; resources.ApplyResources(toolStripSeparator15, "toolStripSeparator15"); // // propertiesToolStripMenuItem // propertiesToolStripMenuItem.Image = Properties.Resources.properties; propertiesToolStripMenuItem.Name = "propertiesToolStripMenuItem"; resources.ApplyResources(propertiesToolStripMenuItem, "propertiesToolStripMenuItem"); propertiesToolStripMenuItem.Click += OpenProperties; // // advancedOperationsToolStripMenuItem // advancedOperationsToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { manualUninstallToolStripMenuItem, msiUninstalltoolStripMenuItem, toolStripSeparator14, renameToolStripMenuItem, disableAutostartToolStripMenuItem, deleteToolStripMenuItem, toolStripSeparator5, createBackupToolStripMenuItem, openKeyInRegeditToolStripMenuItem, toolStripSeparator32, takeOwnershipToolStripMenuItem }); resources.ApplyResources(advancedOperationsToolStripMenuItem, "advancedOperationsToolStripMenuItem"); advancedOperationsToolStripMenuItem.Name = "advancedOperationsToolStripMenuItem"; advancedOperationsToolStripMenuItem.DropDownOpening += advancedOperationsToolStripMenuItem_DropDownOpening; // // manualUninstallToolStripMenuItem // manualUninstallToolStripMenuItem.Image = Properties.Resources.list; manualUninstallToolStripMenuItem.Name = "manualUninstallToolStripMenuItem"; resources.ApplyResources(manualUninstallToolStripMenuItem, "manualUninstallToolStripMenuItem"); manualUninstallToolStripMenuItem.Click += RunAdvancedUninstall; // // msiUninstalltoolStripMenuItem // msiUninstalltoolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { toolStripMenuItem2, toolStripMenuItem3, toolStripMenuItem4 }); msiUninstalltoolStripMenuItem.Name = "msiUninstalltoolStripMenuItem"; resources.ApplyResources(msiUninstalltoolStripMenuItem, "msiUninstalltoolStripMenuItem"); // // toolStripMenuItem2 // toolStripMenuItem2.Name = "toolStripMenuItem2"; resources.ApplyResources(toolStripMenuItem2, "toolStripMenuItem2"); toolStripMenuItem2.Click += msiInstallContextMenuStripItem_Click; // // toolStripMenuItem3 // toolStripMenuItem3.Name = "toolStripMenuItem3"; resources.ApplyResources(toolStripMenuItem3, "toolStripMenuItem3"); toolStripMenuItem3.Click += msiUninstallContextMenuStripItem_Click; // // toolStripMenuItem4 // toolStripMenuItem4.Name = "toolStripMenuItem4"; resources.ApplyResources(toolStripMenuItem4, "toolStripMenuItem4"); toolStripMenuItem4.Click += msiQuietUninstallContextMenuStripItem_Click; // // toolStripSeparator14 // toolStripSeparator14.Name = "toolStripSeparator14"; resources.ApplyResources(toolStripSeparator14, "toolStripSeparator14"); // // renameToolStripMenuItem // renameToolStripMenuItem.Name = "renameToolStripMenuItem"; resources.ApplyResources(renameToolStripMenuItem, "renameToolStripMenuItem"); renameToolStripMenuItem.Click += RenameEntries; // // disableAutostartToolStripMenuItem // disableAutostartToolStripMenuItem.Name = "disableAutostartToolStripMenuItem"; resources.ApplyResources(disableAutostartToolStripMenuItem, "disableAutostartToolStripMenuItem"); disableAutostartToolStripMenuItem.Click += disableAutostartToolStripMenuItem_Click; // // deleteToolStripMenuItem // resources.ApplyResources(deleteToolStripMenuItem, "deleteToolStripMenuItem"); deleteToolStripMenuItem.Name = "deleteToolStripMenuItem"; deleteToolStripMenuItem.Click += DeleteRegistryEntries; // // toolStripSeparator5 // toolStripSeparator5.Name = "toolStripSeparator5"; resources.ApplyResources(toolStripSeparator5, "toolStripSeparator5"); // // createBackupToolStripMenuItem // createBackupToolStripMenuItem.Name = "createBackupToolStripMenuItem"; resources.ApplyResources(createBackupToolStripMenuItem, "createBackupToolStripMenuItem"); createBackupToolStripMenuItem.Click += CreateRegistryBackup; // // openKeyInRegeditToolStripMenuItem // openKeyInRegeditToolStripMenuItem.Name = "openKeyInRegeditToolStripMenuItem"; resources.ApplyResources(openKeyInRegeditToolStripMenuItem, "openKeyInRegeditToolStripMenuItem"); openKeyInRegeditToolStripMenuItem.Click += OpenInRegedit; // // toolStripSeparator32 // toolStripSeparator32.Name = "toolStripSeparator32"; resources.ApplyResources(toolStripSeparator32, "toolStripSeparator32"); // // takeOwnershipToolStripMenuItem // takeOwnershipToolStripMenuItem.Name = "takeOwnershipToolStripMenuItem"; resources.ApplyResources(takeOwnershipToolStripMenuItem, "takeOwnershipToolStripMenuItem"); // // toolsToolStripMenuItem // toolsToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { openStartupManagerToolStripMenuItem, toolStripSeparator25, cleanUpProgramFilesToolStripMenuItem, targetMenuItem, uninstallFromDirectoryToolStripMenuItem, toolStripSeparator13, troubleshootUninstallProblemsToolStripMenuItem, startDiskCleanupToolStripMenuItem, tryToInstallNETV35ToolStripMenuItem, createRestorePointToolStripMenuItem, toolStripSeparator29, openProgramsAndFeaturesToolStripMenuItem, openSystemRestoreToolStripMenuItem, toolStripSeparator19, settingsToolStripMenuItem }); toolsToolStripMenuItem.Name = "toolsToolStripMenuItem"; resources.ApplyResources(toolsToolStripMenuItem, "toolsToolStripMenuItem"); toolsToolStripMenuItem.DropDownOpening += toolsToolStripMenuItem_DropDownOpening; // // openStartupManagerToolStripMenuItem // resources.ApplyResources(openStartupManagerToolStripMenuItem, "openStartupManagerToolStripMenuItem"); openStartupManagerToolStripMenuItem.Name = "openStartupManagerToolStripMenuItem"; openStartupManagerToolStripMenuItem.Click += openStartupManagerToolStripMenuItem_Click; // // toolStripSeparator25 // toolStripSeparator25.Name = "toolStripSeparator25"; resources.ApplyResources(toolStripSeparator25, "toolStripSeparator25"); // // cleanUpProgramFilesToolStripMenuItem // resources.ApplyResources(cleanUpProgramFilesToolStripMenuItem, "cleanUpProgramFilesToolStripMenuItem"); cleanUpProgramFilesToolStripMenuItem.Name = "cleanUpProgramFilesToolStripMenuItem"; cleanUpProgramFilesToolStripMenuItem.Click += cleanUpProgramFilesToolStripMenuItem_Click; // // targetMenuItem // targetMenuItem.Image = Properties.Resources.target; resources.ApplyResources(targetMenuItem, "targetMenuItem"); targetMenuItem.Name = "targetMenuItem"; targetMenuItem.Click += OpenTargetWindow; // // uninstallFromDirectoryToolStripMenuItem // uninstallFromDirectoryToolStripMenuItem.Name = "uninstallFromDirectoryToolStripMenuItem"; resources.ApplyResources(uninstallFromDirectoryToolStripMenuItem, "uninstallFromDirectoryToolStripMenuItem"); uninstallFromDirectoryToolStripMenuItem.Click += uninstallFromDirectoryToolStripMenuItem_Click; // // toolStripSeparator13 // toolStripSeparator13.Name = "toolStripSeparator13"; resources.ApplyResources(toolStripSeparator13, "toolStripSeparator13"); // // troubleshootUninstallProblemsToolStripMenuItem // troubleshootUninstallProblemsToolStripMenuItem.Name = "troubleshootUninstallProblemsToolStripMenuItem"; resources.ApplyResources(troubleshootUninstallProblemsToolStripMenuItem, "troubleshootUninstallProblemsToolStripMenuItem"); troubleshootUninstallProblemsToolStripMenuItem.Click += troubleshootUninstallProblemsToolStripMenuItem_Click; // // startDiskCleanupToolStripMenuItem // startDiskCleanupToolStripMenuItem.Name = "startDiskCleanupToolStripMenuItem"; resources.ApplyResources(startDiskCleanupToolStripMenuItem, "startDiskCleanupToolStripMenuItem"); startDiskCleanupToolStripMenuItem.Click += startDiskCleanupToolStripMenuItem_Click; // // tryToInstallNETV35ToolStripMenuItem // tryToInstallNETV35ToolStripMenuItem.Name = "tryToInstallNETV35ToolStripMenuItem"; resources.ApplyResources(tryToInstallNETV35ToolStripMenuItem, "tryToInstallNETV35ToolStripMenuItem"); tryToInstallNETV35ToolStripMenuItem.Click += tryToInstallNETV35ToolStripMenuItem_Click; // // createRestorePointToolStripMenuItem // createRestorePointToolStripMenuItem.Name = "createRestorePointToolStripMenuItem"; resources.ApplyResources(createRestorePointToolStripMenuItem, "createRestorePointToolStripMenuItem"); createRestorePointToolStripMenuItem.Click += createRestorePointToolStripMenuItem_Click; // // toolStripSeparator29 // toolStripSeparator29.Name = "toolStripSeparator29"; resources.ApplyResources(toolStripSeparator29, "toolStripSeparator29"); // // openProgramsAndFeaturesToolStripMenuItem // openProgramsAndFeaturesToolStripMenuItem.Name = "openProgramsAndFeaturesToolStripMenuItem"; resources.ApplyResources(openProgramsAndFeaturesToolStripMenuItem, "openProgramsAndFeaturesToolStripMenuItem"); openProgramsAndFeaturesToolStripMenuItem.Click += openProgramsAndFeaturesToolStripMenuItem_Click; // // openSystemRestoreToolStripMenuItem // openSystemRestoreToolStripMenuItem.Name = "openSystemRestoreToolStripMenuItem"; resources.ApplyResources(openSystemRestoreToolStripMenuItem, "openSystemRestoreToolStripMenuItem"); openSystemRestoreToolStripMenuItem.Click += openSystemRestoreToolStripMenuItem_Click; // // toolStripSeparator19 // toolStripSeparator19.Name = "toolStripSeparator19"; resources.ApplyResources(toolStripSeparator19, "toolStripSeparator19"); // // settingsToolStripMenuItem // resources.ApplyResources(settingsToolStripMenuItem, "settingsToolStripMenuItem"); settingsToolStripMenuItem.Name = "settingsToolStripMenuItem"; settingsToolStripMenuItem.Click += settingsToolStripMenuItem_Click; // // helpToolStripMenuItem // helpToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { openHelpToolStripMenuItem, startSetupWizardToolStripMenuItem, toolStripSeparator16, checkForUpdatesToolStripMenuItem, submitFeedbackToolStripMenuItem, toolStripSeparator18, resetSettingsToolStripMenuItem, uninstallBCUninstallToolstripMenuItem, toolStripSeparator17, aboutToolStripMenuItem }); helpToolStripMenuItem.Name = "helpToolStripMenuItem"; resources.ApplyResources(helpToolStripMenuItem, "helpToolStripMenuItem"); helpToolStripMenuItem.DropDownOpening += helpToolStripMenuItem_DropDownOpening; // // openHelpToolStripMenuItem // openHelpToolStripMenuItem.Image = Properties.Resources.information_circle; openHelpToolStripMenuItem.Name = "openHelpToolStripMenuItem"; resources.ApplyResources(openHelpToolStripMenuItem, "openHelpToolStripMenuItem"); openHelpToolStripMenuItem.Click += openHelpToolStripMenuItem_Click; // // startSetupWizardToolStripMenuItem // startSetupWizardToolStripMenuItem.Name = "startSetupWizardToolStripMenuItem"; resources.ApplyResources(startSetupWizardToolStripMenuItem, "startSetupWizardToolStripMenuItem"); startSetupWizardToolStripMenuItem.Click += OnClickStartSetupWizard; // // toolStripSeparator16 // toolStripSeparator16.Name = "toolStripSeparator16"; resources.ApplyResources(toolStripSeparator16, "toolStripSeparator16"); // // checkForUpdatesToolStripMenuItem // checkForUpdatesToolStripMenuItem.Name = "checkForUpdatesToolStripMenuItem"; resources.ApplyResources(checkForUpdatesToolStripMenuItem, "checkForUpdatesToolStripMenuItem"); checkForUpdatesToolStripMenuItem.Click += checkForUpdatesToolStripMenuItem_Click; // // submitFeedbackToolStripMenuItem // resources.ApplyResources(submitFeedbackToolStripMenuItem, "submitFeedbackToolStripMenuItem"); submitFeedbackToolStripMenuItem.Name = "submitFeedbackToolStripMenuItem"; submitFeedbackToolStripMenuItem.Click += OpenSubmitFeedbackWindow; // // toolStripSeparator18 // toolStripSeparator18.Name = "toolStripSeparator18"; resources.ApplyResources(toolStripSeparator18, "toolStripSeparator18"); // // resetSettingsToolStripMenuItem // resetSettingsToolStripMenuItem.Name = "resetSettingsToolStripMenuItem"; resources.ApplyResources(resetSettingsToolStripMenuItem, "resetSettingsToolStripMenuItem"); resetSettingsToolStripMenuItem.Click += ResetSettingsDialog; // // uninstallBCUninstallToolstripMenuItem // uninstallBCUninstallToolstripMenuItem.Name = "uninstallBCUninstallToolstripMenuItem"; resources.ApplyResources(uninstallBCUninstallToolstripMenuItem, "uninstallBCUninstallToolstripMenuItem"); uninstallBCUninstallToolstripMenuItem.Click += uninstallBCUninstallToolstripMenuItem_Click; // // toolStripSeparator17 // toolStripSeparator17.Name = "toolStripSeparator17"; resources.ApplyResources(toolStripSeparator17, "toolStripSeparator17"); // // aboutToolStripMenuItem // resources.ApplyResources(aboutToolStripMenuItem, "aboutToolStripMenuItem"); aboutToolStripMenuItem.Name = "aboutToolStripMenuItem"; aboutToolStripMenuItem.Click += aboutToolStripMenuItem_Click; // // debugToolStripMenuItem // debugToolStripMenuItem.Name = "debugToolStripMenuItem"; resources.ApplyResources(debugToolStripMenuItem, "debugToolStripMenuItem"); debugToolStripMenuItem.Click += OpenDebugWindow; // // createBackupFileDialog // createBackupFileDialog.DefaultExt = "reg"; createBackupFileDialog.FileName = "New Uninstaller Backup"; resources.ApplyResources(createBackupFileDialog, "createBackupFileDialog"); createBackupFileDialog.FileOk += createBackupFileDialog_FileOk; // // globalHotkeys1 // globalHotkeys1.ContainerControl = this; globalHotkeys1.StopWhenFormIsDisabled = true; globalHotkeys1.SuppressKeyPresses = true; // // splashScreen1 // splashScreen1.AutomaticallyClose = false; splashScreen1.ContainerControl = this; splashScreen1.SplashScreenImage = Properties.Resources._bcu_logo; // // usageTracker // usageTracker.ContainerControl = this; // // MainWindow // resources.ApplyResources(this, "$this"); AutoScaleMode = AutoScaleMode.Font; Controls.Add(splitContainer1); Controls.Add(settingsSidebarPanel); Controls.Add(menuStrip); KeyPreview = true; Name = "MainWindow"; FormClosing += MainWindow_FormClosing; FormClosed += MainWindow_FormClosed; Shown += MainWindow_Shown; splitContainer1.Panel1.ResumeLayout(false); splitContainer1.Panel2.ResumeLayout(false); splitContainer1.Panel2.PerformLayout(); ((ISupportInitialize)splitContainer1).EndInit(); splitContainer1.ResumeLayout(false); splitContainerListAndMap.Panel1.ResumeLayout(false); splitContainerListAndMap.Panel2.ResumeLayout(false); ((ISupportInitialize)splitContainerListAndMap).EndInit(); splitContainerListAndMap.ResumeLayout(false); listViewPanel.ResumeLayout(false); ((ISupportInitialize)uninstallerObjectListView).EndInit(); toolStrip.ResumeLayout(false); toolStrip.PerformLayout(); statusStrip1.ResumeLayout(false); statusStrip1.PerformLayout(); settingsSidebarPanel.ResumeLayout(false); settingsSidebarPanel.PerformLayout(); groupBox1.ResumeLayout(false); groupBox1.PerformLayout(); uninstallListContextMenuStrip.ResumeLayout(false); menuStrip.ResumeLayout(false); menuStrip.PerformLayout(); ResumeLayout(false); PerformLayout(); } #endregion private SplitContainer splitContainer1; internal ObjectListView uninstallerObjectListView; internal OLVColumn olvColumnDisplayName; internal OLVColumn olvColumnPublisher; internal OLVColumn olvColumnDisplayVersion; internal OLVColumn olvColumnUninstallString; internal OLVColumn olvColumnInstallDate; internal OLVColumn olvColumnIs64; internal OLVColumn olvColumnGuid; internal OLVColumn olvColumnSize; internal OLVColumn olvColumnInstallSource; internal OLVColumn olvColumnInstallLocation; internal OLVColumn olvColumnUninstallerKind; internal OLVColumn olvColumnAbout; internal OLVColumn olvColumnRegistryKeyName; internal OLVColumn olvColumnSystemComponent; internal OLVColumn olvColumnQuietUninstallString; internal OLVColumn olvColumnProtected; private SaveFileDialog exportDialog; private ContextMenuStrip uninstallListContextMenuStrip; private ToolStripMenuItem uninstallContextMenuStripItem; private ToolStripMenuItem propertiesContextMenuStripItem; private Panel settingsSidebarPanel; private MenuStrip menuStrip; private ToolStripMenuItem fileToolStripMenuItem; private ToolStripMenuItem reloadUninstallersToolStripMenuItem; private ToolStripMenuItem exportSelectedToolStripMenuItem; private ToolStripSeparator toolStripSeparator1; private ToolStripMenuItem exitToolStripMenuItem; private ToolStripMenuItem viewToolStripMenuItem; private ToolStripMenuItem displayToolbarToolStripMenuItem; private ToolStripMenuItem displaySettingsToolStripMenuItem; private ToolStripMenuItem basicOperationsToolStripMenuItem; private ToolStripMenuItem quietUninstallToolStripMenuItem; private ToolStripMenuItem propertiesToolStripMenuItem; private ToolStripSeparator toolStripSeparator2; private ToolStripMenuItem helpToolStripMenuItem; private ToolStripMenuItem openHelpToolStripMenuItem; private ToolStripMenuItem checkForUpdatesToolStripMenuItem; private ToolStripMenuItem resetSettingsToolStripMenuItem; private ToolStripMenuItem aboutToolStripMenuItem; private ToolStrip toolStrip; private ToolStripButton toolStripButton1; private ToolStripButton toolStripButtonUninstall; private ToolStripButton toolStripButtonProperties; private Label label1; private SaveFileDialog createBackupFileDialog; private ToolStripMenuItem quietUninstallContextMenuStripItem; private ToolStripSeparator toolStripSeparator8; private ToolStripMenuItem copyToClipboardContextMenuStripItem; private ToolStripMenuItem fullInformationCopyContextMenuStripItem; private ToolStripSeparator toolStripSeparator9; private ToolStripMenuItem programNameCopyContextMenuStripItem; private ToolStripMenuItem gUIDProductCodeCopyContextMenuStripItem; private ToolStripMenuItem fullRegistryPathCopyContextMenuStripItem; private ToolStripMenuItem uninstallStringCopyContextMenuStripItem; private ToolStripMenuItem deleteRegistryEntryContextMenuStripItem; private ToolStripMenuItem renameContextMenuStripItem; private ToolStripSeparator toolStripSeparator6; private ToolStripMenuItem openInExplorerContextMenuStripItem; private ToolStripMenuItem installLocationOpenInExplorerContextMenuStripItem; private ToolStripMenuItem uninstallerLocationOpenInExplorerContextMenuStripItem; private ToolStripMenuItem sourceLocationOpenInExplorerContextMenuStripItem; private ToolStripMenuItem openWebPageContextMenuStripItem; private ToolStripSeparator toolStripSeparator7; private ToolStripButton toolStripButton2; private ToolStripMenuItem uninstallUsingMsiExecContextMenuStripItem; private ToolStripMenuItem msiInstallContextMenuStripItem; private ToolStripMenuItem msiUninstallContextMenuStripItem; private ToolStripMenuItem msiQuietUninstallContextMenuStripItem; private ToolStripMenuItem uninstallToolStripMenuItem; private ToolStripMenuItem useSystemThemeToolStripMenuItem; private ToolStripMenuItem submitFeedbackToolStripMenuItem; private ToolStripMenuItem loadUninstallerListToolStripMenuItem; private ToolStripSeparator toolStripSeparator10; private ToolStripMenuItem toolStripMenuItem8; private ToolStripMenuItem copyFullInformationToolStripMenuItem; private ToolStripSeparator toolStripSeparator11; private ToolStripMenuItem toolStripMenuItem10; private ToolStripMenuItem toolStripMenuItem11; private ToolStripMenuItem toolStripMenuItem12; private ToolStripMenuItem toolStripMenuItem13; private ToolStripMenuItem toolStripMenuItem1; private ToolStripMenuItem toolStripMenuItem5; private ToolStripMenuItem toolStripMenuItem6; private ToolStripMenuItem toolStripMenuItem7; private ToolStripMenuItem toolStripMenuItem14; private ToolStripMenuItem advancedOperationsToolStripMenuItem; private ToolStripMenuItem deleteToolStripMenuItem; private ToolStripMenuItem renameToolStripMenuItem; private ToolStripMenuItem msiUninstalltoolStripMenuItem; private ToolStripMenuItem toolStripMenuItem2; private ToolStripMenuItem toolStripMenuItem3; private ToolStripMenuItem toolStripMenuItem4; private ToolStripSeparator toolStripSeparator5; private ToolStripMenuItem openKeyInRegeditToolStripMenuItem; private ToolStripMenuItem createBackupToolStripMenuItem; private ToolStripMenuItem lookUpOnlineToolStripMenuItem; private ToolStripMenuItem onlineSearchToolStripMenuItem; private PropertiesSidebar propertiesSidebar; private ToolStripMenuItem debugToolStripMenuItem; private ToolStripMenuItem uninstallBCUninstallToolstripMenuItem; private UsageTracker usageTracker; private StatusStrip statusStrip1; private ToolStripStatusLabel toolStripLabelStatus; private ToolStripStatusLabel toolStripLabelSize; private ToolStripStatusLabel toolStripLabelTotal; private ToolStripMenuItem displayStatusbarToolStripMenuItem; private ToolStripMenuItem toolsToolStripMenuItem; private ToolStripMenuItem openProgramsAndFeaturesToolStripMenuItem; private ToolStripSeparator toolStripSeparator13; private ToolStripMenuItem manualUninstallToolStripMenuItem1; private ToolStripMenuItem manualUninstallToolStripMenuItem; private ToolStripSeparator toolStripSeparator14; private ToolStripSeparator toolStripSeparator15; private ToolStripSeparator toolStripSeparator12; private ToolStripSeparator toolStripSeparator16; private ToolStripSeparator toolStripSeparator17; private ToolStripSeparator toolStripSeparator4; private ToolStripMenuItem startSetupWizardToolStripMenuItem; private ToolStripSeparator toolStripSeparator18; private ToolStripSeparator toolStripSeparator19; private ToolStripMenuItem settingsToolStripMenuItem; private ToolStripMenuItem cleanUpProgramFilesToolStripMenuItem; private ToolStripSeparator toolStripSeparator20; private ToolStripMenuItem searchToolStripMenuItem; internal Klocman.Subsystems.GlobalHotkeys globalHotkeys1; private ToolStripMenuItem showColorLegendToolStripMenuItem; private GroupBox groupBox1; private ToolStripSeparator toolStripSeparator21; private ToolStripButton toolStripButtonSelAll; private ToolStripButton toolStripButtonSelInv; private ToolStripButton toolStripButtonSelNone; private ToolStripSeparator toolStripSeparator22; private ToolStripMenuItem openStartupManagerToolStripMenuItem; internal OLVColumn olvColumnStartup; private Panel listViewPanel; private ToolStripMenuItem disableAutostartToolStripMenuItem; internal OLVColumn olvColumnRating; private ToolStripMenuItem rateToolStripMenuItem; private ToolStripMenuItem rateToolStripMenuItem1; private ToolStripButton toolStripButtonTarget; private ToolStripSeparator toolStripSeparator23; private ToolStripMenuItem viewWindowsStoreAppsToolStripMenuItem; internal UninstallTools.Controls.FilterEditor filterEditor1; private Button buttonAdvFiltering; private ToolStripSeparator toolStripSeparator24; private ToolStripButton toolStripButton7; private ToolStripButton toolStripButton8; private AdvancedFilters advancedFilters1; private ToolStripMenuItem advancedClipCopyToolStripMenuItem; private ToolStripMenuItem toolStripMenuItem9; private ToolStripMenuItem viewWindowsFeaturesToolStripMenuItem; private ToolStripMenuItem uninstallFromDirectoryToolStripMenuItem; private ToolStripMenuItem googleToolStripMenuItem; private ToolStripMenuItem alternativeToToolStripMenuItem; private ToolStripMenuItem toolStripMenuItem15; private ToolStripMenuItem toolStripMenuItem16; private ToolStripMenuItem openSystemRestoreToolStripMenuItem; private Klocman.Forms.SplashScreen splashScreen1; private ToolStripSeparator toolStripSeparator3; private ToolStripMenuItem runToolStripMenuItem; private ToolStripMenuItem viewUpdatesToolStripMenuItem; private ToolStripMenuItem targetMenuItem; private ToolStripSeparator toolStripSeparator25; private ToolStripSeparator toolStripSeparator26; private ToolStripMenuItem fossHubcomToolStripMenuItem; private ToolStripMenuItem sourceForgecomToolStripMenuItem; private ToolStripMenuItem fileHippocomToolStripMenuItem; private ToolStripSeparator toolStripSeparator27; private ToolStripMenuItem toolStripMenuItem17; private ToolStripMenuItem toolStripMenuItem18; private ToolStripMenuItem toolStripMenuItem19; private ToolStripMenuItem gitHubcomToolStripMenuItem; private ToolStripMenuItem toolStripMenuItem20; private ToolStripButton toolStripButtonModify; private ToolStripMenuItem modifyToolStripMenuItem; private ToolStripMenuItem excludeToolStripMenuItem; private ToolStripMenuItem includeToolStripMenuItem; private ToolStripSeparator toolStripSeparatorFiltering; private SplitContainer splitContainerListAndMap; private SimpleTreeMap.TreeMap treeMap1; private ToolStripMenuItem showTreemapToolStripMenuItem; private ToolStripSeparator toolStripSeparator28; private ToolStripMenuItem viewUnregisteredToolStripMenuItem; private ToolStripMenuItem tryToInstallNETV35ToolStripMenuItem; private ToolStripSeparator toolStripSeparator29; private ToolStripMenuItem startDiskCleanupToolStripMenuItem; private ToolStripSeparator toolStripSeparator30; private ToolStripMenuItem exportStoreAppsToPowerShellRemoveScriptToolStripMenuItem; private ToolStripMenuItem exportToABatchUninstallScriptToolStripMenuItem; private ToolStripMenuItem troubleshootUninstallProblemsToolStripMenuItem; private ToolStripMenuItem filteringToolStripMenuItem; private ToolStripMenuItem basicApplicationsToolStripMenuItem; private ToolStripMenuItem advancedApplicationsToolStripMenuItem; private ToolStripMenuItem systemComponentsToolStripMenuItem; private ToolStripMenuItem automaticallyStartedToolStripMenuItem; private ToolStripSeparator toolStripSeparator31; private ToolStripMenuItem everythingToolStripMenuItem; private ToolStripMenuItem onlyWebBrowsersToolStripMenuItem; private ToolStripMenuItem viewTweaksToolStripMenuItem; private ToolStripSeparator toolStripSeparator32; private ToolStripMenuItem takeOwnershipToolStripMenuItem; private ToolStripMenuItem slantcoToolStripMenuItem; private ToolStripMenuItem slantcoToolStripMenuItem1; private ToolStripMenuItem createRestorePointToolStripMenuItem; private ToolStripSeparator toolStripSeparator33; private ToolStripMenuItem autosizeAllColumnsToolStripMenuItem; } } ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/MainWindow.ar.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 الاسم الناشر تصنيف المستخدم الاصدار تاريخ التثبيت الحجم البدء 64 بت امر الغاء التثبيت حول الرابط مصدر التثبيت موقع التثبيت نوع غير مثبت مكون النظام حماية مفتاح مكتب التسجيل رمز المنتج امر الغاء التثبيت بهدوء اعاده تحميل التثبيت تحديد الكل الغاء تحديد الكل عكس التحديد الغاء التثبيت حسب الاطار او الدليل او الملف... الغاء التثبيت الغاء التثبيت بهدوء التعديل الخصائص الاعدادات التعليمات BCUninstaller فلترة متقدمة بحث &الغاء التثبيت الغاء التثبيت &بهدوء الغاء التثبيت &يدويا (/I) &تثبيت او تكوين (/X) &الغاء التثبيت (/X /qb) &الغاء التثبيت بهدوء MsiExec& الغاء التثبيت باستخدام ... تشغيل... المتقدمة... &المعلومات الكاملة اسم البرنامج GUID/رمز المنتج مسار مكتب التسجيل الكامل الغاء تثبيت السلسلة &نسخ الى الحافظة... &حذف ادخال التسجيل &اعاده تسميه... &موقع التثبيت &موقع الغاء التثبيت &موقع المصدر فتح في&المستكشف... فتح &صفحه ويب جوجل AlternativeTo.net FossHub.com SourceForge.net GitHub.com FileHippo.com &بحث على الانترنت معدل... &الخصائص XML files|*.xml تصدير خصائص الغاء التثبيت المحددة &تحديث المثبتات &افتح قائمه الغاء التثبيت... &اختيار التصدير... خ&روج &ملف اظهار توضيحات اللون اظهار &شريط الاداوات اظهار شريط &المعلومات اظهار &اعدادات الشريط الجانبي &استخدام موضوع النظام عرض التحديثات عرض تطبيقات مخزن وندوز بحث... &عرض &الغاء التثبيت الغاء التثبيت &بهدوء تعديل المتقدمة... &المعلومات الكاملة اسم البرنامج GUID/ رمز المنتج مسار التسجيل الكامل الغاء تثبيت السلسلة &نسخ الى الحافظة... &موقع التثبيت &موقع الغاء التثبيت &موقع المصدر فتح في &المستكشف... فتح &صفحه ويب جوجل حق النقض FossHub.com SourceForge.net GitHub.com FileHippo.com &بحث على الانترنت معدل... اظهار &الخصائص &العمليات الاساسيه الغاء التثبيت &يدويا (/I)&تثبيت او تكوين (/X)&الغاء التثبيت (/X /qb) الغاء تثبيت بهدوء MsiExec الغاء التثبيت باستخدام &اعاده تسميه... تعطيل التشغيل التلقائي &حذف مفتاح مكتب التسجيل انشاء &نسخ احتياطي... &فتح المفتاح في مكتب التسجيل &العمليات المتقدمة فتح اداره بدء التشغيل &تنظيف "ملفات البرنامج" المجلدات... الغاء التثبيت حسب الاطار او الدليل او الملف... الغاء التثبيت من الدليل... "فتح "&البرامج والميزات "فتح "استرداد النظام &الاعدادات &الاداوات فتح &التعليمات بدء تشغيل معالج الاعداد التحقق من وجود تحديثات ارسال الملاحظات... اعاده تعيين الاعدادات الغاء تثبيت المثبت &حول &التعليمات فتح نافذه &التصحيح ملفات مكتب التسجيل|*.reg انشاء نسخ احتياطي لمكتب التسجيل حماقة سائبة الغاء التثبيت استبعاد تشمل اظهار الشجرة &الخريطة عرض الغير مسجل عرض ميزات وندوز انشاء نقطه استعاده جديده ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/MainWindow.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using BrightIdeasSoftware; using BulkCrapUninstaller.Functions; using BulkCrapUninstaller.Functions.ApplicationList; using BulkCrapUninstaller.Functions.Tools; using BulkCrapUninstaller.Functions.Tracking; using BulkCrapUninstaller.Properties; using Klocman.Binding.Settings; using Klocman.Events; using Klocman.Extensions; using Klocman.Forms; using Klocman.Forms.Tools; using Klocman.IO; using Klocman.Native; using Klocman.Subsystems; using Klocman.Tools; using SimpleTreeMap; using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Threading; using System.Windows.Forms; using UninstallTools; using UninstallTools.Dialogs; using UninstallTools.Factory; using UninstallTools.Lists; using UninstallTools.Uninstaller; namespace BulkCrapUninstaller.Forms { internal sealed partial class MainWindow : Form { private string MainTitleBarText { get; } public static string CertificateCacheFilename { get; } = Path.Combine(Program.AssemblyLocation.FullName, "CertCache.xml"); public static CertificateCache CertificateCache { get; } = new(CertificateCacheFilename); private readonly UninstallerListViewUpdater _listView; private readonly SettingTools _setMan; private readonly WindowStyleController _styleController; private readonly AppUninstaller _appUninstaller; private readonly UninstallerListConfigurator _uninstallerListConfigurator; private readonly ListLegendWindow _listLegendWindow = new(); private DebugWindow _debugWindow; private bool _previousListLegendState = true; private bool _anyStoreApps; private bool _anyWinFeatures; private bool _anyOrphans; private bool _anyProtected; private bool _anySysComponents; private bool _anyUpdates; private bool _anyInvalid; private bool _anyTweaks; /// /// Set to false in the list view clicked event. Prevents firing of extra CellEditStarting events. /// Used to fix buggy ObjectListView. /// private bool _ignoreCellEdit; private readonly UninstallerListPostProcesser _uninstallerListPostProcesser; public MainWindow() { Opacity = 0; Application.DoEvents(); InitializeComponent(); // Setup settings _setMan = new SettingTools(Settings.Default.SettingBinder, this); _setMan.LoadSettings(); BindControlsToSettings(); // Finish up setting controls and window, suspend after settings have loaded SuspendLayout(); ToolStripManager.Renderer = new ToolStripProfessionalRenderer(new StandardSystemColorTable()) { RoundedEdges = true }; // Disable until the first list refresh finishes LockApplication(true); SetupBasicSettingBindings(); // Setup list view _listView = new UninstallerListViewUpdater(this); if (_setMan.Selected.Settings.CacheCertificates) CertificateCache.LoadCertificateCache(); _uninstallerListPostProcesser = new UninstallerListPostProcesser(objects => { uninstallerObjectListView.RefreshObjects(objects); }, CertificateCache); // Start the processing thread when user changes the test certificates option _setMan.Selected.Subscribe(OnTestCertificatesChanged, x => x.AdvancedTestCertificates, this); _uninstallerListConfigurator = new UninstallerListConfigurator(this); _uninstallerListConfigurator.AfterFiltering += (x, y) => _uninstallerListPostProcesser.StartProcessingThread(_listView.FilteredUninstallers); _uninstallerListConfigurator.AfterFiltering += RefreshStatusbarTotalLabel; _appUninstaller = new AppUninstaller(_listView.InitiateListRefresh, LockApplication, SetVisible); toolStripButtonSelAll.Click += _listView.SelectAllItems; toolStripButtonSelNone.Click += _listView.DeselectAllItems; toolStripButtonSelInv.Click += _listView.InvertSelectedItems; _uninstallerListPostProcesser.UninstallerPostprocessingProgressUpdate += UpdateStatusbarOnPostprocessingUpdate; _uninstallerListPostProcesser.UninstallerFileLock = _appUninstaller.PublicUninstallLock; _listView.ListRefreshIsRunningChanged += listView_ListRefreshIsRunningChanged; // Filter changed events advancedFilters1.CurrentListChanged += RefreshSidebarVisibility; advancedFilters1.CurrentListChanged += (sender, args) => { _uninstallerListConfigurator.FilteringOverride = advancedFilters1.CurrentList; _uninstallerListConfigurator.UpdateColumnFiltering(_listView.AllUninstallers.Any()); }; advancedFilters1.FiltersChanged += (sender, args) => { if (_uninstallerListConfigurator.FilteringOverride != null) _uninstallerListConfigurator.UpdateColumnFiltering(_listView.AllUninstallers.Any()); }; advancedFilters1.CurrentListFileNameChanged += RefreshTitleBar; advancedFilters1.UnsavedChangesChanged += RefreshTitleBar; advancedFilters1.SelectedEntryGetter = () => _listView.SelectedUninstallers; // Setup update manager, skip at first boot to let user change the setting UpdateGrabber.Setup(); if (!_setMan.Selected.Settings.MiscFirstRun) { BackgroundSearchForUpdates(); } // Setup the main window Icon = Resources.Icon_Logo; // This is a duplicate of the about window logic-it doesn't have overhead but should probably be refactored. Assembly.GetExecutingAssembly().Modules.First().GetPEKind(out var pekind, out var ifmachine); bool isProbablyARM64; if (Enum.IsDefined(ifmachine)) { isProbablyARM64 = false; } else // Work around .NET 6 not having WoA64 definitions in GetPEKind { isProbablyARM64 = true; } MainTitleBarText = Text.Append(" v", Program.AssemblyVersion.ToString(Program.AssemblyVersion.Build != 0 ? 3 : 2)) .AppendIf(!Program.IsInstalled, " ", Localisable.StrIsPortable) .AppendIf(ProcessTools.Is64BitProcess, " ", Localisable.Str64Bit) .AppendIf(isProbablyARM64, " ", "ARM") .AppendIf(Program.EnableDebug, " ", Localisable.StrDebug); Text = MainTitleBarText; Console.WriteLine(MainTitleBarText); _styleController = new WindowStyleController(this); // Initialize the status bar toolStripLabelStatus_TextChanged(this, EventArgs.Empty); // Debug stuff var isDebug = Program.EnableDebug; debugToolStripMenuItem.Enabled = isDebug; debugToolStripMenuItem.Visible = isDebug; if (isDebug) _setMan.Selected.Settings.AdvancedSimulate = true; // Tracking UsageManager.DataSender = new DatabaseStatSender(Settings.Default.MiscUserId); // Misc filterEditor1.ComparisonMethodChanged += SearchCriteriaChanged; MessageBoxes.DefaultOwner = this; LoadingDialog.DefaultOwner = this; PremadeDialogs.DefaultOwner = this; PremadeDialogs.SendErrorAction = NBug.Exceptions.Report; SetupHotkeys(); treeMap1.ObjectNameGetter = o => ((ApplicationUninstallerEntry)o).DisplayName; treeMap1.ObjectValueGetter = o => ((ApplicationUninstallerEntry)o).EstimatedSize.GetKbSize(); treeMap1.ObjectColorGetter = o => ApplicationListConstants.GetApplicationTreemapColor((ApplicationUninstallerEntry)o); _uninstallerListPostProcesser.UninstallerPostprocessingProgressUpdate += UpdateTreemapOnPostprocessingUpdate; _uninstallerListConfigurator.AfterFiltering += UpdateTreeMap; uninstallerObjectListView.SelectionChanged += (sender, args) => treeMap1.SetSelectedObjects(uninstallerObjectListView.SelectedObjects.Cast()); treeMap1.SliceClicked += OnTreeMapSliceClicked; treeMap1.SliceRightClicked += OnTreeMapSliceRightClicked; treeMap1.SliceHovered += OnTreeMapSliceHovered; _setMan.Selected.BindControl(showTreemapToolStripMenuItem, settings => settings.ShowTreeMap, this); _setMan.Selected.Subscribe((x, y) => splitContainerListAndMap.Panel2Collapsed = !y.NewValue, settings => settings.ShowTreeMap, this); uninstallerObjectListView.ContextMenuStrip = uninstallListContextMenuStrip; } protected override void OnDpiChanged(DpiChangedEventArgs e) { base.OnDpiChanged(e); try { var scaleChange = e.DeviceDpiNew / (double)e.DeviceDpiOld; if (toolStripLabelSize != null) toolStripLabelSize.Width = (int)Math.Round(toolStripLabelSize.Width * scaleChange); if (toolStripLabelTotal != null) toolStripLabelTotal.Width = (int)Math.Round(toolStripLabelTotal.Width * scaleChange); } catch (SystemException exception) { Console.WriteLine(exception); } } protected override void OnFormClosed(FormClosedEventArgs e) { try { new Thread(UsageTrackerSendData).Start(); DisposeListPostProcessor(this, e); _listLegendWindow?.Dispose(); _uninstallerListConfigurator?.Dispose(); _debugWindow?.Dispose(); _uninstallerListPostProcesser?.Dispose(); } catch (Exception exception) { // Eat non-critical exceptions to let the app close in peace Console.WriteLine(exception); } base.OnFormClosed(e); } private void OnTreeMapSliceHovered(object sender, TreeMap.SliceEventArgs args) { toolStripLabelStatus.Text = args.Rectangle.Slice.ToElementNames(); toolStripLabelSize.Text = FileSize.SumFileSizes(args.Objects.Cast().Select(x => x.EstimatedSize)).ToString(); } private void OnTreeMapSliceRightClicked(object sender, TreeMap.SliceClickedEventArgs args) { if (args.AddToSelection || !uninstallerObjectListView.SelectedObjects.Contains(args.Objects.FirstOrDefault())) OnTreeMapSliceClicked(sender, args); uninstallListContextMenuStrip.Show(MousePosition); } private void SetupBasicSettingBindings() { _setMan.Selected.Subscribe((x, y) => { var paths = y.NewValue.SplitNewlines(StringSplitOptions.RemoveEmptyEntries); var trimmed = paths.Select(path => path.Trim().Trim('"').Trim()).ToArray(); UninstallToolsGlobalConfig.CustomProgramFiles = trimmed; }, x => x.FoldersCustomProgramDirs, this); _setMan.Selected.Subscribe((x, y) => _listView.RefreshList(), x => x.AdvancedHighlightSpecial, this); _setMan.Selected.Subscribe(OnApplicationListVisibleItemsChanged, x => x.AdvancedTestCertificates, this); _setMan.Selected.Subscribe(OnApplicationListVisibleItemsChanged, x => x.AdvancedTestInvalid, this); _setMan.Selected.Subscribe(OnApplicationListVisibleItemsChanged, x => x.AdvancedHighlightSpecial, this); _setMan.Selected.Subscribe(OnApplicationListVisibleItemsChanged, x => x.FilterShowStoreApps, this); _setMan.Selected.Subscribe(OnApplicationListVisibleItemsChanged, x => x.FilterShowWinFeatures, this); _setMan.Selected.Subscribe(OnApplicationListVisibleItemsChanged, x => x.AdvancedDisplayOrphans, this); _setMan.Selected.Subscribe((x, y) => UninstallToolsGlobalConfig.ScanSteam = y.NewValue, x => x.ScanSteam, this); _setMan.Selected.Subscribe((x, y) => UninstallToolsGlobalConfig.ScanStoreApps = y.NewValue, x => x.ScanStoreApps, this); _setMan.Selected.Subscribe((x, y) => UninstallToolsGlobalConfig.ScanWinFeatures = y.NewValue, x => x.ScanWinFeatures, this); _setMan.Selected.Subscribe((x, y) => UninstallToolsGlobalConfig.ScanWinUpdates = y.NewValue, x => x.ScanWinUpdates, this); _setMan.Selected.Subscribe((x, y) => UninstallToolsGlobalConfig.ScanDrives = y.NewValue, x => x.ScanDrives, this); _setMan.Selected.Subscribe((x, y) => UninstallToolsGlobalConfig.ScanRegistry = y.NewValue, x => x.ScanRegistry, this); _setMan.Selected.Subscribe((x, y) => UninstallToolsGlobalConfig.ScanPreDefined = y.NewValue, x => x.ScanPreDefined, this); _setMan.Selected.Subscribe((x, y) => UninstallToolsGlobalConfig.ScanChocolatey = y.NewValue, x => x.ScanChocolatey, this); _setMan.Selected.Subscribe((x, y) => UninstallToolsGlobalConfig.ScanOculus = y.NewValue, x => x.ScanOculus, this); _setMan.Selected.Subscribe((x, y) => UninstallToolsGlobalConfig.ScanScoop = y.NewValue, x => x.ScanScoop, this); _setMan.Selected.Subscribe((x, y) => UninstallToolsGlobalConfig.AutoDetectCustomProgramFiles = y.NewValue, x => x.FoldersAutoDetect, this); _setMan.Selected.Subscribe((x, y) => UninstallToolsGlobalConfig.AutoDetectScanRemovable = y.NewValue, x => x.FoldersScanRemovable, this); _setMan.Selected.Subscribe((x, y) => UninstallToolsGlobalConfig.QuietAutomatization = y.NewValue, x => x.QuietAutomatization, this); _setMan.Selected.Subscribe((x, y) => UninstallToolsGlobalConfig.QuietAutomatizationKillStuck = y.NewValue, x => x.QuietAutomatizationKillStuck, this); _setMan.Selected.Subscribe((x, y) => UninstallToolsGlobalConfig.UseQuietUninstallDaemon = y.NewValue, x => x.QuietUseDaemon, this); _setMan.Selected.Subscribe((x, y) => UninstallToolsGlobalConfig.EnableAppInfoCache = y.NewValue, x => x.CacheAppInfo, this); _setMan.Selected.Subscribe((o, args) => _listView.RefreshList(), x => x.MiscColorblind, this); } private void UpdateTreemapOnPostprocessingUpdate(object x, CountingUpdateEventArgs y) { var update = y.Value == y.Maximum || (y.Value - 1) % 100 == 0; if (update) this.SafeInvoke(() => UpdateTreeMap(x, y)); } private void UpdateStatusbarOnPostprocessingUpdate(object x, CountingUpdateEventArgs y) { string result = null; if (y.Value == y.Maximum) result = string.Empty; else if (y.Maximum % 15 == 0) { // Can crash on some locales even though format string is correct try { result = string.Format(CultureInfo.CurrentCulture, Localisable.MainWindow_Statusbar_ProcessingUninstallers, y.Maximum); } catch (FormatException ex) { Console.WriteLine(ex); } } if (result != null) this.SafeInvoke(() => toolStripLabelStatus.Text = result); } private void DisposeListPostProcessor(object x, FormClosedEventArgs y) { try { if (_setMan.Selected.Settings.CacheCertificates) CertificateCache.SaveCertificateCache(); else CertificateCache.ClearChache(); if (!_setMan.Selected.Settings.CacheAppInfo) File.Delete(UninstallToolsGlobalConfig.AppInfoCachePath); } catch (SystemException e) { Console.WriteLine(@"Failed to delete cache: " + e); } _uninstallerListPostProcesser.Dispose(); } private void OnTestCertificatesChanged(object x, SettingChangedEventArgs y) { if (!_listView.FirstRefreshCompleted) return; if (y.NewValue) _uninstallerListPostProcesser.StartProcessingThread(_listView.FilteredUninstallers); else { _uninstallerListPostProcesser.StopProcessingThread(); SafeRefreshObjects(_listView.AllUninstallers.Where(u => u.IsCertificateValid(true).HasValue)); } } private void SafeRefreshObjects(IEnumerable itemsToUpdate) { if (!_listView.CheckIsAppDisposed()) { uninstallerObjectListView.SuspendLayout(); uninstallerObjectListView.RefreshObjects(itemsToUpdate.ToList()); uninstallerObjectListView.ResumeLayout(); } } private void OnTreeMapSliceClicked(object sender, TreeMap.SliceClickedEventArgs args) { var list = args.Objects.ToList(); if (args.AddToSelection) list.AddRange(uninstallerObjectListView.SelectedObjects.Cast()); uninstallerObjectListView.SelectObjects(list); uninstallerObjectListView.EnsureModelVisible(list.FirstOrDefault()); uninstallerObjectListView.Focus(); } private void UpdateTreeMap(object sender, EventArgs args) { treeMap1.Populate(_listView.FilteredUninstallers); } private void OnApplicationListVisibleItemsChanged(object sender, EventArgs e) { UpdateListView(); } private void UpdateListView() { var force = advancedFilters1.CurrentList != null; _listLegendWindow.ListLegend.CertificatesEnabled = force || _setMan.Selected.Settings.AdvancedTestCertificates; _listLegendWindow.ListLegend.InvalidEnabled = force || _setMan.Selected.Settings.AdvancedTestInvalid && _anyInvalid; _listLegendWindow.ListLegend.StoreAppEnabled = force || _setMan.Selected.Settings.FilterShowStoreApps && _anyStoreApps && _setMan.Selected.Settings.AdvancedHighlightSpecial; _listLegendWindow.ListLegend.OrphanedEnabled = force || _setMan.Selected.Settings.AdvancedDisplayOrphans && _anyOrphans && _setMan.Selected.Settings.AdvancedHighlightSpecial; _listLegendWindow.ListLegend.WinFeatureEnabled = force || _setMan.Selected.Settings.FilterShowWinFeatures && _anyWinFeatures && _setMan.Selected.Settings.AdvancedHighlightSpecial; _listLegendWindow.UpdatePosition(uninstallerObjectListView); } private void RefreshTitleBar(object sender, EventArgs e) { var result = MainTitleBarText; if (!string.IsNullOrEmpty(advancedFilters1.CurrentListFileName) || advancedFilters1.UnsavedChanges) { var changedDot = advancedFilters1.UnsavedChanges ? "*" : string.Empty; result = string.Format(CultureInfo.CurrentCulture, "{0} [{1}{2}]", result, advancedFilters1.CurrentListFileName ?? string.Empty, changedDot); } Text = result; } /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing) { try { components?.Dispose(); } catch (NullReferenceException) { // ObjectListView sometimes throws it at exit } _listView?.Dispose(); } try { base.Dispose(disposing); } catch (InvalidOperationException) { } } private void SearchCriteriaChanged(object sender, EventArgs e) { _uninstallerListConfigurator.UpdateColumnFiltering(_listView.AllUninstallers.Any()); } public void LockApplication(bool value) { this.SafeInvoke(() => { UseWaitCursor = value; foreach (Control control in Controls) control.Enabled = !value; Refresh(); }); } private void SetVisible(bool val) { this.SafeInvoke(() => { Visible = val; if (_listLegendWindow != null) { if (val) { _setMan.Selected.Settings.UninstallerListShowLegend = _previousListLegendState; //_listLegendWindow.Visible = _previousListLegendState; } else { _previousListLegendState = _setMan.Selected.Settings.UninstallerListShowLegend; _listLegendWindow.Visible = false; } } }); } internal static void OpenUrls(IEnumerable urls) { if (WindowsTools.IsNetworkAvailable()) { var urlList = urls as IList ?? urls.ToList(); if (MessageBoxes.OpenUrlsMessageBox(urlList.Count)) { try { urlList.ForEach(x => Process.Start(new ProcessStartInfo(x.AbsoluteUri) { UseShellExecute = true })); } catch (Exception e) { MessageBoxes.OpenUrlError(e); } } } else MessageBoxes.NoNetworkConnected(); } private void aboutToolStripMenuItem_Click(object sender, EventArgs e) { using (var abox = new AboutBox()) { abox.ShowDialog(); } } private void advancedOperationsToolStripMenuItem_DropDownOpening(object sender, EventArgs e) { var selectionCount = _listView.SelectedUninstallerCount; openKeyInRegeditToolStripMenuItem.Enabled = selectionCount == 1; deleteToolStripMenuItem.Enabled = selectionCount > 0; createBackupToolStripMenuItem.Enabled = selectionCount > 0; msiUninstalltoolStripMenuItem.Enabled = selectionCount == 1; var autostart = _listView.SelectedUninstallers.Any( u => u.StartupEntries != null && u.StartupEntries.Any(se => !se.Disabled)); disableAutostartToolStripMenuItem.Enabled = autostart; // Take ownership list var ownershipList = takeOwnershipToolStripMenuItem.DropDownItems.Cast().ToList(); takeOwnershipToolStripMenuItem.DropDownItems.Clear(); foreach (var dropDownItem in ownershipList) dropDownItem.Dispose(); takeOwnershipToolStripMenuItem.DropDownItems.AddRange( _listView.SelectedUninstallers .SelectMany(x => new[] { x.InstallLocation, x.UninstallerLocation }) .Where(dir => !string.IsNullOrEmpty(dir)) .DistinctBy(x => x.ToLowerInvariant()) .OrderBy(x => x) .Select(dir => (ToolStripItem)new ToolStripMenuItem(dir, null, (obj, args) => TakeOwnership(dir))) .ToArray()); } private static void TakeOwnership(string directoryPath) { PremadeDialogs.StartProcessSafely("cmd.exe", $"/c takeown /f \"{directoryPath}\" && icacls \"{directoryPath}\" /grant administrators:F && pause"); } private void BackgroundSearchForUpdates() { UpdateGrabber.AutoUpdate(() => _listView.FirstRefreshCompleted, v => this.SafeInvoke(() => UpdateGrabber.AskAndBeginUpdate(v))); } private void basicOperationsToolStripMenuItem_DropDownOpening(object sender, EventArgs e) { var selectionCount = _listView.SelectedUninstallerCount; uninstallToolStripMenuItem.Enabled = selectionCount > 0; quietUninstallToolStripMenuItem.Enabled = selectionCount > 0; propertiesToolStripMenuItem.Enabled = selectionCount > 0; modifyToolStripMenuItem.Enabled = selectionCount == 1 && !string.IsNullOrEmpty(_listView.SelectedUninstallers.FirstOrDefault()?.ModifyPath); } private void BindControlsToSettings() { var settings = _setMan.Selected; // Bind controls to their respective settings settings.BindControl(displayToolbarToolStripMenuItem, x => x.ToolbarsShowToolbar, this); settings.BindControl(displaySettingsToolStripMenuItem, x => x.ToolbarsShowSettings, this); settings.BindControl(useSystemThemeToolStripMenuItem, x => x.WindowUseSystemTheme, this); settings.BindControl(displayStatusbarToolStripMenuItem, x => x.ToolbarsShowStatusbar, this); settings.BindControl(showColorLegendToolStripMenuItem, x => x.UninstallerListShowLegend, this); settings.Subscribe(RefreshSidebarVisibility, x => x.ToolbarsShowSettings, this); settings.Subscribe((x, y) => toolStrip.Visible = y.NewValue, x => x.ToolbarsShowToolbar, this); settings.Subscribe((x, y) => _styleController.SetStyles(y.NewValue), x => x.WindowUseSystemTheme, this); settings.Subscribe((x, y) => statusStrip1.Visible = y.NewValue, x => x.ToolbarsShowStatusbar, this); settings.Subscribe((x, y) => { if (_listView.CheckIsAppDisposed()) return; try { uninstallerObjectListView.CheckBoxes = y.NewValue; } catch (InvalidOperationException) { // Setting CheckBoxes value throws this exception (even though it works fine). } _listView.RefreshList(); uninstallerObjectListView_SelectedChanged(this, EventArgs.Empty); }, x => x.UninstallerListUseCheckboxes, this); settings.Subscribe((x, y) => { if (_listView.CheckIsAppDisposed()) return; uninstallerObjectListView.ShowGroups = y.NewValue; _listView.RefreshList(); }, x => x.UninstallerListUseGroups, this); settings.Subscribe(RefreshList, x => x.FilterHideMicrosoft, this); settings.Subscribe(RefreshList, x => x.FilterShowUpdates, this); settings.Subscribe(RefreshList, x => x.FilterShowSystemComponents, this); settings.Subscribe(RefreshList, x => x.FilterShowProtected, this); settings.Subscribe(RefreshList, x => x.FilterShowStoreApps, this); settings.Subscribe(RefreshList, x => x.FilterShowWinFeatures, this); settings.Subscribe(RefreshList, x => x.FilterShowTweaks, this); settings.Subscribe((sender, args) => { if (_listView.CheckIsAppDisposed()) return; olvColumnRating.IsVisible = args.NewValue; uninstallerObjectListView.RebuildColumns(); }, x => x.MiscUserRatings, this); } private void RefreshSidebarVisibility(object sender, EventArgs e) { this.BeginControlUpdate(); SuspendLayout(); bool ulistOpen = IsAdvancedFilteringEnabled; splitContainer1.Panel1Collapsed = !ulistOpen; splitContainer1.Panel1.Enabled = ulistOpen; var sidebarOpen = _setMan.Selected.Settings.ToolbarsShowSettings && !ulistOpen; settingsSidebarPanel.Visible = sidebarOpen; settingsSidebarPanel.Enabled = sidebarOpen; OnApplicationListVisibleItemsChanged(sender, e); ResumeLayout(); this.EndControlUpdate(); } private bool IsAdvancedFilteringEnabled => advancedFilters1.CurrentList != null; private void checkForUpdatesToolStripMenuItem_Click(object sender, EventArgs e) { if (WindowsTools.IsNetworkAvailable()) { LockApplication(true); UpdateGrabber.LookForUpdates(); LockApplication(false); } else MessageBoxes.NoNetworkConnected(); } private void cleanUpProgramFilesToolStripMenuItem_Click(object sender, EventArgs e) { _appUninstaller.SearchForAndRemoveProgramFilesJunk(_listView.AllUninstallers); } private void ClipboardCopyFullInformation(object x, EventArgs y) { ImportExport.CopyFullInformationToClipboard(_listView.SelectedUninstallers); } private void ClipboardCopyGuids(object x, EventArgs y) { ImportExport.CopyGuidsToClipboard(_listView.SelectedUninstallers); } private void ClipboardCopyProgramName(object x, EventArgs y) { ImportExport.CopyNamesToClipboard(_listView.SelectedUninstallers); } private void ClipboardCopyRegistryPath(object x, EventArgs y) { ImportExport.CopyRegKeysToClipboard(_listView.SelectedUninstallers); } private void ClipboardCopyUninstallString(object x, EventArgs y) { ImportExport.CopyUninstallStringsToClipboard(_listView.SelectedUninstallers); } private void createBackupFileDialog_FileOk(object sender, CancelEventArgs e) { if (!_listView.SelectedUninstallers.Any()) { e.Cancel = true; return; } try { RegistryTools.ExportRegistry(createBackupFileDialog.FileName, _listView.SelectedUninstallers.Select(x => x.RegistryPath)); } catch (Exception ex) { MessageBoxes.ExportFailed(ex.Message, this); e.Cancel = true; } } private void CreateRegistryBackup(object sender, EventArgs e) { createBackupFileDialog.ShowDialog(); } private void DeleteRegistryEntries(object sender, EventArgs eventArgs) { if (_listView.SelectedUninstallerCount == 0) return; var items = _listView.SelectedUninstallers.ToArray(); var protectedItems = items.Where(x => x.IsProtected).ToArray(); if (!_setMan.Selected.Settings.AdvancedDisableProtection && protectedItems.Any()) { var affectedKeyNames = protectedItems.Select(x => x.DisplayName).ToArray(); if (MessageBoxes.ProtectedItemsWarningQuestion(affectedKeyNames) == MessageBoxes.PressedButton.Cancel) return; items = _listView.SelectedUninstallers.Where(x => !x.IsProtected).ToArray(); } if (!items.Any() || !MessageBoxes.DeleteRegKeysConfirmation(items.Select(x => x.DisplayName).ToArray())) return; foreach (var item in items) { try { if (item.IsRegistered) RegistryTools.RemoveRegistryKey(item.RegistryPath); } catch (Exception ex) { PremadeDialogs.GenericError(ex); } } _listView.InitiateListRefresh(); } private void donateButton_Click(object sender, EventArgs e) { OpenUrls(new[] { new Uri(Resources.DonateLink) }); } private void exitToolStripMenuItem_Click(object sender, EventArgs e) { Close(); } private void exportDialog_FileOk(object sender, CancelEventArgs e) { if (!AppUninstaller.ExportUninstallers(_listView.SelectedUninstallers, exportDialog.FileName)) e.Cancel = true; } private void exportSelectedToolStripMenuItem_Click(object sender, EventArgs e) { exportDialog.ShowDialog(); } private void fileToolStripMenuItem_DropDownOpening(object sender, EventArgs e) { var anySelected = _listView.SelectedUninstallerCount > 0; exportSelectedToolStripMenuItem.Enabled = anySelected; exportToABatchUninstallScriptToolStripMenuItem.Enabled = anySelected; exportStoreAppsToPowerShellRemoveScriptToolStripMenuItem.Enabled = _listView.SelectedUninstallers.Any(x => x.UninstallerKind == UninstallerType.StoreApp); } private void HandleListViewMenuKeystroke(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.Apps) { if (_listView.SelectedUninstallerCount > 0) { uninstallListContextMenuStrip.Show(uninstallerObjectListView.PointToScreen(Point.Empty)); } e.SuppressKeyPress = true; } } private void helpToolStripMenuItem_DropDownOpening(object sender, EventArgs e) { //uninstallBCUninstallToolstripMenuItem.Visible = Program.IsInstalled; uninstallBCUninstallToolstripMenuItem.Enabled = Program.IsInstalled; } private void MainWindow_FormClosed(object sender, FormClosedEventArgs e) { _setMan.SaveSettings(); SystemRestore.CancelSysRestore(); } private void MainWindow_FormClosing(object sender, FormClosingEventArgs e) { if (e.CloseReason != CloseReason.UserClosing || _setMan.Selected.Settings.MiscFirstRun || !WindowsTools.IsNetworkAvailable()) return; if (!_setMan.Selected.Settings.MiscFeedbackNagNeverShow) { if (!_setMan.Selected.Settings.MiscFeedbackNagShown && DateTime.Now - Process.GetCurrentProcess().StartTime > TimeSpan.FromMinutes(3)) { FeedbackBox.ShowFeedbackBox(this, true); } // Show the nag every other time _setMan.Selected.Settings.MiscFeedbackNagShown = !_setMan.Selected.Settings.MiscFeedbackNagShown; } } private void MainWindow_Shown(object sender, EventArgs e) { _setMan.Selected.SendUpdates(); // Work around a bug in Object list view try { ResumeLayout(); } catch (ObjectDisposedException) { Application.DoEvents(); ResumeLayout(); } _listView.InitiateListRefresh(); settingsSidebarPanel.Width = propertiesSidebar.GetSuggestedWidth() + settingsSidebarPanel.Padding.Left + settingsSidebarPanel.Padding.Right; } private void SetupAndShowLegendWindow() { if (IsDisposed || Disposing) return; _listLegendWindow.Show(this); AddOwnedForm(_listLegendWindow); _listLegendWindow.UpdatePosition(uninstallerObjectListView); listViewPanel.Resize += (o, args) => _listLegendWindow.UpdatePosition(uninstallerObjectListView); Move += (o, args) => _listLegendWindow.UpdatePosition(uninstallerObjectListView); Controls[0].EnabledChanged += (o, args) => _listLegendWindow.Enabled = Controls[0].Enabled; var settings = _setMan.Selected; settings.Subscribe((x, y) => _listLegendWindow.Visible = y.NewValue, x => x.UninstallerListShowLegend, this); _listLegendWindow.VisibleChanged += (x, y) => { if (!_listLegendWindow.Visible && settings.Settings.UninstallerListShowLegend) settings.Settings.UninstallerListShowLegend = false; }; } private void msiInstallContextMenuStripItem_Click(object sender, EventArgs e) { _appUninstaller.UninstallUsingMsi(MsiUninstallModes.InstallModify, _listView.SelectedUninstallers); } private void msiQuietUninstallContextMenuStripItem_Click(object sender, EventArgs e) { _appUninstaller.UninstallUsingMsi(MsiUninstallModes.QuietUninstall, _listView.SelectedUninstallers); } private void msiUninstallContextMenuStripItem_Click(object sender, EventArgs e) { _appUninstaller.UninstallUsingMsi(MsiUninstallModes.Uninstall, _listView.SelectedUninstallers); } private void OnFirstApplicationStart() { StartSetupWizard(false); // On first start the updates are not searched from constructor to give user a chance to disable them. BackgroundSearchForUpdates(); } private void OpenAssociatedWebPage(object sender, EventArgs eventArgs) { var urls = _listView.SelectedUninstallers.Select(y => y.GetAboutUri()).Where(x => x != null).ToList(); OpenUrls(urls); } private void OpenDebugWindow(object sender, EventArgs e) { if (_debugWindow == null || _debugWindow.IsDisposed) { _debugWindow = new DebugWindow(this, _listView, _appUninstaller); } _debugWindow.Show(); } private void OpenInRegedit(object sender, EventArgs e) { var targetEntry = _listView.SelectedUninstallers.FirstOrDefault(x => x.RegKeyStillExists()); if (targetEntry != null) { try { RegistryTools.OpenRegKeyInRegedit(targetEntry.RegistryPath); } catch (IOException ex) { PremadeDialogs.GenericError(ex); } } } private void OpenInstallationSource(object sender, EventArgs eventArgs) { var sourceDirs = _listView.SelectedUninstallers.Where(x => x.InstallSource.IsNotEmpty()) .Select(y => y.InstallSource) .ToList(); if (MessageBoxes.OpenDirectoriesMessageBox(sourceDirs.Count)) { try { sourceDirs.ForEach(x => Process.Start(new ProcessStartInfo(x) { UseShellExecute = true })); } catch (Exception e) { MessageBoxes.OpenDirectoryError(e); } } } private void OpenInstallLocation(object sender, EventArgs eventArgs) { var sourceDirs = _listView.SelectedUninstallers.Where(x => x.InstallLocation.IsNotEmpty()) .Select(y => y.InstallLocation) .ToList(); if (MessageBoxes.OpenDirectoriesMessageBox(sourceDirs.Count)) { try { sourceDirs.ForEach(x => Process.Start(new ProcessStartInfo(x) { UseShellExecute = true })); } catch (Exception e) { MessageBoxes.OpenDirectoryError(e); } } } private void openProgramsAndFeaturesToolStripMenuItem_Click(object sender, EventArgs e) { try { WindowsTools.OpenControlPanelApplet(ControlPanelCanonicalNames.ProgramsAndFeatures); } catch (Exception ex) { PremadeDialogs.GenericError(ex); } } private void OpenProperties(object sender, EventArgs eventArgs) { if (_listView.SelectedUninstallerCount == 0) return; using (var propertiesWindow = new PropertiesWindow()) { propertiesWindow.ShowPropertiesDialog(_listView.SelectedUninstallers); } } private void OpenSubmitFeedbackWindow(object sender, EventArgs e) { FeedbackBox.ShowFeedbackBox(this, false); } private void OpenUninstallerLocation(object sender, EventArgs eventArgs) { var sourceDirs = _listView.SelectedUninstallers.Where(x => x.UninstallerFullFilename.IsNotEmpty()).ToList(); if (MessageBoxes.OpenDirectoriesMessageBox(sourceDirs.Count)) { try { sourceDirs.ForEach(x => { if (File.Exists(x.UninstallerFullFilename)) WindowsTools.OpenExplorerFocusedOnObject(x.UninstallerFullFilename); else Process.Start(new ProcessStartInfo(x.UninstallerLocation) { UseShellExecute = true }); }); } catch (Exception e) { MessageBoxes.OpenDirectoryError(e); } } } private void OpenUninstallLists(object sender, EventArgs e) { advancedFilters1.LoadUninstallList(); } private void RefreshList(object sender, EventArgs e) { _listView.RefreshList(); } private void RefreshStatusbarTotalLabel(object sender, EventArgs e) { toolStripLabelTotal.Text = string.Format(CultureInfo.CurrentCulture, Localisable.MainWindow_Statusbar_Total, _listView.FilteredUninstallers.Count(), _listView.GetFilteredSize()); } private void ReloadUninstallers(object sender, EventArgs e) { _listView.InitiateListRefresh(); } private void RenameEntries(object sender, EventArgs eventArgs) { var selectedUninstallers = _listView.SelectedUninstallers.ToList(); if (selectedUninstallers.Count != 1) { MessageBoxes.CanSelectOnlyOneItemInfo(); return; } var selected = selectedUninstallers[0]; if (!_setMan.Selected.Settings.AdvancedDisableProtection && selected.IsProtected) { MessageBoxes.ProtectedItemError(selected.DisplayName); return; } if (!selected.IsRegistered) { MessageBoxes.CantRenameUninstallerKind(selected.DisplayName, selected.UninstallerKind); return; } if (StringEditBox.ShowDialog(string.Format(CultureInfo.InvariantCulture, Localisable.MainWindow_Rename_Description, selected.DisplayName), Localisable.MainWindow_Rename_Title, selected.DisplayName, Buttons.ButtonOk, Buttons.ButtonCancel, out var output)) { try { if (selected.Rename(output)) _listView.InitiateListRefresh(); else MessageBoxes.InvalidNewEntryName(); } catch (Exception exception) { PremadeDialogs.GenericError(exception); } } } private void ResetSettingsDialog(object sender, EventArgs e) { _setMan.ResetSettingsDialog(); } private void RunAdvancedUninstall(object sender, EventArgs e) { var items = _listView.SelectedUninstallers.ToArray(); var protectedItems = items.Where(x => x.IsProtected).ToArray(); if (!_setMan.Selected.Settings.AdvancedDisableProtection && protectedItems.Any()) { var affectedKeyNames = protectedItems.Select(x => x.DisplayName).ToArray(); if (MessageBoxes.ProtectedItemsWarningQuestion(affectedKeyNames) == MessageBoxes.PressedButton.Cancel) return; items = _listView.SelectedUninstallers.Where(x => !x.IsProtected).ToArray(); } if (!items.Any()) { MessageBoxes.NoUninstallersSelectedInfo(); return; } _appUninstaller.AdvancedUninstall(items, _listView.AllUninstallers); } private void RunLoudUninstall(object x, EventArgs y) { _appUninstaller.RunUninstall(_listView.SelectedUninstallers, _listView.AllUninstallers, false); } private void RunQuietUninstall(object x, EventArgs y) { _appUninstaller.RunUninstall(_listView.SelectedUninstallers, _listView.AllUninstallers, true); /*var nonQuiet = _listView.SelectedUninstallers.Where(o => !o.QuietUninstallPossible) .Select(p => p.DisplayName) .ToArray(); if (!nonQuiet.Any()) _uninstaller.RunUninstall(_listView.SelectedUninstallers, _listView.AllUninstallers, true); else { switch (MessageBoxes.QuietUninstallersNotAvailableQuestion(nonQuiet)) { case MessageBoxes.PressedButton.Yes: _uninstaller.RunUninstall(_listView.SelectedUninstallers, _listView.AllUninstallers, true); break; case MessageBoxes.PressedButton.No: _uninstaller.RunUninstall(_listView.SelectedUninstallers.Where(p => p.QuietUninstallPossible), _listView.AllUninstallers, true); break; default: return; } }*/ } private void searchToolStripMenuItem_Click(object sender, EventArgs e) { if (!_setMan.Selected.Settings.ToolbarsShowSettings) _setMan.Selected.Settings.ToolbarsShowSettings = true; filterEditor1.FocusSearchbox(); } private void settingsToolStripMenuItem_Click(object sender, EventArgs e) { using (var sw = new SettingsWindow()) sw.ShowDialog(); } private void SetupHotkeys() { // File globalHotkeys1.Add(new HotkeyEntry(Keys.F5, reloadUninstallersToolStripMenuItem)); globalHotkeys1.Add(new HotkeyEntry(Keys.O, false, true, false, loadUninstallerListToolStripMenuItem)); globalHotkeys1.Add(new HotkeyEntry(Keys.F4, true, false, false, exitToolStripMenuItem)); // View globalHotkeys1.Add(new HotkeyEntry(Keys.F, false, true, false, searchToolStripMenuItem_Click, null)); globalHotkeys1.Add(new HotkeyEntry(Keys.F3, searchToolStripMenuItem)); // Basic operations globalHotkeys1.Add(new HotkeyEntry(Keys.Delete, uninstallToolStripMenuItem, () => !_listView.CheckIsAppDisposed() && uninstallerObjectListView.ContainsFocus)); globalHotkeys1.Add(new HotkeyEntry(Keys.Delete, false, false, true, quietUninstallToolStripMenuItem, () => !_listView.CheckIsAppDisposed() && uninstallerObjectListView.ContainsFocus)); globalHotkeys1.Add(new HotkeyEntry(Keys.C, false, true, false, copyFullInformationToolStripMenuItem, () => !_listView.CheckIsAppDisposed() && uninstallerObjectListView.ContainsFocus)); globalHotkeys1.Add(new HotkeyEntry(Keys.Enter, true, false, false, propertiesToolStripMenuItem, () => !_listView.CheckIsAppDisposed() && uninstallerObjectListView.ContainsFocus)); // Advanced operations globalHotkeys1.Add(new HotkeyEntry(Keys.Delete, false, true, true, manualUninstallToolStripMenuItem, () => !_listView.CheckIsAppDisposed() && uninstallerObjectListView.ContainsFocus)); globalHotkeys1.Add(new HotkeyEntry(Keys.B, false, true, false, createBackupToolStripMenuItem, () => !_listView.CheckIsAppDisposed() && uninstallerObjectListView.ContainsFocus)); globalHotkeys1.Add(new HotkeyEntry(Keys.R, false, true, false, openKeyInRegeditToolStripMenuItem, () => !_listView.CheckIsAppDisposed() && uninstallerObjectListView.ContainsFocus)); // Tools globalHotkeys1.Add(new HotkeyEntry(Keys.P, false, true, false, settingsToolStripMenuItem_Click, settingsToolStripMenuItem)); } private void OnClickStartSetupWizard(object sender, EventArgs e) { StartSetupWizard(true); } private void StartSetupWizard(bool canExit) { using (var wizard = new FirstStartBox(canExit)) { wizard.StartPosition = FormStartPosition.CenterParent; wizard.ShowDialog(this); } } private void toolsToolStripMenuItem_DropDownOpening(object sender, EventArgs e) { viewWindowsFeaturesToolStripMenuItem.Enabled = DismTools.DismIsAvailable; tryToInstallNETV35ToolStripMenuItem.Enabled = DismTools.DismIsAvailable && !WindowsTools.CheckNetFramework35Installed(); createRestorePointToolStripMenuItem.Enabled = SysRestore.SysRestoreAvailable(); } private void toolStripLabelStatus_TextChanged(object sender, EventArgs e) { if (string.IsNullOrEmpty(toolStripLabelStatus.Text)) { toolStripLabelStatus.TextChanged -= toolStripLabelStatus_TextChanged; toolStripLabelStatus.Text = Localisable.MainWindow_Statusbar_StatusReady; toolStripLabelStatus.TextChanged += toolStripLabelStatus_TextChanged; } } private void uninstallBCUninstallToolstripMenuItem_Click(object sender, EventArgs e) { _appUninstaller.AskToSelfUninstall(); } private void uninstallerObjectListView_CellEditStarting(object sender, CellEditEventArgs e) { e.Cancel = true; if (_ignoreCellEdit || e.RowObject == null) return; _ignoreCellEdit = true; if (uninstallerObjectListView.CheckBoxes && !uninstallerObjectListView.IsChecked(e.RowObject)) { uninstallerObjectListView.UncheckAll(); uninstallerObjectListView.CheckObject(e.RowObject); } switch (Settings.Default.UninstallerListDoubleClickAction) { case UninstallerListDoubleClickAction.DoNothing: break; case UninstallerListDoubleClickAction.OpenProperties: OpenProperties(sender, e); break; case UninstallerListDoubleClickAction.Uninstall: RunLoudUninstall(sender, e); break; default: throw new ArgumentOutOfRangeException(nameof(UninstallerListDoubleClickAction), Settings.Default.UninstallerListDoubleClickAction, "Unhandled value"); } //uninstallerObjectListView.CancelCellEdit(); } private void uninstallerObjectListView_CellRightClick(object sender, CellRightClickEventArgs e) { if (e.Model == null) return; if (uninstallerObjectListView.CheckBoxes && !uninstallerObjectListView.IsChecked(e.Model)) { //uninstallerObjectListView.UncheckAll(); uninstallerObjectListView.CheckObject(e.Model); } } private void uninstallerObjectListView_Click(object sender, EventArgs e) { _ignoreCellEdit = false; } private void uninstallerObjectListView_KeyDown(object sender, KeyEventArgs e) { e.SuppressKeyPress = _listView.SelectItemFromKeystroke(e.KeyCode); } private void uninstallerObjectListView_SelectedChanged(object sender, EventArgs e) { toolStripLabelStatus.Text = _listView.SelectedUninstallerCount > 0 ? string.Format(CultureInfo.CurrentCulture, Localisable.MainWindow_Statusbar_StatusSelection, _listView.SelectedUninstallerCount) : string.Empty; toolStripLabelSize.Text = _listView.GetSelectedSize().ToString(); // Disable/enable edit menus var anySelected = _listView.SelectedUninstallerCount > 0; basicOperationsToolStripMenuItem.Enabled = anySelected; advancedOperationsToolStripMenuItem.Enabled = anySelected; toolStripButtonModify.Enabled = _listView.SelectedUninstallerCount == 1 && _listView.SelectedUninstallers.Count(x => !string.IsNullOrEmpty(x.ModifyPath)) == 1; } private void UpdateUninstallListContextMenuStrip(object sender, CancelEventArgs e) { if (_listView.SelectedUninstallerCount == 0) { e.Cancel = true; return; } var advancedFiltering = advancedFilters1.CurrentList != null; toolStripSeparatorFiltering.Visible = advancedFiltering; excludeToolStripMenuItem.Visible = advancedFiltering; includeToolStripMenuItem.Visible = advancedFiltering; var selectedUninstallers = _listView.SelectedUninstallers.ToList(); var singleItem = selectedUninstallers.Count == 1; uninstallUsingMsiExecContextMenuStripItem.Enabled = singleItem && !selectedUninstallers.First().BundleProviderKey.IsEmpty(); foreach (var itemToDisable in new[] { uninstallContextMenuStripItem, quietUninstallContextMenuStripItem, gUIDProductCodeCopyContextMenuStripItem, uninstallStringCopyContextMenuStripItem, installLocationOpenInExplorerContextMenuStripItem, uninstallerLocationOpenInExplorerContextMenuStripItem, sourceLocationOpenInExplorerContextMenuStripItem, openWebPageContextMenuStripItem, runToolStripMenuItem, manualUninstallToolStripMenuItem1 }) itemToDisable.Enabled = false; runToolStripMenuItem.DropDownItems.Clear(); foreach (var item in selectedUninstallers) { if (item.IsValid) { if (item.UninstallPossible) uninstallContextMenuStripItem.Enabled = true; if (item.QuietUninstallPossible) quietUninstallContextMenuStripItem.Enabled = true; manualUninstallToolStripMenuItem1.Enabled = true; } if (singleItem) { foreach (var executable in item.GetSortedExecutables()) { if (!runToolStripMenuItem.Enabled) runToolStripMenuItem.Enabled = true; runToolStripMenuItem.DropDownItems.Add(executable); } } if (item.IsRegistered) manualUninstallToolStripMenuItem1.Enabled = true; if (!item.BundleProviderKey.IsEmpty()) gUIDProductCodeCopyContextMenuStripItem.Enabled = true; if (item.UninstallPossible) { uninstallStringCopyContextMenuStripItem.Enabled = true; manualUninstallToolStripMenuItem1.Enabled = true; } if (item.InstallLocation.IsNotEmpty()) { installLocationOpenInExplorerContextMenuStripItem.Enabled = true; manualUninstallToolStripMenuItem1.Enabled = true; } if (item.UninstallerLocation.IsNotEmpty()) { uninstallerLocationOpenInExplorerContextMenuStripItem.Enabled = true; manualUninstallToolStripMenuItem1.Enabled = true; } if (item.InstallSource.IsNotEmpty()) sourceLocationOpenInExplorerContextMenuStripItem.Enabled = true; if (item.AboutUrl.IsNotEmpty()) openWebPageContextMenuStripItem.Enabled = true; } openInExplorerContextMenuStripItem.Enabled = installLocationOpenInExplorerContextMenuStripItem.Enabled || uninstallerLocationOpenInExplorerContextMenuStripItem.Enabled || sourceLocationOpenInExplorerContextMenuStripItem.Enabled; } private void UsageTrackerSendData() { if (_setMan.Selected.Settings.MiscSendStatistics) { UsageManager.FinishCollectingData(); if (Program.EnableDebug || !WindowsTools.IsNetworkAvailable()) return; var count = UsageManager.AppLaunchCount; //Reduce frequency of the uploads if (count != 2 && (count <= 0 || count % 5 != 0)) return; try { UsageManager.SendUsageData(); } catch { // Ignore, will try again next time } } else { UsageManager.RemoveStoredData(); } } private void listView_ListRefreshIsRunningChanged(object sender, UninstallerListViewUpdater.ListRefreshEventArgs e) { if (e.RefreshIsRunning) { _uninstallerListPostProcesser.StopProcessingThread(); return; } // If refresh has finished update the interface _anyStoreApps = _listView.AllUninstallers.Any(x => x.UninstallerKind == UninstallerType.StoreApp); _anyWinFeatures = _listView.AllUninstallers.Any(x => x.UninstallerKind == UninstallerType.WindowsFeature); _anyOrphans = _listView.AllUninstallers.Any(x => x.IsOrphaned); _anyProtected = _listView.AllUninstallers.Any(x => x.IsProtected); _anySysComponents = _listView.AllUninstallers.Any(x => x.SystemComponent); _anyUpdates = _listView.AllUninstallers.Any(x => x.IsUpdate); _anyInvalid = _listView.AllUninstallers.Any(x => !x.IsValid); _anyTweaks = _listView.AllUninstallers.Any(x => x.RatingId != null && x.RatingId.StartsWith("tweak", StringComparison.OrdinalIgnoreCase)); propertiesSidebar.StoreAppsEnabled = _anyStoreApps; propertiesSidebar.WinFeaturesEnabled = _anyWinFeatures; propertiesSidebar.ShowTweaksEnabled = _anyTweaks; propertiesSidebar.OrphansEnabled = _anyOrphans; propertiesSidebar.ProtectedEnabled = _anyProtected; propertiesSidebar.SysCompEnabled = _anySysComponents; propertiesSidebar.UpdatesEnabled = _anyUpdates; propertiesSidebar.InvalidEnabled = _anyInvalid; if (e.FirstRefresh) { _setMan.LoadSorting(); var args = Environment.GetCommandLineArgs(); var dir = args.Skip(1).FirstOrDefault(); if (!string.IsNullOrEmpty(dir)) { try { advancedFilters1.LoadUninstallList(dir); } catch (Exception ex) { PremadeDialogs.GenericError(ex); } } if (advancedFilters1.CurrentList == null && _setMan.Selected.Settings.MiscAutoLoadDefaultList) { try { var defaultUninstallListPath = Path.Combine(Program.AssemblyLocation.FullName, Resources.DefaultUninstallListFilename); if (File.Exists(defaultUninstallListPath)) advancedFilters1.LoadUninstallList(defaultUninstallListPath); } catch (Exception ex) { PremadeDialogs.GenericError(ex); } } splashScreen1.CloseSplashScreen(); // Display the legend first so it is hidden under the splash _listLegendWindow.Opacity = 0; SetupAndShowLegendWindow(); // Needed in case main window starts maximized _listLegendWindow.UpdatePosition(uninstallerObjectListView); _listLegendWindow.Visible = _setMan.Selected.Settings.UninstallerListShowLegend; new Thread(() => { this.SafeInvoke(() => { var isFirstRun = _setMan.Selected.Settings.MiscFirstRun; if (isFirstRun) { // Run the welcome wizard at first start of the application OnFirstApplicationStart(); } if (Program.IsAfterUpgrade || isFirstRun) { NewsPopup.ShowPopup(this); } //if (!_setMan.Selected.Settings.MiscNet4NagShown && !Program.Net4IsAvailable) //{ // _setMan.Selected.Settings.MiscNet4NagShown = true; // MessageBoxes.Net4MissingInfo(); //} }); }).Start(); } OnApplicationListVisibleItemsChanged(sender, e); filterEditor1.FocusSearchbox(); } private void openStartupManagerToolStripMenuItem_Click(object sender, EventArgs e) { var results = StartupManagerWindow.ShowManagerDialog(this); toolStripLabelStatus.Text = Localisable.MainWindow_Statusbar_RefreshingStartup; //Application.DoEvents(); //if (_listView.CheckIsAppDisposed()) // return; Cursor = Cursors.WaitCursor; statusStrip1.Refresh(); _listView.ReassignStartupEntries(true, results); toolStripLabelStatus.Text = string.Empty; Cursor = DefaultCursor; } private void disableAutostartToolStripMenuItem_Click(object sender, EventArgs e) { foreach (var uninstaller in _listView.SelectedUninstallers) { if (uninstaller.StartupEntries == null) continue; foreach (var entry in uninstaller.StartupEntries) { try { entry.Disabled = true; } catch (Exception ex) { PremadeDialogs.GenericError(ex); } } uninstallerObjectListView.RefreshObject(uninstaller); } } private void rateToolStripMenuItem_Click(object sender, EventArgs e) { _uninstallerListConfigurator.RatingManagerWrapper.RateEntries(_listView.SelectedUninstallers.ToArray(), Point.Empty); } private void OpenTargetWindow(object sender, EventArgs e) { var results = TargetWindow.ShowDialog(this, SetVisible); if (results == null) return; var apps = AppUninstaller.GetApplicationsFromDirectories(_listView.AllUninstallers, results); if (apps.Count == 0) { MessageBoxes.UninstallFromDirectoryNothingFound(); return; } _appUninstaller.RunUninstall(apps, _listView.AllUninstallers, true); } private void viewWindowsFeaturesToolStripMenuItem_Click(object sender, EventArgs e) { _setMan.Selected.Settings.FilterShowWinFeatures = true; filterEditor1.Search(nameof(UninstallerType.WindowsFeature), ComparisonMethod.Equals, nameof(ApplicationUninstallerEntry.UninstallerKind)); } private void viewWindowsStoreAppsToolStripMenuItem_Click(object sender, EventArgs e) { _setMan.Selected.Settings.FilterShowStoreApps = true; filterEditor1.Search(nameof(UninstallerType.StoreApp), ComparisonMethod.Equals, nameof(ApplicationUninstallerEntry.UninstallerKind)); } private void buttonAdvFiltering_Click(object sender, EventArgs e) { advancedFilters1.LoadUninstallList(new UninstallList(_uninstallerListConfigurator.GenerateEquivalentFilter())); } private void OpenAdvancedClipboardCopy(object sender, EventArgs e) { AdvancedClipboardCopyWindow.ShowDialog(this, _listView.SelectedUninstallers); } private void openHelpToolStripMenuItem_Click(object sender, EventArgs e) { MessageBoxes.DisplayHelp(); } private void uninstallFromDirectoryToolStripMenuItem_Click(object sender, EventArgs e) { _appUninstaller.UninstallFromDirectory(_listView.AllUninstallers); } private void openSystemRestoreToolStripMenuItem_Click(object sender, EventArgs e) { try { WindowsTools.OpenControlPanelApplet(ControlPanelCanonicalNames.Recovery); } catch (Exception ex) { PremadeDialogs.GenericError(ex); } } private void runToolStripMenuItem_DropDownItemClicked(object sender, ToolStripItemClickedEventArgs e) { PremadeDialogs.StartProcessSafely(e.ClickedItem.Text); } private void viewUpdatesToolStripMenuItem_Click(object sender, EventArgs e) { _setMan.Selected.Settings.FilterShowUpdates = true; filterEditor1.Search(true.ToString(), ComparisonMethod.Equals, nameof(ApplicationUninstallerEntry.IsUpdate)); } private void filterEditor1_FocusSearchTarget(object sender, EventArgs e) { uninstallerObjectListView.Focus(); } private void googleToolStripMenuItem_Click(object sender, EventArgs e) { OnlineSearchTools.SearchGoogle(_listView.SelectedUninstallers); } private void alternativeToToolStripMenuItem_Click(object sender, EventArgs e) { OnlineSearchTools.SearchAlternativeTo(_listView.SelectedUninstallers); } private void slantcoToolStripMenuItem_Click(object sender, EventArgs e) { OnlineSearchTools.SearchSlantCo(_listView.SelectedUninstallers); } private void fossHubcomToolStripMenuItem_Click(object sender, EventArgs e) { OnlineSearchTools.SearchFosshub(_listView.SelectedUninstallers); } private void sourceForgecomToolStripMenuItem_Click(object sender, EventArgs e) { OnlineSearchTools.SearchSourceforge(_listView.SelectedUninstallers); } private void fileHippocomToolStripMenuItem_Click(object sender, EventArgs e) { OnlineSearchTools.SearchFilehippo(_listView.SelectedUninstallers); } private void gitHubcomToolStripMenuItem_Click(object sender, EventArgs e) { OnlineSearchTools.SearchGithub(_listView.SelectedUninstallers); } private void modifyToolStripMenuItem_Click(object sender, EventArgs e) { _appUninstaller.Modify(_listView.SelectedUninstallers); } private void excludeToolStripMenuItem_Click(object sender, EventArgs e) { AddSelectedAsAdvancedFilters(true); } private void includeToolStripMenuItem_Click(object sender, EventArgs e) { AddSelectedAsAdvancedFilters(false); } private void AddSelectedAsAdvancedFilters(bool exclude) { var selectedUninstallers = _listView.SelectedUninstallers; var filters = advancedFilters1.CurrentList.Filters; var existingFilters = filters.Where(x => selectedUninstallers.Any(y => x.Name == y.DisplayName)); filters.RemoveAll(existingFilters.ToList()); filters.AddRange(selectedUninstallers.Select(x => new Filter(x.DisplayName, exclude, new FilterCondition(x.DisplayName, ComparisonMethod.Equals, nameof(ApplicationUninstallerEntry.DisplayName))))); advancedFilters1.RepopulateList(); } private void viewUnregisteredToolStripMenuItem_Click(object sender, EventArgs e) { _setMan.Selected.Settings.AdvancedDisplayOrphans = true; filterEditor1.Search(true.ToString(), ComparisonMethod.Equals, nameof(ApplicationUninstallerEntry.IsOrphaned)); } private void viewToolStripMenuItem_DropDownOpening(object sender, EventArgs e) { } private void tryToInstallNETV35ToolStripMenuItem_Click(object sender, EventArgs e) { PremadeDialogs.StartProcessSafely(DismTools.DismFullPath, "/Online /Enable-Feature /FeatureName:NetFx3 /All"); } private void startDiskCleanupToolStripMenuItem_Click(object sender, EventArgs e) { PremadeDialogs.StartProcessSafely("cleanmgr.exe"); } private void exportStoreAppsToPowerShellRemoveScriptToolStripMenuItem_Click(object sender, EventArgs e) { using (var d = new SaveFileDialog()) { d.OverwritePrompt = true; d.CreatePrompt = false; d.AddExtension = true; d.DefaultExt = ".ps1"; d.Filter = "PowerShell script|*.ps1"; d.Title = exportStoreAppsToPowerShellRemoveScriptToolStripMenuItem.Text; d.RestoreDirectory = true; d.InitialDirectory = WindowsTools.GetEnvironmentPath(CSIDL.CSIDL_DESKTOPDIRECTORY); if (d.ShowDialog() == DialogResult.OK) { try { File.WriteAllLines(d.FileName, StoreAppFactory.ToPowerShellRemoveCommands(_listView.SelectedUninstallers).ToArray()); } catch (SystemException ex) { PremadeDialogs.GenericError(ex); } } } } private void exportToABatchUninstallScriptToolStripMenuItem_Click(object sender, EventArgs e) { using (var d = new SaveFileDialog()) { d.OverwritePrompt = true; d.CreatePrompt = false; d.AddExtension = true; d.DefaultExt = ".bat"; d.Filter = "Batch file|*.bat"; d.Title = exportToABatchUninstallScriptToolStripMenuItem.Text; d.RestoreDirectory = true; d.InitialDirectory = WindowsTools.GetEnvironmentPath(CSIDL.CSIDL_DESKTOPDIRECTORY); if (d.ShowDialog() == DialogResult.OK) { try { File.WriteAllLines(d.FileName, new[] { "@echo off", "echo BCU Generated batch uninstall script" }.Concat( _listView.SelectedUninstallers .Select(x => x.QuietUninstallPossible ? x.QuietUninstallString : x.UninstallString) .Where(x => !string.IsNullOrEmpty(x)) ).Concat(new[] { "pause", "exit" }).ToArray()); } catch (SystemException ex) { PremadeDialogs.GenericError(ex); } } } } private void troubleshootUninstallProblemsToolStripMenuItem_Click(object sender, EventArgs e) { var toolPath = Path.Combine(Program.AssemblyLocation.FullName, @"Resources\MicrosoftProgram_Install_and_Uninstall.meta.diagcab"); PremadeDialogs.StartProcessSafely(toolPath); } private void filteringToolStripMenuItem_DropDownOpening(object sender, EventArgs e) { var isSimpleFiltering = !IsAdvancedFilteringEnabled; viewUnregisteredToolStripMenuItem.Enabled = isSimpleFiltering; viewUpdatesToolStripMenuItem.Enabled = isSimpleFiltering; viewWindowsStoreAppsToolStripMenuItem.Enabled = isSimpleFiltering; viewWindowsFeaturesToolStripMenuItem.Enabled = isSimpleFiltering; } private void automaticallyStartedToolStripMenuItem_Click(object sender, EventArgs e) { filterEditor1.Search(true.ToString(), ComparisonMethod.Equals, nameof(ApplicationUninstallerEntry.HasStartups)); var s = _setMan.Selected.Settings; s.AdvancedDisplayOrphans = true; s.FilterHideMicrosoft = false; s.FilterShowSystemComponents = true; s.FilterShowProtected = true; s.FilterShowUpdates = true; s.FilterShowWinFeatures = true; s.FilterShowStoreApps = true; s.FilterShowTweaks = true; } private void basicApplicationsToolStripMenuItem_Click(object sender, EventArgs e) { filterEditor1.Search(null, ComparisonMethod.Any); var s = _setMan.Selected.Settings; s.AdvancedDisplayOrphans = false; s.FilterHideMicrosoft = true; s.FilterShowSystemComponents = false; s.FilterShowProtected = false; s.FilterShowUpdates = false; s.FilterShowWinFeatures = false; s.FilterShowStoreApps = true; s.FilterShowTweaks = false; } private void advancedApplicationsToolStripMenuItem_Click(object sender, EventArgs e) { filterEditor1.Search(null, ComparisonMethod.Any); var s = _setMan.Selected.Settings; s.AdvancedDisplayOrphans = true; s.FilterHideMicrosoft = true; s.FilterShowSystemComponents = false; s.FilterShowProtected = false; s.FilterShowUpdates = false; s.FilterShowWinFeatures = false; s.FilterShowStoreApps = true; s.FilterShowTweaks = true; } private void systemComponentsToolStripMenuItem_Click(object sender, EventArgs e) { filterEditor1.Search(true.ToString(), ComparisonMethod.Equals, nameof(ApplicationUninstallerEntry.SystemComponent)); var s = _setMan.Selected.Settings; s.AdvancedDisplayOrphans = false; s.FilterHideMicrosoft = false; s.FilterShowSystemComponents = true; s.FilterShowProtected = false; s.FilterShowUpdates = false; s.FilterShowWinFeatures = true; s.FilterShowStoreApps = true; s.FilterShowTweaks = true; } private void everythingToolStripMenuItem_Click(object sender, EventArgs e) { filterEditor1.Search(null, ComparisonMethod.Any); var s = _setMan.Selected.Settings; s.AdvancedDisplayOrphans = true; s.FilterHideMicrosoft = false; s.FilterShowSystemComponents = true; s.FilterShowProtected = true; s.FilterShowUpdates = true; s.FilterShowWinFeatures = true; s.FilterShowStoreApps = true; s.FilterShowTweaks = true; } private void onlyWebBrowsersToolStripMenuItem_Click(object sender, EventArgs e) { filterEditor1.Search(true.ToString(), ComparisonMethod.Equals, nameof(ApplicationUninstallerEntry.IsWebBrowser)); var s = _setMan.Selected.Settings; s.AdvancedDisplayOrphans = true; s.FilterHideMicrosoft = false; s.FilterShowSystemComponents = true; s.FilterShowProtected = true; s.FilterShowUpdates = true; s.FilterShowWinFeatures = true; s.FilterShowStoreApps = true; s.FilterShowTweaks = true; } private void viewTweaksToolStripMenuItem_Click(object sender, EventArgs e) { everythingToolStripMenuItem_Click(sender, e); filterEditor1.Search(@"\Resources\Scripts\Tweak", ComparisonMethod.Contains, nameof(ApplicationUninstallerEntry.UninstallString)); } private void createRestorePointToolStripMenuItem_Click(object sender, EventArgs e) { LockApplication(true); try { SystemRestore.BeginSysRestore(0, false, this); } catch (Exception exception) { PremadeDialogs.GenericError(exception); } finally { LockApplication(false); } } private void autosizeAllColumnsToolStripMenuItem_Click(object sender, EventArgs e) { uninstallerObjectListView.AutoResizeColumns(); } } } ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/MainWindow.cs.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Vyhledávání Jméno Vydavatel Verze Datum instalace Velikost Spuštění Příkaz pro odinstalaci Adresa informací Zdroj instalace Umístění instalace Typ odinstalátoru Systémové součástí Chráněné Klíč registru Kód produktu Příkaz tiché odinstalace Obnova odinstalace Seznam otevřených odinstalaci ... Vybrat vše Zrušit výběr všech Obrátit výběr Odinstalace Odinstalovat potichu Vlastnosti &Odinstalovat Odinstalovat &potichu Odinstalovat &ručně Odinstalovat za použití &MsiExec... &Instalovat nebo konfigurovat (/I) &Odinstalovat (/X) &Tichý odinstalace (/X /qb) &Zkopírovat do schránky ... &Kompletní informace Název programu Kód produktu / GUID Celá cesta registru Odinstalovat řetězce &Smazat položku registru &Přejmenovat ... Otevřít v &průzkumníku ... &Umístění instalace &Umístění odinstalátoru &Umístění zdroje Otevřít &Webové stránky &Vyhledávání na řádku &Vlastnosti Export vybraných vlastností odinstalátoru &Soubor &Obnovit odinstalátory &Otevřít seznam odinstalátorů &Exportovat výběr ... Ko&nec &Náhled Ukázat barvy legendy Ukázat &Panel nástrojů Ukázat stavový řá&dek Zobrazit &nastavení postranního panelu Po&užití systémového motivu Hledání ... &Základní operace &Odinstalovat Odinstalovat &potichu &Zkopírovat do schránky ... &Kompletní informace Název programu Kód produktu / GUID Celá cesta registru Řetězec odinstalace Otevřít v &průzkumníku ... &Umístění instalace &Umístění odinstalátoru &Umístění zdroje Otevřít &Webovou stránku &Vyhledávání na řádku Zobrazit &vlastnosti &Pokročilé operace Odinstalace &ručně Odinstalovat za použití &MsiExec... &Instalovat nebo konfigurovat (/I) &Odinstalovat (/X) &Tichý odinstalace (/X /qb) &Přejmenovat... Zakázat autostart &Odstranění klíče registru Vytvořit &zálohu... &Otevřít klíč v REGEDITU &Nástroje &Vyčistit "Program Files" složky ... Otevřít Manažera po spuštění Otevřít "&Programy a funkce" &Nastavení &Pomoc Otevřít &Pomoc Spustit průvodce nastavením Kontrola aktualizací Odeslat zpětnou vazbu ... Původní nastavení Odinstalovat BCUninstaller &O Programu Otevřít &ladicí okno Soubor registrů|*.reg Vytvořit zálohu registru BCUninstaller 64bit Hodnocení uživatele Hodnotit... Hodnotit... Bulk Crap Uninstaller Pomoc Pokročilé filtrování Spustit... Upřesnit... Google AlternativaTo Zobrazit aktualizace Zobrazit Windows Store aplikace Upřesnit... Google AlternativaTo Odebrat z adresáře ... Otevřete "Obnovení systému" Odinstalovat z windows adresáře nebo souboru... Odinstalovat z windows adresáře nebo souboru... FossHub.com SourceForge.net GitHub.com FileHippo.com FossHub.com SourceForge.net GitHub.com FileHippo.com Upravit Vyloučit Patřící Zobrazit strom&mapu Zobrazit neregistrovaných Zobrazení funkce systému Windows Upravit Vytvořit nový bod obnovení ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/MainWindow.de.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Suche Herausgeber Installationsdatum Größe Autostart Uninstall-Befehl Info URL Installationsquelle Installationspfad Deinstallationsart Systemkomponente Geschützt Registryschlüssel Produktcode Befehl für stille Deinstallation Uninstaller neu laden Bestehende Listen laden... Alles auswählen Alles abwählen Auswahl umkehren Deinstallieren Stille Deinstallation Eigenschaften &Deinstallieren S&tille Deinstallation &Manuell deinstallieren &Installieren oder konfigurieren (/I) &Deinstallieren (/X) &Stille Deinstallation (/X /qb) Deinstallation mit &MSIExec... K&omplette Information Programm-Name Produktcode/GUID Vollständiger Pfad Deinstallationsanweisung In Zwischenablage &kopieren... &Registryschlüssel löschen Umbe&nennen... &Installationspfad &Pfad &Quellpfad Im &Explorer öffnen... &Webseite aufrufen Online &Suche &Eigenschaften Export ausgewählter Uninstaller-Eigenschaften Uninstaller &neu laden &Uninstall Liste(n) laden... Auswahl &exportieren... Been&den &Datei Farblegende anzeigen Symbolleis&te anzeigen Statusleiste an&zeigen Einstellungen-&Seitenleiste anzeigen Systemdesign ben&utzen Suche... &Ansicht &Deinstallieren &Stille Deinstallation &Vollständige Info Programm-Name Produktcode/GUID Vollständiger Registry-Pfad Deinstallationsanweisung In Zwischenablage &kopieren... &Installationspfad &Programmpfad &Quellpfad Im &Explorer öffnen... &Webseite aufrufen Online-&Suche Ei&genschaften anzeigen &Hauptfunktionen &Manuell deinstallieren &Installieren oder konfigurieren (/I) &Deinstallieren (/X) &Stille Deinstallation (/X /qb) Deinstallation mit &MSIExec &Registryschlüssel löschen &Umbenennen &Backup anlegen... Schlüssel mit REGEDIT ö&ffnen Er&weiterte Funktionen Programmverzeichnisse &bereinigen... Autostart Manager "&Programme und Features" öffnen Ein&stellungen &Werkzeuge &Hilfe öffnen Setup-Assistenten starten Nach Updates suchen Feedback senden... Einstellungen zurücksetzen BCUninstaller deinstallieren Ü&ber &Hilfe &Debug-Fenster öffnen Registry-Dateien|*.reg Registry-Sicherung erstellen Name 64bit Version Autostart verhindern BCUninstaller Benutzer-Bewertung Bewerten... Bewerten... Bulk Crap Uninstaller Google AlternativeTo Google AlternativeTo FossHub.com SourceForge.net GitHub.com FileHippo.com FossHub.com SourceForge.net GitHub.com FileHippo.com Deinstallieren über Fenster, Ordner oder Datei Ändern Hilfe Erweiterte Filter Ausschließen Einschließen Ausführen Erweitert Zeige Windows Store Programme &Schnelle Filter Änderungen Erweitert Deinstalliere durch Fenster, Ordner oder Datei Deinstalliere aus Ordner Installiere .NET v3.5 (für weitere Funktionen) Öffne "Systemwiederherstellung" Zeige Baumstruktur&Verzeichnis &Voreingestellte Filter Nur &Grundlegende Anwendungen Nur System Komponenten &Alles Nur Automatisch startend Nur Web Browser Zeige Verbesserungen Zeige Unregistrierte Zeige Updates Zeige Windows Eigenschaften Exportiere in einem Batch Uninstall script Erzeuge eine PowerShell entfernungs script für Store Programme Beheben von Installationsproblemen Starte Disk Cleanup XML Dateien|*.xml Einen neuen Wiederherstellungspunkt setzen Automatische Größenänderung aller Spalten Slant.co Slant.co Verantwortung übernehmen ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/MainWindow.es.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Nombre Editor Calificación del usuario Versión Fecha de instalación Tamaño Inicio 64 bits Comando de desinstalación Acerca de URL Fuente de la instalación Ubicación de la instalación Tipo de desinstalador Componente del sistema Protegido Clave de registro Código del producto Comando de desinstalación silenciosa Actualizar desinstaladores Seleccionar todo Deseleccionar todo Invertir selección Desinstalar Desinstalación silenciosa Propiedades Configuración Ayuda BCUninstaller Filtrado avanzado Buscar &Desinstalar Desinstalación &silenciosa Desinstalar &manualmente &Instalar o configurar (/I) &Desinstalar (/X) &Desinstalación silenciosa (/X /qb) Desinstalar usando &MsiExec... Avanzado... &Información completa Nombre del programa Código del producto / GUID Ruta completa del registro Desinstalar cadena &Copiar al portapapeles &Eliminar entrada del registro &Renombrar... &Ubicación de instalación &Ubicación del desinstalador &Ubicación de la fuente Abrir en el &explorador... Abrir &página web &Buscar en línea Calificar... &Propiedades Archivos XML|*.xml Exportar propiedades de los desinstaladores seleccionados &Actualizar desinstaladores &Abrir lista de desinstalación.... &Exportar selección... S&alir &Archivo Mostrar leyenda de colores Mostrar barra de &herramientas Mostrar barra de &estado Mostrar barra lateral de &configuración &Usar tema del sistema Mostrar apps de Windows Store Buscar... &Mostrar &Desinstalar Desinstalación &silenciosa Avanzado... &Información completa Nombre del programa Código del producto / GUID Ruta completa de registro Cadena de desinstalación &Copiar al portapapeles &Ubicación de instalación &Ubicación del desinstalador &Ubicación de origen Abrir en el &explorador... Abrir &página web &Buscar en línea Calificar... Mostrar &propiedades &Operaciones básicas Desinstalar &manualmente &Instalar o configurar (/I) &Desinstalar (/X) &Desinstalación silenciosa (/X /qb) &Desinstalar usando MsiExec &Renombrar... Desactivar autoinicio &Eliminar clave de registro Crear &copia de seguridad... &Abrir clave en RegEdit &Operaciones avanzadas &Limpiar carpetas "Archivos de programas"... Abrir administrador de inicio Abrir "&Programas y características &Configuración &Herramientas Abrir &ayuda Asistente de configuración de inicio Comprobar actualizaciones Enviar comentario... Restaurar configuración Desinstalar BCUninstaller &Acerca de &Ayuda Abrir &ventana de depuración Archivos de registro|*.reg Crear copia del registro Bulk Crap Uninstaller Google AlternativeTo Mostrar actualizaciones Google AlternativeTo Desinstalar desde directorio... Abrir "Restauración de sistema" Ejecutar... Desinstalar por ventana, directorio o archivo... FossHub.com SourceForge.net GitHub.com FileHippo.com FossHub.com SourceForge.net GitHub.com FileHippo.com Desinstalar por ventana, directorio o archivo... Modificar Modificar Instalar .NET v3.5 (Añadir característica) Iniciar limpieza del disco Crear un nuevo punto de restauración Excluir Incluir Slant.co Exportar a un script de desinstalación grupal... Crear script de eliminación de PowerShell para Aplicaciones de la Tienda Mostrar árbol&mapa &Filtros predeterminados Solo aplicaciones &básicas Solo componentes del sistema &Todo Solo las que inician automáticamente Solo navegadores web Ver Retoques Ver No Registradas Ver Características de Windows &Filtros rápidos Slant.co Tomar posesión Solucionar problemas de desinstalación... Redimensionar automáticamente todas las columnas ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/MainWindow.fr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Nom Éditeur Date d'installation Taille 64bits Commande de désinstallation URL relative Source d'installation Emplacement d'installation Genre de désinstalleur Composant système Protégé Clé de registre Code produit Commande de désinstallation silencieuse Recharger les désinstalleurs Désinstaller Désinstaller en silence Propriétés &Désinstaller Désinstaller en &silence Désinstaller &manuellement &Installer ou configurer (/I) &Désinstaller (/X) Désinstaller en &silence (/X /qb) Désinstaller en utilisant &MsiExec... Information &complète Nom de programme Code produit / GUID Chemin complet de registre Chaîne de désinstallation &Copier dans le presse-papiers... &Supprimer l'entrée du registre &Renommer... Emplacement d'&installation Emplacement du &désinstalleur Emplacement de la &source Ouvrir dans l'&explorateur... Ouvrir la Page &Web &Rechercher en ligne &Propriétés Exporter les propriétés du désinstalleur sélectionné &Recharger les désinstalleurs &Ouvrir la Liste de Désinstallation... &Exporter les données des désinstalleurs sélectionnés... &Quitter &Fichier Afficher la légende des couleurs Afficher la barre d'ou&tils Afficher la &barre d'état Afficher la barre latérale des réglage&s &Utiliser le thème système Chercher... &Affichage &Désinstaller Désinstaller en &silence In&formation complète Nom de programme Code produit / GUID Chemin complet de registre Chaîne de désinstallation &Copier dans le presse-papiers... Emplacement d'&installation Emplacement du &désinstalleur Emplacement de la &source Ouvrir dans l'&explorateur... Ouvrir la Page &Web &Rechercher en ligne Afficher les &propriétés Opérations &basiques Désinstaller &manuellement &Installer ou configurer (/I) &Désinstaller (/X) Désinstaller en &silence (/X /qb) Désinstaller en &utilisant MsiExec &Supprimer la clé de registre &Renommer Créer une sau&vegarde... &Ouvrir la clé dans Regedit Opérations a&vancées &Nettoyer les dossiers "Program Files"... Ouvrir "&Programmes et Fonctionnalités" &Réglages Ou&tils Ouvrir l'&aide Démarrer l'assistant d'installation Vérifier les mises à jour Soumettre un retour... Réinitialiser les réglages Désinstaller BCUninstaller À &propos Ai&de Ouvrir la fenêtre de débo&guage Fichiers registre|*.reg Créer une sauvegarde du registre Version Réglages Sélectionner tout Désélectionner tout Inverser la sélection Chercher Démarrage Ouvrir le Gestionnaire de Démarrage Désactiver démar. auto BCUninstaller Note utilisateur Noter... Noter... Bulk Crap Uninstaller Aide Filtrage avancé Avancé... Voir les Applis Windows Store Avancé... Lancer... Google AlternativeTo.net Voir les Mises à jour Google AlternativeTo Désinstaller depuis le dossier... Ouvrir "Récupération" Désinstaller par fenêtre, dossier ou fichier... Désinstaller par fenêtre, dossier ou fichier... FossHub.com SourceForge.net GitHub.com FileHippo.com FossHub.com SourceForge.net GitHub.com FileHippo.com Modifier Exclure Inclure Afficher la &carte arborescente Voir les Non Enregistrés Voir les Fonctionnalités Windows Modifier Exporter vers un script de désinstallation batch... Créer un script PowerShell de désinstallation pour les applications du Windows Store... Filtres par &défaut Applications &basiques seules Composants système seuls &Tout Démarrages automatiques seuls Navigateurs web seuls Filtres &Rapides Résoudre les problèmes de désinstallation... Lancer le Nettoyage de disque Installer .NET v3.5 (ajout de fonctionalité) Fichiers XML|*.xml Voir les Perfectionnements Créer un nouveau point de restauration Slant.co Slant.co Devenir propriétaire Redimensionner auto toutes les colonnes ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/MainWindow.hu.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Név Kiadó Felhasználói minősítés Verzió Telepítés dátuma Méret Indítópult 64-bites Eltávolítási parancs Névjegy URL Telepítési forrás Telepítési hely Eltávolító fajtája Rendszerösszetevő Védett Beállításkulcs Termékkód Csendes eltávolító parancs Eltávolítók újratöltése Mindet kijelöl Egyiket sem Kijelölés megfordítása Eltávolítás Csendes eltávolítás Tulajdonságok Beállítások Súgó BCUninstaller Speciális szűrés Keresés El&távolítás &Csendes eltávolítás &Kézi eltávolítás &Telepítés, vagy beállítás (/I) Eltá&volítás (/X) Cse&ndes eltávolítás (/X /qb) Eltávolítás az &MsiExec-el... Futtatás... Speciális... &Teljes információ Programnév Termékkód / GUID Teljes registry útvonal Eltávolítási karakterlánc Másolás a &Vágólapra... &Registry bejegyzés törlése Át&nevezés... Tele&pítési hely Eltáv&olító helye Forrá&s helye Megnyitás az &Intézőben... &Weboldal megnyitása Google AlternativeTo &Keresés az Interneten Minősítés... T&ulajdonságok XML fájlok|*.xml Kijelölt eltávolító-tulajdonságok exportálása Eltávolítók ú&jratöltése Eltávolítási &lista megnyitása... Kijelöltek e&xportálása... &Kilépés &Fájl Színmagyarázat mutatása Eszk&ztár mutatása Állapot&sor mutatása &Beállítások oldalsáv mutatása Ren&dszertéma használata Microsoft Store alkalmazások mutatása Keresés... &Nézet El&távolítás &Csendes eltávolítás Speciális... &Teljes információ Programnév Termékkód / GUID Teljes registry útvonal Eltávolítási karakterlánc Másolás a &Vágólapra... Tele&pítési hely Eltáv&olító helye Forrá&s helye Megnyitás az &Intézőben... &Weboldal megnyitása Google AlternativeTo &Keresés az Interneten Minősítés... Tula&jdonságok mutatása &Alapműveletek &Kézi eltávolítás &Telepítés, vagy beállítás (/I) Eltá&volítás (/X) Cse&ndes eltávolítás (/X /qb) Eltávolítás az &MsiExec-el Át&nevezés... Automatikus indítás letiltása &Beállításkulcs törlése Men&tés készítése... Kulcs megnyitása a &Regedit-ben &Speciális műveletek "Program Files" mappák &kitakarítása... Indítópult kezelő megnyitása Eltávolítás a könyvtárból... "&Programok és szolgáltatások" megnyitása "Rendszer-helyreállítás" megnyitása Beállítás&ok Esz&közök Sú&gó megnyitása Telepítővarázsló elindítása Frissítések ellenőrzése Visszajelzés küldése... Beállítások visszaállítása A BCUninstaller eltávolítása &Névjegy &Súgó &Hibakeresés ablak megnyitása Registry fájlok|*.reg Beállításjegyzék mentésének létrehozása Bulk Crap Uninstaller Frissítések mutatása FossHub.com SourceForge.net GitHub.com FileHippo.com FossHub.com SourceForge.net GitHub.com FileHippo.com Eltávolítás ablak, mappa vagy fájl segítségével... Módosítás Ne tartalmazza Tartalmazza Slant.co Mappafa&térkép mutatása Összes oszlop automatikus méretezése &Gyorsszűrők Exportálás egy kötegelt eltávolítási szkriptbe... PowerShell eltávolító szkript létrehozása a Microsoft Store alkalmazásokhoz... Alapértelmezett szűrők Csak sima alkalmazások Csak rendszerösszetevők &Minden Csak automatikusan indulók Csak böngészők Javítások mutatása Nem regisztráltak mutatása Windows-szolgáltatások mutatása Módosítás Slant.co Tulajdonba vétel Eltávolítás ablak, mappa vagy fájl segítségével... Eltávolítási problémák hibaelhárítása... Lemezkarbantartó indítása .NET v3.5 telepítése (funkcíó hozzádása) Új visszaállítási pont létrehozása ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/MainWindow.it.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Nome Editore Valutazione utente Versione Data installazione Dimensione Avvio 64bit Comando disinstallazione URL relativa Sorgente installazione Percorso installazione Tipo disinstallatore Componente di sistema Protetto Chiave di registro Codice prodotto Comando disinstallazione silenziosa Ricarica disinstallatori Seleziona tutto Deseleziona tutto Inverti selezione Disinstalla Disinstalla silenziosamente Proprietà Configurazioni Aiuto BCUninstaller Filtro avanzato Cerca &Disinstalla Disinstalla &silenziosamente Disinstalla &manualmente &Installa o imposta (/I) &Disinstalla (/X) &Disinstallazione silenziosa (/X /qb) Disinstalla tramite&MsiExec... Esegui... Avanzato... &Informazione completa Nome programma Codice prodotto / GUID Percorso completo chiave registro Stringa disinstallazione &Copia negli Appunti &Elimina voce registro &Rinomina &Percorso installazione &Percorso disinstallatore &Percorso sorgente Apri in &Explorer... Apri &pagina web Google AlternativeTo &Ricerca in internet Valutazione... &Proprietà File XML|*.xml Esporta proprietà disinstallatore selezionato &Ricarica disinstallatori &Apri elenco disinstallazione... &Esporta selezione... &Esci &File Visualizza legenda colori Visualizza &barra strumenti Visualizza &barra di stato Visualizza barra laterale &impostazioni &Usa tema di sistema Visualizza App Store di Windows Cerca... &Visualizza &Disinstalla Disinstalla &silenziosamente Avanzate... Informazioni &Complete Nome programma Codice prodotto / GUID Percorso completo registro Stringa disinstallazione &Copia negli Appunti &Percorso installazione Percorso &disinstallatore &Percorso sorgente Apri in &Explorer... Apri pagina &web &Cerca in internet Valuta... Visualizza &proprietà Operazioni di &base Disinstalla &manualmente &Installa o imposta (/I) &Disinstalla (/X) &Disinstallazione silenziosa (/X /qb) &Disinstalla tramite MsiExec &Rinomina Disabilita avvio automatico &Elimina chiave registro Crea &backup &Apri chiave in Regedit Operazioni &avanzate &Pulizia cartella "Program files"... Apri gestore avvio automatico Disinstalla da cartella... Apri "&Programmi e funzionalità" Apri "Ripristino di sistema" &Impostazioni &Strumenti Apri &Guida in linea Avvia assistente configurazione Controlla aggiornamenti Invia feedback... Ripristina impostazioni Disinstalla BCUninstaller &Info sul programma &Aiuto Apri finestra di &debug File registro|*.reg Crea backup registro Bulk Crap Uninstaller Google AlternativeTo FossHub.com SourceForge.net GitHub.com FileHippo.com FossHub.com SourceForge.net GitHub.com FileHippo.com Disinstalla da finestra, cartella o file... Modifica Escludi Includi Visualizza struttura ad &albero Visualizza non registrato Visualizza aggiornamenti Visualizza funzionalità di Windows Modifica Disinstalla da finestra, cartella o file... Esporta in uno script per disinstallazione a blocchi... Crea uno script PowerShell di rimozione per applicazioni dello Store... Filtri pre&definiti Solo applicazioni di &base Solo componenti di sistema &Tutto Solo avviati automaticamente Solo browser web Visualizza ottimizzazioni Filtro &rapido Risoluzione dei problemi di disinstallazione... Avvia pulizia disco Installa .NET v3.5 (aggiungi funzionalità) Creare un nuovo punto di ripristino Slant.co Slant.co Assumi proprietà Ridimensionamento automatico di tutte le colonne ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/MainWindow.ja.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 名前 発行元 ユーザー評価 バージョン インストール日 サイズ スタートアップ 64ビット アンインストールコマンド 詳細URL インストール元 インストール場所 アンインストーラーの種類 システムコンポーネント 保護されている レジストリキー 製品コード 静かなアンインストールコマンド アンインストーラーを再読み込み すべて選択 すべて選択解除 選択を反転 ウィンドウ、ディレクトリ、またはファイルによるアンインストール... アンインストール 静かにアンインストール 変更 プロパティ 設定 ヘルプ BCUninstaller 高度なフィルタリング 検索 &アンインストール 静かにアンインストール 手動でアンインストールする &インストールまたは設定する (/I) &アンインストールする (/X) &静かなアンインストール (/X /qb) MsiExecを使ってアンインストール... 除外 含める 実行... 詳細... &すべての情報 プログラム名 製品コード / GUID 完全なレジストリパス アンインストール文字列 &クリップボードにコピー... &レジストリエントリを削除 &名前を変更... &インストール場所 &アンインストーラーの場所 &ソースの場所 エクスプローラーで開く... ウェブページを開く Google AlternativeTo.net Slant.co FossHub.com SourceForge.net GitHub.com FileHippo.com &オンラインで検索 評価する &プロパティ XMLファイル|*.xml 選択したアンインストーラーのプロパティをエクスポート &アンインストーラーを再読み込み &アンインストールリストを開く... &選択したアンインストーラーのデータをエクスポート... バッチアンインストールスクリプトにエクスポート... ストアアプリ用のPowerShell削除スクリプトを作成... &終了 &ファイル 色の説明を表示 ツールバーを表示 ツリーマップを表示 設定サイドバーを表示 ステータスバーを表示 &システムテーマを使用 &表示 &デフォルトフィルター 基本的なアプリケーションのみ システムコンポーネントのみ &すべて 自動的に開始されたもののみ 自動的に開始されたもののみ Tweaksを表示 未登録のものを表示 更新を表示 Windows機能を表示 Windowsストアアプリを表示 検索... クイックフィルター &アンインストール 静かにアンインストール 変更 詳細... &すべての情報 プログラム名 製品コード / GUID 完全なレジストリパス アンインストール文字列 &クリップボードにコピー &インストール場所 &アンインストーラーの場所 &ソースの場所 &エクスプローラーで開く... &ウェブページを開く Google AlternativeTo Slant.co FossHub.com SourceForge.net GitHub.com FileHippo.com &オンラインで検索 評価する &プロパティを表示 &基本操作 &手動でアンインストール &インストールまたは設定 (/I) &アンインストール (/X) &静かにアンインストール (/X /qb) &MsiExecを使ってアンインストール &名前を変更... 自動起動を無効にする &レジストリキーを削除 &バックアップを作成... &Regeditでキーを開く 所有権を得る &高度な操作 スタートアップマネージャを開く &「プログラムフォルダ」をクリーンアップ... ウィンドウ、ディレクトリ、またはファイルからアンインストール... ディレクトリからアンインストール... アンインストールの問題をトラブルシューティング ディスククリーンアップを開始 .NET v3.5をインストール(機能を追加) &「プログラムと機能」を開く 「システム回復」を開く &設定 &ツール &ヘルプを開く セットアップウィザードを開始 アップデートを確認 フィードバックを送信... 設定をリセット BCUninstallerをアンインストール &詳細 &ヘルプ &デバッグウィンドウを開く レジストリファイル|*.reg レジストリバックアップを作成 Bulk Crap Uninstaller 新しい復元ポイントを作成 ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/MainWindow.nl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Naam Uitgever Gebruikers waardering Versie Installatie datum Grootte Opstarten 64bit De-installeer opdracht Info URL Installatie bron Installatie pad De-installatie methode Systeem component Beveiligd Registersleutel Productcode 'Stille' de-installatie opdracht De-installers opnieuw laden Selecteer alles Deselecteer alles Omkeren selectie De-installeer De-installeer 'stil' Eigenschappen Instellingen Help BCUninstaller Geavanceerde filtering Zoeken &De-installeer &De-installeer 'stil' De-installeer &handmatig &Installeren of configureren (/l) &De-installeren (/X) 'Stille' &de-installatie (/X /qb) De-installeren met &MsiExec... Uitvoeren... Geavanceerd... &Volledige informatie Programmanaam Productcode / GUID Volledig register pad De-installatie string &Kopiëren naar klembord Registersleutel &verwijderen &Hernoemen... &Installatie pad &De-installatie pad &Bron locatie Openen in &verkenner &Website openen Google Alternatief voor Online &zoeken Waardering... &Eigenschappen XML bestanden|*.xml Exporteer geselecteerde de-installer eigenschappen De-installers &opnieuw laden De-installatie lijst(en) &openen &Exporteren selectie... &Afsluiten &Bestand Kleurenlegenda tonen &Werkbalk tonen Statusbalk &tonen Instellingen &zijbalk tonen &Gebruik systeemthema Bekijk updates Bekijk Windows Store apps Zoeken... &Beeld &De-installeren De-installeer &onzichtbaar Geavanceerd... &Volledige informatie Programma naam Product code / GUID Volledig register pad De-installatie string &Kopieer naar klembord... &Installatie locatie &De-installatie locatie &Bron locatie Openen in &verkenner... &Website oproepen Google Alternatief voor... Online &zoeken Waardering... Eigenschappen &tonen &Basis bewerkingen &Handmatig de-installeren &Installeren of configureren (/l) &De-installeren (/X) &Stille de-installatie (/X /qb) &De-installeren met MsiExec &Hernoemen... Autostart uitschakelen &Verwijder registersleutel &Backup van register maken &Open de sleutel met Regedit &Geavanceerde bewerkingen &Opruimen "Programma bestanden" mappen... Opstartmanager openen De-installeer uit de map... &Instellingen &Gereedschappen Setup assistent starten Naar updates zoeken Feedback sturen Instellingen terugzetten De-installeer BCUninstaller &Over &Help Open venster &foutopsporing Register bestanden|*.reg Backup van register maken Bulk Crap Uninstaller "&Programma's en onderdelen" openen "Systeemherstel" openen &Help openen De-installeer mbv. venster, map of bestand... De-installeer mbv. venster, map of bestand... FossHub.com SourceForge.net GitHub.com FileHippo.com FossHub.com SourceForge.net GitHub.com FileHippo.com Bekijk ongeregistreerd Bekijk Windows onderdelen Wijzigen Uitsluiten Inbegrepen Exporteren naar een batch de-installeer script... Creëer een PowerShell verwijder script voor Store Apps... Boomstructuur &map tonen &Standaard filters Alleen &basis toepassingen Alleen systeemcomponenten &Alles Alleen automatisch gestart Alleen web browsers &Snelle filters Wijzigen Foutopsporing de-installatie problemen Start schijfopruiming Installeer .NET v3.5 (toevoeg functie) Bekijk tweaks Maak een nieuw herstelpunt Neem eigenaarschap op Slant.co Slant.co ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/MainWindow.pl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Wyszukiwarka Nazwa Wydawca Wersja Data instalacji Rozmiar Autostart 64bity Komenda dezinstalacji Adres informacji Źródło instalacji Miejsce zainstalowania Rodzaj dezinstalatora Element systemowy Zabezpieczony Klucz rejestru Kod produktu Komenda cichej dezinstalacji Odśwież dezinstalatory Otwórz listy dezinstalatorów... Zaznacz wszystko Odznacz wszystko Odwróć zaznaczenie Odinstaluj Odinstaluj cicho Właściwości &Odinstaluj Odinstaluj &cicho Odinstaluj &ręcznie &Instaluj lub skonfiguruj (/I) &Odinstaluj (/X) Odinstaluj &cicho (/X /qb) Odinstaluj przez &MsiExec &Pełne informacje Nazwa programu Kod produktu / GUID Ścieżka klucza w rejestrze Komenda dezinstalacji &Kopiuj do schowka... &Usuń klucze rejestru &Zmień nazwę... Miejsce &zainstalowania Miejsce &dezinstalatora Źródło &instalacji Otwórz w &explorerze... Otwórz stronę &Web &Szukaj online &Właściwości Pliki XML|*.xml Eksportuj właściwości wybranych elementów &Odśwież dezinstalatory Załaduj zaznaczenie z &list... &Eksportuj zaznaczone pozycje... Za&mknij &Plik Pokaż legendę kolorów Pokaż pasek &narzędzi Pokaż pasek &stanu Pokaż panel &ustawień &Użyj motywu systemowego Szukaj... &Widok &Odinstaluj zaznaczone &Cicho odinstaluj zaznaczone &Pełne informacje Nazwa programu Kod produktu / GUID Ścieżka klucza w rejestrze Komenda dezinstalacji &Kopiuj do schowka... Miejsce &zainstalowania Miejsce &dezinstalatora Źródło &instalacji Otwórz w &explorerze... Otwórz stronę &Web &Szukaj online &Właściwości Po&dstawowe operacje Odinstaluj &ręcznie &Instaluj lub skonfiguruj (/I) &Odinstaluj (/X) Odinstaluj &cicho (/X /qb) Odinstaluj przez &MsiExec &Zmień nazwę... Wyłącz autostart &Usuń klucze rejestru Utwórz &kopię zapasową... &Otwórz klucz w Regedit &Zaawansowane operacje &Wyczyść foldery "Program Files"... Otwórz Menedżer Autostartu Otwórz &Programy i funkcje Dezinstaluj z folderu... &Ustawienia &Narzędzia Otwórz &pomoc Uruchom kreator konfiguracji Sprawdź uaktualnienia Wyślij feedback... Resetuj ustawienia Odinstaluj BCUninstaller &O programie Po&moc Otwórz okno &debugowania Pliki rejestru|*.reg Utwórz kopię rejestru BCUninstaller Ocena użytkowników Oceń... Oceń... Pomoc Zaawansowane filtrowanie Bulk Crap Uninstaller Zaawansowane... Pokaż aplikacje Windows Store Zaawansowane... Google AlternativeTo Otwórz "Przywracanie systemu" Google AlternativeTo Uruchom... Pokaż aktualizacje Odinstaluj wskazujac okno, folder, lub plik... FossHub.com SourceForge.net GitHub.com FileHippo.com FossHub.com SourceForge.net GitHub.com FileHippo.com Odinstaluj wskazując okno, folder, lub plik... Pokaż tree&map Pokaż niezarejestrowane Pokaż funkcje systemu Windows Modyfikuj Uruchom Oczyszczanie dysku Zainstaluj .NET v3.5 (dodaj funkcję) Modyfikuj Wyklucz Załącz Rozwiązywanie problemów z odinstalowaniem... &Domyślne filtry Tylko podstawowe aplikacje Tylko komponenty systemowe &Wszystko Tylko automatycznie uruchamiane Tylko przeglądarki internetowe Eksportuj do skryptu dezinstalacyjnego (.bat)... Utwórz skrypt PowerShell usuwający Store Apps... &Szybkie filtry Pokaż usprawnienia Utwórz nowy punkt przywracania ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/MainWindow.pt-BR.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Nome Editor Classificação do usuário Versão Data da instalação Tamanho Inicialização 64bit Comando de desinstalação Sobre o URL Fonte da Instalação Local da instalação Tipo de desinstalador Componente do sistema Protegido Chave do registro Código do produto Comando da desinstalação silenciosa Recarregar desinstaladores Selecionar tudo Desmarcar tudo Inverter seleção Desinstalar por janela, diretório ou arquivo ... Desinstalar Desinstalar silenciosamente Modificar Propriedades Configurações Ajuda BCUninstaller Filtragem avançada Procurar &Desinstalar Desinstalar &silenciosamente Desinstalar &manualmente &Instalar ou configurar (/I) Desins&talar (/X) Desinstalação &Silenciosa(/X /qb) Desinstalar usando o &MsiExec... Excluir Incluir Executar Avançado... In&formações completas Nome do programa Código do produto / GUID Caminho completo do registro Sequência de desinstalação &Copiar para a Área de Transferência... Excluir a entra&da do registro &Renomear... Local da &instalação Localização do &desinstalador Localização da &fonte Abrir no &explorer... Abrir Página da &Web Google AlternativeTo FossHub.com SourceForge.net GitHub.com FileHippo.com Pe&squisar on-line Avalie... &Propriedades Arquivos XML|*.xml Exportar as propriedades do desinstalador selecionado &Recarregar desinstaladores Abrir as listas de desinstalaçã&o &Exportar a seleção... S&air Ar&quivo Mostrar legenda de cores Mos&trar barra de ferramentas Mostrar árvore e &mapa Mostrar a barra de configuraçõe&s lateral Mostrar a &barra de status &Usar o tema do sistema Exibir não registrado Ver atualizações Exibir recursos do Windows Exibir Apps da Windows Store Procurar... &Visualizar &Desinstalar Desinstalar &silenciosamente Modificar Avançado.. In&formações completas Nome do programa Código do produto / GUID Caminho completo do registro Sequência de desinstalação &Copiar para a Área de Transferência... Local da &instalação Localização do &desinstalador Localização da &fonte Abrir no &explorer... Abrir Página da &Web Google AlternativeTo FossHub.com SourceForge.net GitHub.com FileHippo.com Pe&squisar on-line Avalie... Exibir &Propriedades Operações &básicas Desinstalar &manualmente &Instalar ou configurar (/I) Desins&talar (/X) Desinstalação &Silenciosa(/X /qb) Desinstalar usando o &MsiExec... &Renomear... Desativar auto-inicialização Excluir a chave &do registro Criar &backup... Abrir a chave n&o Regedit Operações &avançadas Abrir o Gerenciador de Inicialização &Limpar pastas "Arquivos de Programas"... Desinstalar por janela, diretório ou arquivo... Desinstalar do diretório... Abrir "&Programas e Recursos" Abrir "Recuperação do Sistema" &Configurações &Ferramentas Abrir &ajuda Iniciar o assistente de configuração Verificar atualizações Enviar comentário... Redefinir configurações Desinstalar o BCUninstaller &Sobre &Ajuda Abrir a janela de &depuração Arquivos do registro|*.reg Criar cópia de segurança do registro Bulk Crap Uninstaller Slant.co Redimensionar automaticamente todas as colunas &Filtros rápidos Exportar para um script de desinstalação em lote... Criar um script Powershell para remover Store Apps.. &Filtros padrão Apenas aplicações &básicas Apenas componentes do sistema &Tudo Apenas inicialização automática Apenas navegadores Ver mudanças Slant.co Assumir a propriedade Solução de problemas de desinstalação.. Iniciar Limpeza de Disco Instalar .NET v3.5 (add recurso) Criar um novo ponto de restauração ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/MainWindow.pt.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Nome Editor Classificação do utilizador Versão Data da isntalação Tamanho Inicialização Comando de desinstalação Acerca do URL Origem da instalação Localização da instalação Tipo de desinstalador Componente do sistema Protegido Chave do registo Código do produto Comando da desinstalação em segundo plano Recarregar desinstaladores Seleccionar tudo Desmarcar tudo Inverter selecção Desinstalar Desinstalar em segundo plano Propriedades Configurações Ajuda Filtragem avançada Procurar &Desinstalar Desinstalar em &segundo plano Desinstalar &manualmente &Instalar ou configurar (/I) &Desinstalar (/X) &Desinstalação em segundo plano(/X /qb) Desinstalar usando o &MsiExec... Avançado... &Informação completa Nome do programa Código do produto / GUID Percurso completo do registo Cadeia de desinstalação &Copiar para a Área de Transferência... &Suprimir a entrada do registo &Renomear... Localização da&instalação &Localização do desinstalador &Localização da origem Abrir no&explorador... Abrir &P agina Web Classificar... &Propriedades Ficheiros XML|*.xml Exportar as propriedades do desinstalador seleccionado &Recarregar os desinstaladores &Abrir as listas de desinstalação &Exportar a selecção... S&air &Ficheiro Mostrar a legenda das cores Mostrar a&barra de ferramentas Mostrar a barra de &estado Mostrar a &barra lateral de configurações &Usar o tema do sistema Ver app no Windows Store Procurar... &Visualizar &Desinstalar Desinstalar em &segundo plano Avançado.. &Informação completa Nome do programa Código do produto / GUID Percurso completo do registo Cadeia de desinstalação &Copiar para a Área de Transferência &Localização da instalação &Localização da desinstalação &Localização da origem Abrir em &explorador... Abrir &Página Web &Procuraron line Classificar... Mostrar &propriedades &Operações básicas Desinstalar&manualmente &Instalar e configurar (/I) &Desinstalar (/X) &Desinstalar em segundo plano (/X /qb) &Desinstalar usando o MsiExec &Renomear... Desactivar o arranque automático &Apagar a chave do registo Criar &cópia de segurança... &Abrir a chave no Regedit &Operações avançadas &Limpar as pastas dos "Ficheiros do programa"... Abrir o Gestor da Inicialização Abrir "&Programas e Funcionalidades" &Configurações &Ferramentas Abrir &ajuda Iniciar o assistente de instalação Verificar actualizações Enviar comentário... Redefinir configurações Desinstalar o BCUninstaller &Acerca do &Ajuda Abrir a &janela de depuração Ficheiros do registo|*.reg Criar cópia de segurança do registo Bulk Crap Uninstaller 64bit BCUninstaller Google AlternativeTo Google AlternativeTo Desinstalar do directório. Abrir o "Sistema de Recuperação". Executar Mostrar actualizações FossHub.com SourceForge.net GitHub.com FileHippo.com FossHub.com SourceForge.net GitHub.com FileHippo.com Desinstalar através de janela, directório ou arquivo... Desinstalar através de janela, directório ou arquivo... Criar um novo ponto de restauro ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/MainWindow.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Fill 228, 24 4, 3, 4, 3 Fill 0, 0 5, 3, 5, 3 417, 598 0 advancedFilters1 BulkCrapUninstaller.Controls.AdvancedFilters, BCUninstaller, Culture=neutral, PublicKeyToken=null splitContainer1.Panel1 0 0, 0, 0, 2 splitContainer1.Panel1 System.Windows.Forms.SplitterPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 splitContainer1 0 320 Fill 0, 30 4, 3, 4, 3 Horizontal Name 249 Publisher 160 User rating 80 Version Install Date 70 Size 65 Startup 52 64bit 40 Uninstall command 160 About URL 160 Install Source 160 Install Location 160 Uninstaller Kind System Component 40 Protected 40 Registry key 160 Product code 260 Quiet uninstall command 160 Fill 0, 0 4, 3, 4, 3 377, 485 0 uninstallerObjectListView BrightIdeasSoftware.ObjectListView, ObjectListView, Culture=neutral, PublicKeyToken=null listViewPanel 0 Fill 0, 0 4, 3, 4, 3 379, 487 6 listViewPanel System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 splitContainerListAndMap.Panel1 0 splitContainerListAndMap.Panel1 System.Windows.Forms.SplitterPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 splitContainerListAndMap 0 Fill 0, 0 5, 3, 5, 3 379, 56 1 treeMap1 SimpleTreeMap.TreeMap, SimpleTreeMap, Culture=neutral, PublicKeyToken=null splitContainerListAndMap.Panel2 0 splitContainerListAndMap.Panel2 System.Windows.Forms.SplitterPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 splitContainerListAndMap 1 379, 548 487 5 7 splitContainerListAndMap System.Windows.Forms.SplitContainer, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 splitContainer1.Panel2 0 17, 17 NoControl iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAALhSURBVGhD7ZlPhFZRGMa/T5EkzSKSpChGEmkRLUpajhYt iqLFGIZK2yiSlAzTLlpFi5hNtGiRFEWLDLNNtJo2ERkzUZLkq99T93Kd7517zz3n3Jm53IefM6753nOf e8/7nj+316lTp1ZqFDb9/7PdOgNvoPVmZOQPrLqZDbAPTsI4TMBZOAFboUq5kZU3MxgMttNchzn4CfmN WLyHaZBZS0UjYkXMKDFn4DcUO/flGRyFolwj4iKkF29gI81dqHr6vjyCfNhZRi5Bcu2Ad+B2Fss8HIDm jfAmDtF8BrejVCzClHNNJDWifFgAt5Miv+AVKPHHMH6Y9hichsvwBL6B9dsy0hjhhjbTfACrE/EDlDPb oFRZfl2Br2DFskj2Ru6D1YFQOdXYriuZfg1WTJd4I9nwsIKL2Bqv3yqGFbtIkjeiWm8Ffws+JjSMvpSg BLfiF4k2sh+swN9hD/hKM7kVx5doI7fBCqzErqsYM9FGlMhuUC1HdkOIQs1EGdEq1gqq5IzRHdADqsM5 CNYRGDLS7/dv0rZKe0GzsUudJO/UaY1Iw9YazjuhPcoKyVCBybYPwVLJs0phGVpcroNQaQvgGtEuVFNB sDQJuUF9eAi1zfDUdYBh7f31gKIUakSEmLkFViytBqIUY0TUMbMLtBAdihObH5KPkSWwluY52n9XSeP/ JVjxn0O0fIzEbqxk4ilYsfU2tKmLlu/QmoWQZYvmBm3OrJjiASRRnRxRiVRSVh4+oBG4AWU7w4+g/0si y8jAuFZE5VPD7SqcyhJVu8wxmITHUHV6ouOig5BMlhGdV31yrqVkMUWVcmUZ0XGm8qGpI1MdAibXckYk Vap7UDXUfFAMJfYWaEQa026nuZFcOpiL+azwIlWJLZNV410j/8TNaJ10DZToVZ8aVJF0CrPch55G5Jox jThaD6pU+tx2AfSR5jwcB5/y3JiKZnyMrGnlZlpvRJKZ0IO5Tp06rZp6vb/qRp+fJ/k5hwAAAABJRU5E rkJggg== Magenta 132, 26 Reload uninstallers 6, 29 iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHrSURBVGhD7ZahSgVREIYXDCZBEBHxAcRiMBiMNpvFF7DZ RDD4ACJYfACjQTAIRoNBm0Uf4QaDzaIYDKv/r3vkMMzu3fXMmOaDj13O3Ts/s3vvnK2CIAiCIAiCoSzA xZ9TGz7/0RNY1XU9hcMjfMb5Ctcs0AI9vIATcBLeNmv0Ba7DYvIwL28gG2Aj581a7iucg0XIotY+wGlI jqB2zR4sRits5Qj/gXkcyS7UrjmFJmjFrdmCNZQ5d5A/ORNkcWrJGnyHMmMEZ6AZMoBawX2CU0nW5597 CZoiQ6iEj593dgjc8J6grM2f2AY0RwbRHDZxBT/gJhfGkW14Wm2TCaWhhSVSE2mdd3MbdsHvXMO8XtJs QmlogYlLKD9jMztQo23Do98TCk9rFkcXtNAE7742Nuk+lLRteGlC8WndQxe04JyuZg5hgk9JuyafUGeQ ay7IYC2oq5lj2LbhcS1NqAOY1l3Ig7uCupppM00oTrv8uy7kweOChjTzPaHw517G4a1ZS7qQB/QJ6tNM /g6lbYouyJA+QV3NyHco7RoX/hqkNaO9Q+WfJ10oCcqb4VF7h5K1qQulQamZtneo0vq9KQ7CZFptTjWK 6/fFO8i7/i9akLcuaEHeuqAFeeuCFuStC1qQt0EQBEEQDKOqvgAXhV7oKQ97YAAAAABJRU5ErkJggg== Magenta 26, 26 Select all iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACBSURBVGhD7c2xDcAwAMOw/P90+oBHgx1iAZp51lprrfVo 96frJURcLyHiegkR10uIuJ5AhEEQYRBEGAQRBkGEQRBhEEQYBBEGQYRBEGEQRBgEEQZBhEEQYRBEGAQR BkGEQRBhEEQYBBFGRMT1EiKulxBxvYSI6yVEvNZaa63HOucDln3yHBqFG0wAAAAASUVORK5CYII= Magenta 26, 26 Deselect all iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAKSSURBVGhD7Zk/aBRBGMUPFEREEMRKAnZWNqLWYiFomTpV CFYpbAQVEWwVFG0trWwEEYsUKULqkCIgEuwUBIukiIWInL53uS+8GWd2Zu9mLqvsD37sZWfv++axf26W DHp6/j/mxtsq/K7oEM5Dcg3+gLdHf1UgNIFS3oLkAtyFtv85PAKLoo1L+gCSs/Az9McfwaJo8aIMh8OT 2GxC7UG/QQYsijYoyTG4ArU+/YmAV7AtjjYpyUuotc0FWAVtUoqHUOuaT2E1tJEDLoGL2KzC06MdeSxC rWmyzlFYDW12wDjEDuT+LZhzc96Ev6DWpNvwFKyKNhzhhTA5maYwl+B3qN+he/A8rI42Nd5A3W9+gaFJ nYNfoX88f9lvwJmgjY0TcA3qmMkw/KU2eP98gKFj78GZoY2VpjA748uPvxWxY15BwktuJmhzn8YwkE+i 0NgGgh6HZ/CZZ3BaluA6/ASfsDZ3+ugEQjSFCcmJ86GgZ2tSWOM19HuwLufloAfEyA2jy49n0PZPAkO8 hVpf5XwcdLCJnDC6/ND9bUmFMB2iAwGawvjLDx1ry3XIR7fWCOkQHYgQCvMe+ssPHc+FZ8LgUicVxiE6 0ICGiS0/2ta1mo9Hf+2TCuMQHUjAxu9gbPnRpq5/lnPDOEQHpiS3buhSpTlhHKIDU5JTNxbCTIVx0IFa hkiFMGNheG86+F+soU9uCNMP8xH+9UoR+mJplbYhTA2jj+lDYdIQ5n146EwbIvZSN1P6ELAPUYo+BOxD lKIPAfsQpeAr7j8fwrgDQ5NM2akQRtswnQxh5IbpXAjeH3f3Px6QCtPJM3EVcnL60kNiYTp7Ob2ANslU mE7fE/5/qWJhOh3iMtQQph9mGVYIMRj8AeHfJWi9bK+YAAAAAElFTkSuQmCC Magenta 26, 26 Invert selection 6, 29 Magenta 26, 26 Uninstall by window, directory, or file... 6, 29 iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAFKSURBVGhD7dfBrcIwEEXRdMCSBqiBIqiFLtjBmjVV0AT1 sESBiUQi84iNx56MbTRXekJC+uDzI4joLMuyrLG+77f0cKXdaLvhuaZyAE9YG6AAAFcniAHA1QHKAODK gAQBOB3QggDcMiBFAE4GVBCAywLtaXMvWnJnGr9/uSJTzX9GsOa/tbAFQToATBBUBLB6P05lgHyAr/cQ yznsg3ahbWgfMUA+wJp2ot1pslcpcLgUUAwg9m/iYvx3Y0ApAFwaiAEZ5wXNxAGMU7sy40IgfQCWCSoP wBJB9QCwBNCv6QIwAZA+4H3oI41z7/DNBxg+TweaPG7mkDH3DvfQ7kIA/EKQuVoRh+KAOABcFojzU/cX KBWAU/up6wU5lbunCIHKAbAMUB0ALAEUOx0AJggqA8AyQHUAMAaoTgAWALUBwBxQmwDLsqyF6roXJMB3 ommlYIwAAAAASUVORK5CYII= Magenta 79, 26 Uninstall iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIySURBVGhD7ZcxLwRBGIYvUSgUCoVChIRERCMKiUKi9lv8 BJ1SrRatTkThLyj8AIVKKSiUsrzv2e/y+W5mbnZvdmdP9kmeDG72Zh97u7c76Onp6ekRiqLYx3AHH+Ax /zZTqIBv42wEBQKs3QyqEGDtRtAUAdY8QQkDrO0ENRhgbSaoxQBrmqCMAdapgk6g601zegGr81+OyIiZ P0csM3/VsjQY1E6AJWFQloDFchwxRZAvYGyNZKid/YKXcBP+oUKQL2AZnsNPmPYoBXauTlBMQOw2caid eYauBcSYoDoB1npB5U5cwRV4BCct9gFXYQxVAsRkH7UD+Apdi3CHGKuZL0dN1gAuPtwpHKU9DG9QL6Qj OI/zyRo8hTxKWQMIP1ZP8AbKf3gb3kIuZiM4j/O5HdmC/D1bAJEIWUDHEAYc/v44ipC5Osa+j8/kAcS3 uI0hNkKMjWkkQFiHL9C1sI7xRVAdsgQfoX7dF8Dz6Qwmi+PnOxSzUI6u10MRoQB7QUh2tEIx746/UR3B IyYRVQKsSYJCMVYdMaT8Yq0bYK33qKuIiRmL8JD9O2UHFtC1EO+3NqBwDe39V/YAEro6iaOrmboDkBvK 7AEkJkJ0xbjm+WwkgFSJEOvENBZAQhE8sXl7wtH1emxMowFkUoRcnTjWiWk8QNiFrpPTdYn1xXB7vg9h 0D1sLUBjnwpdEYKN4XZyez8H+VzSeoBGYkIRgsToiE7Bk3pShMB58ozS09PTGQaDHxF+Z1FP1tq4AAAA AElFTkSuQmCC Magenta 118, 26 Uninstall quietly Magenta 26, 26 Modify 6, 29 Magenta 86, 26 Properties 6, 29 Magenta 26, 26 Settings Magenta 26, 26 Help 0, 0 0, 0, 0, 1 379, 30 0 toolStrip System.Windows.Forms.ToolStrip, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 splitContainer1.Panel2 1 132, 17 No 62, 17 MiddleLeft False No 70, 17 MiddleLeft False 230, 17 MiddleRight 0, 578 1, 0, 16, 0 379, 22 1 statusStrip1 System.Windows.Forms.StatusStrip, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 splitContainer1.Panel2 2 splitContainer1.Panel2 System.Windows.Forms.SplitterPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 splitContainer1 1 803, 600 417 7 1 splitContainer1 System.Windows.Forms.SplitContainer, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 1 GrowAndShrink True GrowAndShrink Top 7, 193 5, 3, 5, 3 117, 115 213, 369 1 propertiesSidebar BulkCrapUninstaller.Controls.PropertiesSidebar, BCUninstaller, Culture=neutral, PublicKeyToken=null settingsSidebarPanel 0 True Bottom False Microsoft Sans Serif, 15.75pt NoControl 7, 568 4, 0, 4, 0 143, 25 2 BCUninstaller label1 System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 settingsSidebarPanel 1 True GrowAndShrink Top NoControl 9, 155 4, 3, 4, 3 195, 27 1 Advanced filtering buttonAdvFiltering System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBox1 0 True GrowAndShrink Top 9, 21 0, 0, 0, 0 117, 0 195, 134 0 filterEditor1 UninstallTools.Controls.FilterEditor, UninstallTools, Culture=neutral, PublicKeyToken=null groupBox1 1 Top 7, 2 4, 3, 4, 3 9, 5, 9, 9 213, 191 0 Search groupBox1 System.Windows.Forms.GroupBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 settingsSidebarPanel 2 Left 2, 24 4, 3, 4, 3 7, 2, 6, 7 226, 600 0 settingsSidebarPanel System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 2 269, 17 iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO vAAADrwBlbxySQAAAbZJREFUaEPd1z1OAzEQhuGNlK0puQBn4BCchVvQQU3NKei35jyUSItXykjW6PXP jO2AUzzNxwJ+E2VXWbZtuwk4zgjHGeE4IxxnhOOMcOxl3/fHZVk+g6/gia7pBcdWUcCuDAvC0SsToHUP wtHKEKB1C8KxVkOA1hyEY0nHAM0dhGPKwADNHISjdsUArToIR/GHAVoxCMfD6XR6Vn/sP3insx5wFDfx jsSm/4xo09+1tIFB5gCBY62OQe4AgWPOuq53emsIwgD6HyU4kuiwP8FHuD0/ZK6hQ8cw4Hw+34f9LfhO XZOCYyxzOE9QTUDV72g4Hgyvbk2QJ0DLBuF4MISIZJBmDBC+ENEzaESAwJG0BI0MEDjmOIOGBQgcaziC SlwBAkeLDkFNAQLHlMuhX43PjhQMuHyeXuhnOThqcMiaZ0d86FguQN8Qqt8tHEXFoSxBlgCtGITjIRzO 8lW3FOQN0K72VTcZJEY9U3DUegSNChA4pniDgmEBAscSR1Atc4DAsVbHIHeAwNGqIag5QODoZQjqFiBw bJUJ6h4gcOwlChoWIHCcEY4zwnFGOM4IxxnhOJ9t+QUUCa3NNFC+OwAAAABJRU5ErkJggg== 211, 26 &Uninstall iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO vAAADrwBlbxySQAAAtdJREFUaEPdlz+L1EAYxrP/WFgLC2Et5FBQELE5LASLBWs/ix/BztLaWmztDrGw 29rCD3CFlaWoxZWH6/MeecO77z6ZmUyS1bnAjyRPZmfmt5NMJtV2u70W0LBEaFgiNCwRGpYIDUuEhkOx 2+2eVlX1CXwBL1iZoaBhX4zAzjGaEA1zCQh4BheiYVc6CHgGE6JhKj0EPL2FaBhjQAFPthAN2xhRwNNZ iIaeIwp4koVoqPxDAU9UiIbCZDJ56Sr7H3jL+irQULkWI2Ip/hnxFD9reUYU6iyg0DCVAYWyBRQahlgs Fjd91kOICrA2YtCQYTp7Cd5hen4QKMM6baEC8/n8NvI34KKtTBs0tAQ6lyOUIpD0Gw8NBdOZb4A1oKQI 5Qh4gkI0FOpOvJ/NZnfQyec4jjX2G5ywujwdBZQ8EQ+2Z+AHYI1ciKwtv1qtlvZcGENAoaFFGtdOYZSe oNKfphGhkZByUl6OMZJ3kb/C9ZMxBRQaKnJbobJzcKYy2B6Bj0Aa25PA+Rk4l99JNp1OH8q5lAO+o210 ElBoKBgJbaCREernZiPHRkLLNjKknjayBBQaBhrfkxGIhJIq00tAoSH+7Xuo/LtpzNLIBCSERgTPyC2c f3XXqUD9PL1m10LQUKjv71aZ5XJ5Q/YuV0ISIQE/ISSPFg2ViMwvkgmNRD1iKtFFwBMVoqElIuNpJJT6 xZor4Mn71FUSZQ4kGJkC/UdEgcxjVPbHVG65hMR9LYvtA9hbf40loNDQE5mdlGY2MyuAqwUlGE1AoaEl UUJhMqxcG50FFBoqHSWUHJlsAYWGQkRC3tKbes+up8r0FlBoGJPQ2Un2cu6uKyGZwQQUGmK2OUVD7OE8 mGIDMrIyPpUy9R/zGQwuoNBQqFe3Vqb1PUFkmuX9er2e4Vi+S0YRUGioGJnoy87IHHwtHgMaWrBtYhJK LXP1jXJsaFgiNCwRGpYIDctjW/0F5PnkmYCIcpwAAAAASUVORK5CYII= 211, 26 Uninstall &quietly 211, 26 Uninstall &manually 196, 22 &Install or configure (/I) 196, 22 &Uninstall (/X) 196, 22 &Quiet uninstall (/X /qb) 211, 26 Uninstall using &MsiExec... 208, 6 211, 26 Exclude 211, 26 Include 208, 6 211, 26 Run... 208, 6 183, 22 Advanced... 180, 6 183, 22 &Full information 183, 22 Program name 183, 22 Product code / GUID 183, 22 Full registry path 183, 22 Uninstall string iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO vAAADrwBlbxySQAAAc5JREFUaEPdlEGOwzAMA3sL0P3/Q/YH2Ze19UFANBaoxrEMZAvMQVQpmpc89n3/ F4TiHQlF4/N7TeRv27afKGcGoWjgITMoKxOKBh4xi5IyoWjgATOZXiYUDYS/ov9kPJ/P7eP95a0PU8uE ooFgV4S7i1wuFYoGwiqLNC6VCUUDQdVFGsNlQtFAyIoijaEyoWggQBY57jLoDThdJhQNHK8scvmrFooG DpcVmfGJDkUDR8uKNO1qmVA0cLC0SONKmVA0cKy8SGO0TCgaOLSkSGOkTCccwZFlRRpny7iB4MDSIg1V hv91A4G5rMgI3U0KR5RZ7TLoHaG7SeGIMqtdBr0jdDcpHFFmtcugd4TuJoUjyqx2FWR5biDKrHYVZHlu IMqsdhVkeW4gyqx2FWR5biDKrHYVZHluIMqsdhVkeW4gyqx2FWR5biDKrHYVZHluIMqsdhVkeW4gyqx2 FWR5biDKrHYVZHluIMqsdhVkeW4gyqx2FWR5biA0KyL/TLI8NxCaFZF/JlmeGwjNisg/kyzPDYRmReSf SZbnhjNkh2eT5bnhDDy8mu49FL6Fh1fTvYfCt/Dwarr3UPgWHl5N9x4KdyUU70go3pFQvB/74w3YjMUD zoYarAAAAABJRU5ErkJggg== 211, 26 &Copy to Clipboard... 211, 26 &Delete registry entry 211, 26 &Rename... 208, 6 176, 22 &Install location 176, 22 &Uninstaller location 176, 22 &Source location iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO vAAADrwBlbxySQAAAitJREFUaEPd1TGS2lAQhGEBF3DuAzj3CbZ8PN/HOefY2PFGGzlh1RRDDf1+8SQ9 EPVM1Re41cxoam3vcDwe/wsY9gjDHmHYIwx7hGGPMNzC4XD4PgzD++i0FM0rgi20HCE0swierfUIoblF 8EyPOEJodhE8y6OOEJpfBK8091j6bhG8ypKfGH2/CF5h6V87mlEEmQ94kL/7/f5H7Fjzbye/YyiCzAc8 wNIjfkP28kMWHzH1DjEjK4LMBzRYdcTUO8SzrAgyH7DS6iOm3iE/v/YoDD5AqDfX0iPEnss/75x7FAYb cEa9OdYcIdb53O12b9ijMNiQM+rVrD1CUudj9Is6gmFIQ66od8/SI9TPf750Pk6n08+cOwzDZcgN6k1Z c8SYveds/Nz8ZzEFwzB+iuXUI2uP0LOczzlCMAyXhTeo51qOkPxsLgxDDM6o58bPn/wdc/cIyc/nwjDk 4YF67s5P5OYIGT9FzztzYBh8gVCPwDHFEZKeX1GvBsPgC4R6U9IxeITE3Ix6NRgGXyDUu2f8TfyN8uDz hXo1GAZfINRr4fOFejUYBl8g1Gvh84V6NRgGXyDUa+HzhXo1GAZfINRr4fOFejUYBl8g1Gvh84V6NRgG XyDUa+HzhXo1GAZfINRr4fOFejUYBl8g1Gvh84V6NRgGX7AVepcaDIMv2Aq9Sw2GwRdshd6lBsPgC7ZC 71KDYfAFW6F3qcGwRxj2CMMeYdgjDHuEYX+OwxdPcURPbbSJlwAAAABJRU5ErkJggg== 211, 26 Open in &explorer... 211, 26 Open &Web Page 163, 22 Google 163, 22 AlternativeTo.net 163, 22 Slant.co 160, 6 163, 22 FossHub.com 163, 22 SourceForge.net 163, 22 GitHub.com 163, 22 FileHippo.com iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO vAAADrwBlbxySQAAAu9JREFUaEPdmD+IE0EUxjckIRgRrSIiB7YW11hYi4VFesFCRARbu+vtLA60ukIt xMJGsDg7K3OIzRWCiLYWFhGR44orhBDX75MZmUy+zb7d29MdH/zI5ds37813s7N/kk0mk/8CKaaIFFNE iikixRSRYopIMUWkmCJSTBEpHpZOp9PLsuwy2AK74Av4Ab6Cj+Apcq4xT42vgxTrMhqNupjkDcCJ5waY d4fjVL0qSLEOeZ6fwaTeBJOswttut3tW1bUixarAxAVMZhpNripT1Lmo6luQYhVwnp/jJKJJkQPwGIzB 2nA4HPR6vdOcLL7fA/sgHvMNrKk+ZUjRymAwOI7Gn4KJeF5w0mqMh8eR9yQaR3brXASkaAWxEUzAs6ly i0BwdeIat/1x/rPC/CKkaMGtBk+FcALPVG4ZHBfUIFO/KogdixkpWkBcBWHzg7LTqQh3mnFPhfXGPOb+ LjUjRQsI3uzCxlsqjyA26t4rXO1SM1K0gHgXNMlxKlxSecTlfEDO9aqr5sZ6Cs0sCVYQC/uj3++fVHkk zGsAaWbhSxWi4rnK8cS5DbBkZqFhFaLCf3NFPAtmlppaQSw8GBr2yFHw55611NQK4nlQkKy6aoV5TdHM imAFbkaFC+8jiE3w0+U1QXN7hIVQ0HxnR6zzOIjHVKXZqxZBHPpZq4yotjTxO0+JFtyKvIoaeUqffq0E NQtNECmW4UzsBE0UfHZ6CMY0xfcR7Cu+u/h3+e8gHrMHzoe9nL7SBJHiKowm6rCn3hARpSaIFIs4QhP8 ZWW9qKfSY6SoMJp4CXgBsF6Z9nG63Z3NZsdUzypIMcZoYpv7gPn8xPcr4AF4D/y7Bj8/g21waz6fn4h7 1UWKIVVN/Cuk6EnFBJEiSckEkSJBPAomrGiNCSJFt1n5o7MyQFplgkjR/aqhDJDWmSBSJAi1P1ppgkiR uOei184A3yXut9UEkWIIDJ1a9T7eFqSYIlJMESmmiBRTRIopIsUUkWJ6TLJfuKvOc7bir0gAAAAASUVO RK5CYII= 211, 26 &Search online 211, 26 Rate... 208, 6 Tahoma, 8.25pt, style=Bold 211, 26 &Properties 212, 424 uninstallListContextMenuStrip System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 530, 17 XML files|*.xml Export selected uninstaller properties 675, 17 iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO vAAADrwBlbxySQAAA5xJREFUaEPdmUFIFUEYx9X3RDKiDmFISEFBSAjRQehQREfp0CFBoUMEQUrXoCBC ihD0FngSOgRdgg4dIgqM50GCriF0yksQRFighKRmv892Yhr/vp3dffbYPvixz7/zfTv/92Zmd2dbarXa f4EUy4gUy4gUy4gUm01bW9uxjo6O3ep/2yHFZkMMwmwWM1JsNomRjSxmpFiUzs7ODjrR29raeh4u8/kK xyGO5zjuVzk+hDMSbUaKedjY2Oimk7c58VtY8TqimIcJ6FW1CN+IkWpGilmwicmJHsOad+IsPIfTfk0i NGKM+G1CpBjD6urqLopPQtq3H8sjN+wIZWQ07IOPFNOoVCoHKfwuOFEj+AB9sPNGmAsnKfopOEkjWYTx QDMaZySZD1+CE4T8gJlk4g9gvJ/jGf6+CNf5/BSWQOXWozFG1tfX91DsfVDc5ztMVqvVAyrfJ5lfN+Bb khtDY4wQU17REFtO+1RePcw0ea+9OvUobiQZHqq4kelWIsRyrUZQU1HcCGFrvSo+F3XV/T2MPtfBJriq 71PMCBP8uChqLLMMH1E5CsKu5KpOLMWMEPe8Yj6Tqn09iCJmChuxiRwWXWMpPazap0HkNZPfSHIXq4rO qvaxEPfBvqAsDKtaDik6iFOwxQi/xphq30yk6KDDR+1qHJJlkv8rpFhGpFhGpNhMbNiq4czc7FHtHVJs JnR6LFxcDHt8UO0dUnQQw6CWwnpMdXV1VVS9GIgZCI2s2KVAtXdI0UGMesWy8DCPGb71bnLVs/+8au8j RQeR14iR2Qxx18v3mVDtfaToIIoYMaLNMMkP0X45yN8kbX4YUnQQMUa+gro1d4yr2j7JrdArUPVfqJwQ KTqIGCOFHqwSE8+Cmn8g+lVeiBQdROzQepPntoXogbmkhmJa5Smk6CCyzBHbqJuI2XzgWrGPtneg3pPh grVT+QopOghl5KfQfGz5nKUTN+GCTdTkKXMArsITSNs9WSL3hOrTdkjRQWwxwglsv+pjqDeQxZhVKkSK DkL9IoM2HzjuyJapbQKqvqQhRQchjdj/km2cB5A21GKwGtPt7e17wz7EIkUHYWM6POmmEa+NbToXea3w MnaJrYcUHdus8X8ZcdAZu0+6BbbZlvaqYQHslYR80ZMHKfoIM9KIDwtC1VYqjkNwjZwRjpfgbMzynAcp hgRmUo00AykqPDPlNmKYGYZHro25nUaKZUSKZUSKZUSK5aPW8guPW9SgVPCdQwAAAABJRU5ErkJggg== 331, 22 &Reload uninstallers 328, 6 iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO vAAADrwBlbxySQAAAf5JREFUaEPd169LBFEQB/C924WFs5jOYLAIVpPBbjFbNQg2q8UoGOSiXfEPMFou bRHBYrCJoPmK5ZIcrDOP945x7ovryco4Pvjg3nfvDd/1fqxmVVX9CzD0CIYewdAjGHoEQ49g6BEMPYKh RzD0CIYewbAteZ4vZ1n2Quo5XKJZTWDYhn6/n1OpW1XyW9C8JjBsA61dWW4eaF4TGLaB1p0sNw80rwkM mR5uCfXTYMj0MEuonwZDpodZQv00GDI9zBLqp8GQ6WHKEO2xBEOmikuTTqezjvZYgiFT5aVw56W1JTJr Q3gRTD0xGfOfHfSKFHT8oM5ZCe8QeBFMPTk5ief2RWbtInSS5SX1ZDYqy3KB8bE6Z2VcFMVS6KsvIFEb 2EHMT0Vm7XjaNx1oasMjfy7o87FCx2N1zsorvzumfWV5SW3ajtmVyKztfeorH0hiQ7j51XW9ITJr9zN9 dZDEDdObH60f/ZP0SzZn+uogiRvCzY8uZic+/guudVc2EyS0ws2v1+uVdPwch1h7p1/qKuyLQkbrLP48 ImiohYHumcCQ8Vcb32xo85saZmVEr8Yi6spgmNA6F4NM0UUcoo4JDFm3212jARM90MgTXUiBeiYwZLRu xCBr4Yb8FRh6BEOPYOgRDD2CoUcw9AiGHsHQIxh6BEOPYOgRDD2CoT9V9gFIcLIAMRBa5AAAAABJRU5E rkJggg== 331, 22 &Open Uninstall List... 328, 6 331, 22 &Export data of selected uninstallers... 331, 22 Export to a batch uninstall script... 331, 22 Create PowerShell remove script for Store Apps... 328, 6 331, 22 E&xit 37, 20 &File 198, 22 Show color legend 198, 22 Show &toolbar 198, 22 Show tree&map 198, 22 Show &settings sidebar 198, 22 Show status &bar 195, 6 198, 22 &Use system theme 195, 6 198, 22 Auto-resize all columns 44, 20 &View 213, 22 &Default filters 213, 22 Only &basic applications 213, 22 Only system components 213, 22 &Everything 210, 6 213, 22 Only started automatically 213, 22 Only web browsers 210, 6 213, 22 View Tweaks 213, 22 View Unregistered 213, 22 View Updates 213, 22 View Windows Features 213, 22 View Windows Store Apps 210, 6 iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO vAAADrwBlbxySQAAAplJREFUaEPd2D1rFFEYBeBZdpeFtTCFrIik8h9YCKayEItgIQF7S/0B/gIJKQJa BIuYQiwsLSxsrFYsBAshBLsthAQMIiFFCisn58jd8Ho549472Y95vfAQ9uR+vTs7M7tTDIfD/4IMPZKh RzL0SIYeydAjGXokQ49k6JEMp2kwGLSLorgJm/AZ9uFX+MvXL1ut1t1+v99T41PJcBpCAfdhBGWCQxT0 EDpqvklkeF5lWV7Bxj5GG0211263r6l5/0WG54EirmMz36PN5TrCPDfU/FVkWBfeyavYxEG0KTqBHViF ZZ4P/AsrsAE/IR7zA5bVOooM6+BnGwvz5I039KbT6VxWY8Ywdgn9XkTjaDf1nJFhHVjwgdjIpupbBW3d jP2D86q+MRnmCkcjvjq9Vn0nQXtl5qBRyqVZhrlQyO1o8ZNJH6cqHMfxdj7Or/paMsyF9twuzNeqXyq0 LTNX0nwyzIX2xSzKd/CW6peK4+188En1s2SYC42XyrOFu93uRdUvFRovzbaQkepnyTBXtGip+uTgGxHN eaz6WTLMFS06iyOyr/pZMsyF9tUs6vocmfVVa1v1s2SYC23NLEo+7yPhS+BfVy6Y1p3929zu7IT22Cw+ 5uu7Vjgib+NNBD6+/U4oYoyf+W1YZVHcXDgX+HvkCSz290hiEXUcodisS7gMU8ywiPn9Zk8s4gM8AvWx Ueb7FCW1iF6vd8H0vwPPYBd4vvyGQ+C3Zj7XujfuX5cMq+QWMU8yVJpcBMkw1vQiSIYxtKdmw8pCiyAZ WuFo8KGzKoAWXgTJ0Ap3YFUANaIIkmEM7b3ZfOOKIBnGwtP1d8DrP4vYaVIRJMMq/C2Om9cl9b9Fk6FH MvRIhh7J0CMZeiRDj2Toz7A4BUDIb3C2NXkmAAAAAElFTkSuQmCC 213, 22 Search... 82, 20 &Quick filters iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO vAAADrwBlbxySQAAAbZJREFUaEPd1z1OAzEQhuGNlK0puQBn4BCchVvQQU3NKei35jyUSItXykjW6PXP jO2AUzzNxwJ+E2VXWbZtuwk4zgjHGeE4IxxnhOOMcOxl3/fHZVk+g6/gia7pBcdWUcCuDAvC0SsToHUP wtHKEKB1C8KxVkOA1hyEY0nHAM0dhGPKwADNHISjdsUArToIR/GHAVoxCMfD6XR6Vn/sP3insx5wFDfx jsSm/4xo09+1tIFB5gCBY62OQe4AgWPOuq53emsIwgD6HyU4kuiwP8FHuD0/ZK6hQ8cw4Hw+34f9LfhO XZOCYyxzOE9QTUDV72g4Hgyvbk2QJ0DLBuF4MISIZJBmDBC+ENEzaESAwJG0BI0MEDjmOIOGBQgcaziC SlwBAkeLDkFNAQLHlMuhX43PjhQMuHyeXuhnOThqcMiaZ0d86FguQN8Qqt8tHEXFoSxBlgCtGITjIRzO 8lW3FOQN0K72VTcZJEY9U3DUegSNChA4pniDgmEBAscSR1Atc4DAsVbHIHeAwNGqIag5QODoZQjqFiBw bJUJ6h4gcOwlChoWIHCcEY4zwnFGOM4IxxnhOJ9t+QUUCa3NNFC+OwAAAABJRU5ErkJggg== 180, 22 &Uninstall iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO vAAADrwBlbxySQAAAtdJREFUaEPdlz+L1EAYxrP/WFgLC2Et5FBQELE5LASLBWs/ix/BztLaWmztDrGw 29rCD3CFlaWoxZWH6/MeecO77z6ZmUyS1bnAjyRPZmfmt5NMJtV2u70W0LBEaFgiNCwRGpYIDUuEhkOx 2+2eVlX1CXwBL1iZoaBhX4zAzjGaEA1zCQh4BheiYVc6CHgGE6JhKj0EPL2FaBhjQAFPthAN2xhRwNNZ iIaeIwp4koVoqPxDAU9UiIbCZDJ56Sr7H3jL+irQULkWI2Ip/hnxFD9reUYU6iyg0DCVAYWyBRQahlgs Fjd91kOICrA2YtCQYTp7Cd5hen4QKMM6baEC8/n8NvI34KKtTBs0tAQ6lyOUIpD0Gw8NBdOZb4A1oKQI 5Qh4gkI0FOpOvJ/NZnfQyec4jjX2G5ywujwdBZQ8EQ+2Z+AHYI1ciKwtv1qtlvZcGENAoaFFGtdOYZSe oNKfphGhkZByUl6OMZJ3kb/C9ZMxBRQaKnJbobJzcKYy2B6Bj0Aa25PA+Rk4l99JNp1OH8q5lAO+o210 ElBoKBgJbaCREernZiPHRkLLNjKknjayBBQaBhrfkxGIhJIq00tAoSH+7Xuo/LtpzNLIBCSERgTPyC2c f3XXqUD9PL1m10LQUKjv71aZ5XJ5Q/YuV0ISIQE/ISSPFg2ViMwvkgmNRD1iKtFFwBMVoqElIuNpJJT6 xZor4Mn71FUSZQ4kGJkC/UdEgcxjVPbHVG65hMR9LYvtA9hbf40loNDQE5mdlGY2MyuAqwUlGE1AoaEl UUJhMqxcG50FFBoqHSWUHJlsAYWGQkRC3tKbes+up8r0FlBoGJPQ2Un2cu6uKyGZwQQUGmK2OUVD7OE8 mGIDMrIyPpUy9R/zGQwuoNBQqFe3Vqb1PUFkmuX9er2e4Vi+S0YRUGioGJnoy87IHHwtHgMaWrBtYhJK LXP1jXJsaFgiNCwRGpYIDctjW/0F5PnkmYCIcpwAAAAASUVORK5CYII= 180, 22 Uninstall &quietly 180, 22 Modify 177, 6 183, 22 Advanced... 180, 6 183, 22 &Full information 183, 22 Program name 183, 22 Product code / GUID 183, 22 Full registry path 183, 22 Uninstall string iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO vAAADrwBlbxySQAAAc5JREFUaEPdlEGOwzAMA3sL0P3/Q/YH2Ze19UFANBaoxrEMZAvMQVQpmpc89n3/ F4TiHQlF4/N7TeRv27afKGcGoWjgITMoKxOKBh4xi5IyoWjgATOZXiYUDYS/ov9kPJ/P7eP95a0PU8uE ooFgV4S7i1wuFYoGwiqLNC6VCUUDQdVFGsNlQtFAyIoijaEyoWggQBY57jLoDThdJhQNHK8scvmrFooG DpcVmfGJDkUDR8uKNO1qmVA0cLC0SONKmVA0cKy8SGO0TCgaOLSkSGOkTCccwZFlRRpny7iB4MDSIg1V hv91A4G5rMgI3U0KR5RZ7TLoHaG7SeGIMqtdBr0jdDcpHFFmtcugd4TuJoUjyqx2FWR5biDKrHYVZHlu IMqsdhVkeW4gyqx2FWR5biDKrHYVZHluIMqsdhVkeW4gyqx2FWR5biDKrHYVZHluIMqsdhVkeW4gyqx2 FWR5biDKrHYVZHluIMqsdhVkeW4gyqx2FWR5biA0KyL/TLI8NxCaFZF/JlmeGwjNisg/kyzPDYRmReSf SZbnhjNkh2eT5bnhDDy8mu49FL6Fh1fTvYfCt/Dwarr3UPgWHl5N9x4KdyUU70go3pFQvB/74w3YjMUD zoYarAAAAABJRU5ErkJggg== 180, 22 &Copy to Clipboard... 176, 22 &Install location 176, 22 &Uninstaller location 176, 22 &Source location iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO vAAADrwBlbxySQAAAitJREFUaEPd1TGS2lAQhGEBF3DuAzj3CbZ8PN/HOefY2PFGGzlh1RRDDf1+8SQ9 EPVM1Re41cxoam3vcDwe/wsY9gjDHmHYIwx7hGGPMNzC4XD4PgzD++i0FM0rgi20HCE0swierfUIoblF 8EyPOEJodhE8y6OOEJpfBK8091j6bhG8ypKfGH2/CF5h6V87mlEEmQ94kL/7/f5H7Fjzbye/YyiCzAc8 wNIjfkP28kMWHzH1DjEjK4LMBzRYdcTUO8SzrAgyH7DS6iOm3iE/v/YoDD5AqDfX0iPEnss/75x7FAYb cEa9OdYcIdb53O12b9ijMNiQM+rVrD1CUudj9Is6gmFIQ66od8/SI9TPf750Pk6n08+cOwzDZcgN6k1Z c8SYveds/Nz8ZzEFwzB+iuXUI2uP0LOczzlCMAyXhTeo51qOkPxsLgxDDM6o58bPn/wdc/cIyc/nwjDk 4YF67s5P5OYIGT9FzztzYBh8gVCPwDHFEZKeX1GvBsPgC4R6U9IxeITE3Ix6NRgGXyDUu2f8TfyN8uDz hXo1GAZfINRr4fOFejUYBl8g1Gvh84V6NRgGXyDUa+HzhXo1GAZfINRr4fOFejUYBl8g1Gvh84V6NRgG XyDUa+HzhXo1GAZfINRr4fOFejUYBl8g1Gvh84V6NRgGX7AVepcaDIMv2Aq9Sw2GwRdshd6lBsPgC7ZC 71KDYfAFW6F3qcGwRxj2CMMeYdgjDHuEYX+OwxdPcURPbbSJlwAAAABJRU5ErkJggg== 180, 22 Open in &explorer... 180, 22 Open &Web Page 160, 22 Google 160, 22 AlternativeTo 160, 22 Slant.co 157, 6 160, 22 FossHub.com 160, 22 SourceForge.net 160, 22 GitHub.com 160, 22 FileHippo.com iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO vAAADrwBlbxySQAAAu9JREFUaEPdmD+IE0EUxjckIRgRrSIiB7YW11hYi4VFesFCRARbu+vtLA60ukIt xMJGsDg7K3OIzRWCiLYWFhGR44orhBDX75MZmUy+zb7d29MdH/zI5ds37813s7N/kk0mk/8CKaaIFFNE iikixRSRYopIMUWkmCJSTBEpHpZOp9PLsuwy2AK74Av4Ab6Cj+Apcq4xT42vgxTrMhqNupjkDcCJ5waY d4fjVL0qSLEOeZ6fwaTeBJOswttut3tW1bUixarAxAVMZhpNripT1Lmo6luQYhVwnp/jJKJJkQPwGIzB 2nA4HPR6vdOcLL7fA/sgHvMNrKk+ZUjRymAwOI7Gn4KJeF5w0mqMh8eR9yQaR3brXASkaAWxEUzAs6ly i0BwdeIat/1x/rPC/CKkaMGtBk+FcALPVG4ZHBfUIFO/KogdixkpWkBcBWHzg7LTqQh3mnFPhfXGPOb+ LjUjRQsI3uzCxlsqjyA26t4rXO1SM1K0gHgXNMlxKlxSecTlfEDO9aqr5sZ6Cs0sCVYQC/uj3++fVHkk zGsAaWbhSxWi4rnK8cS5DbBkZqFhFaLCf3NFPAtmlppaQSw8GBr2yFHw55611NQK4nlQkKy6aoV5TdHM imAFbkaFC+8jiE3w0+U1QXN7hIVQ0HxnR6zzOIjHVKXZqxZBHPpZq4yotjTxO0+JFtyKvIoaeUqffq0E NQtNECmW4UzsBE0UfHZ6CMY0xfcR7Cu+u/h3+e8gHrMHzoe9nL7SBJHiKowm6rCn3hARpSaIFIs4QhP8 ZWW9qKfSY6SoMJp4CXgBsF6Z9nG63Z3NZsdUzypIMcZoYpv7gPn8xPcr4AF4D/y7Bj8/g21waz6fn4h7 1UWKIVVN/Cuk6EnFBJEiSckEkSJBPAomrGiNCSJFt1n5o7MyQFplgkjR/aqhDJDWmSBSJAi1P1ppgkiR uOei184A3yXut9UEkWIIDJ1a9T7eFqSYIlJMESmmiBRTRIopIsUUkWJ6TLJfuKvOc7bir0gAAAAASUVO RK5CYII= 180, 22 &Search online 180, 22 Rate... 177, 6 180, 22 Show &properties False 105, 20 &Basic operations 198, 22 Uninstall &manually 196, 22 &Install or configure (/I) 196, 22 &Uninstall (/X) 196, 22 &Quiet uninstall (/X /qb) 198, 22 &Uninstall using MsiExec 195, 6 198, 22 &Rename... 198, 22 Disable autostart iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO vAAADrwBlbxySQAAAR5JREFUaEPdjrGJRUEMxF7/VW1n98GhrUCR8VygRKBhvvfevwBlIigTQZkIykRQ JoIyEZSJoEwEZSIsv+/vMvgZJcSXwM8oIb4EfkYJ8SXwM0qIL4GfUUJ8CfyMEuJL4GeUEF8CP6MU4Sbm zxAlRbiJ+TNESRFuYv4MUVKEm5g/Q5QU4SbmzxAlRbiJ+TNESRFuYv4MUVKEnd5YaKtjmiFKirDTGwtt dUwzREkRdnpjoa2OaYYoKcJObyy01THNECVFuIn5M0RJEW5i/gxRUoSbmD9DlBThJubPECVFuIn5M0RJ EW5i/gxRUoSbmD9DlGzhNfAzSogvgZ9RQnwJ/IwS4kvgZ5KJoEwEZSIoE0GZCMpEUCaCMhGUiaDM430/ Y9GlZ2dLox0AAAAASUVORK5CYII= 198, 22 &Delete registry key 195, 6 198, 22 Create &backup... 198, 22 &Open key in Regedit 195, 6 198, 22 Take ownership False 131, 20 &Advanced operations iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO vAAADrwBlbxySQAABJ5JREFUaEPdmU1oHVUYhvNzQyAiCtZIF4JgpQupSFFBoSKigYqLIi0olCLSgroS oaAuRJBQquAiIkIL3bgQugsi4sYGRAoFhS5EF0ULCoEg7aJFSzC9Pm+Yc/ny8c7cOzfZjB883Lnv+X7O uXPmzJm5EysrK/8LrNhFrNhFrNhFrNhFrNhFrNhFrNjE1NTUwxMTEy/BEXh8bm5u1vm1hbx7lXNycvI4 PNM2rxUdVcevQj/xB4UPuZhRUKfJ8UvKKa7T9vr8/Py0i8tYMYN9Ggo4/un3+/tdbBN0dA+xN1KuzBcu NmPFCMWOmuSFW/AZ3J/j9EuqowzwCYHPvpmZmbuyX6/Xu4+2j+EmuBp98hzPcRkrRrDVmDRwGR6KvhR8 FG0RLoEG6eJ+hzP4PhenDYPdjf598IusxjoOKxaqC9sl/jxejJgu/h+rtjZcgTfKgPTJ91OhfYD6Uuo5 rFjQKTVJT5b26enpB/n+XWofh59gX8mLnaz0AfTlaGl3WLGAvRmTwWAQJNZq81dqj/wNv4GmmdBx7XUA N8k5WP2wPJgjpc1hxULV2ZLobNJdp27DMu2HNzY27oy5qrge7c/COXDX0HoajBaSzTbVjLkyVixUhTWP r3J8tzTsKXCD+AoG02MY5NPS+2WIL6zD8/LRj8GxzuQV9SXniFgxgj0NCzom2S6O/4RY+Db6O+7GNTs7 ewfL6z1ZjxCr61CdjznXtCxX7Tr7m/WbsGId2JmqUEFT6RXnSwd0/ykdvNy05cD3UJUr5j7nfOuwooNi mgr/pmKLzldgF4Kf5vge51fA3ov+YlhMxIoO7GwsAo3zFtsykGH3AeXCT9djrDFYYIZhxYymBUmvxSIU ftX5FrBWAxHKGWPg2qi7YCtmKBCXYbHadDYE1nogAtuyJVJt55exYoZkH8TksOT8Iti4A1mKcart/DJW zGDLMTkMXw7HH4iee2KtndnGC0x7oVadwrYMBHTz0506c7rcM6q4BYhxF2LeOqyYwX4Oidlx9+91fhEs D6SJwVTFngy6uBjz1mHFDLZlIMzboes7pl87dqiJ8yVOF3dq29Ez8m1IPNJKwlnbj2/eztTxfonD8jWy HPPWYcUM9klILD50fhkG3IPH4DAx6qBjIe7T8M0r5KmYsw4rZjAVjMl/dX47gXKHOqLxOaRgxYxeGpAw Pz+84Hy3A3Yw5Be3hu2eC1Z0YOdDAXHJ+W0H5Qz5xWARGIYVHdUrnVhEnHC+44C9FvJuoprO12HFOrCv YyFYb1OsDnI8Qi4948fc3zjfOqxYByvKAxS4ngpqV3zQ+Y8CphtgXqZvsHvY6/zrsGITmFaw/DSn76cZ 6OZz/SjoMZiYdyE/5opjLqYJKw4D03zOgxE6W4tNezGm0W4G/BZ+ayEuMnjl1AYrjgJWN5iCXqlqo/hR hY4vQlPMWIMQVhwV7AC4vxrassZZetHVGBUrtkFzvdpW5EVgFPR+bIn4XS53G6w4DtXFewz0ELbl+T6h i/sHeDs+h2wXK24XfuGelk8+9b7qhOD4ZT4PuFepO4EVu4gVu4gVu4gVu4gVu4gVu4gVu8fKxH8/CDAt CHsE6AAAAABJRU5ErkJggg== 280, 22 Open Startup Manager 277, 6 iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO vAAADrwBlbxySQAAAsRJREFUaEPt2D+IE0EYBfBNsiEYES0EueKw8MBCtFLBTiwsRMTGwlawMKVwYC1Y WYiClaCFncU1cgg2RsTC6w4RwUILC8FGwSvEXIzvLbsyDm+Tmf2XjNzAj0vezs7Od7Ob3SQaDof/BRmG SIYhkmGIZNikyWRyMoqidf5V213JsEksAiap9VarFat+s8iwKelqZEXQI9XPhQybgmauxjZWY0X1cyHD JlS5GiTDJqA9M4ootRokw7qhnTOKKL0aJMO6oW0YRZReDZJhndAqXw2SYZ3QKl8NkmFd0GpZDZJhVdrt 9hFM9jY8Ba7EF6h8NUiGZfX7/R4m+hh+GxO3bbKf2r8IGZaFxiLU5G2Fn61sMiwD7awxURerahxfMiyr 0+kcwgRvgnlN5PmkxvAlwyJwipzGpD7DXTxHHUuzGO8vwBpsgypk0u1299rj+ZKhr7SILWuCm3Ad2/az D4pbwusbyN4bfTLL9pi+ZOgjpwjTL1hDv/OQXNjpPg+B+23ZYxYhQ1cORdi+Au8rR7k/Tym8PmOPW4QM XRQowsZTb4BxklOvLBnOUkERphfqGL5kOA3aCaiqCJpPIbhHHMTBwy+E0C4ZEylrfoUQ2hWY9lDoar6F UPpLyEdrYr7mXwiNRqNdmMwt+GlMzke9hcRxfMBF1h9tGe7BN1ATzpMUwn+IGl8Zj8d7suP+Pb4dZKyD TfMKkjs19Xq93XjP6+c58PFE7WNKCkEbGNks97PjZf55Y7J2nIUX/RNeM+YYuHHug4vYdgdeww+w912o QkxvYRXf1w+rcVHYCrbzR4ircBlOMUfLK+QB8OOe+DWBWSOFmD4AJ3INBRznaaeORWh5hQyMPu/SrPFC FD4B84HxDbwEXmMs+Duo/gtbiK+dQhLpDouAn3Q8HSn73h9kIcpOIYvGvZDQyDBEMgyRDEMkwxDJMDzD 6A+ao+bo+vxNcgAAAABJRU5ErkJggg== 280, 22 &Clean up "Program Files" folders... Magenta 280, 22 Uninstall by window, directory, or file... 280, 22 Uninstall from directory... 277, 6 280, 22 Troubleshoot uninstallation problems... 280, 22 Start Disk Cleanup 280, 22 Install .NET v3.5 (add feature) 280, 22 Create a new restore point 277, 6 280, 22 Open "&Programs and Features" 280, 22 Open "System Recovery" 277, 6 iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO vAAADrwBlbxySQAAA8NJREFUaEPdmU9IVFEYxdWZYciIhMqIiISCFm0iol3QSshFhCAUtIhoFREhCQkR kQsXrVpIRAtpEYFgECEtHYgWBhUR0kZw0UKQkCAXgY7TOfKu3K7nzXz3zRi8+eDHG87ce+5337z7701H pVJpC6SYR6SYR6SYR6SYR6SYlVKptFfpIbVa7XRnZ+cp9V1WpBgL4hx4DX4Xi8V9qowPYhbUwBy43t3d XVblYpCiBdzRIpK4Aj4lSTlGVHlHV1fXyaA8WQGPy+XyblXHghQtIJ4kSYQs17vDiAmvrM+iKm9FihZS 7uwm+LWuqTq84/ied1/VG1V1rEjRCmLGS8RnAZ05ww7h8wjB56u4jiXfh6xjAjik2rAiRSuIfi+ZZphS /jFIMQbEvJdQVgaUdwxStJI88x+CpLIw1cyMRaTooDmnWfUdn2kk8DlIqBnm0Vafaos0Wmuk6ECMgyUw 5jdSrVb3QPsCVEJ/wDQHN2a2E7j2rK2t7SoUCkehXwBPwS+g6n71fxkurqh/F/p3MO50hRQJDLjgsROu kQ3wDgyCl4kW8hYJH1N+PkjwIMpOBnUdb9D2eVzZBm+K05eYk/IjUiSIIc+kERto5F5vb29BeaWBOjdQ dz3wqseQ8iFSJAi3H7IwrDwsoDO3hF8as8qDSLHeqi14pTxioIfnVxfmJj2UmHSEqzbHhTRMWMWYOKw8 YkjGzGrgrZjDbHlWeWwTfPCz96EyZ66fnpnPpKqXBXp5vj7s4HPkUvf8IsUQzuEwehg0QFIHXyz08nwd 42i3R5UPkaIChtz0hQ0dUWWzkDIuL6qyCikqEKNeA5u04mTnwLN/IPQHN1VZhRQViG0dUeWywvN+6A/M 07oUFXi0uHj90xDvoiqbBfgfD/2BeQxKMeQ/DXZufUL/1gx2mOR7+m2bBbFttigEkf9NI0G0xzaeMxUq LnsmloPV9A4erOq/+FOiAyGPuslLh4/AT8CxddRlp3gsZgKcFKA3Oup+Q72t6bYlR11iePnQijcoDnZi Z14+NCJ5/F4ECWVhDp3Yr9qwIsUYEK142zivvGOQYgyIKS+hZuhX/lakaCUZJ2nT5yM8LpdxHQYP8PkO rgNgAajyM6oNK1K0gti2tU9YSXsFig7xDb2qk7pqW5CiFcSin4jHhCpPxPrk80zVsSBFC0wId/c+Gv8R JNPwziL4n4lfh4/bba45qrwFKcaAzhTBJSTidsup+yEHFzqU4273PRiM3doopJgVdKjP+pxzolB6VqSY R6SYR6SYR6SYR6SYPyodfwH48uDGAyghMQAAAABJRU5ErkJggg== 280, 22 &Settings 46, 20 &Tools 194, 22 Open &help 194, 22 Start setup wizard 191, 6 194, 22 Check for updates iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO vAAADrwBlbxySQAAAcBJREFUaEPd1T9KA1EcxPH8g0AsLUQ8gIWNrRfwDJa2NnaWXsR7iG1sbS08go2l lYj6G2Gb4avGxAfzXPiAzO4O84qso+Vy+S9g2CMMe4RhjzDsEYY9wrBHGPYIwx5hKHW9J6KtgqF4QQra KhiKF6SgrYKheEEK2ioYihekoK2CoXhBCtoqGIoXpKCtgqF4QQraKhiKF6SgrYKheEEK2ioYihekoK2C oXhBCtoqGIoXpKCtgqF4QQraKhiKF6SgrYKheEEK2ioYihekoK2CoXhBCtoqGIoXpKCtgqF4QQraKhiK F6SgrYKheEEK2ioYihekoK2CoXhBCtoqGIoXpKCtgqF4QQraKhiKF6SgrYKheEEK2ioYihekoK2C4Vfq OitvQymZTCYH9G5rGH6nruPyPAwHl/Reaxj+ZDweH9bgRzvA4I7eaQ3DVUyn070afW+H+FTXLr3TEoar ms/nWzX8xg9Szun5ljD8jcViMa/hV3aQW3q2JQzXUddFGb5or7PZbIeeawXDddVH4KQO8aLD1N+n9Ewr GG6irqPyVK7pfisYbqr+Ke7XQR70MaD7LWD4F+o3sq0D0b0WMOzPcvQBNno1XPGrmk4AAAAASUVORK5C YII= 194, 22 Submit feedback... 191, 6 194, 22 Reset settings 194, 22 Uninstall BCUninstaller 191, 6 iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO vAAADrwBlbxySQAAAWdJREFUaEPt2D1KA1EUhuFMCAxi6RYEC2sLOyvBxs5NuBV3YGdrI+ICHAsbWxEb S6s0Nlam0O+CgWF4I8n9rugJ98DTvGSGeyBMfkZd160FjBFhjAhjRBgjwhgRxlI0e3Ij7zKVi8lkskWv dWEsQXMkH/I58Ni27SZd48BYguapd/ihU7rGgdHVNM02HL7vkq5zYHQtscg1XefAWILmoXfwoRhvrUSz L+lpNVzifjabbdA1DoyljMfjHR38XF7lWc5+44mVYIwIY0QYI8KYQ3Ms6WvIMq7oHg6MOTQnMnxCLXJL 93BgzKGpi5SAMYfmUNIXxeRFaIG5/7tInz4Id+HwfXWRRTC66iIGjK66iAGjqy5iwOiqixgwuuoiBoyu uogBo6suYsDoCr1I0zQHOuDdt5/+903eZP7aIn9oY8yhWeU3e9+U7rcqjDk0dRG636ow5tCsxyJ/DWNE GCPCGBHGiDDG042+AGxBHCp0R/J2AAAAAElFTkSuQmCC 194, 22 &About 44, 20 &Help 130, 20 Open &debug window 2, 0 0, 2, 0, 2 1029, 24 0 menuStrip System.Windows.Forms.MenuStrip, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 3 802, 17 Registry files|*.reg Create registry backup 1017, 17 True 7, 15 1031, 624 4, 3, 4, 3 522, 338 2, 0, 0, 0 Bulk Crap Uninstaller olvColumnDisplayName BrightIdeasSoftware.OLVColumn, ObjectListView, Culture=neutral, PublicKeyToken=null olvColumnPublisher BrightIdeasSoftware.OLVColumn, ObjectListView, Culture=neutral, PublicKeyToken=null olvColumnRating BrightIdeasSoftware.OLVColumn, ObjectListView, Culture=neutral, PublicKeyToken=null olvColumnDisplayVersion BrightIdeasSoftware.OLVColumn, ObjectListView, Culture=neutral, PublicKeyToken=null olvColumnInstallDate BrightIdeasSoftware.OLVColumn, ObjectListView, Culture=neutral, PublicKeyToken=null olvColumnSize BrightIdeasSoftware.OLVColumn, ObjectListView, Culture=neutral, PublicKeyToken=null olvColumnStartup BrightIdeasSoftware.OLVColumn, ObjectListView, Culture=neutral, PublicKeyToken=null olvColumnIs64 BrightIdeasSoftware.OLVColumn, ObjectListView, Culture=neutral, PublicKeyToken=null olvColumnUninstallString BrightIdeasSoftware.OLVColumn, ObjectListView, Culture=neutral, PublicKeyToken=null olvColumnAbout BrightIdeasSoftware.OLVColumn, ObjectListView, Culture=neutral, PublicKeyToken=null olvColumnInstallSource BrightIdeasSoftware.OLVColumn, ObjectListView, Culture=neutral, PublicKeyToken=null olvColumnInstallLocation BrightIdeasSoftware.OLVColumn, ObjectListView, Culture=neutral, PublicKeyToken=null olvColumnUninstallerKind BrightIdeasSoftware.OLVColumn, ObjectListView, Culture=neutral, PublicKeyToken=null olvColumnSystemComponent BrightIdeasSoftware.OLVColumn, ObjectListView, Culture=neutral, PublicKeyToken=null olvColumnProtected BrightIdeasSoftware.OLVColumn, ObjectListView, Culture=neutral, PublicKeyToken=null olvColumnRegistryKeyName BrightIdeasSoftware.OLVColumn, ObjectListView, Culture=neutral, PublicKeyToken=null olvColumnGuid BrightIdeasSoftware.OLVColumn, ObjectListView, Culture=neutral, PublicKeyToken=null olvColumnQuietUninstallString BrightIdeasSoftware.OLVColumn, ObjectListView, Culture=neutral, PublicKeyToken=null toolStripButton1 System.Windows.Forms.ToolStripButton, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripSeparator22 System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripButtonSelAll System.Windows.Forms.ToolStripButton, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripButtonSelNone System.Windows.Forms.ToolStripButton, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripButtonSelInv System.Windows.Forms.ToolStripButton, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripSeparator23 System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripButtonTarget System.Windows.Forms.ToolStripButton, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripSeparator21 System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripButtonUninstall System.Windows.Forms.ToolStripButton, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripButton2 System.Windows.Forms.ToolStripButton, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripButtonModify System.Windows.Forms.ToolStripButton, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripSeparator4 System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripButtonProperties System.Windows.Forms.ToolStripButton, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripSeparator24 System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripButton7 System.Windows.Forms.ToolStripButton, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripButton8 System.Windows.Forms.ToolStripButton, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripLabelStatus System.Windows.Forms.ToolStripStatusLabel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripLabelSize System.Windows.Forms.ToolStripStatusLabel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripLabelTotal System.Windows.Forms.ToolStripStatusLabel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 uninstallContextMenuStripItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 quietUninstallContextMenuStripItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 manualUninstallToolStripMenuItem1 System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 uninstallUsingMsiExecContextMenuStripItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 msiInstallContextMenuStripItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 msiUninstallContextMenuStripItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 msiQuietUninstallContextMenuStripItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripSeparator3 System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 excludeToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 includeToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripSeparatorFiltering System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 runToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripSeparator8 System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 copyToClipboardContextMenuStripItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripMenuItem9 System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripSeparator9 System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 fullInformationCopyContextMenuStripItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 programNameCopyContextMenuStripItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 gUIDProductCodeCopyContextMenuStripItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 fullRegistryPathCopyContextMenuStripItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 uninstallStringCopyContextMenuStripItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 deleteRegistryEntryContextMenuStripItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 renameContextMenuStripItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripSeparator6 System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 openInExplorerContextMenuStripItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 installLocationOpenInExplorerContextMenuStripItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 uninstallerLocationOpenInExplorerContextMenuStripItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 sourceLocationOpenInExplorerContextMenuStripItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 openWebPageContextMenuStripItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 lookUpOnlineToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripMenuItem15 System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripMenuItem16 System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 slantcoToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripSeparator26 System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 fossHubcomToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 sourceForgecomToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 gitHubcomToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 fileHippocomToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 rateToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripSeparator7 System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 propertiesContextMenuStripItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 exportDialog System.Windows.Forms.SaveFileDialog, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 fileToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 reloadUninstallersToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripSeparator1 System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 loadUninstallerListToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripSeparator30 System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 exportSelectedToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 exportToABatchUninstallScriptToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 exportStoreAppsToPowerShellRemoveScriptToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripSeparator10 System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 exitToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 viewToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 showColorLegendToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 displayToolbarToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 showTreemapToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 displaySettingsToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 displayStatusbarToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripSeparator12 System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 useSystemThemeToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripSeparator33 System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 autosizeAllColumnsToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 filteringToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 advancedApplicationsToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 basicApplicationsToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 systemComponentsToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 everythingToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripSeparator20 System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 automaticallyStartedToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 onlyWebBrowsersToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripSeparator31 System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 viewTweaksToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 viewUnregisteredToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 viewUpdatesToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 viewWindowsFeaturesToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 viewWindowsStoreAppsToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripSeparator28 System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 searchToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 basicOperationsToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 uninstallToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 quietUninstallToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 modifyToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripSeparator2 System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripMenuItem8 System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 advancedClipCopyToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripSeparator11 System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 copyFullInformationToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripMenuItem10 System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripMenuItem11 System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripMenuItem12 System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripMenuItem13 System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripMenuItem1 System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripMenuItem5 System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripMenuItem6 System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripMenuItem7 System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripMenuItem14 System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 onlineSearchToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 googleToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 alternativeToToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 slantcoToolStripMenuItem1 System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripSeparator27 System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripMenuItem17 System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripMenuItem18 System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripMenuItem20 System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripMenuItem19 System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 rateToolStripMenuItem1 System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripSeparator15 System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 propertiesToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 advancedOperationsToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 manualUninstallToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 msiUninstalltoolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripMenuItem2 System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripMenuItem3 System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripMenuItem4 System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripSeparator14 System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 renameToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 disableAutostartToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 deleteToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripSeparator5 System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 createBackupToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 openKeyInRegeditToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripSeparator32 System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 takeOwnershipToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolsToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 openStartupManagerToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripSeparator25 System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 cleanUpProgramFilesToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 targetMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 uninstallFromDirectoryToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripSeparator13 System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 troubleshootUninstallProblemsToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 startDiskCleanupToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tryToInstallNETV35ToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 createRestorePointToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripSeparator29 System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 openProgramsAndFeaturesToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 openSystemRestoreToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripSeparator19 System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 settingsToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 helpToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 openHelpToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 startSetupWizardToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripSeparator16 System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 checkForUpdatesToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 submitFeedbackToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripSeparator18 System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 resetSettingsToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 uninstallBCUninstallToolstripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripSeparator17 System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 aboutToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 debugToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 createBackupFileDialog System.Windows.Forms.SaveFileDialog, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 globalHotkeys1 Klocman.Subsystems.GlobalHotkeys, KlocTools, Culture=neutral, PublicKeyToken=null splashScreen1 Klocman.Forms.SplashScreen, KlocTools, Culture=neutral, PublicKeyToken=null usageTracker BulkCrapUninstaller.Functions.Tracking.UsageTracker, BCUninstaller, Culture=neutral, PublicKeyToken=null MainWindow System.Windows.Forms.Form, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 1175, 17 17, 60 ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/MainWindow.ru.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Имя Издатель Рейтинг пользователей Версия Дата установки Размер Автозагрузка x64 Команда удаления Сайт программы Откуда установлен Куда установлен Тип деинсталлятора Компонент системы Защищён Реестр Код продукта Команда тихого удаления Обновить список Выбрать всё Отменить выбор Обратить выбор Удаление Удалить тихо Свойства Параметры Справка BCUninstaller Расширенный фильтр Поиск &Удалить Удалить &тихо &Ручное удаление Установка и &настройка (/I) &Удалить (/X) Удалить &тихо (/X /qb) Испол&ьзовать MsiExec... Больше настроек... &Всю информацию Название программы Код продукта / GUID Полный путь реестра Команду удаления &Копировать в буфер... Удалить запись &реестра &Переименовать... &Место установки Папку &деинстраллятора &Локацию установщика Открыть в &проводнике... &Сайт программы Поиск &онлайн Рейтинг... &Свойства XML файл|*.xml Экспорт свойств выбранных элементов Обновить &список &Открыть список деинсталляции... &Экспорт выбранного... Вы&ход &Файл Показать легенду подсветки Показывать &тулбар Показывать &статусбар Показывать &панель настроек &Использовать тему Windows Просмотр приложений магазина Windows Поиск... &Вид &Удалить Удалить &тихо Больше опций... &Вся информация Название программы Код продукта / GUID Полный путь реестра Команду удаления &Копировать в буфер... &Место установки Папку &деинстраллятора &Локацию установщика Открыть в &проводнике... &Сайт программы Поиск &онлайн Рейтинг... &Свойства &Базовые операции &Ручное удаление Установка и &настройка (/I) &Удалить (/X) Удалить &тихо (/X /qb) &Использовать MsiExec... &Переименовать... Отключить автозагрузку Удалить запись &реестра Создать &бекап... &Открыть ключ в Regedit &Расширенные операции &Очистка папки "Program Files"... Открыть автозагрузку Открыть "&Программы и компоненты" &Настройки &Сервис Открыть &справку Мастер настройки Проверить обновления Обратная связь... Сбросить настройки по умолчанию Самоудаление BCUninstaller &О программе &Справка Открыть окно &отладки Reg файл|*.reg Создать бэкап реестра Bulk Crap Uninstaller Google AlternativeTo.net Google Альтернативный Просмотр обновлений Удалить из каталога... Открыть "Восстановление системы" Запустить... Удаление по окну, каталогу или файлу... Удаление по окну, каталогу или файлу... FossHub.com SourceForge.net GitHub.com FileHippo.com FossHub.com SourceForge.net GitHub.com FileHippo.com Исключая Включая Показывать карту &дерева Просмотр незарегистрированных Просмотр функций Windows Изменённые Изменить Создание новой точки восстановления Экспортировать в скрипт пакетного удаления Создать скрипт-деинсталлятор PowerShell для приложений магазина... &Стандартная фильтрация Только &базовые приложения Только системные приложения &Всё подряд Только автозапускающиеся Только веб-браузеры Показать твики &Быстрая фильтрация Взять ответственность на себя Решить проблемы удаления... Запустить очистку диска Установить .NET v3.5 (доп. фича) Slant.co Slant.co 462, 17 958, 17 139, 17 17, 17 354, 17 560, 17 738, 17 835, 17 True 1074, 17 ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/MainWindow.sl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 BCUninstaller Poišči Ime Založnik Različica Datum namestitve Velikost Zagon 64-bitni Ukaz za odstranjevanje O URL naslovu Vir namestitve Mesto namestitve Vrsta odstranjevalca Sistemska sestavina Zaščiten Registrski ključ Koda izdelka Ukaz tihega odstranjevanja Znova naloži odstranjevalce Odpri sezname odstranjevanja... Izberi vse Odstrani vse Obrni izbor Odstrani Odstrani tiho Lastnosti &Odstrani Odstrani &tiho Odstrani &ročno &Namesti ali nastavi (/I) &Odstrani (/X) &Tiho odstrani (/X /qb) Odstrani z &MsiExec... Pol&ne informacije Ime programa Koda programa / GUID Polna pot registra Odstranjevalni niz &Kopiraj v odložišče &Izbriši registrski vnos P&reimenuj... &Mesto namestitve Mesto o&dstranjevalca Mesto &vira Odpri v Ra&ziskovalcu... Odpri &spletno stran Po&išči na spletu &Lastnosti Izvozi izbrane lastnosti odstranjevalca &Znova naloži odstranjevalce &Odpri seznam odstranjevanja... I&zvozi izbor... &Izhod &Datoteka Prikaži barvno legendo Prikaži o&rodno vrstico Prikaži statusno &vrstico Prikaži &stransko vrstico z nastavitvami &Uporabi sistemsko temo Poišči... O&gled Ods&trani Odstrani ti&ho &Polna informacija Ime programa Koda izdelka/GUID Polna registrska pot Niz za odstranjevanje &Kopiraj v odložišče... &Mesto namestitve Mesto od&stranjevalca Mesto &vira Odpri v &Raziskovalcu... Odpri sple&tno stran Poišči na s&pletu Prikaži &lastnosti Osnov&ne operacije &Ročno odstrani Namest&i ali konfiguriraj (/I) &Odstrani (/X) &Tiho odstrani (/X /qb) Ods&trani z uporabo MsiExec P&reimenuj... Onemogoči samodejni zagon Iz&briši registrski ključ Ustvari &varnostno kopijo... &Odpri ključ z Regeditom &Napredne operacije &Čiščenje map "Programske datoteke"... Odpri upravitelja zagona Odpri "&Programi in funkcije" Na&stavitve O&rodja Odpri po&moč Zažni čarovnika za namestitev Preveri obstoj posodobitev Pošlji povratne informacije... Ponastavi nastavitve Odstrani BCUninstaller &Vizitka Po&moč Odpri o&kno za razhroščanje Registrske datoteke|*.reg Ustvari varnostno kopijo registra Bulk Crap Uninstaller Uporabnikova ocena Pomoč Napredno filtriranje Napredno... Ocena... Prikaz Windows Store aplikacije Napredno... Oceni... Google Neobvezno Google Neobvezno za Odstrani iz imenika... Odpri "Obnovitev sistema" Odstranitev po oknu, imeniku ali datoteki... Zaženi... Prikaz posodobitev Odstranitev z oknom, imenikom ali datoteko... FossHub.com SourceForge.net GitHub.com FileHippo.com FossHub.com SourceForge.net GitHub.com FileHippo.com Spremeni Izključi Vključi Spremeni Prikaz neregistriranih Prikaz Windows funkcij Prikaži drevo &map Začni čiščenje diska Namesti .NET v3.5 (dodaj funkcijo) Izvozi v serijsko skripto za odstranitev... Ustvarite PowerShell skripto za shranjevanje aplikacij... Privzeti &filtri Samo &osnovne aplikacije Samo sistemske komponente &Vse Samo zagnane aplikacije Samo spletne brskalnike Prikaz izboljšav &Hitri filtri Odpravljanje težav pri odstranjevanju... 628, 17 140, 56 305, 17 183, 17 520, 17 726, 17 904, 17 17, 56 True 256, 56 Ustvari novo obnovitveno točko ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/MainWindow.sv.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Namn Utgivare Användarbedömning Version Installationsdatum Storlek Uppstart 64bit Avinstallationskommando Om URL Installationskälla Installationsmål Avinstallation typ Systemkomponent Skyddad Registernyckel Produktkod Tyst avinstallationskommando Ladda om avinstallationsprogram Välj alla Avvälj alla Omvänd val Avinstallera via fönster, mapp eller fil... Avinstallera Avinstallera tyst Ändra Egenskaper Inställningar Hjälp BCUninstaller Avancerad filtrering Sök &Avinstallera Avinstallera &tyst Avinstallera &manuellt &Avinstllera eller konfigurera (/I) &Avinstallera (/X) &Tyst avinstallation (/X /qb) Avinstallera med &MsiExec... Exkludera Inkludera Kör... Avancerad... &Full information Programnamn Produkt kod / GUID Register sökväg Avinstallationssträng &Kopiera till Urklipp... &Radera registerpost &Döp om... &Installationsplats &Avinstallationsplats Källplats Öppna i &utforskaren... Öppna &Webbsida Google AlternativeTo.net Slant.co FossHub.com SourceForge.net GitHub.com FileHippo.com &Sök online Betygsätt... &Egenskaper XML filer|*.xml Exportera valda avinstallationsprogram egenskaper &Ladda om avinstallationsprogram &Öppna avinstalltionslista &Exportera data för valda avinstallationer... Exportera till ett batch avinstallations-script Skapa PowerShell borttagningsscript för Store Appar... &Avsluta &Arkiv Visa färgförklaring Visa &verktygsfält Visa träd&map Visa &inställningar i sidofältet Visa status &fält &Använd system tema &Vy &Standard filter Endast &grundläggande appar Bara systemkomponenter &Allting Bara automatiskt startade Bara webbläsare Visa Justeringar Visa Oregistrerade Visa uppdateringar Visa Windows-funktioner Visa Windows Store Appar Sök... &Snabbfilter &Avinstallera Avinstallera &tyst Modifiera Avancerat... &Fullständig information Programnamn Produkt kod / GUID Fullständig registersökväg Avinstallationssträng &Kopiera till Urklipp... &Installationsplats &Avinstallationsplats &Källplats Öppna med &utforskaren... Öppna &Webbsida Google AlternativeTo Slant.co FossHub.com SourceForge.net GitHub.com FileHippo.com &Sök online Betygsätt... Visa &egenskaper &Grundläggande åtgärder Avinstallera &manuellt &Installera eller konfigurera (/I) &Avinstallera (/X) &Tyst avinstallation (/X /qb) &Avinstallera med MsiExec &Döp om... Inaktivera autostart &Radera registernyckel Skapa &backup... &Öppna nyckel i Regedit Ta ägarskap &Avancerade åtgärder Öppna Uppstartshanteraren &Rensa "Program Files" mappar... Avinstallera via fönster, katalog eller fil... Avinstallera från mapp... Felsök avinstallations problem... Starta Diskrensning Installera .NET v3.5 (lägg till funktion) Skapa ny återställningspunkt Öppna "&Program och funktioner Öppna "Systemåterställning" &Inställningar &Verktyg Öppna &hjälp Starta installationsguiden Sök efter uppdateringar Skicka feedback... Återställ inställningar Avinstallera BCUninstaller &Om &Hjälp Öppna &debug fönster Register filer|*.reg Skapa backup av registret Bulk Crap Uninstaller ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/MainWindow.tr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Adı Yayıncı Kullanıcı oyu Versiyon Kurulum Tarihi Boyut Başlangıç 64 Bit Kaldırma komutu URL Hakkında Kurulum kaynağı Kurulum Yeri Kaldırıcı Türü Sistem Bileşeni Korumalı Kayıt defteri anahtarı Ürün kodu Sessiz kaldırma komutu Kaldırıcıları yeniden yükle Tümünü seç Tüm seçilenleri temizle Seçimi ters çevir Pencere, dizin veya dosyaya göre kaldır ... Kaldır Sessizce kaldır Değiştir Özellikler Ayarlar Yardım BCUninstaller Gelişmiş filtreleme Ara &Kaldır &Sessizce kaldır &Manuel kaldır &Yükle veya yapılandır &Kaldır (/X) &Sessiz kaldırma (/X /qb) &MsiExec kullanarak kaldır... Hariç tut Dahil et Çalıştır... Gelişmiş... &Tam bilgi Program adı Ürün kodu / GUID Tam kayıt defteri yolu Dizgeyi kaldır &Panoya kopyala &Kayıt girdilerini sil &Adını değiştir &Kurulum yeri &Kaldırma yeri &Kaynak yeri &Dosya yöneticisinde aç &Web sayfasını aç Google AlternativeTo.net FossHub.com SourceForge.net GitHub.com FileHippo.com &Çevrimiçi ara Oyla... &Özellikler XML dosyalar|*.xml Seçilen kaldırıcı özelliklerini dışa aktar &Kaldırıcıları yenile &Kaldırılacak listesi aç &Seçilen kaldırıcıların verilerini dışa aktar... Toplu kaldırma komut dosyasına aktar ... Mağaza Uygulamaları için PowerShell kaldır komut dosyası oluştur ... Ç&ıkış &Dosya Renk göstergesini göster Araç &çubuğunu göster &Ağaç yapısını ve haritayı göster Ayarları k&enar çubuğunda göster D&urum çubuğunu göster &Sistem temasını kullan &Görünüm &Varsayılan filtreler Sade&ce basit uygulamalar Sadece sistem bileşenleri &Herşey Sadece otomatik olarak başlat Sadece web tarayıcıları Düzenlemeleri görüntüle Kayıtsız olanları görüntüle Güncellemeleri görüntüle Windows Özelliklerini Görüntüle Windows Mağazası Uygulamalarını Görüntüle Ara... &Hızlı filtreler &Kaldır &Sessizce kaldır Düzenle Gelişmiş... &Tam bilgi Program adı Ürün kodu / GUID Tam kayıt defteri yolu Dizgeyi kaldır &Panoya kopyala &Kurulum yeri &Kaldırma yeri &Kaynak yeri &Dosya yöneticisinde aç &İnternet sayfasını aç Google AlternativeTo FossHub.com SourceForge.net GitHub.com FileHippo.com &Çevrimiçi ara Oyla... &Özellikleri göster &Basit operasyonlar &Manuel Kaldır &Yükle veya yapılandır &Kaldır (/X) &Sessiz kaldırma (/ X / qb) &MsiExec kullanarak kaldır &Adını değiştir Otomatik başlangıcı devre dışı bırak &Kayıt defteri anahtarını silin Yedekleme &oluştur Anahtarı kayı&t defterinde aç &Gelişmiş operasyonlar Başlangıç yöneticisini aç "Program Dosyaları" klasörlerini temiz&le ... Pencere, dizin veya dosyaya göre kaldır ... Dizinden kaldır ... Kaldırma sorunlarını giderme ... Disk Temizleme'yi Başlat .NET v3.5'i yükleyin (özellik ekleyin) "Programlar ve Özellikler" i açın "Sistem Kurtarma" yı açın &Ayarlar A&raçlar Ya&rdım'ı aç Kurulum sihirbazını başlat Güncellemeleri kontrol et Geri bildirim gönder ... Ayarları Sıfırla BCUninstaller öğesini kaldır &Hakkında &Yardım Ha&ta ayıklama penceresini aç Kayıt dosyaları|*.reg Kayıt defteri yedeği oluştur Bulk Crap Uninstaller Yeni bir geri yükleme noktası oluştur Slant.co Slant.co Sahipliği alın ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/MainWindow.vi.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Tên Nhà phát hành Đánh giá của người dùng Phiên bản Ngày cài đặt Kích thước Khởi động cùng hệ thống 64bit Câu lệnh gỡ cài đặt URL giới thiệu Nguồn cài đặt Vị trí cài đặt Loại trình gỡ cài đặt Thành phần hệ thống Được bảo vệ Khoá registry Mã sản phẩm Câu lệnh gỡ cài đặt âm thầm Làm mới danh sách trình gỡ cài đặt Chọn tất cả Bỏ chọn tất cả Đảo ngược lựa chọn Gỡ cài đặt dựa vào cửa sổ, thư mục hoặc tệp... Gỡ cài đặt Gỡ cài đặt âm thầm Sửa đổi Thuộc tính Cài đặt Trợ giúp BCUninstaller Bộ lọc nâng cao Tìm kiếm &Gỡ cài đặt Gỡ cài đặt âm &thầm Gỡ cài đặt thủ &công &Cài đặt hoặc cấu hình (/I) &Gỡ cài đặt (/X) Gỡ cài đặt âm &thầm (/X /qb) Gỡ cài đặt bằng &MsiExec... Ngoại trừ Bao gồm Khởi chạy... Nâng cao... &Thông tin đầy đủ Tên ứng dụng Mã sản phẩm / GUID Đường dẫn đầy đủ đến registry Câu lệnh gỡ cài đặt &Sao chép vào bảng nhớ tạm... &Xoá mục registry Đổi &tên... Vị trí &cài đặt Vị trí &trình gỡ cài đặt Vị trí &nguồn Mở trong &Explorer... Mở Trang &web Google AlternativeTo.net Slant.co FossHub.com SourceForge.net GitHub.com FileHippo.com Tìm &kiếm trực tuyến Đánh giá... &Thuộc tính Tệp XML|*.xml Xuất các thuộc tính của trình gỡ cài đặt đã chọn &Làm mới danh sách trình gỡ cài đặt &Mở danh sách bộ lọc gỡ cài đặt... &Xuất dữ liệu của các trình gỡ cài đặt đã chọn... Xuất sang tập lệnh gỡ cài đặt hàng loạt... Tạo tập lệnh PowerShell để xoá Store App... &Thoát &Tệp Hiển thị chú thích màu Hiển thị &thanh công cụ Hiển thị &bản đồ cây Hiển thị &cài đặt ở cạnh bên Hiển thị th&anh trạng thái &Sử dụng chủ đề hệ thống &Xem &Bộ lọc mặc định Chỉ mình ứng &dụng cơ bản Chỉ mình thành phần hệ thống &Tất cả mọi thứ Chỉ mình úng dụng tự động khởi chạy Chỉ mình trình duyệt Xem các tinh chỉnh Xem các mục chưa đăng ký Xem các ứng dụng cập nhật Xem Windows Features Xem Windows Store App Tìm kiếm... &Bộ lọc Gỡ cài đặt Gỡ cài đặt âm &thầm Sửa đổi &Nâng cao... &Thông tin đầy đủ Tên chương trình Mã sản phẩm / GUID Đường dẫn đầy đủ đến registry Câu lệnh gỡ cài đặt &Sao chép vào bảng nhớ tạm... Vị trí &cài đặt Vị trí &trình gỡ cài đặt Vị trí &nguồn Mở trong &Explorer... Mở trang &web Google AlternativeTo Slant.co FossHub.com SourceForge.net GitHub.com FileHippo.com Tìm &kiếm trực tuyến Đánh giá... Hiển thị &thuộc tính Tính năng &cơ bản Gỡ cài đặt thủ &công &Cài đặt hoặc cấu hình (/I) &Gỡ cài đặt (/X) &Gỡ cài đặt âm thầm (/X /qb) Gỡ cài đặt bằng &MsiExec Đổi &tên... Tắt tính năng tự khởi động &Xóa khóa registry Tạo &bản sao lưu... &Mở khoá trong Regedit Lấy quyền sở hữu Tính năng &nâng cao Mở Trình quản lý Khởi động cùng hệ thống &Dọn dẹp thư mục "Program Files"... Gỡ cài đặt dựa vào cửa sổ, thư mục hoặc tệp... Gỡ cài đặt từ thư mục... Giải quyết vấn đề gỡ cài đặt... Khởi chạy dọn dẹp đĩa Cài đặt .NET v3.5 (và các tính năng đi kèm) Tạo một điểm khôi phục mới Mở "&Programs and Features" Mở "System Recovery" &Cài đặt &Công cụ Mở &trợ giúp Khởi chạy trợ lý thiết lập Kiểm tra các bản cập nhật Gửi phản hồi... Đặt lại cài đặt Gỡ cài đặt BCUninstaller &Giới thiệu Trợ &giúp &Mở cửa sổ gỡ lỗi Tệp registry|*.reg Tạo bản sao thanh ghi Bulk Crap Uninstaller ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/MainWindow.zh-Hans.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 程序名 默认筛选器 高级选项... 高级操作 关于 Bulk Crap Uninstaller 发布者 用户评分 版本 安装日期 大小 开机启动项 64位 卸载命令 关于URL 安装源 安装位置 卸载程序类型 系统组件 受保护 注册表项 产品代码 静默卸载命令 重新加载卸载程序 全选 取消全选 反向选择 通过窗口,目录,或文件卸载... 卸载 静默卸载 修改 属性 设置 帮助 BCUninstaller 高级筛选器 搜索 卸载 静默卸载 手动卸载 安装或配置(/i) 卸载(/X) 静默卸载(/X /qb) 使用&MsiExec卸载... 排除 包括 运行... 高级... 完整信息 程序名称 产品代码/GUID 完整注册表路径 卸载字符串 复制到剪贴板 删除注册表项 重命名 安装位置 卸载程序位置 源位置 在&资源管理器中打开... 打开&网页 Google AlternativeTo.net Slant.co FossHub.com SourceForge.net GitHub.com FileHippo.com 联机搜索 评分... 属性 XML文件|*.xml 导出选中的卸载程序属性 重新加载卸载程序 打开卸载程序列表... 导出选中卸载程序数据... 导出到批量卸载脚本... 为商店应用创建PowerShell删除脚本... 退出 文件 显示颜色图例 显示工具栏 显示树状矩形图 显示设置侧边栏 显示状态栏 使用系统主题 视图 仅基本应用 仅系统组件 所有 仅自动启动 仅网页浏览器 查看调整 查看未注册应用 查看更新 查看Windows功能 查看Windows商店应用 搜索... 快速筛选 卸载 静默卸载 修改 完整信息 程序名 产品代码/GUID 完整注册表路径 卸载字符串 复制到剪贴板 安装位置 卸载位置 源位置 在资源管理器中打开 打开网页 Google AlternativeTo Slant.co FossHub.com SourceForge.net GitHub.com FileHippo.com 联机搜索 评分... 显示属性 基本操作 手动卸载 安装或配置(/I) 卸载(/X) 静默卸载(/X /qb) 使用MsiExec卸载 重命名... 禁用自动启动 删除注册表键 创建备份... 在Regedit中打开键 取得所有权 打开开机启动项管理器 清理"Program Files"文件夹 通过窗口,目录,或文件卸载... 从目录卸载... 卸载问题疑难解答... 启动硬盘清理 安装.Net v3.5(添加功能) 创建新还原点 打开"应用和功能" 打开"系统还原" 设置 工具 打开帮助 启动设置向导 检查更新 提交反馈... 重置设置 卸载BCUninstaller 帮助 打开调试窗口 注册表文件|*.reg 创建注册表备份 ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/MainWindow.zh-Hant.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 程式名 發布人員 使用者評分 版本 安裝日期 大小 開機啟動項 64位元 移除指令 關於網站 安裝來源 安裝位置 移除程式類型 系統元件 受保護 註冊表 產品代碼 最小化安裝命令 重新載入移除程式 全選 取消全選 反向選擇 透過視窗,目錄,或文件移除... 移除 最小化移除 修改 屬性 設定 幫助 BCUninstaller 進階選項 搜尋 解除安裝 最小化解除安裝 手動解除安裝 安裝或設置(/I) 解除安裝(/X) 最小化解除安裝(/X /qb) 使用&MsiExec解除安裝... 排除 包含 執行... 進階... 完整資訊 程式名稱 產品代碼/GUID 完整註冊表路徑 解除安裝字串 複製到剪貼簿 刪除註冊表項目 重新命名 安裝位置 移除程序位置 安裝來源位置 在&檔案總管中打開 打開&網頁 Google AlternativeTo.net Slant.co FossHub.com SourceForge.net GitHub.com FileHippo.com 在網路上尋找 評分 屬性 XML文件|*.xml 匯出選中的移除程式屬性 重新載入移除程式 開啟解除安裝程式清單 匯出移除程式資料 匯出到批量解除安裝腳本 為商店應用程式創建PowerShell移除腳本 退出 檔案 顯示顏色圖例 顯示工作列 顯示樹狀圖 顯示設定側邊攔 顯示狀態列 使用系統主題 顯示 默認選項 僅基本應用 僅系統元件 所有 僅自動啟動 僅網頁瀏覽器 查看調整工具 查看未註冊應用 查看更新 查看Windows功能 查看Windows商店應用 搜尋... 快速選項 解除安裝 最小化解除安裝 修改 進階選項... 完整資訊 程序名稱 產品代碼/GUID 完整註冊表路徑 解除安裝字串 複製到剪貼簿 安裝位置 解除安裝位置 來源位置 在檔案總管中打開 開啟網頁 Google AlternativeTo Slant.co FossHub.com SourceForge.net GitHub.com FileHippo.com 在網路上尋找 評分... 顯示屬性 基本操作 手動解除安裝 安裝或設置(/I) 解除安裝(/X) 最小化解除安裝(/X /qb) 使用MsiExec解除安裝 重新命名... 禁止自動啟動 刪除註冊表鍵 建立備份 在登錄編輯器中打開鍵 取得所有權限 進階操作 開啟開機啟動項管理 清理"Program Files"文件夾 通過視窗,目錄,或文件解除安裝 從目錄解除安裝 移除問題解答 啟動硬碟清理 安裝.Net v3.5(添加功能) 建立新還原點 打開"應用和功能" 打開"系統還原" 設定 工具 開啟幫助 啟動設置精靈 檢查更新 提交回饋 重置設定 解除安裝BCUninstaller 關於 幫助 開啟測試視窗 註冊表文件|*.reg 新增註冊表備份 Bulk Crap Uninstaller 重設所有欄位 ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/SettingsWindow.Designer.cs ================================================ using System.ComponentModel; using System.Windows.Forms; using BulkCrapUninstaller.Functions.Tracking; namespace BulkCrapUninstaller.Forms { partial class SettingsWindow { /// /// Required designer variable. /// private IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { ComponentResourceManager resources = new ComponentResourceManager(typeof(SettingsWindow)); splitContainer1 = new SplitContainer(); textBoxPreUninstall = new TextBox(); label5 = new Label(); textBoxPostUninstall = new TextBox(); label6 = new Label(); groupBoxMisc = new GroupBox(); flowLayoutPanel3 = new FlowLayoutPanel(); checkBoxColorblind = new CheckBox(); checkBoxDpiaware = new CheckBox(); panel5 = new Panel(); comboBoxDoubleClick = new ComboBox(); label3 = new Label(); checkBoxAutoLoad = new CheckBox(); checkBoxRatings = new CheckBox(); checkBoxUpdateSearch = new CheckBox(); checkBoxSendStats = new CheckBox(); panel3 = new Panel(); comboBoxLanguage = new ComboBox(); label9 = new Label(); label10 = new Label(); groupBoxMessages = new GroupBox(); groupBoxBackup = new GroupBox(); directorySelectBoxBackup = new Klocman.Controls.DirectorySelectBox(); flowLayoutPanel9 = new FlowLayoutPanel(); radioButtonBackupAsk = new RadioButton(); radioButtonBackupNever = new RadioButton(); radioButtonBackupAuto = new RadioButton(); flowLayoutPanel1 = new FlowLayoutPanel(); checkBoxShowAllBadJunk = new CheckBox(); checkBoxLoud = new CheckBox(); checkBoxNeverFeedback = new CheckBox(); panel1 = new Panel(); comboBoxJunk = new ComboBox(); label1 = new Label(); panel2 = new Panel(); comboBoxRestore = new ComboBox(); label2 = new Label(); groupBoxExternal = new GroupBox(); checkBoxEnableExternal = new CheckBox(); flowLayoutPanel2 = new FlowLayoutPanel(); label7 = new Label(); button2 = new Button(); tabControl = new TabControl(); tabPageGeneral = new TabPage(); propertiesSidebar1 = new BulkCrapUninstaller.Controls.PropertiesSidebar(); tabPageInterface = new TabPage(); groupBoxLanguage = new GroupBox(); tabPageUninstallation = new TabPage(); uninstallationSettings1 = new BulkCrapUninstaller.Controls.UninstallationSettings(); tabPageDetection = new TabPage(); groupBoxAppStores = new GroupBox(); labelWinUpdateInfo = new Label(); checkBoxScanWinUpdates = new CheckBox(); labelWinFeatureInfo = new Label(); checkBoxScanWinFeatures = new CheckBox(); checkBoxScanStoreApps = new CheckBox(); checkBoxScanSteam = new CheckBox(); checkBoxScoop = new CheckBox(); checkBoxOculus = new CheckBox(); checkBoxChoco = new CheckBox(); groupBox1 = new GroupBox(); flowLayoutPanel7 = new FlowLayoutPanel(); checkBoxScanRegistry = new CheckBox(); checkBoxScanDrives = new CheckBox(); checkBoxPreDefined = new CheckBox(); tabPageExternal = new TabPage(); tabPageFolders = new TabPage(); groupBoxProgramFolders = new GroupBox(); textBoxProgramFolders = new TextBox(); checkBoxRemovable = new CheckBox(); checkBoxAutoInstallFolderDetect = new CheckBox(); labelProgramFolders = new Label(); tabPageMisc = new TabPage(); cacheSettings1 = new BulkCrapUninstaller.Controls.Settings.CacheSettings(); groupBox2 = new GroupBox(); flowLayoutPanel4 = new FlowLayoutPanel(); groupBox3 = new GroupBox(); flowLayoutPanel10 = new FlowLayoutPanel(); panel4 = new Panel(); usageTracker1 = new UsageTracker(); ((ISupportInitialize)splitContainer1).BeginInit(); splitContainer1.Panel1.SuspendLayout(); splitContainer1.Panel2.SuspendLayout(); splitContainer1.SuspendLayout(); groupBoxMisc.SuspendLayout(); flowLayoutPanel3.SuspendLayout(); panel5.SuspendLayout(); panel3.SuspendLayout(); groupBoxMessages.SuspendLayout(); groupBoxBackup.SuspendLayout(); flowLayoutPanel9.SuspendLayout(); flowLayoutPanel1.SuspendLayout(); panel1.SuspendLayout(); panel2.SuspendLayout(); groupBoxExternal.SuspendLayout(); flowLayoutPanel2.SuspendLayout(); tabControl.SuspendLayout(); tabPageGeneral.SuspendLayout(); tabPageInterface.SuspendLayout(); groupBoxLanguage.SuspendLayout(); tabPageUninstallation.SuspendLayout(); tabPageDetection.SuspendLayout(); groupBoxAppStores.SuspendLayout(); groupBox1.SuspendLayout(); flowLayoutPanel7.SuspendLayout(); tabPageExternal.SuspendLayout(); tabPageFolders.SuspendLayout(); groupBoxProgramFolders.SuspendLayout(); tabPageMisc.SuspendLayout(); groupBox2.SuspendLayout(); flowLayoutPanel4.SuspendLayout(); groupBox3.SuspendLayout(); flowLayoutPanel10.SuspendLayout(); panel4.SuspendLayout(); SuspendLayout(); // // splitContainer1 // splitContainer1.BorderStyle = BorderStyle.Fixed3D; resources.ApplyResources(splitContainer1, "splitContainer1"); splitContainer1.Name = "splitContainer1"; // // splitContainer1.Panel1 // splitContainer1.Panel1.Controls.Add(textBoxPreUninstall); splitContainer1.Panel1.Controls.Add(label5); // // splitContainer1.Panel2 // splitContainer1.Panel2.Controls.Add(textBoxPostUninstall); splitContainer1.Panel2.Controls.Add(label6); // // textBoxPreUninstall // resources.ApplyResources(textBoxPreUninstall, "textBoxPreUninstall"); textBoxPreUninstall.Name = "textBoxPreUninstall"; // // label5 // resources.ApplyResources(label5, "label5"); label5.Name = "label5"; // // textBoxPostUninstall // resources.ApplyResources(textBoxPostUninstall, "textBoxPostUninstall"); textBoxPostUninstall.Name = "textBoxPostUninstall"; // // label6 // resources.ApplyResources(label6, "label6"); label6.Name = "label6"; // // groupBoxMisc // resources.ApplyResources(groupBoxMisc, "groupBoxMisc"); groupBoxMisc.Controls.Add(flowLayoutPanel3); groupBoxMisc.Controls.Add(panel5); groupBoxMisc.Name = "groupBoxMisc"; groupBoxMisc.TabStop = false; // // flowLayoutPanel3 // resources.ApplyResources(flowLayoutPanel3, "flowLayoutPanel3"); flowLayoutPanel3.Controls.Add(checkBoxColorblind); flowLayoutPanel3.Controls.Add(checkBoxDpiaware); flowLayoutPanel3.Name = "flowLayoutPanel3"; // // checkBoxColorblind // resources.ApplyResources(checkBoxColorblind, "checkBoxColorblind"); checkBoxColorblind.Name = "checkBoxColorblind"; checkBoxColorblind.UseVisualStyleBackColor = true; // // checkBoxDpiaware // resources.ApplyResources(checkBoxDpiaware, "checkBoxDpiaware"); checkBoxDpiaware.Name = "checkBoxDpiaware"; checkBoxDpiaware.UseVisualStyleBackColor = true; // // panel5 // resources.ApplyResources(panel5, "panel5"); panel5.Controls.Add(comboBoxDoubleClick); panel5.Controls.Add(label3); panel5.Name = "panel5"; // // comboBoxDoubleClick // resources.ApplyResources(comboBoxDoubleClick, "comboBoxDoubleClick"); comboBoxDoubleClick.DropDownStyle = ComboBoxStyle.DropDownList; comboBoxDoubleClick.FormattingEnabled = true; comboBoxDoubleClick.Name = "comboBoxDoubleClick"; comboBoxDoubleClick.SelectedIndexChanged += comboBoxDoubleClick_SelectedIndexChanged; // // label3 // resources.ApplyResources(label3, "label3"); label3.Name = "label3"; // // checkBoxAutoLoad // resources.ApplyResources(checkBoxAutoLoad, "checkBoxAutoLoad"); checkBoxAutoLoad.Name = "checkBoxAutoLoad"; checkBoxAutoLoad.UseVisualStyleBackColor = true; // // checkBoxRatings // resources.ApplyResources(checkBoxRatings, "checkBoxRatings"); checkBoxRatings.Name = "checkBoxRatings"; checkBoxRatings.UseVisualStyleBackColor = true; // // checkBoxUpdateSearch // resources.ApplyResources(checkBoxUpdateSearch, "checkBoxUpdateSearch"); checkBoxUpdateSearch.Name = "checkBoxUpdateSearch"; checkBoxUpdateSearch.UseVisualStyleBackColor = true; // // checkBoxSendStats // resources.ApplyResources(checkBoxSendStats, "checkBoxSendStats"); checkBoxSendStats.Name = "checkBoxSendStats"; checkBoxSendStats.UseVisualStyleBackColor = true; // // panel3 // resources.ApplyResources(panel3, "panel3"); panel3.Controls.Add(comboBoxLanguage); panel3.Controls.Add(label9); panel3.Name = "panel3"; // // comboBoxLanguage // resources.ApplyResources(comboBoxLanguage, "comboBoxLanguage"); comboBoxLanguage.DropDownStyle = ComboBoxStyle.DropDownList; comboBoxLanguage.FormattingEnabled = true; comboBoxLanguage.Name = "comboBoxLanguage"; comboBoxLanguage.SelectedIndexChanged += comboBoxLanguage_SelectedIndexChanged; // // label9 // resources.ApplyResources(label9, "label9"); label9.Name = "label9"; // // label10 // resources.ApplyResources(label10, "label10"); label10.Name = "label10"; // // groupBoxMessages // resources.ApplyResources(groupBoxMessages, "groupBoxMessages"); groupBoxMessages.Controls.Add(groupBoxBackup); groupBoxMessages.Controls.Add(flowLayoutPanel1); groupBoxMessages.Controls.Add(panel1); groupBoxMessages.Controls.Add(panel2); groupBoxMessages.Name = "groupBoxMessages"; groupBoxMessages.TabStop = false; // // groupBoxBackup // resources.ApplyResources(groupBoxBackup, "groupBoxBackup"); groupBoxBackup.Controls.Add(directorySelectBoxBackup); groupBoxBackup.Controls.Add(flowLayoutPanel9); groupBoxBackup.Name = "groupBoxBackup"; groupBoxBackup.TabStop = false; // // directorySelectBoxBackup // directorySelectBoxBackup.DirectoryPath = ""; resources.ApplyResources(directorySelectBoxBackup, "directorySelectBoxBackup"); directorySelectBoxBackup.Name = "directorySelectBoxBackup"; // // flowLayoutPanel9 // resources.ApplyResources(flowLayoutPanel9, "flowLayoutPanel9"); flowLayoutPanel9.Controls.Add(radioButtonBackupAsk); flowLayoutPanel9.Controls.Add(radioButtonBackupNever); flowLayoutPanel9.Controls.Add(radioButtonBackupAuto); flowLayoutPanel9.Name = "flowLayoutPanel9"; // // radioButtonBackupAsk // resources.ApplyResources(radioButtonBackupAsk, "radioButtonBackupAsk"); flowLayoutPanel9.SetFlowBreak(radioButtonBackupAsk, true); radioButtonBackupAsk.Name = "radioButtonBackupAsk"; radioButtonBackupAsk.TabStop = true; radioButtonBackupAsk.UseVisualStyleBackColor = true; radioButtonBackupAsk.CheckedChanged += radioButtonBackup_CheckedChanged; // // radioButtonBackupNever // resources.ApplyResources(radioButtonBackupNever, "radioButtonBackupNever"); flowLayoutPanel9.SetFlowBreak(radioButtonBackupNever, true); radioButtonBackupNever.Name = "radioButtonBackupNever"; radioButtonBackupNever.TabStop = true; radioButtonBackupNever.UseVisualStyleBackColor = true; radioButtonBackupNever.CheckedChanged += radioButtonBackup_CheckedChanged; // // radioButtonBackupAuto // resources.ApplyResources(radioButtonBackupAuto, "radioButtonBackupAuto"); flowLayoutPanel9.SetFlowBreak(radioButtonBackupAuto, true); radioButtonBackupAuto.Name = "radioButtonBackupAuto"; radioButtonBackupAuto.TabStop = true; radioButtonBackupAuto.UseVisualStyleBackColor = true; radioButtonBackupAuto.CheckedChanged += radioButtonBackup_CheckedChanged; // // flowLayoutPanel1 // resources.ApplyResources(flowLayoutPanel1, "flowLayoutPanel1"); flowLayoutPanel1.Controls.Add(checkBoxShowAllBadJunk); flowLayoutPanel1.Controls.Add(checkBoxLoud); flowLayoutPanel1.Controls.Add(checkBoxNeverFeedback); flowLayoutPanel1.Name = "flowLayoutPanel1"; // // checkBoxShowAllBadJunk // resources.ApplyResources(checkBoxShowAllBadJunk, "checkBoxShowAllBadJunk"); checkBoxShowAllBadJunk.Name = "checkBoxShowAllBadJunk"; checkBoxShowAllBadJunk.UseVisualStyleBackColor = true; // // checkBoxLoud // resources.ApplyResources(checkBoxLoud, "checkBoxLoud"); checkBoxLoud.Name = "checkBoxLoud"; checkBoxLoud.UseVisualStyleBackColor = true; // // checkBoxNeverFeedback // resources.ApplyResources(checkBoxNeverFeedback, "checkBoxNeverFeedback"); checkBoxNeverFeedback.Name = "checkBoxNeverFeedback"; checkBoxNeverFeedback.UseVisualStyleBackColor = true; // // panel1 // resources.ApplyResources(panel1, "panel1"); panel1.Controls.Add(comboBoxJunk); panel1.Controls.Add(label1); panel1.Name = "panel1"; // // comboBoxJunk // resources.ApplyResources(comboBoxJunk, "comboBoxJunk"); comboBoxJunk.DropDownStyle = ComboBoxStyle.DropDownList; comboBoxJunk.FormattingEnabled = true; comboBoxJunk.Name = "comboBoxJunk"; comboBoxJunk.SelectedIndexChanged += comboBoxJunk_SelectedIndexChanged; // // label1 // resources.ApplyResources(label1, "label1"); label1.Name = "label1"; // // panel2 // resources.ApplyResources(panel2, "panel2"); panel2.Controls.Add(comboBoxRestore); panel2.Controls.Add(label2); panel2.Name = "panel2"; // // comboBoxRestore // resources.ApplyResources(comboBoxRestore, "comboBoxRestore"); comboBoxRestore.DropDownStyle = ComboBoxStyle.DropDownList; comboBoxRestore.FormattingEnabled = true; comboBoxRestore.Name = "comboBoxRestore"; comboBoxRestore.SelectedIndexChanged += comboBoxRestore_SelectedIndexChanged; // // label2 // resources.ApplyResources(label2, "label2"); label2.Name = "label2"; // // groupBoxExternal // resources.ApplyResources(groupBoxExternal, "groupBoxExternal"); groupBoxExternal.Controls.Add(splitContainer1); groupBoxExternal.Controls.Add(checkBoxEnableExternal); groupBoxExternal.Controls.Add(flowLayoutPanel2); groupBoxExternal.Name = "groupBoxExternal"; groupBoxExternal.TabStop = false; // // checkBoxEnableExternal // resources.ApplyResources(checkBoxEnableExternal, "checkBoxEnableExternal"); checkBoxEnableExternal.Checked = true; checkBoxEnableExternal.CheckState = CheckState.Checked; checkBoxEnableExternal.Name = "checkBoxEnableExternal"; checkBoxEnableExternal.UseVisualStyleBackColor = true; checkBoxEnableExternal.CheckedChanged += checkBoxEnableExternal_CheckedChanged; // // flowLayoutPanel2 // resources.ApplyResources(flowLayoutPanel2, "flowLayoutPanel2"); flowLayoutPanel2.Controls.Add(label7); flowLayoutPanel2.Name = "flowLayoutPanel2"; // // label7 // resources.ApplyResources(label7, "label7"); label7.Name = "label7"; // // button2 // resources.ApplyResources(button2, "button2"); button2.DialogResult = DialogResult.Cancel; button2.Name = "button2"; button2.UseVisualStyleBackColor = true; button2.Click += button2_Click; // // tabControl // tabControl.Controls.Add(tabPageGeneral); tabControl.Controls.Add(tabPageInterface); tabControl.Controls.Add(tabPageUninstallation); tabControl.Controls.Add(tabPageDetection); tabControl.Controls.Add(tabPageExternal); tabControl.Controls.Add(tabPageFolders); tabControl.Controls.Add(tabPageMisc); resources.ApplyResources(tabControl, "tabControl"); tabControl.Multiline = true; tabControl.Name = "tabControl"; tabControl.SelectedIndex = 0; tabControl.SizeMode = TabSizeMode.FillToRight; tabControl.SelectedIndexChanged += tabControl_SelectedIndexChanged; // // tabPageGeneral // tabPageGeneral.Controls.Add(propertiesSidebar1); resources.ApplyResources(tabPageGeneral, "tabPageGeneral"); tabPageGeneral.Name = "tabPageGeneral"; tabPageGeneral.UseVisualStyleBackColor = true; // // propertiesSidebar1 // resources.ApplyResources(propertiesSidebar1, "propertiesSidebar1"); propertiesSidebar1.Name = "propertiesSidebar1"; // // tabPageInterface // resources.ApplyResources(tabPageInterface, "tabPageInterface"); tabPageInterface.Controls.Add(groupBoxMisc); tabPageInterface.Controls.Add(groupBoxMessages); tabPageInterface.Controls.Add(groupBoxLanguage); tabPageInterface.Name = "tabPageInterface"; tabPageInterface.UseVisualStyleBackColor = true; // // groupBoxLanguage // resources.ApplyResources(groupBoxLanguage, "groupBoxLanguage"); groupBoxLanguage.Controls.Add(panel3); groupBoxLanguage.Controls.Add(label10); groupBoxLanguage.Name = "groupBoxLanguage"; groupBoxLanguage.TabStop = false; // // tabPageUninstallation // resources.ApplyResources(tabPageUninstallation, "tabPageUninstallation"); tabPageUninstallation.Controls.Add(uninstallationSettings1); tabPageUninstallation.Name = "tabPageUninstallation"; tabPageUninstallation.UseVisualStyleBackColor = true; // // uninstallationSettings1 // resources.ApplyResources(uninstallationSettings1, "uninstallationSettings1"); uninstallationSettings1.Name = "uninstallationSettings1"; // // tabPageDetection // resources.ApplyResources(tabPageDetection, "tabPageDetection"); tabPageDetection.Controls.Add(groupBoxAppStores); tabPageDetection.Controls.Add(groupBox1); tabPageDetection.Name = "tabPageDetection"; tabPageDetection.UseVisualStyleBackColor = true; // // groupBoxAppStores // resources.ApplyResources(groupBoxAppStores, "groupBoxAppStores"); groupBoxAppStores.Controls.Add(labelWinUpdateInfo); groupBoxAppStores.Controls.Add(checkBoxScanWinUpdates); groupBoxAppStores.Controls.Add(labelWinFeatureInfo); groupBoxAppStores.Controls.Add(checkBoxScanWinFeatures); groupBoxAppStores.Controls.Add(checkBoxScanStoreApps); groupBoxAppStores.Controls.Add(checkBoxScanSteam); groupBoxAppStores.Controls.Add(checkBoxScoop); groupBoxAppStores.Controls.Add(checkBoxOculus); groupBoxAppStores.Controls.Add(checkBoxChoco); groupBoxAppStores.Name = "groupBoxAppStores"; groupBoxAppStores.TabStop = false; // // labelWinUpdateInfo // resources.ApplyResources(labelWinUpdateInfo, "labelWinUpdateInfo"); labelWinUpdateInfo.Name = "labelWinUpdateInfo"; // // checkBoxScanWinUpdates // resources.ApplyResources(checkBoxScanWinUpdates, "checkBoxScanWinUpdates"); checkBoxScanWinUpdates.Name = "checkBoxScanWinUpdates"; checkBoxScanWinUpdates.UseVisualStyleBackColor = true; // // labelWinFeatureInfo // resources.ApplyResources(labelWinFeatureInfo, "labelWinFeatureInfo"); labelWinFeatureInfo.Name = "labelWinFeatureInfo"; // // checkBoxScanWinFeatures // resources.ApplyResources(checkBoxScanWinFeatures, "checkBoxScanWinFeatures"); checkBoxScanWinFeatures.Name = "checkBoxScanWinFeatures"; checkBoxScanWinFeatures.UseVisualStyleBackColor = true; // // checkBoxScanStoreApps // resources.ApplyResources(checkBoxScanStoreApps, "checkBoxScanStoreApps"); checkBoxScanStoreApps.Name = "checkBoxScanStoreApps"; checkBoxScanStoreApps.UseVisualStyleBackColor = true; // // checkBoxScanSteam // resources.ApplyResources(checkBoxScanSteam, "checkBoxScanSteam"); checkBoxScanSteam.Name = "checkBoxScanSteam"; checkBoxScanSteam.UseVisualStyleBackColor = true; // // checkBoxScoop // resources.ApplyResources(checkBoxScoop, "checkBoxScoop"); checkBoxScoop.Name = "checkBoxScoop"; checkBoxScoop.UseVisualStyleBackColor = true; // // checkBoxOculus // resources.ApplyResources(checkBoxOculus, "checkBoxOculus"); checkBoxOculus.Name = "checkBoxOculus"; checkBoxOculus.UseVisualStyleBackColor = true; // // checkBoxChoco // resources.ApplyResources(checkBoxChoco, "checkBoxChoco"); checkBoxChoco.Name = "checkBoxChoco"; checkBoxChoco.UseVisualStyleBackColor = true; // // groupBox1 // resources.ApplyResources(groupBox1, "groupBox1"); groupBox1.Controls.Add(flowLayoutPanel7); groupBox1.Name = "groupBox1"; groupBox1.TabStop = false; // // flowLayoutPanel7 // resources.ApplyResources(flowLayoutPanel7, "flowLayoutPanel7"); flowLayoutPanel7.Controls.Add(checkBoxScanRegistry); flowLayoutPanel7.Controls.Add(checkBoxScanDrives); flowLayoutPanel7.Controls.Add(checkBoxPreDefined); flowLayoutPanel7.Name = "flowLayoutPanel7"; // // checkBoxScanRegistry // resources.ApplyResources(checkBoxScanRegistry, "checkBoxScanRegistry"); flowLayoutPanel7.SetFlowBreak(checkBoxScanRegistry, true); checkBoxScanRegistry.Name = "checkBoxScanRegistry"; checkBoxScanRegistry.UseVisualStyleBackColor = true; // // checkBoxScanDrives // resources.ApplyResources(checkBoxScanDrives, "checkBoxScanDrives"); flowLayoutPanel7.SetFlowBreak(checkBoxScanDrives, true); checkBoxScanDrives.Name = "checkBoxScanDrives"; checkBoxScanDrives.UseVisualStyleBackColor = true; // // checkBoxPreDefined // resources.ApplyResources(checkBoxPreDefined, "checkBoxPreDefined"); flowLayoutPanel7.SetFlowBreak(checkBoxPreDefined, true); checkBoxPreDefined.Name = "checkBoxPreDefined"; checkBoxPreDefined.UseVisualStyleBackColor = true; // // tabPageExternal // tabPageExternal.Controls.Add(groupBoxExternal); resources.ApplyResources(tabPageExternal, "tabPageExternal"); tabPageExternal.Name = "tabPageExternal"; tabPageExternal.UseVisualStyleBackColor = true; // // tabPageFolders // tabPageFolders.Controls.Add(groupBoxProgramFolders); resources.ApplyResources(tabPageFolders, "tabPageFolders"); tabPageFolders.Name = "tabPageFolders"; tabPageFolders.UseVisualStyleBackColor = true; // // groupBoxProgramFolders // resources.ApplyResources(groupBoxProgramFolders, "groupBoxProgramFolders"); groupBoxProgramFolders.Controls.Add(textBoxProgramFolders); groupBoxProgramFolders.Controls.Add(checkBoxRemovable); groupBoxProgramFolders.Controls.Add(checkBoxAutoInstallFolderDetect); groupBoxProgramFolders.Controls.Add(labelProgramFolders); groupBoxProgramFolders.Name = "groupBoxProgramFolders"; groupBoxProgramFolders.TabStop = false; // // textBoxProgramFolders // resources.ApplyResources(textBoxProgramFolders, "textBoxProgramFolders"); textBoxProgramFolders.Name = "textBoxProgramFolders"; // // checkBoxRemovable // resources.ApplyResources(checkBoxRemovable, "checkBoxRemovable"); checkBoxRemovable.Name = "checkBoxRemovable"; checkBoxRemovable.UseVisualStyleBackColor = true; // // checkBoxAutoInstallFolderDetect // resources.ApplyResources(checkBoxAutoInstallFolderDetect, "checkBoxAutoInstallFolderDetect"); checkBoxAutoInstallFolderDetect.Name = "checkBoxAutoInstallFolderDetect"; checkBoxAutoInstallFolderDetect.UseVisualStyleBackColor = true; // // labelProgramFolders // resources.ApplyResources(labelProgramFolders, "labelProgramFolders"); labelProgramFolders.Name = "labelProgramFolders"; // // tabPageMisc // tabPageMisc.Controls.Add(cacheSettings1); tabPageMisc.Controls.Add(groupBox2); tabPageMisc.Controls.Add(groupBox3); resources.ApplyResources(tabPageMisc, "tabPageMisc"); tabPageMisc.Name = "tabPageMisc"; tabPageMisc.UseVisualStyleBackColor = true; // // cacheSettings1 // resources.ApplyResources(cacheSettings1, "cacheSettings1"); cacheSettings1.Name = "cacheSettings1"; // // groupBox2 // resources.ApplyResources(groupBox2, "groupBox2"); groupBox2.Controls.Add(flowLayoutPanel4); groupBox2.Name = "groupBox2"; groupBox2.TabStop = false; // // flowLayoutPanel4 // resources.ApplyResources(flowLayoutPanel4, "flowLayoutPanel4"); flowLayoutPanel4.Controls.Add(checkBoxAutoLoad); flowLayoutPanel4.Name = "flowLayoutPanel4"; // // groupBox3 // resources.ApplyResources(groupBox3, "groupBox3"); groupBox3.Controls.Add(flowLayoutPanel10); groupBox3.Name = "groupBox3"; groupBox3.TabStop = false; // // flowLayoutPanel10 // resources.ApplyResources(flowLayoutPanel10, "flowLayoutPanel10"); flowLayoutPanel10.Controls.Add(checkBoxUpdateSearch); flowLayoutPanel10.Controls.Add(checkBoxSendStats); flowLayoutPanel10.Controls.Add(checkBoxRatings); flowLayoutPanel10.Name = "flowLayoutPanel10"; // // panel4 // panel4.Controls.Add(button2); resources.ApplyResources(panel4, "panel4"); panel4.Name = "panel4"; // // usageTracker1 // usageTracker1.ContainerControl = this; // // SettingsWindow // resources.ApplyResources(this, "$this"); AutoScaleMode = AutoScaleMode.Font; CancelButton = button2; Controls.Add(tabControl); Controls.Add(panel4); FormBorderStyle = FormBorderStyle.FixedSingle; MaximizeBox = false; MinimizeBox = false; Name = "SettingsWindow"; FormClosing += SettingsWindow_FormClosing; splitContainer1.Panel1.ResumeLayout(false); splitContainer1.Panel1.PerformLayout(); splitContainer1.Panel2.ResumeLayout(false); splitContainer1.Panel2.PerformLayout(); ((ISupportInitialize)splitContainer1).EndInit(); splitContainer1.ResumeLayout(false); groupBoxMisc.ResumeLayout(false); groupBoxMisc.PerformLayout(); flowLayoutPanel3.ResumeLayout(false); flowLayoutPanel3.PerformLayout(); panel5.ResumeLayout(false); panel5.PerformLayout(); panel3.ResumeLayout(false); panel3.PerformLayout(); groupBoxMessages.ResumeLayout(false); groupBoxMessages.PerformLayout(); groupBoxBackup.ResumeLayout(false); groupBoxBackup.PerformLayout(); flowLayoutPanel9.ResumeLayout(false); flowLayoutPanel9.PerformLayout(); flowLayoutPanel1.ResumeLayout(false); flowLayoutPanel1.PerformLayout(); panel1.ResumeLayout(false); panel1.PerformLayout(); panel2.ResumeLayout(false); panel2.PerformLayout(); groupBoxExternal.ResumeLayout(false); groupBoxExternal.PerformLayout(); flowLayoutPanel2.ResumeLayout(false); flowLayoutPanel2.PerformLayout(); tabControl.ResumeLayout(false); tabPageGeneral.ResumeLayout(false); tabPageGeneral.PerformLayout(); tabPageInterface.ResumeLayout(false); tabPageInterface.PerformLayout(); groupBoxLanguage.ResumeLayout(false); groupBoxLanguage.PerformLayout(); tabPageUninstallation.ResumeLayout(false); tabPageUninstallation.PerformLayout(); tabPageDetection.ResumeLayout(false); tabPageDetection.PerformLayout(); groupBoxAppStores.ResumeLayout(false); groupBoxAppStores.PerformLayout(); groupBox1.ResumeLayout(false); groupBox1.PerformLayout(); flowLayoutPanel7.ResumeLayout(false); flowLayoutPanel7.PerformLayout(); tabPageExternal.ResumeLayout(false); tabPageExternal.PerformLayout(); tabPageFolders.ResumeLayout(false); tabPageFolders.PerformLayout(); groupBoxProgramFolders.ResumeLayout(false); groupBoxProgramFolders.PerformLayout(); tabPageMisc.ResumeLayout(false); tabPageMisc.PerformLayout(); groupBox2.ResumeLayout(false); groupBox2.PerformLayout(); flowLayoutPanel4.ResumeLayout(false); flowLayoutPanel4.PerformLayout(); groupBox3.ResumeLayout(false); groupBox3.PerformLayout(); flowLayoutPanel10.ResumeLayout(false); flowLayoutPanel10.PerformLayout(); panel4.ResumeLayout(false); ResumeLayout(false); } #endregion private GroupBox groupBoxMessages; private CheckBox checkBoxLoud; private ComboBox comboBoxRestore; private ComboBox comboBoxJunk; private Label label2; private Label label1; private Button button2; private GroupBox groupBoxMisc; private CheckBox checkBoxUpdateSearch; private UsageTracker usageTracker1; private GroupBox groupBoxExternal; private FlowLayoutPanel flowLayoutPanel1; private Panel panel1; private Panel panel2; private FlowLayoutPanel flowLayoutPanel3; private CheckBox checkBoxSendStats; private FlowLayoutPanel flowLayoutPanel2; private Label label5; private TextBox textBoxPreUninstall; private Label label6; private TextBox textBoxPostUninstall; private Label label7; private CheckBox checkBoxEnableExternal; private Panel panel3; private ComboBox comboBoxLanguage; private Label label9; private Label label10; private SplitContainer splitContainer1; private TabControl tabControl; private TabPage tabPageMisc; private TabPage tabPageExternal; private Panel panel4; private TabPage tabPageGeneral; private Controls.PropertiesSidebar propertiesSidebar1; private TabPage tabPageFolders; private GroupBox groupBoxProgramFolders; private Label labelProgramFolders; private TextBox textBoxProgramFolders; private CheckBox checkBoxAutoLoad; private CheckBox checkBoxRatings; private TabPage tabPageUninstallation; private Controls.UninstallationSettings uninstallationSettings1; private CheckBox checkBoxShowAllBadJunk; private CheckBox checkBoxNeverFeedback; private TabPage tabPageDetection; private GroupBox groupBoxAppStores; private CheckBox checkBoxScanSteam; private CheckBox checkBoxScanStoreApps; private CheckBox checkBoxScanWinFeatures; private CheckBox checkBoxScanWinUpdates; private Label labelWinFeatureInfo; private Label labelWinUpdateInfo; private CheckBox checkBoxAutoInstallFolderDetect; private GroupBox groupBox1; private FlowLayoutPanel flowLayoutPanel7; private CheckBox checkBoxScanRegistry; private CheckBox checkBoxScanDrives; private CheckBox checkBoxPreDefined; private TabPage tabPageInterface; private GroupBox groupBoxLanguage; private GroupBox groupBoxBackup; private FlowLayoutPanel flowLayoutPanel9; private RadioButton radioButtonBackupAsk; private RadioButton radioButtonBackupNever; private RadioButton radioButtonBackupAuto; private Klocman.Controls.DirectorySelectBox directorySelectBoxBackup; private Controls.Settings.CacheSettings cacheSettings1; private GroupBox groupBox3; private FlowLayoutPanel flowLayoutPanel10; private CheckBox checkBoxChoco; private CheckBox checkBoxOculus; private CheckBox checkBoxRemovable; private CheckBox checkBoxColorblind; private CheckBox checkBoxScoop; private CheckBox checkBoxDpiaware; private GroupBox groupBox2; private FlowLayoutPanel flowLayoutPanel4; private Panel panel5; private ComboBox comboBoxDoubleClick; private Label label3; } } ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/SettingsWindow.ar.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 سطر الاوامر قبل بدء تشغيل الغاء التثبيت سطر الاوامر بعد انتهاء التثبيت misc.5 في البداية "Default.bcul"تحميل تلقائيا قائمه الغاء التثبيت المسمى البحث عن التحديثات عند بدء التشغيل ارسال احصائيات الاستخدام المجهول تمكين تصنيفات المستخدم للتطبيقات لغة التطبيق: سيتعين اعاده تشغيل التطبيق لتصبح تغييرات اللغة نافذه المفعول. مربعات الرسائل تظهر دائما الغير مرغوب فيه مع انخفاض الثقة اطلب ازاله المثبتات بصوت عال من المهمة بهدوء لا تطلب ابدا للحصول على ملاحظات او مساعده البحث عن الخردة بعد الغاء التثبيت انشاء نقطه استعاده قبل الغاء التثبيت التطبيقات الخارجية تمكين تنفيذ التطبيقات الخارجية يمكنك تحديد الاوامر التي سيتم تشغيلها قبل الغاء التثبيت وبعده. سطر واحد يساوي امر واحد سيتم تنفيذها كما لو كنت تستخدم "تشغيل..." مربع الحوار. سينتظر حتى اكتمال الامر قيد التشغيل الحالي قبل تنفيذ التالية BCU &اغلاق عام (مكتب التسجيل (مستحسن تركة ممكن (المحركات (يكتشف تطبيقات غير مسجله استنادا الى قواعد محدده مسبقا بحث عن التطبيقات في... مخازن التطبيقات للمسح كشف ادوات خارجيه مجلد متنوع يتبخر تطبيقات ويندوز مخزن ميزات ويندوز ويمكن ان يكون بطيئا او حتى يفشل على بعض الانظمه (عاده ما تشير الى تلف النظام). WMI، يستخدم الكشف عن ميزات وندوز تحديث ويندوز وهو بطيء. ويمكن ان يستغرق بضع دقائق لاكمال. WUA,يستخدم الكشف عن تحديثات وندوز مجلدات تثبيت البرنامج العمل بشكل افضل. BCU للبحث عن البقايا، والتطبيقات الغير مسجلة وعدد قليل من الاشياء الاخرى. في حين انه ليس من الضروري ، فان قائمه من هذه المجلدات السماح BCU وسوف تستخدم هذه المجلدات من قبل (e.g. D:\Applications).يمكنك تحديد المجلدات المخصصة التي تقوم بتثبيت تطبيقاتك فيها يتم دائما فحص مجلدات وندوز الافتراضية ، ولا تحتاج الى تضمينها في هذه القائمة. استخدام مسارات الدليل الكامل ، مسار واحد لكل سطر. سيتم تجاهل المسارات غير الصالحة والدلائل غير الموجودة. محاولة الكشف عن مجلدات التثبيت المخصصة تلقائيا محاولة الكشف عن مجلدات التثبيت المخصصة تلقائيا اطلب الانشاء دائما لا تطلب ابدا انشاء انشاء تلقائيا في الدليل: نسخ احتياطي قبل ازالة البقايا اللغة الواجهه الغاء التثبيت الشبكة Oculus Store Chocolatey ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/SettingsWindow.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.ComponentModel; using System.Globalization; using System.Linq; using System.Windows.Forms; using BulkCrapUninstaller.Functions; using BulkCrapUninstaller.Properties; using Klocman; using Klocman.Binding.Settings; using Klocman.Forms.Tools; using Klocman.Localising; namespace BulkCrapUninstaller.Forms { public partial class SettingsWindow : Form { private readonly SettingBinder _settings = Settings.Default.SettingBinder; private bool _restartNeeded; [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public int OpenedTab { get { return tabControl.SelectedIndex; } set { tabControl.SelectedIndex = value; } } public SettingsWindow() { InitializeComponent(); } protected override void OnLoad(EventArgs e) { base.OnLoad(e); if (DesignMode) return; Icon = Resources.Icon_Logo; _settings.BindControl(checkBoxLoud, x => x.MessagesAskRemoveLoudItems, this); _settings.BindControl(checkBoxShowAllBadJunk, x => x.MessagesShowAllBadJunk, this); _settings.BindControl(checkBoxNeverFeedback, x => x.MiscFeedbackNagNeverShow, this); _settings.BindControl(checkBoxUpdateSearch, x => x.MiscCheckForUpdates, this); _settings.BindControl(checkBoxSendStats, x => x.MiscSendStatistics, this); _settings.BindControl(checkBoxAutoLoad, x => x.MiscAutoLoadDefaultList, this); _settings.BindControl(checkBoxRatings, x => x.MiscUserRatings, this); _settings.BindControl(checkBoxColorblind, x => x.MiscColorblind, this); _settings.BindControl(checkBoxDpiaware, x => x.WindowDpiAware, this); _settings.BindControl(checkBoxEnableExternal, x => x.ExternalEnable, this); _settings.BindControl(textBoxPreUninstall, x => x.ExternalPreCommands, this); _settings.BindControl(textBoxPostUninstall, x => x.ExternalPostCommands, this); _settings.BindControl(textBoxProgramFolders, x => x.FoldersCustomProgramDirs, this); _settings.BindControl(checkBoxAutoInstallFolderDetect, x => x.FoldersAutoDetect, this); _settings.BindControl(checkBoxRemovable, x => x.FoldersScanRemovable, this); _settings.Subscribe((x, y) => checkBoxRemovable.Enabled = y.NewValue, x => x.FoldersAutoDetect, this); _settings.BindControl(checkBoxChoco, x => x.ScanChocolatey, this); _settings.BindControl(checkBoxScoop, x => x.ScanScoop, this); _settings.BindControl(checkBoxScanSteam, x => x.ScanSteam, this); _settings.BindControl(checkBoxScanStoreApps, x => x.ScanStoreApps, this); _settings.BindControl(checkBoxOculus, x => x.ScanOculus, this); _settings.BindControl(checkBoxScanWinFeatures, x => x.ScanWinFeatures, this); _settings.BindControl(checkBoxScanWinUpdates, x => x.ScanWinUpdates, this); _settings.BindControl(checkBoxScanDrives, x => x.ScanDrives, this); _settings.BindControl(checkBoxScanRegistry, x => x.ScanRegistry, this); _settings.BindControl(checkBoxPreDefined, x => x.ScanPreDefined, this); foreach (YesNoAsk value in Enum.GetValues(typeof(YesNoAsk))) { var wrapper = new LocalisedEnumWrapper(value); comboBoxJunk.Items.Add(wrapper); comboBoxRestore.Items.Add(wrapper); } _settings.Subscribe(JunkSettingChanged, x => x.MessagesRemoveJunk, this); _settings.Subscribe(RestoreSettingChanged, x => x.MessagesRestorePoints, this); foreach (UninstallerListDoubleClickAction value in Enum.GetValues(typeof(UninstallerListDoubleClickAction))) { var wrapper = new LocalisedEnumWrapper(value); comboBoxDoubleClick.Items.Add(wrapper); } _settings.Subscribe(DoubleClickSettingChanged, x => x.UninstallerListDoubleClickAction, this); comboBoxLanguage.Items.Add(Localisable.DefaultLanguage); foreach (var languageCode in CultureConfigurator.SupportedLanguages.OrderBy(x => x.DisplayName)) { comboBoxLanguage.Items.Add(new ComboBoxWrapper(languageCode, x => x.DisplayName)); } _settings.Subscribe(LanguageSettingChanged, x => x.Language, this); _settings.Subscribe(BackupSettingChanged, x => x.BackupLeftovers, this); _settings.BindProperty(directorySelectBoxBackup, box => box.DirectoryPath, nameof(directorySelectBoxBackup.DirectoryPathChanged), settings => settings.BackupLeftoversDirectory, this); _settings.SendUpdates(this); _restartNeeded = false; } private void button2_Click(object sender, EventArgs e) { Close(); if (_restartNeeded && MessageBoxes.RestartNeededForSettingChangeQuestion()) { EntryPoint.Restart(); } } private void checkBoxEnableExternal_CheckedChanged(object sender, EventArgs e) { splitContainer1.Enabled = checkBoxEnableExternal.Checked; //textBoxPreUninstall.Enabled = checkBoxEnableExternal.Checked; //textBoxPostUninstall.Enabled = checkBoxEnableExternal.Checked; } private void comboBoxJunk_SelectedIndexChanged(object sender, EventArgs e) { if (comboBoxJunk.SelectedItem is LocalisedEnumWrapper wrapper) { _settings.Settings.MessagesRemoveJunk = (YesNoAsk)wrapper.TargetEnum; } } private void comboBoxLanguage_SelectedIndexChanged(object sender, EventArgs e) { if (comboBoxLanguage.SelectedItem is ComboBoxWrapper wrapper) { _settings.Settings.Language = wrapper.WrappedObject.Name; _restartNeeded = true; } else if (comboBoxLanguage.SelectedItem is string) { _settings.Settings.Language = string.Empty; _restartNeeded = true; } } private void comboBoxRestore_SelectedIndexChanged(object sender, EventArgs e) { if (comboBoxRestore.SelectedItem is LocalisedEnumWrapper wrapper) { _settings.Settings.MessagesRestorePoints = (YesNoAsk)wrapper.TargetEnum; } } private void JunkSettingChanged(object sender, SettingChangedEventArgs args) { var newSelection = comboBoxJunk.Items.Cast().FirstOrDefault(x => x.TargetEnum.Equals(args.NewValue)); if (newSelection == null || newSelection.Equals(comboBoxJunk.SelectedItem)) return; comboBoxJunk.SelectedItem = newSelection; } private void LanguageSettingChanged(object sender, SettingChangedEventArgs args) { if (!string.IsNullOrEmpty(args.NewValue)) { var selectedItem = comboBoxLanguage.Items.OfType>() .FirstOrDefault(x => x.WrappedObject.Name.Equals(args.NewValue)); if (selectedItem != null) { comboBoxLanguage.SelectedItem = selectedItem; return; } } comboBoxLanguage.SelectedIndex = 0; } private void RestoreSettingChanged(object sender, SettingChangedEventArgs args) { var newSelection = comboBoxRestore.Items.Cast() .FirstOrDefault(x => x.TargetEnum.Equals(args.NewValue)); if (newSelection == null || newSelection.Equals(comboBoxRestore.SelectedItem)) return; comboBoxRestore.SelectedItem = newSelection; } private void SettingsWindow_FormClosing(object sender, FormClosingEventArgs e) { _settings.RemoveHandlers(this); } private void tabControl_SelectedIndexChanged(object sender, EventArgs e) { } private void radioButtonBackup_CheckedChanged(object sender, EventArgs e) { directorySelectBoxBackup.Enabled = false; if (radioButtonBackupAsk.Checked) _settings.Settings.BackupLeftovers = YesNoAsk.Ask; else if (radioButtonBackupAuto.Checked) { _settings.Settings.BackupLeftovers = YesNoAsk.Yes; directorySelectBoxBackup.Enabled = true; } else if (radioButtonBackupNever.Checked) _settings.Settings.BackupLeftovers = YesNoAsk.No; else throw new InvalidOperationException(); } private void BackupSettingChanged(object sender, SettingChangedEventArgs args) { switch (args.NewValue) { case YesNoAsk.Ask: radioButtonBackupAsk.Checked = true; break; case YesNoAsk.Yes: radioButtonBackupAuto.Checked = true; break; case YesNoAsk.No: radioButtonBackupNever.Checked = true; break; default: throw new ArgumentOutOfRangeException(nameof(args), args.NewValue, "Unknown value"); } } private void comboBoxDoubleClick_SelectedIndexChanged(object sender, EventArgs e) { if (comboBoxDoubleClick.SelectedItem is LocalisedEnumWrapper wrapper) { _settings.Settings.UninstallerListDoubleClickAction = (UninstallerListDoubleClickAction)wrapper.TargetEnum; } } private void DoubleClickSettingChanged(object sender, SettingChangedEventArgs args) { var newSelection = comboBoxDoubleClick.Items.Cast().FirstOrDefault(x => x.TargetEnum.Equals(args.NewValue)); if (newSelection == null || newSelection.Equals(comboBoxDoubleClick.SelectedItem)) return; comboBoxDoubleClick.SelectedItem = newSelection; } } } ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/SettingsWindow.cs.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Příkazový řádek před spuštěním odinstalace Příkazový řádek po odinstalaci ukončit Vyhledat aktualizace po spuštění Poslat anonymní statistiky používání Jazyk aplikace: Aplikace bude muset být restartována. Aby se změna jazyka projevíla. Různé Zeptat se, zda chcete odebrat hlasité odinstalace z tichého zadání Hledání pozůstatky odinstalování Vytvoření bodu obnovení Okno zpráv Povolit spuštení externích aplikací Můžete zadat příkazy, které mají být provedeny před a po odinstalaci. Jeden řádek obsahuje jeden příkaz, který bude proveden jako okno "Spustit ...". BCU bude čekat na dokončení příkazu před zahájením dalšího. Externí aplikace &Zavřít Obecné Externí nástroje Můžete určit vlastní instalaci aplikace do složky (např D: \ Applications). Tento seznam bude používán BCU k hledání zbytků po odinstalaci, neregistrované aplikací a pár dalších věcí. I když to není nutné, seznam složek pro zlepšení operací BCU. Výchozí složky systému Windows jsou vždy zahrnuty do vyhledávání, nemusíte je přidávat. Použít celou cestu ke složce, jedna cesta na řádek. Neplatné cesty a neexistující složky budou ignorovány. Složky instalačních programů Složky Různé BCUninstaller Nastavení Automaticky otevřený seznam "Default.bcul" na startu Aktivovat uživatelských ratingy aplikací Vždy zobrazovat nepotřebné s nízkou důvěrou Nepožadovat zpětnou vazbu, nebo pomoc Steam Registry (doporučeno ponechat povolené) Jednotky (detekuje neregistrované aplikace) Na základě předem definovaných pravidel Hledání aplikací v ... Úložiště aplikací pro skenování Detekce Aplikace Windows Store Funkce systému Windows Detekce funkcí systému Windows používá službu WMI a v některých systémech může být pomalá nebo dokonce selhávat (obvykle indikuje poškození systému). Windows aktualizace Zjišťování aktualizací systému Windows agentem WUA, což je pomalé. A může trvat několik minut do dokončení. Pokusit se automaticky rozpoznat vlastní instalační složky Vždy požádat o vytvoření Nikdy se neptat Vytvořit automaticky v adresáři: Zálohování před odebráním zbytku Jazyk Rozhraní Odinstalace Oculus Store Chocolatey 17, 17 True ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/SettingsWindow.de.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Anweisung VOR Ausführung der Deinstallation Anweisung NACH Beendigung der Deinstallation Suche nach Updates beim Start Anonyme Nutzungsstatistiken senden Sprache: Die Anwendung muss neu gestartet werden, damit die Änderung der Sprache wirksam wird. Div. Fragen, ob normale Uninstaller von der Liste der stillen entfernt werden sollen Nach Deinstallation nach Programmresten suchen Vor Deinstallation einen Wiederherstellungspunkt erstellen Message-Boxen Ausführung von externen Anwendungen erlauben Sie können Befehle angeben, die vor und nach der Deinstallation ausgeführt werden. Eine Zeile entspricht einem Befehl und wird ausgeführt, als hätten Sie das Dialogfeld "Ausführen..." verwendet. BCU wartet mit der nächsten Ausführung, bis der aktuell ausgeführte Befehl abgeschlossen ist. Externe Anwendungen S&chließen Allgemein Externe Werkzeuge Verschiedenes BCUninstaller Einstellungen Ordner Sie können benutzerdefinierte Ordner angeben, in denen Sie Ihre Anwendungen installiert haben (z.B. D:\Anwendungen). Diese Ordner werden von BCU durchsucht, um Deinstallations-Reste und nicht registrierte Anwendungen zu finden. Zwar ist es nicht notwendig, aber mit einer Liste dieser Ordner wird BCU besser funktionieren. Die Standard-Ordner werden immer gescannt. Sie müssen diese nicht in die Liste aufnehmen. Verwenden Sie vollständige Verzeichnispfade, ein Pfad pro Zeile. Ungültige Pfade und nicht vorhandene Verzeichnisse werden ignoriert. Programm Installationsordner Automatisch offene Liste "Default.bcul" beim Start Aktivieren nutzerbewertungen von Applikationen Steam Oculus Store Chocolatey Immer Fragen beim Erstellen Niemals Fragen beim Erstellen Erzeuge automatisch im Verzeichnis: Backup vor der Resteentfernung Anzeige von Junk immer mit geringem Vertrauen Niemals nach Rückmeldungen und Hilfe fragen Sprache Schnittstelle Deinstallation Erkennung, dass Windows Update WUA benutzt welches langsam ist. Es kann einige Minuten dauern um fertig zu stellen. Windows Update Erkennung das Windowseigenschaften nutzen WMI, welches sehr langsam und manchmal auf bestimmten Systemen versagt. (weist in der Regel auf Systembeschädigung hin) Windows Eigenschaft Windows Store Programme Anwendungsspeicher Scannen Registrierung (empfohlen, aktiviert zu lassen) Laufwerke (Erkennung nicht registrieter Programme) Basierend auf vordefinierten Regeln Suche nach Programmen in... Erkennung Überprüfe Wechseldatenträger Scan pendrives, USB hard drives, SD Cards, etc. Automatischer Versuch benutzerdefinierte Installallierte Ordner zu finden Netzwerk Farbblinden Einstellung Switches colors to be better for color-blind people Aktivieren der DPI-kompatiblen Skalierung der Oberfläche Doppelklick in der Anwendungsliste Scoop ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/SettingsWindow.es.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Buscar actualizaciones al iniciar Idioma de la aplicación: Línea de comandos antes de que se inicie la desinstalación Línea de comando después de que la desinstalación finalice Cargar automáticamente la lista de desinstalación llamada "Default.bcul" al iniciar Activar calificaciones de las aplicaciones Carpetas Configuración de Bulk Crap Uninstaller Aplicaciones externas &Cerrar General Herramientas externas Carpetas de instalación de programas Crear un punto de restauración antes de desinstalar Cajas de mensaje Enviar estadísticas de uso anónimas Buscar restos tras desinstalar Reinicie la aplicación para cambiar el idioma. Variedad Preguntar para eliminar desinstaladores fuertes de una tarea silenciosa Permitir la ejecución de aplicaciones externas Puede especificar los comandos que se ejecutarán antes y después de la desinstalación. Una línea es igual a un comando y se ejecutará como si utilizara el diálogo "Ejecutar...". BCU esperará hasta que el comando activado se complete antes de ejecutar el siguiente. Puede indicar carpetas en las que instale sus aplicaciones (p,ej, D:\Aplicaciones). Estas carpetas serán utilizadas por BCU para buscar restos, aplicaciones no registradas y otras cosas. Si bien no es necesario, una lista de estas carpetas permitirá BCU trabajar mejor. Las carpetas de Windows predeterminadas siempre se analizan, no es necesario incluirlas en esta lista. Utilice rutas de directorio completas, una ruta por línea. Las rutas no válidas y los directorios no existentes se ignorarán. Variados Mostrar siempre restos de baja confianza Nunca solicitar comentarios o ayuda Steam Registro (se recomienda dejar habilitado) Unidades (detecta aplicaciones no registradas) Basado en reglas predefinidas Buscar aplicaciones en... Almacenes de aplicaciones para escanear Detección Apps de Windows Store Características de Windows Detección de características de Windows utiliza WMI, y puede ser lento o incluso fallar en algunos sistemas (por lo general indica corrupción del sistema). Actualización de Windows La detección de actualizaciones de Windows utiliza WUA, que es lento. Puede tardar un par de minutos en completarse. Buscar siempre las carpetas de instalación personalizadas Oculus Store Chocolatey Modo para daltónicos Switches colors to be better for color-blind people Habilitar el escalado de la interfaz en función del DPI Siempre pedir crear Nunca pedir crear Crear automáticamente en el directorio: Respaldar antes de limpiar restos Idioma Interfaz Desinstalación Scoop Escanear unidades extraíbles Scan pendrives, USB hard drives, SD Cards, etc. Red Doble clic en la lista de aplicaciones ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/SettingsWindow.fr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Ligne de commande avant le début de désinstallation Ligne de commande après la fin de désinstallation Chercher des mises à jour au démarrage Envoyer des statistiques anonymes d'utilisation Langage de l'application : L'application devra être relancée pour prendre en compte le changement de langage. Divers Demander pour supprimer les désinstalleurs causants d'une tâche silencieuse Rechercher des résidus après désinstallation Créer un point de restauration avant de désinstaller Boîtes de message Activer l'exécution d'applications externes Vous pouvez spécifier des commandes qui se lanceront avant et après la désinstallation. Une ligne égale une commande et sera exécutée comme en utilisant le dialogue "Exécuter...". BCU attendra la fin de la commande courante avant d'exécuter la suivante. Applications externes &Fermer Général Outils externes Divers Réglages de Bulk Crap Uninstaller Dossiers Vous pouvez spécifier des dossiers personnalisés dans lesquels vous installez vos applications (par ex. D:\Applications). Ces dossiers seront utilisés par BCU pour chercher des vestiges de désinstallation, des applications non enregistrées et quelques autres choses. Bien que ce ne soit pas nécessaire, une liste de ces dossiers fera mieux fonctionner BCU. Les dossiers Windows par défaut sont toujours scannés, vous n'avez pas besoin de les inclure dans la liste. Utilisez des chemins complets de dossiers, un chemin par ligne. Les chemins invalides et les dossiers non-existants seront ignorés. Dossiers d'installation des programmes Charger automatiquement la liste de désinstalleurs "Default.bcul" au démarrage Activer les notes utilisateurs des applications Toujours montrer les résidus avec faible confiance Ne jamais demander les retours ou de l'aide Steam Registre (il est recommandé de laisser activé) Lecteurs (détecte les applis non enregistrées) Basé sur des règles pré-définies Chercher des applications dans... Magasins d'application à scanner Détection Applis du Windows Store Fonctionnalités Windows La détection des Fonctionnalités Windows utilise WMI et peut être lente et même échouer sur certains systèmes (indiquant d'habitude une corruption du système). Windows Update La détection de Windows Update utilise WUA, qui est lent. Cela peut prendre quelques minutes. Toujours demander pour créer Ne jamais demander pour créer Créer automatiquement dans le dossier : Sauvegarder avant la suppression des résidus Langage Interface Désinstallation Tenter de détecter automatiquement les dossiers d'installation personnalisés Réseau Oculus Store Chocolatey Scanner les lecteurs amovibles Scan pendrives, USB hard drives, SD Cards, etc. Mode daltonien Switches colors to be better for color-blind people Activer la mise à l'échelle de l'interface compatible DPI Double-cliquer dans la liste d'applications Scoop Démarrage ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/SettingsWindow.hu.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Az eltávolítás elindítása előtt végrehajtandó parancsok Az eltávolítás befejeződése után végrehajtandó parancsok Indításkor automatikusan töltse be a "Default.bcul" eltávolítási listát Frissítések keresése a program elindításakor Névtelen használati statisztika küldése Programok felhasználói értékelésének engedélyezése A program nyelve: A programot újra kell indítani, a nyelvi módosítások érvényesítéséhez. Vegyes Mindig mutatja, ha egy program kevésbé megbízható Kérdezzen rá a normál eltávolítók eltávolítására egy csendes feladatból Ne kérjen visszajelzést vagy segítséget Maradványok keresése az eltávolítást követően Visszaállítási pont készítése az eltávolítás előtt Üzenetablakok Külső alkalmazások futtatásának engedélyezése Megadhat olyan parancsokat, amelyek az eltávolítás előtt, vagy után fognak végrehajtódni. Egy sorba egy parancs kerüljön, és az úgy kerül végrehajtásra, mintha a "Futtatás..." ablakot használná. A BCU, a következő elindítása előtt megvárja amíg az adott parancs befejeződik. Külső alkalmazások &Bezárás Általános Külső eszközök Az alkalmazások telepítéséhez megadhat egyéni mappákat is (pl. D:\Applications). A BCU ezeket a mappákat is használni fogja az eltávolítás utáni maradványok, nem regisztrált alkalmazások, és egyéb nyomok felkutatásához. Bár nem szükségesek, de ezeknek a mappáknak a megadásával a BCU hatékonyabban használható. Az alapértelmezett Windows mappák mindig ellenőrzésre kerülnek, így azokat nem kell megadnia ebben a listában. Soronként egy teljes elérési útvonalat adjon meg. Az érvénytelen útvonalak, vagy nem létező mappák kihagyásra kerülnek. Programtelepítési mappák Mappák Vegyes A Bulk Crap Uninstaller beállításai Steam Oculus Store Chocolatey Színvak mód Switches colors to be better for color-blind people Felhasználó felület DPI-méretezésének engedélyezése Dupla kattintás az alkalmazáslistán Mindig kérdezze Soha ne kérdezze Automatikusan ebbe a mappába: Biztonsági mentés a maradványok eltávolítása előtt Nyelv Felület Eltávolítás A Windows-frissítések keresése a WUA-t használja, ami lassú. Több percig is eltarthat, mire befejeződik. Windows Update A Windows-szolgáltatások keresése a WMI-t használja, ami lassú. Egyes rendszereken ez a folyamat akár meg is hiúsulhat (ami általában a rendszer sérülését jelzi). Windows-szolgáltatások Microsoft Store alkalmazások Scoop Alkalmazásforrások az ellenőrzéshez Beállításjegyzékben (ajánlott) Meghajtókban (nem regisztrált alkalmazásokat észlel) Előre meghatározott szabályok alapján Alkalmazások keresése... Ellenőrzés Cserélhető meghajtók ellenőrzése Scan pendrives, USB hard drives, SD Cards, etc. Egyéni telepítési mappák automatikus felismerése Inditás Hálózat ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/SettingsWindow.it.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Riga di comando prima che la disinstallazione sia avviata Riga di comando quando la disinstallazione termina Carica automaticamente all'avvio elenco disinstallazione "Default.bcul" Cerca aggiornamenti all'avvio Invia statistiche d'uso anonime Abilita valutazioni utente delle applicazioni Lingua applicazione: Per applicare le modifiche alla lingua l'applicazione deve essere riavviata Varie Visualizza sempre i residui con basso livello di affidabilità Chiedi di rimuovere i disinstallatori guidati da una procedura silenziosa Non chiedere mai per aiuto o feedback Dopo la disinstallazione cerca i residui Prima della disinstallazione crea un punto di ripristino Riquadro messaggi Abilita esecuzione di applicazioni esterne Puoi specificare comandi che saranno eseguiti prima e dopo la disinstallazione. Una linea corrisponde ad un comando e sarà eseguita come se usassi la finestra "Esegui...". BCU attenderà il completamento del comando in esecuzione prima dell'esecuzione del successivo. Applicazioni esterne &Chiudi Generale Strumenti esterni Puoi specificare cartelle personalizzate in cui installare le applicazioni (ad es. D:\Applicazioni). Le cartelle saranno usate da BCU durante la ricerca degli oggetti residui della disinstallazione, applicazioni non registrate e altro. Anche se non necessario, un elenco di queste cartelle permetterà a BCU di lavorare meglio. Le cartelle predefinite di WIndows sono sempre controllate, non hai bisogno di includerle nell'elenco. Usa il percorso completo delle cartelle, un percorso per linea. I percorsi non validi e non esistenti saranno ignorati. Cartelle installazione programma Cartelle Varie Impostazioni Bulk Crap Uninstaller Steam Chiedi sempre per creare Non chiedere mai per creare Crea automaticamente nella cartella: Backup prima della rimozione dei residui Lingua Interfaccia Disinstallazione Registro (si raccomanda di lasciarlo abilitato) Dischi (rilevamento applicazioni non registrate) Basato su regole predefinite Cerca applicazioni in... App di Windows Store Funzionalità di Windows Il rilevamento di funzionalità di Windows usa WMI, può quindi essere lento o persino fallire in alcuni sistemi (generalmente indica una corruzione del sistema). Windows Update Il rilevamento di Windows Update usa WUA, che è lento. Potrebbe essere completato in alcuni minuti. Archivi applicazioni da scansionare Rilevamento Prova a rilevare automaticamente la cartella di installazione personalizzata Rete Oculus Store Chocolatey Modalità per daltonici Switches colors to be better for color-blind people Scansiona dischi rimovibili Scan pendrives, USB hard drives, SD Cards, etc. Abilita ridimensionamento interfaccia sensibile ai DPI Scoop Avvio Doppio clic nell'elenco delle applicazioni ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/SettingsWindow.ja.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 アンインストール開始前のコマンドライン アンインストール終了後のコマンドライン バリアフリーカラーモード (色盲の方に配慮した色に切り替えます) Switches colors to be better for color-blind people DPI対応インターフェーススケーリングを有効にする アプリケーションリストでのダブルクリック その他 起動時に「Default.bcul」という名前のアンインストールリストを自動的に読み込む アプリケーションのユーザー評価を有効にする 起動時にアップデートを確認 匿名の使用統計を送信 アプリケーション言語: 言語変更を反映させるには、アプリケーションを再起動する必要があります。 作成時、常に確認 作成時、確認しない 自動的にディレクトリに作成: 残留物を削除する前にバックアップ 信頼度の低いジャンクを常に表示 静かなタスクから騒音アンインストーラーを削除するか確認 フィードバックやヘルプを求めない アンインストール後にジャンクを検索 アンインストール前に復元ポイントを作成 メッセージボックス 外部アプリケーションの実行を有効にする アンインストールの前後に実行するコマンドを指定できます。1行が1コマンドに相当し、「実行...」ダイアログを使用したかのように実行されます。 現在実行中のコマンドが完了するまでBCUは次のコマンドの実行を待ちます。 外部アプリケーション &閉じる 一般 言語 インターフェース アンインストール Windowsアップデートの検出にはWUAを使用しており、これが遅い場合があります。完了するまでに数分かかることがあります。 Windowsアップデート Windows機能の検出にはWMIを使用しており、一部のシステムでは遅くなったり、失敗したりすることがあります(通常はシステムの破損を示しています)。 Windowsの機能 Windowsストアアプリ Steam Scoop Oculusストア Chocolatey スキャンするアプリケーションストア レジストリ(有効のままにすることを推奨) ドライブ(登録されていないアプリを検出) 定義済みのルールに基づく ...でアプリケーションを検索 検出 外部ツール リムーバブルドライブをスキャン Scan pendrives, USB hard drives, SD Cards, etc. カスタムインストールフォルダーを自動的に検出しようとします。 アプリケーションをインストールするカスタムフォルダー(例:D:\Applications)を指定できます。これらのフォルダーは、BCUがアンインストールの残骸や未登録アプリケーション、その他のいくつかの項目を検索する際に使用されます。必須ではありませんが、これらのフォルダーのリストを提供することで、BCUの機能が向上します。 デフォルトのWindowsフォルダーは常にスキャンされるため、このリストに含める必要はありません。 完全なディレクトリパスを使用し、1行につき1つのパスを指定してください。無効なパスや存在しないディレクトリは無視されます。 プログラムインストールフォルダー フォルダー スタートアップ ネットワーク その他 Bulk Crap Uninstaller 設定 ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/SettingsWindow.nl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Div. Automatisch openen lijst "Default.bcul" tijdens het starten Zoeken naar updates tijdens het starten Anonieme gebruikers statistieken sturen Inschakelen gebruikers waarderingen van programma's Taal: Het programma moet opnieuw worden gestart, om de taal wijziging te gebruiken. Bericht vensters Rommel dat u niet vertrouwt altijd weergeven Vragen of normale de-installers uit de lijst met stille de-installers moet worden verwijderd Vraag nooit om feedback of hulp Na de-installatie zoeken naar programma restanten Voor de-installatie een herstelpunt maken Externe programma's Uitvoeren van externe programma's toestaan Sluiten Algemeen Steam Windows Store apps Windows onderdelen De detectie van Windows onderdelen gebruikt WMI en kan traag zijn of zelfs mislukken op sommige systemen (meestal een gevolg van systeem corruptie). Windows update Detectie van Windows updates gebruikt WUA, wat traag verloopt. Dit kan enkele minuten duren tot het is afgerond. Programma opslaan om te scannen Detectie Externe gereedschappen Mappen Diversen Programma installatie map Bulk Crap Uninstaller instellingen Dubbelklikken in applicatielijst Opdrachtregel voordat de de-installatie start Opdrachtregel nadat de de-installatie is voltooid U kunt opdrachten opgeven die voor en/of na de de-installatie worden uitgevoerd. Op elke regel één opdracht en deze wordt dan uitgevoerd alsof u de dialoog "Uitvoeren..." zou gebruiken. BCU wacht tot de momenteel uitgevoerde opdracht is voltooid, voordat de volgende wordt uitgevoerd. U kunt aangepaste mappen opgeven, waarin u uw programma's heeft geïnstalleerd (bijv. D:\Programmas). Deze mappen worden door BCU gebruikt om te zoeken naar de-installatie van restanten, ongeregistreerde programma's en andere zaken. Ofschoon niet noodzakelijk, laat een lijst met dergelijke mappen BCU beter functioneren. De standaard Windows mappen worden altijd gescand, deze hoeven niet opgenomen te worden in genoemde lijst. Gebruik volledige map paden, één pad per regel. Ongeldige paden en niet bestaande mappen zullen worden genegeerd. Register (aanbevolen om ingeschakeld te laten) Schijven (detecteert niet geregistreerde apps) Gebasseerd op vooraf gedefinieerde regels Zoeken naar programma's in... Proberen aangepaste installatiemappen te detecteren Altijd vragen om te maken Nooit vragen om te maken Maak automatisch in de map: Back-up alvorens restanten te verwijderen Taal Interface De-installatie Oculus Store Chocolatey Netwerk Kleurenblind modus Switches colors to be better for color-blind people Scan verwijderbare schijven Scan pendrives, USB hard drives, SD Cards, etc. DPI-bewuste interface-schaling inschakelen Opstart Scoop ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/SettingsWindow.pl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Komendy do wykonania przed dezinstalacją Komendy do wykonania po dezinstalacji Szukaj uaktualnień po starcie aplikacji Wysyłaj anonimowe statystyki Język aplikacji Aby dokończyć zmianę języka będzie wymagane ponownie uruchomienie aplikacji. Pozostałe Zapytaj czy usunąć głośne dezinstalatory z cichego zadania Nigdy nie proś o tworzenie Szukaj pozostałości po dezinstalacji Utwórz punkt przywracania Okna komunikatów Włącz uruchamianie zewnętrznych aplikacji Możesz określić komendy które zostaną wykonane przed i po dezinstalacji. Jedna linia zawiera jedną komendę, która zostanie wykonana tak jak przez okno "Uruchom...". BCU będzie czekać aż uruchomiona komenda zakończy pracę przed uruchomieniem następnej. Zewnętrzne aplikacje &Zamknij Ogólne Narzedzia zewnetrzne Różne Ustawienia BCUninstaller Możesz określić niestandardowe foldery instalacji aplikacji (np D: \ Aplikacje). Lista ta będzie wykorzystywana przez BCU do wyszukiwania resztek po dezinstalacji, niezarejestrowanych aplikacji, i kilku innych rzeczy. O ile nie jest ona konieczna, lista tych folderach usprawni działanie BCU. Domyślne foldery systemu Windows są zawsze zawarte przeszukiwane, nie musisz ich dodawać. Użyj pełnych ścieżek folderów, jedna ścieżka na linię. Nieprawidłowe ścieżki i nieistniejące foldery będą ignorowane. Foldery instalacji programów Foldery Automatycznie otwórz listę "Default.bcul" na starcie Włącz oceny użytkowników dla aplikacji Zawsze proś o utworzenie Zawsze pokazuj śmieci z niskim wynikiem Nigdy nie pytaj o opinię lub pomoc Steam Aplikacje Windows Store Funkcje systemu Windows Wykrywanie funkcji systemu Windows wykorzystuje WMI i może działać wolno, lub nawet wcale na niektórych systemach (zwykle oznacza to uszkodzenie systemu). Aktualizacje systemu Windows Wykrywanie aktualizacji systemu Windows używa technologii WUA, która działa wolno. Skanowanie może potrwać kilka minut. Typy aplikacji do skanowania Wykrywanie Rejestr (zalecane włączenie) Dyski (wykrywa niezarejestrowane programy) Ręcznie sprecyzowane sygnatury Szukwaj aplikacji w... Spróbuj wykryć niestandardowe foldery z programami automatycznie Utwórz automatycznie w katalogu: Twórz kopię zapasową przed usunięciem Język Interfejs Dezinstalacja Sieć Oculus Store Chocolatey Tryb dla daltonistów Switches colors to be better for color-blind people Skanuj napędy przenośne Scan pendrives, USB hard drives, SD Cards, etc. ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/SettingsWindow.pt-BR.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Linha de comando antes do início da desinstalação Linha de comando após o fim da desinstalação Carregue automaticamente a Lista de desinstalação chamada "Default.bcul" no início Habilitar classificações de usuários de aplicativos Procure por atualizações na inicialização Enviar estatísticas anônimas de uso Diversos Idioma do aplicativo: O aplicativo terá que ser reiniciado para que a alteração de idioma entre em vigor. Sempre pergunte para criar Nunca pergunte para criar Crie automaticamente no diretório: Backup antes da remoção de sobras Sempre exibir sobras com baixo nível de confiança Perguntar para remover desinstaladores fortes de uma tarefa silenciosa Nunca pedir comentários ou ajuda Procurar sobras após a desinstalação Criar ponto de restauração antes de desinstalar Caixas de mensagens Habilitar a execução de aplicativos externos Você pode especificar comandos que serão executados antes e depois da desinstalação. Uma linha é igual a um comando e será executada como se você usasse a caixa de diálogo "Executar...". O BCU aguardará até que o comando em execução seja finalizado antes de executar o próximo. Aplicações externas &Fechar Geral Idioma Interface Desinstalação Registro (recomendado deixar ativado) Drives (detecta aplicativos não registrados) Com base em regras pré-definidas Procurar aplicativos em... Steam Apps da Window Store Recursos do Windows A detecção de recursos do Windows usa WMI e pode ser lenta ou mesmo falhar em alguns sistemas (geralmente indicando corrupção do sistema). Windows Update A detecção de atualizações do Windows usa a WUA, que é lenta. Pode demorar alguns minutos para ser concluído. Armazenamento de aplicativos para examinar Detecção Ferramentas externas Você pode especificar pastas personalizadas nas quais você instalou seus aplicativos (por exemplo, D: \ Applications). Essas pastas serão usadas pelo BCU para procurar sobras de desinstalação, aplicativos não registrados e algumas outras coisas. Embora não seja necessário, uma lista dessas pastas permitirá que o BCU funcione melhor. As pastas padrão do Windows são sempre examinadas, você não precisa incluí-las nesta lista. Use caminhos de diretório completo, um caminho por linha. Caminhos inválidos e diretórios não existentes serão ignorados. Tente detectar automaticamente as pastas de instalação personalizadas Pastas de instalação dos programas Pastas Diversos Configurações do Bulk Crap Uninstaller Oculus Store Chocolatey Modo para daltônicos Switches colors to be better for color-blind people Habilitar escalonamento de interface com DPI Clique duplo na lista de aplicação Scoop Escanear armazenamentos externos Scan pendrives, USB hard drives, SD Cards, etc. Inicializar Rede ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/SettingsWindow.pt.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Linha de comando antes do início da desinstalação Linha de comando após o fim da desinstalação Carregamento automático no início da lista de desinstalação "Default.bcul". Verificar actualizações no arranque. Enviar estatísticas anónimas de utilização Permitir avaliações do utilizador das aplicações Idioma da aplicação: A aplicação terá de ser reiniciada para que a alteração do idioma tenha efeito. Diversos Pedir para remover desinstaladores activos de uma tarefa em segundo plano. Procurar lixo após a desinstalação Criar um ponto de restauro antes da desinstalação Caixas de mensagens Permitir a execução de aplicações externas. Pode especificar comandos que serão executados antes e após a desinstalação. Uma linha é igual a um comando e este será executado como se você usasse a caixa de diálogo "Executar ...". O BCU vai esperar até que o comando actualmente em execução esteja concluído antes de executar o próximo. Aplicações externas &Fechar Geral Ferramentas externas Pode especificar pastas personalizadas onde instalará as suas aplicações (por exemplo, D: \ Applicações). Essas pastas serão utilizadas pela BCU para procurar restos da desinstalação, aplicações não registada e algumas coisas mais. Embora não seja necessário, uma lista dessas pastas vai permitir que o BCU tenha um melhor desempenho. As pastas padrão Windows são sempre verificadas, não precisa de as incluir na lista. Utilize caminhos de diretório completos, um caminho por linha. Caminhos inválidos e diretórios inexistentes serão ignorados. Pastas de instalação dos programas Pastas Diversos Configurações do Bulk Crap Uninstaller Mostra sempre que um determinado programa não é de confiança. Nunca pedir comentários ou ajuda. Steam Apps da Window Store Componentes do Windows A detecção de recursos do Windows é feita pelo WMI e pode ser lenta ou mesmo falhar em alguns sistemas (geralmente indicando corrupção do sistema). Actualização do Windows A detecção das actualizações do Windows é feita pelo WUA, que é lento. Pode levar alguns minutos até estar concluído. Armazenamento de aplicativos para digitalizar Detecção Registo (é recomendável deixá-lo activo) Drives (detecta aplicativos não registados) Com base em regras pré-definidas Procurar aplicativos em... Oculus Store Chocolatey 17, 17 True ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/SettingsWindow.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Fill True 7, 145 4, 3, 4, 3 Horizontal Fill 0, 21 4, 3, 4, 3 True 412, 109 1 textBoxPreUninstall System.Windows.Forms.TextBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 splitContainer1.Panel1 0 True Top NoControl 0, 0 4, 0, 4, 0 1, 3, 4, 3 234, 21 0 Command line before uninstallation starts label5 System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 splitContainer1.Panel1 1 splitContainer1.Panel1 System.Windows.Forms.SplitterPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 splitContainer1 0 Fill 0, 21 4, 3, 4, 3 True 412, 111 1 textBoxPostUninstall System.Windows.Forms.TextBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 splitContainer1.Panel2 0 True Top NoControl 0, 0 4, 0, 4, 0 1, 3, 4, 3 221, 21 0 Command line after uninstallation ends label6 System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 splitContainer1.Panel2 1 splitContainer1.Panel2 System.Windows.Forms.SplitterPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 splitContainer1 1 416, 275 134 5 1 splitContainer1 System.Windows.Forms.SplitContainer, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBoxExternal 0 True True True NoControl 6, 3 4, 3, 4, 3 121, 19 1 Color-blind mode checkBoxColorblind System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel3 0 True 5, 28 207, 19 2 Enable DPI-aware interface scaling checkBoxDpiaware System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel3 1 Fill TopDown 4, 46 4, 3, 4, 3 2, 0, 2, 2 405, 52 0 flowLayoutPanel3 System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBoxMisc 0 True Right 260, 0 4, 3, 4, 3 139, 23 1 comboBoxDoubleClick System.Windows.Forms.ComboBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel5 0 True Left NoControl 6, 0 4, 0, 4, 0 0, 3, 0, 0 182, 18 0 Double clicking in application list label3 System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel5 1 Top 4, 19 4, 3, 4, 3 117, 27 6, 0, 6, 0 405, 27 1 panel5 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBoxMisc 1 Top 4, 374 4, 3, 4, 3 4, 3, 4, 3 413, 101 1 Misc groupBoxMisc System.Windows.Forms.GroupBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tabPageInterface 0 True NoControl 4, 3 4, 3, 4, 3 356, 19 0 Automatically load Uninstall List named "Default.bcul" on start checkBoxAutoLoad System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel4 0 True NoControl 4, 53 4, 3, 4, 3 206, 19 2 Enable user ratings of applications checkBoxRatings System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel10 2 True NoControl 4, 3 4, 3, 4, 3 181, 19 0 Search for updates on startup checkBoxUpdateSearch System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel10 0 True NoControl 4, 28 4, 3, 4, 3 200, 19 1 Send anonymous usage statistics checkBoxSendStats System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel10 1 True Fill 136, 0 4, 3, 4, 3 263, 23 1 comboBoxLanguage System.Windows.Forms.ComboBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel3 0 True Left NoControl 6, 0 4, 0, 4, 0 0, 3, 7, 0 130, 18 0 Application language: label9 System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel3 1 Top 4, 56 4, 3, 4, 3 117, 27 6, 0, 6, 0 405, 27 1 panel3 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBoxLanguage 0 True Top NoControl 4, 19 4, 0, 4, 0 420, 0 0, 2, 0, 5 393, 37 0 The application will have to be restarted for the language change to take effect. label10 System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBoxLanguage 1 True True Top 4, 94 5, 3, 5, 3 116667, 25 12, 25 23, 0, 6, 0 397, 25 3 directorySelectBoxBackup Klocman.Controls.DirectorySelectBox, KlocTools, Culture=neutral, PublicKeyToken=null groupBoxBackup 0 True GrowAndShrink True NoControl 4, 3 4, 3, 4, 3 131, 19 0 Always ask to create radioButtonBackupAsk System.Windows.Forms.RadioButton, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel9 0 True NoControl 4, 28 4, 3, 4, 3 125, 19 1 Never ask to create radioButtonBackupNever System.Windows.Forms.RadioButton, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel9 1 True NoControl 4, 53 4, 3, 4, 3 200, 19 2 Create automatically in directory: radioButtonBackupAuto System.Windows.Forms.RadioButton, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel9 2 Top 4, 19 4, 3, 4, 3 397, 75 2 flowLayoutPanel9 System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBoxBackup 1 Top 4, 150 4, 3, 4, 3 4, 3, 4, 8 405, 127 2 Backup before leftover removal groupBoxBackup System.Windows.Forms.GroupBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBoxMessages 0 True GrowAndShrink True NoControl 6, 3 4, 3, 4, 3 230, 19 0 Always show junk with low confidence checkBoxShowAllBadJunk System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel1 0 True NoControl 6, 28 4, 3, 4, 3 284, 19 1 Ask to remove loud uninstallers from a quiet task checkBoxLoud System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel1 1 True NoControl 6, 53 4, 3, 4, 3 186, 19 3 Never ask for feedback or help checkBoxNeverFeedback System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel1 2 Top TopDown 4, 73 4, 3, 4, 3 2, 0, 2, 2 405, 77 2 False flowLayoutPanel1 System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBoxMessages 1 True Right 318, 0 4, 3, 4, 3 81, 23 1 comboBoxJunk System.Windows.Forms.ComboBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel1 0 True Left NoControl 6, 0 4, 0, 4, 0 0, 3, 0, 0 178, 18 0 Search for junk after uninstalling label1 System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel1 1 Top 4, 46 4, 3, 4, 3 117, 27 6, 0, 6, 0 405, 27 1 panel1 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBoxMessages 2 True Right 318, 0 4, 3, 4, 3 81, 23 1 comboBoxRestore System.Windows.Forms.ComboBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel2 0 True Left NoControl 6, 0 4, 0, 4, 0 0, 3, 0, 0 213, 18 0 Create restore point before uninstalling label2 System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel2 1 Top 4, 19 4, 3, 4, 3 117, 27 6, 0, 6, 0 405, 27 0 panel2 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBoxMessages 3 Top 4, 94 4, 3, 4, 3 4, 3, 4, 3 413, 280 1 Message boxes groupBoxMessages System.Windows.Forms.GroupBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tabPageInterface 1 True True Top NoControl 7, 121 4, 3, 4, 3 2, 0, 0, 5 416, 24 0 Enable execution of external applications checkBoxEnableExternal System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBoxExternal 1 True True Top NoControl 0, 0 0, 0, 0, 0 0, 0, 0, 9 411, 99 0 You can specify commands that will run before and after uninstallation. One line equals to one command and will be executed as if you used the "Run..." dialog. BCU will wait until the currently running command completes before executing the next one. label7 System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel2 0 Top TopDown 7, 22 4, 3, 4, 3 416, 99 0 flowLayoutPanel2 System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBoxExternal 2 Fill 4, 3 4, 3, 4, 3 7, 6, 7, 7 430, 427 0 External applications groupBoxExternal System.Windows.Forms.GroupBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tabPageExternal 0 Bottom, Right NoControl 349, 12 4, 3, 4, 3 88, 27 0 &Close button2 System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel4 0 True GrowAndShrink Fill 4, 3 5, 3, 5, 3 198, 196 430, 407 0 propertiesSidebar1 BulkCrapUninstaller.Controls.PropertiesSidebar, BCUninstaller, Culture=neutral, PublicKeyToken=null tabPageGeneral 0 4, 44 4, 3, 4, 3 4, 3, 4, 3 438, 413 2 General tabPageGeneral System.Windows.Forms.TabPage, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tabControl 0 True True Top 4, 3 4, 3, 4, 3 4, 3, 4, 8 413, 91 0 Language groupBoxLanguage System.Windows.Forms.GroupBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tabPageInterface 2 4, 24 4, 3, 4, 3 4, 3, 4, 3 438, 433 6 Interface tabPageInterface System.Windows.Forms.TabPage, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tabControl 1 True True GrowAndShrink Fill 4, 3 5, 3, 5, 3 430, 427 0 uninstallationSettings1 BulkCrapUninstaller.Controls.UninstallationSettings, BCUninstaller, Culture=neutral, PublicKeyToken=null tabPageUninstallation 0 4, 24 4, 3, 4, 3 4, 3, 4, 3 438, 433 4 Uninstallation tabPageUninstallation System.Windows.Forms.TabPage, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tabControl 2 True True True Top Microsoft Sans Serif, 8.25pt, style=Italic NoControl 4, 206 4, 0, 4, 0 420, 0 18, 0, 0, 7 411, 33 7 Detection of Windows Updates uses WUA, which is slow. It can take a couple of minutes to complete. labelWinUpdateInfo System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBoxAppStores 0 True Top NoControl 4, 184 4, 3, 4, 3 4, 0, 4, 3 422, 22 6 Windows Update checkBoxScanWinUpdates System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBoxAppStores 1 True Top Microsoft Sans Serif, 8.25pt, style=Italic NoControl 4, 151 4, 0, 4, 0 420, 0 18, 0, 0, 7 410, 33 5 Detection of Windows Features uses WMI, and can be slow or even fail on some systems (usually indicating system corruption). labelWinFeatureInfo System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBoxAppStores 2 True Top NoControl 4, 129 4, 3, 4, 3 4, 0, 4, 3 422, 22 4 Windows Features checkBoxScanWinFeatures System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBoxAppStores 3 True Top NoControl 4, 107 4, 3, 4, 3 4, 0, 4, 3 422, 22 3 Windows Store Apps checkBoxScanStoreApps System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBoxAppStores 4 True Top NoControl 4, 85 4, 3, 4, 3 4, 0, 4, 3 422, 22 2 Steam checkBoxScanSteam System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBoxAppStores 5 True Top NoControl 4, 63 4, 3, 4, 3 4, 0, 4, 3 422, 22 8 Scoop checkBoxScoop System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBoxAppStores 6 True Top NoControl 4, 41 4, 3, 4, 3 4, 0, 4, 3 422, 22 1 Oculus Store checkBoxOculus System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBoxAppStores 7 True Top NoControl 4, 19 4, 3, 4, 3 4, 0, 4, 3 422, 22 0 Chocolatey checkBoxChoco System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBoxAppStores 8 Top 4, 100 4, 3, 4, 3 4, 3, 4, 3 430, 242 1 Application stores to scan groupBoxAppStores System.Windows.Forms.GroupBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tabPageDetection 0 True GrowAndShrink True GrowAndShrink True NoControl 4, 3 4, 3, 4, 3 246, 19 0 Registry (recommended to leave enabled) checkBoxScanRegistry System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel7 0 True NoControl 4, 28 4, 3, 4, 3 204, 19 1 Drives (detects unregistered apps) checkBoxScanDrives System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel7 1 True NoControl 4, 53 4, 3, 4, 3 167, 19 2 Based on pre-defined rules checkBoxPreDefined System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel7 2 Top 4, 19 4, 3, 4, 3 422, 75 0 flowLayoutPanel7 System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBox1 0 Top 4, 3 4, 3, 4, 3 4, 3, 4, 3 430, 97 0 Search for applications in... groupBox1 System.Windows.Forms.GroupBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tabPageDetection 1 4, 24 4, 3, 4, 3 4, 3, 4, 3 438, 433 5 Detection tabPageDetection System.Windows.Forms.TabPage, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tabControl 3 4, 24 4, 3, 4, 3 4, 3, 4, 3 438, 433 1 External tools tabPageExternal System.Windows.Forms.TabPage, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tabControl 4 True Fill 7, 227 4, 3, 4, 3 True 416, 193 3 textBoxProgramFolders System.Windows.Forms.TextBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBoxProgramFolders 0 True Top NoControl 7, 202 4, 3, 4, 3 18, 3, 4, 3 416, 25 2 Scan removable drives checkBoxRemovable System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBoxProgramFolders 1 True Top NoControl 7, 177 4, 3, 4, 3 4, 3, 4, 3 416, 25 1 Try to detect custom installation folders automatically checkBoxAutoInstallFolderDetect System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBoxProgramFolders 2 True Top NoControl 7, 22 0, 0, 0, 0 420, 0 0, 0, 0, 5 420, 155 0 You can specify custom folders you install your applications into (e.g. D:\Applications). Those folders will be used by BCU to search for uninstallation leftovers, unregistered applications and a few other things. While it is not necessary, a list of these folders will let BCU work better. The default Windows folders are always scanned, you do not need to include them in this list. Use full directory paths, one path per line. Invalid paths and non-existing directories will be ignored. labelProgramFolders System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBoxProgramFolders 3 Fill 4, 3 4, 3, 4, 3 7, 6, 7, 7 430, 427 0 Program installation folders groupBoxProgramFolders System.Windows.Forms.GroupBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tabPageFolders 0 4, 24 4, 3, 4, 3 4, 3, 4, 3 438, 433 3 Folders tabPageFolders System.Windows.Forms.TabPage, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tabControl 5 True GrowAndShrink Top 4, 145 5, 3, 5, 3 430, 211 2 cacheSettings1 BulkCrapUninstaller.Controls.Settings.CacheSettings, BCUninstaller, Culture=neutral, PublicKeyToken=null tabPageMisc 0 True GrowAndShrink True Top TopDown 3, 18 3, 2, 3, 2 424, 25 0 flowLayoutPanel4 System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBox2 0 Top 4, 100 3, 2, 3, 2 3, 2, 3, 2 430, 45 3 Startup groupBox2 System.Windows.Forms.GroupBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tabPageMisc 1 True GrowAndShrink True GrowAndShrink Top TopDown 4, 19 4, 3, 4, 3 422, 75 0 False flowLayoutPanel10 System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBox3 0 Top 4, 3 4, 3, 4, 3 4, 3, 4, 3 430, 97 0 Network groupBox3 System.Windows.Forms.GroupBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tabPageMisc 2 4, 44 4, 3, 4, 3 4, 3, 4, 3 438, 413 0 Miscellaneous tabPageMisc System.Windows.Forms.TabPage, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tabControl 6 Fill 7, 7 4, 3, 4, 3 446, 461 0 tabControl System.Windows.Forms.TabControl, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 0 Bottom 7, 468 4, 3, 4, 3 446, 46 1 panel4 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 1 17, 17 True 7, 15 460, 521 4, 3, 4, 3 7, 7, 7, 7 CenterParent Bulk Crap Uninstaller Settings usageTracker1 BulkCrapUninstaller.Functions.Tracking.UsageTracker, BCUninstaller, Culture=neutral, PublicKeyToken=null SettingsWindow System.Windows.Forms.Form, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/SettingsWindow.ru.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Командная строка до деинсталляции Командная строка после деинсталляции Автозагрузка списка деинсталляции "Default.bcul" при запуске Поиск обновлений при запуске Отправлять анонимную статистику Включить пользовательский рейтинг приложений Язык приложения: Приложение надо перезапустить, чтобы изменения языка вступили в силу. Разное Запрос отключения громких деинсталляторов из тихих задач Искать мусор после деинсталляции Создать точку восстановления перед удалением Окна сообщений Включить выполнение внешних приложений Можно указать команды, которые будут выполняться до и после удаления. Одна линия равна одной команде и будет выполняться, как через диалог «Выполнить...». BCU будет ждать завершения одной команды для начала выполнения следующей. Внешние приложения &Закрыть Общие Внешние инструменты Можно задать пользовательские папки установки приложений (например, D:\Applications). Эти папки будут использоваться BCU для поиска и удаления остатков незарегистрированных приложений и некоторых других вещей. Хотя это необязательно, со списком таких папок BCU будет работать лучше. По умолчанию папки Windows всегда проверяются, Вам не нужно включать их в этот список. Используйте полный путь каталога, один путь на строку. Недопустимые пути и несуществующие каталоги будут игнорироваться. Папки установки программ Папки Прочее Настройки Bulk Crap Uninstaller Всегда показывать мусорные с низким рейтингом Никогда не просить отзыв или помощь Steam Реестр (рекомендуется оставить включенным) Диски (обнаружение незарегистрированных приложений) Основываясь на предопределённых правилах Поиск приложений в... Места с приложениями для сканирования Обнаружение Приложения Windows Store Функции Windows Обнаружение функций Windows использует WMI и может быть медленным или даже неработоспособным в некоторых системах (обычно это указывает на повреждение системы). Обновления Windows Обнаружение обновлений Windows использует WUA, что происходит медленно. Это может занять пару минут. Попытатся автоопределить папки с приложениями Всегда спрашивать о создании Никогда не спрашивать о создании Создавать автоматически в каталоге: Резервное копирование перед удалением остатков Язык Интерфейс Деинсталляция Сеть Oculus Store Chocolatey Сканировать извлекаемые носители Scan pendrives, USB hard drives, SD Cards, etc. Scoop (консольный установщик) Режим цветовой слепоты (для дальтоников) Switches colors to be better for color-blind people масштабирование интерфейса с учётом DPI 17, 17 True ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/SettingsWindow.sl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Ukazna vrstica pred začetkom odstranjevanja Ukazna vrstica po koncu odstranjevanja Ob zagonu, samodejno naloži seznam odstranjevanja "Default.bcul" Ob zagonu, pošči posodobitve Pošlji anonimno statistiko uporabe Jezik aplikacije: Za spremembo jezika morate ponovno zagnati aplikacijo. Razno Vprašaj za odstranjevanje glasnih odstranjevalcev iz tihega opravila Po odstranjevanju poišči neuporabne datoteke Pred odstranjevanjem ustvari obnovitveno točko Sporočilna okna Omogoči izvajanje zunanjih aplikacij Lahko določite ukaze, ki bodo zagnani pred, ali po odstranjevanju. Ena vrstica je enaka enemu ukazu in bo izvedena kot, če bi uporabili pogovorno okno "Zaženi...". BCU bo počakal, da se trenutno delujoč ukaz konča preden izvede naslednjega. Zunanje aplikacije &Zapri Splošno Zunanja orodja Lahko določite mape po meri, kamor boste namestili vaše aplikacije (npr. D:\Aplikacije). Te mape bo BCU uporabil za iskanje ostankov odstranjevanja, neregistriranih aplikacij in še nekaj drugih stvari. Čeprav to ni potrebno, bo seznam teh datotek omogočil boljše delo BCU. Privzete se Windows mape vedno pregledujejo. Ni jih potrebno vključiti na seznam. Uporabite polne poti imenikov, eno pot na vrstico. Neveljavne poti in neobstoječi imeniki bodo prezrti. Mape namestitve programa Mape Razno Nastavitve BCUninstallerja Omogoči uporabnikove ocene aplikacij Vedno pokaži smeti z nizko oceno Nikoli ne prosi za pomoč Steam Register (priporočeno, da pustite omogočeno) Pogoni (zaznava neregistrirane aplikacije) Temelji na pred določnih pravilih Poišči aplikacije v... Shranjena aplikacija za pregled Odkrivanje Windows Store aplikacije Lastnosti sistema Windows Odkrivanje funkcij Windows uporablja WMI in je lahko v nekaterih sistemih počasno ali celo neuspešno (ponavadi kaže na okvaro sistema). Posodobitev Windows Odkrivanje posodobitev Windows uporablja WUA, kar je počasno. Za dokončanje lahko vzame nekaj minut časa, Poskusi samodejno odkriti namestitvene mape po meri Vedno vprašaj za ustvarjanje Nikoli ne vprašaj za ustvarjanje Samodejno ustvari v imeniku: Varnostno kopiraj pred odstranjevanjem ostankov Jezik Vmesnik Odstranjevanje Omrežje Oculus Store Chocolatey Preišči odstranljive diske Scan pendrives, USB hard drives, SD Cards, etc. 17, 17 True ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/SettingsWindow.sv.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Kommando innan avinstallationen startar Kommando efter avinstallationen avslutas Färgblind läge Switches colors to be better for color-blind people Aktivera DPI-anpassning för gränssnittsskalning Dubbelklicka i applistan Övrigt Automatisk laddning av avinstallationslista med namnet "Default.bcul" vid start Aktivera användarbedömningar av appar Sök efter uppdateringar vid start Skicka anonym användningsstatistik Appspråk: Appen måste startas om för att språkändringen ska träda i kraft Fråga alltid om att skapa Fråga aldrig om att skapa Skapa automatiskt i mapp: Säkerhetskopiera innan borttagning av rester Visa alltid skräp med låg tillförlitlighet Fråga om att ta bort synliga avinstallationsprogram från en tyst uppgift Fråga aldrig efter feedback eller hjälp Sök upp skräp efter avinstallation Skapa återställningspunkt innan avinstallation Dialogrutor Aktivera körning av externa appar Du kan ange kommandon som ska köras före och efter avinstallationen. En rad motsvarar ett kommando och kommer att köras som om du använde dialogrutan "Kör...". BCU kommer att vänta tills det aktuella kommandot är klart innan det kör nästa. Externa appar &Stäng Allmänt Språk Gränssnitt Avinstallation Upptäckt av Windows-uppdateringar använder WUA, vilket är långsamt. Det kan ta några minuter att slutföra. Windows Update Upptäckt av Windows-funktioner använder WMI och kan vara långsam eller till och med misslyckas på vissa system (vilket vanligtvis indikerar systemkorruption). Windows Funktioner Windows Store Appar Steam Scoop Oculus Store Chocolatey Applikationsbutiker att skanna Register (rekommenderas att lämna aktiverat) Enheter (upptäcker oregistrerade appar) Baserat på fördefinierade regler Sök efter appar i... Upptäckt Externa verktyg Skanna flyttbara enheter Scan pendrives, USB hard drives, SD Cards, etc. Försök att automatiskt upptäcka anpassade installationsmappar Du kan ange anpassade mappar där du installerar dina appar (t.ex. D:\Program). Dessa mappar kommer att användas av BCU för att söka upp rester efter avinstallation, oregistrerade appar och några andra saker. Även om det inte är nödvändigt, kommer en lista över dessa mappar, göra att BCU fungerar bättre. Standard-Windows-mapparna skannas alltid, du behöver inte inkludera dem i denna lista. Använd fullständiga sökvägar, en sökväg per rad. Ogiltiga sökvägar och icke-existerande mappar kommer att ignoreras. Programinstallationsmappar Mappar Uppstart Nätverk Övrigt Bulk Crap Uninstaller Inställningar ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/SettingsWindow.tr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Kaldırma işleminden önce komut satırı Kaldırma sona erdikten sonra komut satırı Başlangıçta "Default.bcul" adlı Kaldırma Listesini otomatik olarak yükle Renk körü modu Switches colors to be better for color-blind people Çeşitli Uygulamaların kullanıcı derecelendirmelerini etkinleştir Başlangıçta güncellemeleri denetle Anonim kullanım istatistikleri gönder Uygulama dili: Dil değişikliğinin etkili olması için uygulamanın yeniden başlatılması gerekir. Mesaj kutusu Arta kalan kaldırma işleminden önce yedekleme Oluşturmak için her zaman sor Oluşturmak için asla sorma Dizinde otomatik olarak oluştur: Önemsiz olanları her zaman düşük güvenli olarak göster Kaldırmak için sessiz modu veya normal modu seçin Geribildirim veya yardım için asla sorma Kaldırdıktan sonra kalıntıları tara Kaldırmadan önce geri yükleme noktası oluştur Harici uygulamalar Harici uygulamaların yürütülmesini etkinleştir Kaldırma işleminden önce ve sonra çalışacak komutları belirtebilirsiniz. Bir satır bir komuta eşittir ve "Çalıştır ..." iletişim kutusunu kullanmış gibi yürütülür. BCU, o sırada çalışan komutun bir sonraki çalıştırılmadan önce tamamlanmasını bekleyecektir. &Kapat Genel Arabirim Kaldırma Tespit Harici araçlar Klasörler Çeşitli Dil Tarama için uygulama depoları Windows Güncellemelerinin Saptanması, yavaş olan WUA kullanır. Tamamlanması birkaç dakika sürebilir. Windows güncelleme Windows Özelliklerinin Algılanması WMI'yi kullanır ve bazı sistemlerde yavaş ve hatta başarısız olabilir (genellikle sistem bozulmasını gösterir). Pencere özellikleri Windows Mağazası Uygulamaları Akış Oculus Mağazası Chocolatey Uygulamalarda ara ... Kayıt defteri (izinli kalması önerilir) Sürücüler (kayıtsız uygulamaları algılar) Önceden belirlenmiş kurallara göre Program yükleme klasörleri Çıkarılabilir sürücüleri tara Scan pendrives, USB hard drives, SD Cards, etc. Özel yükleme klasörlerini otomatik olarak algılamaya çalışın Uygulamalarınızı yüklediğiniz özel klasörleri belirtebilirsiniz (ör. D: \ Uygulamalar). Bu klasörler BCU tarafından kaldırım artıkları, kayıt dışı uygulamalar ve birkaç başka şey aramak için kullanılacaktır. Gerekli olmasa da, bu klasörlerin bir listesi BCU'nun daha iyi çalışmasına izin verecektir. Toplu Düzeltme Kaldırıcı Ayarları DPI farkındalı arayüz ölçeklendirmeyi etkinleştirin Uygulama listesinde çift tıklama Kazıma Başlangıç ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/SettingsWindow.vi.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Câu lệnh trước khi bắt đầu gỡ cài đặt Câu lệnh sau khi gỡ cài đặt kết thúc Chế độ mù màu Switches colors to be better for color-blind people Bật tính năng tỷ lệ giao diện hỗ trợ DPI Nhấp đúp vào danh sách ứng dụng Lặt vặt Tự động nạp danh sách bộ lọc gỡ cài đặt có tên "Default.bcul" khi khởi động Hiển thị xếp hạng người dùng cho ứng dụng Kiểm tra các bản cập nhật khi khởi động Gửi số liệu thống kê sử dụng ẩn danh Ngôn ngữ ứng dụng: Ứng dụng phải được khởi động lại để thay đổi ngôn ngữ có hiệu lực. Luôn yêu cầu tạo Không bao giờ yêu cầu tạo Tự động tạo trong thư mục: Sao lưu trước khi xóa phần còn sót lại Luôn hiển thị nội dung rác với độ tin cậy thấp Yêu cầu xóa trình gỡ cài đặt gốc khỏi tác vụ âm thầm Không bao giờ yêu cầu phản hồi hoặc trợ giúp Tìm kiếm rác sau khi gỡ cài đặt Tạo điểm khôi phục trước khi gỡ cài đặt Hộp tin nhắn Cho phép thực thi các ứng dụng bên ngoài Bạn có thể chỉ định các câu lệnh sẽ thực thi trước và sau khi gỡ cài đặt. Mỗi dòng tương ứng với một lệnh và được thực thi như thể sử dụng hộp thoại "Khởi chạy...". BCU sẽ đợi cho đến khi lệnh hiện đang thực thi hoàn tất trước khi thực thi lệnh tiếp theo. Ứng dụng bên ngoài Đó&ng Chung Ngôn ngữ Giao diện Gỡ cài đặt Phát hiện Windows Updates sử dụng WUA, vốn khá chậm. Quá trình này có thể mất vài phút để hoàn tất. Windows Update Phát hiện Windows Features sử dụng WMI và trên một số hệ thống quá trình này có thể chậm hoặc thậm chí thất bại (thường là dấu hiệu cho thấy hệ thống bị lỗi). Windows Features Windows Store App Steam Scoop Oculus Store Chocolatey Kho ứng dụng để quét Registry (khuyến khích bật) Ổ đĩa (phát hiện các ứng dụng chưa đăng ký) Dựa trên các quy tắc được xác định trước Tìm kiếm ứng dụng trong... Phát hiện Công cụ bên ngoài Quét các ổ đĩa di động Scan pendrives, USB hard drives, SD Cards, etc. Cố gắng tự động phát hiện các thư mục cài đặt tùy chỉnh Bạn có thể thiết lập các thư mục cài đặt ứng dụng tùy chỉnh (ví dụ: D:\Applications). Những thư mục đó sẽ được BCU sẽ sử dụng các thư mục này để tìm kiếm các tệp sót lại sau khi gỡ cài đặt, các ứng dụng chưa đăng ký và một vài thứ khác. Mặc dù không bắt buộc, nhưng việc cung cấp danh sách các thư mục này sẽ giúp BCU hoạt động hiệu quả hơn. Các thư mục mặc định của Windows luôn được quét, bạn không cần đưa chúng vào danh sách này. Hãy sử dụng đường dẫn thư mục đầy đủ, một dòng một đường dân. Đường dẫn không hợp lệ và thư mục không tồn tại sẽ bị bỏ qua. Thư mục cài đặt ứng dụng Thư mục Khởi động cùng hệ thống Mạng Lặt vặt Cài đặt Bulk Crap Uninstaller ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/SettingsWindow.zh-Hans.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 卸载程序启动前命令行 卸载程序结束后命令行 启动时自动加载名为"Default.bcul"的卸载程序列表 色盲模式 Switches colors to be better for color-blind people 启用DPI感知界面缩放 杂项 启用应用程序用户评分 启动时搜索更新 发送匿名使用情况统计信息 应用程序语言: 必须重新启动应用程序才能使语言更改生效。 创建时总是询问 创建时从不询问 自动在目录中创建: 删除前备份 总是显示低置信度垃圾 从静默任务中删除交互卸载程序时询问 从不询问反馈或帮助 卸载后搜索垃圾 卸载前创建还原点 消息框 启用外部应用程序的执行 你可以指定将在卸载前后运行的命令。一行一个命令,执行时就像使用"运行..."对话框一样。 BCU将等待当前运行的命令完成后再执行下一个命令。 外部应用程序 关闭 常规 语言 界面 卸载 使用WUA检测Windows更新,速度很慢。可能需要几分钟才能完成。 Windows更新 使用WMI检测Windows功能,在某些系统上可能会缓慢甚至失败(通常表示系统损坏)。 Windows功能 Windows商店应用 Steam Scoop Oculus Store Chocolatey 要扫描的应用程序商店 注册表(推荐启用) 驱动器(检测未注册的应用程序) 基于预定义规则 在...中搜索应用程序 检测 外部工具 扫描可删除驱动 Scan pendrives, USB hard drives, SD Cards, etc. 尝试自动检测自定义安装文件夹 你可以指定安装应用程序的自定义文件夹(例如D:\applications)。BCU将使用这些文件夹来搜索卸载遗留问题、未注册的应用程序和其他一些内容。虽然没有必要,但列出这些文件夹可以让BCU更好地工作。 默认的Windows文件夹总是被扫描的,不需要将它们包含在此列表中。 使用完整的目录路径,每行一个路径。无效路径和不存在的目录将被忽略。 程序安装文件夹 文件夹 网络 其他 Bulk Crap Uninstaller设置 在应用程序列表双击 启动 ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/SettingsWindow.zh-Hant.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 移除安裝啟動前命令列 移除安裝啟動後命令列 身障者模式 Switches colors to be better for color-blind people 啟用DPI感知介面縮放 在應用程式清單雙擊 其他項目 啟動時自動載入名為"Default.bcul"的移除程式清單 啟用應用程式使用者評分 啟動時搜尋更新 發送匿名使用情況統計資訊 應用程式語言: 必須重新啟動應用程式才能使變更語言生效 總是於建立時詢問 總不於建立時詢問 自動在目錄中建立: 刪除前備份 總是顯示低信任度 從最小化任務中刪除交互移除程式時詢問 從不詢問回饋或幫助 解除安裝後搜尋垃圾 解除安裝前建立還原點 訊息中心 啟用外部應用程式的執行 你可以在移除前後執行的指令。一行一個指令,執行時就像使用"執行..."視窗一樣。 BCU將等待目前執行的指令完成後再執行下一個指令 外部應用程式 關閉 設置 語言 介面 移除 使用WUA檢測Windows更新,速度較慢。可能需要幾分鐘才能完成。 Windows更新 使用WMI檢測Windows功能,在某些系統上可能會緩慢甚至失敗(通常表示系統損壞)。 Windows功能 Windows商店應用程式 Steam Scoop Oculus Store Chocolatey 要掃描的應用程式商店 註冊表(建議啟用) 驅動程式(檢測未註冊的應用程式) 預先定義規則 在...中搜尋應用程式 檢測 外部工具 掃描卸除式裝置 Scan pendrives, USB hard drives, SD Cards, etc. 嘗試自動檢測自訂安裝資料夾 你可以指定安裝應用程式的自訂資料夾(例如 D:\applications)。BCU將使用這些資料夾來搜尋移除殘留問題、未註冊的應用程式和其他一些內容。雖然沒有必要,但列出這些資料夾可以讓BCU運作流暢。 默認的Windows資料夾總是被掃瞄的,不需要將它們包含在此列表中。 使用完整的目錄路徑,每行一個路徑。無效路徑和不存在的目錄將被忽略。 程式安裝資料夾 資料夾 啟動 網路 其他 Bulk Crap Uninstaller設定 ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/UninstallProgressWindow.Designer.cs ================================================ using System.ComponentModel; using System.Windows.Forms; using BrightIdeasSoftware; using BulkCrapUninstaller.Functions.Tracking; namespace BulkCrapUninstaller.Forms { partial class UninstallProgressWindow { /// /// Required designer variable. /// private IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { components = new Container(); ComponentResourceManager resources = new ComponentResourceManager(typeof(UninstallProgressWindow)); progressBar1 = new ProgressBar(); label1 = new Label(); buttonClose = new Button(); olvColumnStatus = new OLVColumn(); olvColumnIsSilent = new OLVColumn(); olvColumnName = new OLVColumn(); objectListView1 = new ObjectListView(); olvColumnId = new OLVColumn(); contextMenuStrip1 = new ContextMenuStrip(components); skipToolStripMenuItem = new ToolStripMenuItem(); terminateToolStripMenuItem = new ToolStripMenuItem(); toolStripSeparator3 = new ToolStripSeparator(); runNowToolStripMenuItem = new ToolStripMenuItem(); manualUninstallToolStripMenuItem = new ToolStripMenuItem(); toolStripSeparator4 = new ToolStripSeparator(); openInstallDirectoryToolStripMenuItem = new ToolStripMenuItem(); propertiesToolStripMenuItem = new ToolStripMenuItem(); label3 = new Label(); groupBox1 = new GroupBox(); toolStrip1 = new ToolStrip(); toolStripButtonRun = new ToolStripButton(); toolStripButtonSkip = new ToolStripButton(); toolStripButtonTerminate = new ToolStripButton(); toolStripButtonManualUninstall = new ToolStripButton(); toolStripSeparator2 = new ToolStripSeparator(); toolStripButtonFolderOpen = new ToolStripButton(); toolStripButtonProperties = new ToolStripButton(); toolStripSeparator1 = new ToolStripSeparator(); toolStripButtonSettings = new ToolStripButton(); toolStripButtonHelp = new ToolStripButton(); label2 = new Label(); usageTracker1 = new UsageTracker(); panel3 = new Panel(); panel1 = new Panel(); pictureBox1 = new PictureBox(); flowLayoutPanel1 = new FlowLayoutPanel(); forceUpdateTimer = new Timer(components); flowLayoutPanel2 = new FlowLayoutPanel(); checkBoxFinishSleep = new CheckBox(); sleepTimer = new Timer(components); ((ISupportInitialize)objectListView1).BeginInit(); contextMenuStrip1.SuspendLayout(); groupBox1.SuspendLayout(); toolStrip1.SuspendLayout(); panel3.SuspendLayout(); panel1.SuspendLayout(); ((ISupportInitialize)pictureBox1).BeginInit(); flowLayoutPanel1.SuspendLayout(); flowLayoutPanel2.SuspendLayout(); SuspendLayout(); // // progressBar1 // resources.ApplyResources(progressBar1, "progressBar1"); progressBar1.Name = "progressBar1"; // // label1 // label1.AutoEllipsis = true; resources.ApplyResources(label1, "label1"); label1.Name = "label1"; // // buttonClose // resources.ApplyResources(buttonClose, "buttonClose"); buttonClose.DialogResult = DialogResult.Cancel; buttonClose.Name = "buttonClose"; buttonClose.UseVisualStyleBackColor = true; buttonClose.Click += buttonClose_Click; // // olvColumnStatus // resources.ApplyResources(olvColumnStatus, "olvColumnStatus"); // // olvColumnIsSilent // resources.ApplyResources(olvColumnIsSilent, "olvColumnIsSilent"); // // olvColumnName // olvColumnName.FillsFreeSpace = true; resources.ApplyResources(olvColumnName, "olvColumnName"); // // objectListView1 // objectListView1.AllColumns.Add(olvColumnId); objectListView1.AllColumns.Add(olvColumnStatus); objectListView1.AllColumns.Add(olvColumnIsSilent); objectListView1.AllColumns.Add(olvColumnName); objectListView1.CellEditUseWholeCell = false; objectListView1.Columns.AddRange(new ColumnHeader[] { olvColumnId, olvColumnStatus, olvColumnIsSilent, olvColumnName }); objectListView1.ContextMenuStrip = contextMenuStrip1; resources.ApplyResources(objectListView1, "objectListView1"); objectListView1.FullRowSelect = true; objectListView1.MultiSelect = false; objectListView1.Name = "objectListView1"; objectListView1.ShowItemToolTips = true; objectListView1.UseCompatibleStateImageBehavior = false; objectListView1.View = View.Details; objectListView1.SelectedIndexChanged += objectListView1_SelectedIndexChanged; // // olvColumnId // resources.ApplyResources(olvColumnId, "olvColumnId"); // // contextMenuStrip1 // contextMenuStrip1.Items.AddRange(new ToolStripItem[] { skipToolStripMenuItem, terminateToolStripMenuItem, toolStripSeparator3, runNowToolStripMenuItem, manualUninstallToolStripMenuItem, toolStripSeparator4, openInstallDirectoryToolStripMenuItem, propertiesToolStripMenuItem }); contextMenuStrip1.Name = "contextMenuStrip1"; resources.ApplyResources(contextMenuStrip1, "contextMenuStrip1"); contextMenuStrip1.Opening += contextMenuStrip1_Opening; // // skipToolStripMenuItem // skipToolStripMenuItem.Name = "skipToolStripMenuItem"; resources.ApplyResources(skipToolStripMenuItem, "skipToolStripMenuItem"); skipToolStripMenuItem.Click += toolStripButtonSkip_Click; // // terminateToolStripMenuItem // terminateToolStripMenuItem.Name = "terminateToolStripMenuItem"; resources.ApplyResources(terminateToolStripMenuItem, "terminateToolStripMenuItem"); terminateToolStripMenuItem.Click += toolStripButtonTerminate_Click; // // toolStripSeparator3 // toolStripSeparator3.Name = "toolStripSeparator3"; resources.ApplyResources(toolStripSeparator3, "toolStripSeparator3"); // // runNowToolStripMenuItem // runNowToolStripMenuItem.Name = "runNowToolStripMenuItem"; resources.ApplyResources(runNowToolStripMenuItem, "runNowToolStripMenuItem"); runNowToolStripMenuItem.Click += toolStripButtonRun_Click; // // manualUninstallToolStripMenuItem // manualUninstallToolStripMenuItem.Name = "manualUninstallToolStripMenuItem"; resources.ApplyResources(manualUninstallToolStripMenuItem, "manualUninstallToolStripMenuItem"); manualUninstallToolStripMenuItem.Click += toolStripButtonManualUninstall_Click; // // toolStripSeparator4 // toolStripSeparator4.Name = "toolStripSeparator4"; resources.ApplyResources(toolStripSeparator4, "toolStripSeparator4"); // // openInstallDirectoryToolStripMenuItem // openInstallDirectoryToolStripMenuItem.Name = "openInstallDirectoryToolStripMenuItem"; resources.ApplyResources(openInstallDirectoryToolStripMenuItem, "openInstallDirectoryToolStripMenuItem"); openInstallDirectoryToolStripMenuItem.Click += toolStripButtonFolderOpen_Click; // // propertiesToolStripMenuItem // propertiesToolStripMenuItem.Name = "propertiesToolStripMenuItem"; resources.ApplyResources(propertiesToolStripMenuItem, "propertiesToolStripMenuItem"); propertiesToolStripMenuItem.Click += toolStripButtonProperties_Click; // // label3 // resources.ApplyResources(label3, "label3"); label3.Name = "label3"; // // groupBox1 // groupBox1.Controls.Add(objectListView1); groupBox1.Controls.Add(toolStrip1); groupBox1.Controls.Add(label2); resources.ApplyResources(groupBox1, "groupBox1"); groupBox1.Name = "groupBox1"; groupBox1.TabStop = false; // // toolStrip1 // toolStrip1.GripStyle = ToolStripGripStyle.Hidden; toolStrip1.Items.AddRange(new ToolStripItem[] { toolStripButtonRun, toolStripButtonSkip, toolStripButtonTerminate, toolStripButtonManualUninstall, toolStripSeparator2, toolStripButtonFolderOpen, toolStripButtonProperties, toolStripSeparator1, toolStripButtonSettings, toolStripButtonHelp }); resources.ApplyResources(toolStrip1, "toolStrip1"); toolStrip1.Name = "toolStrip1"; // // toolStripButtonRun // resources.ApplyResources(toolStripButtonRun, "toolStripButtonRun"); toolStripButtonRun.Image = Properties.Resources.layerdown; toolStripButtonRun.Name = "toolStripButtonRun"; toolStripButtonRun.Click += toolStripButtonRun_Click; // // toolStripButtonSkip // resources.ApplyResources(toolStripButtonSkip, "toolStripButtonSkip"); toolStripButtonSkip.Image = Properties.Resources.control_fastforward_variant; toolStripButtonSkip.Name = "toolStripButtonSkip"; toolStripButtonSkip.Click += toolStripButtonSkip_Click; // // toolStripButtonTerminate // resources.ApplyResources(toolStripButtonTerminate, "toolStripButtonTerminate"); toolStripButtonTerminate.Image = Properties.Resources.stop; toolStripButtonTerminate.Name = "toolStripButtonTerminate"; toolStripButtonTerminate.Click += toolStripButtonTerminate_Click; // // toolStripButtonManualUninstall // toolStripButtonManualUninstall.DisplayStyle = ToolStripItemDisplayStyle.Image; toolStripButtonManualUninstall.Image = Properties.Resources.list; resources.ApplyResources(toolStripButtonManualUninstall, "toolStripButtonManualUninstall"); toolStripButtonManualUninstall.Name = "toolStripButtonManualUninstall"; toolStripButtonManualUninstall.Click += toolStripButtonManualUninstall_Click; // // toolStripSeparator2 // toolStripSeparator2.Name = "toolStripSeparator2"; resources.ApplyResources(toolStripSeparator2, "toolStripSeparator2"); // // toolStripButtonFolderOpen // toolStripButtonFolderOpen.DisplayStyle = ToolStripItemDisplayStyle.Image; resources.ApplyResources(toolStripButtonFolderOpen, "toolStripButtonFolderOpen"); toolStripButtonFolderOpen.Image = Properties.Resources.fullscreen; toolStripButtonFolderOpen.Name = "toolStripButtonFolderOpen"; toolStripButtonFolderOpen.Click += toolStripButtonFolderOpen_Click; // // toolStripButtonProperties // toolStripButtonProperties.DisplayStyle = ToolStripItemDisplayStyle.Image; resources.ApplyResources(toolStripButtonProperties, "toolStripButtonProperties"); toolStripButtonProperties.Image = Properties.Resources.properties; toolStripButtonProperties.Name = "toolStripButtonProperties"; toolStripButtonProperties.Click += toolStripButtonProperties_Click; // // toolStripSeparator1 // toolStripSeparator1.Name = "toolStripSeparator1"; resources.ApplyResources(toolStripSeparator1, "toolStripSeparator1"); // // toolStripButtonSettings // toolStripButtonSettings.DisplayStyle = ToolStripItemDisplayStyle.Image; toolStripButtonSettings.Image = Properties.Resources.settings; resources.ApplyResources(toolStripButtonSettings, "toolStripButtonSettings"); toolStripButtonSettings.Name = "toolStripButtonSettings"; toolStripButtonSettings.Click += toolStripButtonSettings_Click; // // toolStripButtonHelp // toolStripButtonHelp.DisplayStyle = ToolStripItemDisplayStyle.Image; toolStripButtonHelp.Image = Properties.Resources.information_circle; resources.ApplyResources(toolStripButtonHelp, "toolStripButtonHelp"); toolStripButtonHelp.Name = "toolStripButtonHelp"; toolStripButtonHelp.Click += toolStripButtonHelp_Click; // // label2 // resources.ApplyResources(label2, "label2"); label2.Name = "label2"; // // usageTracker1 // usageTracker1.ContainerControl = this; // // panel3 // panel3.Controls.Add(label1); panel3.Controls.Add(panel1); resources.ApplyResources(panel3, "panel3"); panel3.Name = "panel3"; // // panel1 // panel1.Controls.Add(progressBar1); resources.ApplyResources(panel1, "panel1"); panel1.Name = "panel1"; // // pictureBox1 // resources.ApplyResources(pictureBox1, "pictureBox1"); pictureBox1.Image = Properties.Resources.layerdelete; pictureBox1.Name = "pictureBox1"; pictureBox1.TabStop = false; // // flowLayoutPanel1 // resources.ApplyResources(flowLayoutPanel1, "flowLayoutPanel1"); flowLayoutPanel1.Controls.Add(label3); flowLayoutPanel1.Name = "flowLayoutPanel1"; // // forceUpdateTimer // forceUpdateTimer.Interval = 3500; // // flowLayoutPanel2 // resources.ApplyResources(flowLayoutPanel2, "flowLayoutPanel2"); flowLayoutPanel2.Controls.Add(buttonClose); flowLayoutPanel2.Controls.Add(checkBoxFinishSleep); flowLayoutPanel2.Name = "flowLayoutPanel2"; // // checkBoxFinishSleep // resources.ApplyResources(checkBoxFinishSleep, "checkBoxFinishSleep"); checkBoxFinishSleep.Name = "checkBoxFinishSleep"; checkBoxFinishSleep.UseVisualStyleBackColor = true; // // UninstallProgressWindow // resources.ApplyResources(this, "$this"); AutoScaleMode = AutoScaleMode.Font; CancelButton = buttonClose; Controls.Add(groupBox1); Controls.Add(flowLayoutPanel2); Controls.Add(pictureBox1); Controls.Add(panel3); Controls.Add(flowLayoutPanel1); Name = "UninstallProgressWindow"; FormClosing += UninstallProgressWindow_FormClosing; ((ISupportInitialize)objectListView1).EndInit(); contextMenuStrip1.ResumeLayout(false); groupBox1.ResumeLayout(false); groupBox1.PerformLayout(); toolStrip1.ResumeLayout(false); toolStrip1.PerformLayout(); panel3.ResumeLayout(false); panel1.ResumeLayout(false); ((ISupportInitialize)pictureBox1).EndInit(); flowLayoutPanel1.ResumeLayout(false); flowLayoutPanel1.PerformLayout(); flowLayoutPanel2.ResumeLayout(false); flowLayoutPanel2.PerformLayout(); ResumeLayout(false); PerformLayout(); } #endregion private ProgressBar progressBar1; private Label label1; private Button buttonClose; private OLVColumn olvColumnStatus; private OLVColumn olvColumnIsSilent; private OLVColumn olvColumnName; private ObjectListView objectListView1; private GroupBox groupBox1; private Label label2; private Label label3; private UsageTracker usageTracker1; private Panel panel3; private PictureBox pictureBox1; private FlowLayoutPanel flowLayoutPanel1; private ToolStrip toolStrip1; private ToolStripButton toolStripButtonRun; private ToolStripButton toolStripButtonFolderOpen; private ToolStripSeparator toolStripSeparator1; private ToolStripButton toolStripButtonSettings; private ToolStripButton toolStripButtonSkip; private ToolStripSeparator toolStripSeparator2; private ToolStripButton toolStripButtonProperties; private OLVColumn olvColumnId; private ToolStripButton toolStripButtonTerminate; private ToolStripButton toolStripButtonHelp; private Timer forceUpdateTimer; private ToolStripButton toolStripButtonManualUninstall; private Panel panel1; private ContextMenuStrip contextMenuStrip1; private ToolStripMenuItem skipToolStripMenuItem; private ToolStripMenuItem terminateToolStripMenuItem; private ToolStripSeparator toolStripSeparator3; private ToolStripMenuItem runNowToolStripMenuItem; private ToolStripMenuItem manualUninstallToolStripMenuItem; private ToolStripSeparator toolStripSeparator4; private ToolStripMenuItem openInstallDirectoryToolStripMenuItem; private ToolStripMenuItem propertiesToolStripMenuItem; private FlowLayoutPanel flowLayoutPanel2; private CheckBox checkBoxFinishSleep; private Timer sleepTimer; } } ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/UninstallProgressWindow.ar.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 الحالة... الغاء الامر الحالة بهدوء الاسم هوية سيتم الان تنفيذ الغاء تثبيت محدد واحد في كل مره. اذا كانت العملية تبدو عالقه يمكنك النقر على زر "تخطي" لتجنب الانتظار لاكماله. هذا يمكن ان يحدث اذا تم تعطل الغاء التثبيت او يبدا عمليه جديده ولا يغلق عليه. تشغيل الغاء المثبت تخطي انهاء فتح موقع التثبيت خصائص الاعدادات التعليمات سيتم الغاء تثبيت محتويات هذه القائمة من الاعلى الى الاسفل. قائمة الغاء التثبيت تقدم الغاء التثبيت الغاء التثبيت يدويا ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/UninstallProgressWindow.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.Globalization; using System.Linq; using System.Media; using System.Threading; using System.Windows.Forms; using BulkCrapUninstaller.Functions; using BulkCrapUninstaller.Properties; using Klocman.Binding.Settings; using Klocman.Extensions; using Klocman.Forms; using Klocman.Forms.Tools; using Klocman.Tools; using UninstallTools; using UninstallTools.Uninstaller; namespace BulkCrapUninstaller.Forms { internal sealed partial class UninstallProgressWindow : Form { private readonly SettingBinder _settings = Settings.Default.SettingBinder; private BulkUninstallTask _currentTargetStatus; [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2213:Disposable fields should be disposed", Justification = "False positive")] private CustomMessageBox _walkAwayBox; private BulkUninstallTask _status; private static Func, bool> _uninstallManuallyAction; private int _sleepTimePassed; public static void ShowUninstallDialog(BulkUninstallTask status, Func, bool> uninstallManuallyAction) { _uninstallManuallyAction = uninstallManuallyAction; using (var uninstallWindow = new UninstallProgressWindow()) { uninstallWindow._status = status; uninstallWindow.ShowDialog(MessageBoxes.DefaultOwner); } } protected override void OnShown(EventArgs e) { base.OnShown(e); SetTargetStatus(_status); var workingArea = Screen.FromControl(this).WorkingArea; Location = new Point(workingArea.Right - Size.Width - 5, workingArea.Top + 10); Refresh(); Opacity = 1; } private UninstallProgressWindow() { InitializeComponent(); Text += " - Bulk Crap Uninstaller"; Opacity = 0; Icon = Resources.Icon_Logo; toolStrip1.Renderer = new ToolStripProfessionalRenderer(new StandardSystemColorTable()); var windowHandle = Handle; // Shutdown blocking not available below Windows Vista if (Environment.OSVersion.Version >= new Version(6, 0)) { _settings.Subscribe((sender, args) => { if (args.NewValue) SleepControls.PreventSleepOrShutdown(windowHandle, "Bulk uninstallation is in progress."); else SleepControls.AllowSleepOrShutdown(windowHandle); }, settings => settings.UninstallPreventShutdown, this); } _settings.SendUpdates(this); FormClosing += (sender, args) => { if (args.CloseReason == CloseReason.WindowsShutDown && _settings.Settings.UninstallPreventShutdown) args.Cancel = true; }; FormClosed += (o, eventArgs) => { _settings.RemoveHandlers(this); SleepControls.AllowSleepOrShutdown(windowHandle); _walkAwayBox?.Dispose(); }; olvColumnName.AspectGetter = BulkUninstallTask.DisplayNameAspectGetter; olvColumnStatus.AspectGetter = BulkUninstallTask.StatusAspectGetter; olvColumnIsSilent.AspectGetter = BulkUninstallTask.IsSilentAspectGetter; olvColumnId.AspectName = nameof(BulkUninstallEntry.Id); olvColumnStatus.GroupKeyGetter = rowObject => (rowObject as BulkUninstallEntry)?.CurrentStatus; olvColumnName.GroupKeyGetter = rowObject => (rowObject as BulkUninstallEntry)?.UninstallerEntry.DisplayName.SafeNormalize().FirstOrDefault(); olvColumnId.GroupKeyGetter = rowObject => (rowObject as BulkUninstallEntry)?.Id / 10; objectListView1.PrimarySortColumn = olvColumnStatus; objectListView1.SecondarySortColumn = olvColumnId; forceUpdateTimer.Tick += (o, args) => { if (_currentTargetStatus != null && !_currentTargetStatus.Finished) currentTargetStatus_OnCurrentTaskChanged(o, args); else forceUpdateTimer.Stop(); }; // Handle sleeping after task finishes sleepTimer.Interval = 1000; sleepTimer.Tick += (sender, args) => { if (_currentTargetStatus.Finished && checkBoxFinishSleep.Checked) { _sleepTimePassed++; const int sleepDelay = 30; label1.Text = Localisable.UninstallProgressWindow_TaskDone + "\n" + string.Format(Localisable.UninstallProgressWindow_StatusPuttingToSleepInSeconds, sleepDelay - _sleepTimePassed); if (_sleepTimePassed > sleepDelay) { checkBoxFinishSleep.Checked = false; checkBoxFinishSleep.Enabled = false; SleepControls.AllowSleepOrShutdown(windowHandle); SleepControls.PutToSleep(); } } else { _sleepTimePassed = 0; if (_currentTargetStatus.Finished) label1.Text = Localisable.UninstallProgressWindow_TaskDone; } }; } private IEnumerable SelectedTaskEntries => objectListView1.SelectedObjects.Cast(); private IEnumerable SelectedUninstallerEntries => SelectedTaskEntries.Select(x => x.UninstallerEntry); private void SetTargetStatus(BulkUninstallTask targetStatus) { _currentTargetStatus = targetStatus ?? throw new ArgumentNullException(nameof(targetStatus)); progressBar1.Maximum = _currentTargetStatus.AllUninstallersList.Count; objectListView1.SetObjects(_currentTargetStatus.AllUninstallersList); _currentTargetStatus.OnStatusChanged += currentTargetStatus_OnCurrentTaskChanged; currentTargetStatus_OnCurrentTaskChanged(this, EventArgs.Empty); } private void buttonClose_Click(object sender, EventArgs e) { Close(); } private void currentTargetStatus_OnCurrentTaskChanged(object sender, EventArgs e) { sleepTimer.Enabled = true; forceUpdateTimer.Stop(); // Needed to call from another thread to avoid blocking the calling thread and deadlocking new Thread(() => objectListView1.SafeInvoke(() => { objectListView1.SetObjects(_currentTargetStatus.AllUninstallersList, true); if (_currentTargetStatus.Finished) OnTaskFinished(); else OnTaskUpdated(); })) { IsBackground = false }.Start(); // Reset the timer forceUpdateTimer.Start(); } private void OnTaskFinished() { if (_walkAwayBox != null && _walkAwayBox.Visible) _walkAwayBox.Close(); if (!_currentTargetStatus.Aborted && _currentTargetStatus.Configuration.PreferQuiet) { var failedSilent = _currentTargetStatus.AllUninstallersList .Where(x => x.CurrentStatus == UninstallStatus.Failed && x.IsSilentPossible).ToList(); if (failedSilent.Count > 0 && MessageBoxes.AskToRetryFailedQuietAsLoud(this, failedSilent.Select(x => x.UninstallerEntry.DisplayName))) { foreach (var uninstallEntry in failedSilent) { uninstallEntry.Reset(); uninstallEntry.IsSilentPossible = false; } objectListView1.UpdateObjects(failedSilent); objectListView1.BuildGroups(); _currentTargetStatus.Start(); return; } } label1.Text = Localisable.UninstallProgressWindow_TaskDone; progressBar1.Value = progressBar1.Maximum; buttonClose.Text = Buttons.ButtonClose; pictureBox1.Image = Resources.check; buttonClose.Enabled = true; WindowsTools.FlashWindowEx(this); SystemSounds.Exclamation.Play(); } private void OnTaskUpdated() { SuspendLayout(); try { var uninstList = _currentTargetStatus.AllUninstallersList; // Show the walk away box if there are no running/waiting loud uninstallers and at least one quiet unistaller running/waiting if (_walkAwayBox == null && // There is at least one loud uninstaller uninstList.Any(x => !x.IsSilentPossible) && // There are no loud uninstallers running or waiting !uninstList.Any(x => !x.IsSilentPossible && (x.CurrentStatus == UninstallStatus.Waiting || x.CurrentStatus == UninstallStatus.Uninstalling)) && // There is at least one silent uninstaller running or waiting uninstList.Any(x => x.IsSilentPossible && (x.CurrentStatus == UninstallStatus.Waiting || x.CurrentStatus == UninstallStatus.Uninstalling))) { _walkAwayBox = MessageBoxes.CanWalkAwayInfo(this); Enabled = false; _walkAwayBox.FormClosed += (x1, y1) => Enabled = true; } buttonClose.Enabled = true; var progress = uninstList.Count(x => x.CurrentStatus != UninstallStatus.Waiting); var statusString = string.Join("; ", uninstList.Where(x1 => x1.CurrentStatus == UninstallStatus.Uninstalling) .Select(x2 => x2.UninstallerEntry.DisplayName) .ToArray()); label1.Text = string.Format(CultureInfo.CurrentCulture, "{0} {1}/{2}: {3}", Localisable.UninstallProgressWindow_Uninstalling, progress, uninstList.Count, statusString); buttonClose.Text = Buttons.ButtonCancel; progressBar1.Value = Math.Max(0, progress - 1); progressBar1.Style = ProgressBarStyle.Continuous; } catch { progressBar1.Style = ProgressBarStyle.Marquee; } ResumeLayout(); Refresh(); } private void UninstallProgressWindow_FormClosing(object sender, FormClosingEventArgs e) { if (_currentTargetStatus == null) return; if (_currentTargetStatus.Finished || _currentTargetStatus.Aborted || e.CloseReason != CloseReason.UserClosing) { _currentTargetStatus.Dispose(); return; } if (MessageBoxes.TaskStopConfirmation(this) == MessageBoxes.PressedButton.Yes) { _currentTargetStatus.Aborted = true; buttonClose.Enabled = false; } e.Cancel = true; } private void toolStripButtonSettings_Click(object sender, EventArgs e) { using (var sw = new SettingsWindow()) { sw.OpenedTab = 1; sw.ShowDialog(); } _currentTargetStatus.OneLoudLimit = _settings.Settings.UninstallConcurrentOneLoud; _currentTargetStatus.ConcurrentUninstallerCount = _settings.Settings.UninstallConcurrency ? _settings.Settings.UninstallConcurrentMaxCount : 1; } private void toolStripButtonProperties_Click(object sender, EventArgs e) { using (var propertiesWindow = new PropertiesWindow()) { propertiesWindow.ShowPropertiesDialog(SelectedUninstallerEntries); } } private void toolStripButtonFolderOpen_Click(object sender, EventArgs e) { var sourceDirs = SelectedUninstallerEntries.Where(x => x.InstallLocation.IsNotEmpty()) .Select(y => y.InstallLocation).ToList(); if (MessageBoxes.OpenDirectoriesMessageBox(sourceDirs.Count)) { try { sourceDirs.ForEach(x => Process.Start(new ProcessStartInfo(x) { UseShellExecute = true })); } catch (Exception ex) { MessageBoxes.OpenDirectoryError(ex); } } } private void toolStripButtonRun_Click(object sender, EventArgs e) { var targetGroups = SelectedTaskEntries.GroupBy(x => x.IsRunning).ToList(); var running = targetGroups.SingleOrDefault(x => x.Key); var notRunning = targetGroups.SingleOrDefault(x => !x.Key); if (running != null && running.Any()) MessageBoxes.ForceRunUninstallFailedError(this, running.Select(x => x.UninstallerEntry.DisplayName).OrderBy(x => x)); if (notRunning == null || !notRunning.Any()) return; foreach (var target in notRunning) { target.Reset(); target.IsSilentPossible = false; } OnTaskUpdated(); if (_currentTargetStatus.Finished) _currentTargetStatus.Start(); } private void objectListView1_SelectedIndexChanged(object sender, EventArgs e) { var ste = SelectedTaskEntries.ToList(); toolStripButtonFolderOpen.Enabled = ste.Any(x => x.UninstallerEntry.InstallLocation.IsNotEmpty()); toolStripButtonProperties.Enabled = ste.Any(); toolStripButtonRun.Enabled = ste.Any(x => x.CurrentStatus == UninstallStatus.Waiting || x.CurrentStatus == UninstallStatus.Failed || x.CurrentStatus == UninstallStatus.Skipped); toolStripButtonSkip.Enabled = ste.Any(x => x.CurrentStatus != UninstallStatus.Skipped && x.CurrentStatus != UninstallStatus.Completed && x.CurrentStatus != UninstallStatus.Invalid && x.CurrentStatus != UninstallStatus.Protected && !(x.CurrentStatus == UninstallStatus.Uninstalling && x.UninstallerEntry.UninstallerKind == UninstallerType.Msiexec)); toolStripButtonTerminate.Enabled = ste.Any(x => x.CurrentStatus == UninstallStatus.Uninstalling); } private void toolStripButtonTerminate_Click(object sender, EventArgs e) { SelectedTaskEntries.ForEach(x => x.SkipWaiting(true)); } private void toolStripButtonSkip_Click(object sender, EventArgs e) { SelectedTaskEntries.ForEach(x => x.SkipWaiting(false)); } private void toolStripButtonHelp_Click(object sender, EventArgs e) { MessageBoxes.DisplayHelp(); } private void toolStripButtonManualUninstall_Click(object sender, EventArgs e) { var targetGroups = SelectedTaskEntries.GroupBy(x => x.IsRunning).ToList(); var running = targetGroups.SingleOrDefault(x => x.Key); var notRunning = targetGroups.SingleOrDefault(x => !x.Key); if (running != null && running.Any()) MessageBoxes.ForceRunUninstallFailedError(this, running.Select(x => x.UninstallerEntry.DisplayName).OrderBy(x => x)); if (notRunning == null || !notRunning.Any()) return; foreach (var bulkUninstallEntry in notRunning) bulkUninstallEntry.Pause(); var result = _uninstallManuallyAction(notRunning.Select(x => x.UninstallerEntry)); foreach (var bulkUninstallEntry in notRunning) { if (result) bulkUninstallEntry.ForceFinished(); else bulkUninstallEntry.Resume(); } OnTaskUpdated(); } private void contextMenuStrip1_Opening(object sender, System.ComponentModel.CancelEventArgs e) { if (objectListView1.SelectedObjects.Count == 0) e.Cancel = true; } } } ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/UninstallProgressWindow.cs.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Quiet Seznam odinstalátorů Vybrané odinstalace budou nyní provedeny jedna po druhé. Pokud se zdá, že se proces zasekl, můžete kliknout na tlačítko "Přeskočit", aby se zabránilo čekání na dokončení. Tato situace může nastat, pokud odinstalace havaruje nebo zahájí nový proces, a není zavřen. Zrušit Postup odinstalace Obsah tohoto seznamu bude odinstalován postupně od shora dolů. Název Status Status... Přeskočit Id Spustit odinstalaci Ukončit Otevřít umístění instalace Vlastnosti Nastavení Pomoc Ručně odinstalovat True 17, 17 ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/UninstallProgressWindow.de.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Still Uninstaller Liste Ausgewählte Uninstaller werden nacheinander ausgeführt. Wenn der Prozess stecken zu bleiben scheint, klicken Sie auf "Weiter", um zu vermeiden, dass Sie bis zum Abschluss der Ausführung warten müssen. Dies kann passieren, wenn der Uninstaller abstürzt oder einen neuen Prozess startet und diesen nicht abschließt. Abbrechen Deinstallations-Fortschritt Inhalt dieser Liste wird von oben nach unten deinstalliert. Name Status Status... Überspringen Id Starte Uninstaller Abbruch Manuelles Deinstallieren Öffne Install Ordner Eigenschaften Einstellungen Hilfe Überspringen Beenden Sie Deinstallationsprogramm jetzt ausführen Manuelle Deinstallation Installationsverzeichnis öffnen Eigenschaften PC in den Ruhezustand versetzen, wenn er fertig ist fr True 17, 17 ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/UninstallProgressWindow.es.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Estado... Cancelar Estado Silencioso Nombre ID Lista de desinstalación Ejecutar desinstalador ahora Saltar Terminar Abrir ubicación de instalación Propiedades Configuración Ayuda Progreso de desinstalación Los desinstaladores seleccionados se ejecutan uno a la vez. Si el proceso parece atascarse pulse "Saltar" para evitar tener que esperar a que se complete. Puede ocurrir si el desinstalador se bloquea o se inicia un nuevo proceso y no se cierra. El contenido de esta lista se puede desinstalar desde arriba hacia abajo. Desinstalar manualmente Omitir Terminar Ejecutar desinstalador ahora Desinstalación manual Abrir directorio de instalación Propiedades Poner la PC en reposo cuando haya terminado ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/UninstallProgressWindow.fr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Statut... Annuler Statut Silencieux Nom Les désinstalleurs sélectionnés vont maintenant être exécutés un à la fois. Si le processus semble bloqué, vous pouvez cliquer sur le bouton "Passer" pour éviter d'attendre qu'il se termine. Cela peut arriver si le désinstalleur plante ou démarre un nouveau processus et ne le ferme pas. Liste de désinstalleurs Le contenu de cette liste sera désinstallé en allant du début à la fin. Progression de la désinstallation Passer Id Lancer le désinstalleur Interrompre Ouvrir l'emplacement d'installation Propriétés Réglages Aide Désinstaller manuellement Passer Mettre fin Lancer le désinstalleur maintenant Désinstaller manuellement Ouvrir le dossier d'installation Propriétés Mettre le PC en veille lorsque c'est fait ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/UninstallProgressWindow.hu.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Állapot... Mégse Állapot Csendes Név ID A kijelölt eltávolítók, egyesével kerülnek végrehajtásra. Ha úgy tűnik, hogy egy folyamat beragadt kattintson a "Kihagyás" gombra, hogy elkerülje a felesleges várakozást. Ez akkor fordulhat elő, ha egy eltávolító összeomlik, vagy úgy indul el egy új folyamat, hogy az előző nem záródott be. Eltávolító futtatása most Kihagyás Leállítás Telepítési hely megnyitása Tulajdonságok Beállítások Súgó Ez a lista az eltávolítandókat tartalmazza felülről lefelé haladva. Eltávolítási lista Eltávolítási folyamat Kihagyás Leállítás Eltávolító futtatása most Kézi eltávolítás Telepítési hely megnyitása Tulajdonságok Kézi eltávolítás Számítógép alvó üzemmódba helyezése ha készen van ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/UninstallProgressWindow.it.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Stato... Annulla Stato Silenzioso Nome ID I disinstallatori selezionati saranno eseguiti uno per volta. Se il processo sembra bloccato puoi selezionare "Salta" per evitare di attendere il suo completamento. Questo accade se il disinstallatore si blocca o avvia un nuovo processo e non si chiude. Esegui disinstallatore Salta Interrompi Apri cartella di installazione Proprietà Configurazioni Aiuto I contenuti di questo elenco saranno disinstallati in ordine dall'alto verso il basso Elenco disinstallazione Avanzamento disinstallazione Disinstallare manualmente Salta Interrompi Esegui dinsistallazione ora Disinstallazione manuale Apri cartella installazione Proprietà Ad operazioni completate manda il PC in sleep ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/UninstallProgressWindow.ja.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ステータス キャンセル ステータス サイレント 名前 ID スキップ 終了 今すぐアンインストーラーを実行 手動アンインストール インストールディレクトリを開く プロパティ 選択したアンインストーラーは、1つずつ実行されます。 プロセスがハングしているように見える場合は、「スキップ」ボタンをクリックして完了を待たずに進むことができます。これは、アンインストーラーがクラッシュしたり、新しいプロセスを開始して閉じない場合に発生することがあります。 アンインストーラーを実行 スキップ 終了 手動でアンインストール インストール場所を開く プロパティ 設定 ヘルプ このリストの内容は、上から下へ順にアンインストールされます。 アンインストーラーリスト 完了後にPCをスリープ状態にする アンインストール進行状況 ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/UninstallProgressWindow.nl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Status... Annuleren Status Stil Naam Id Geselecteerde de-installers worden achtereen volgens uitgevoerd. Als het proces onverhoopt vastloopt, klikt u op de knop "Overslaan", om te voorkomen dat u bij het afsluiten van de uitvoering moet wachten. Dit kan gebeuren als de de-installer 'crasht' of een nieuw proces start en deze niet afsluit. Overslaan Afbreken Openen installatie locatie Eigenschappen Instellingen Help De inhoud van deze lijst wordt van boven naar beneden gede-installeerd. De-installer lijst De-installatie voortgang De-installer uitvoeren De-installeer handmatig Overslaan Beëindigen De-installatie nu uitvoeren Manuale de-installatie Open installatie map Eigenschappen Plaats computer in slaapstand bij voltooiing ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/UninstallProgressWindow.pl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Anuluj Cichy Nazwa Wybrane aplikacje zostaną odinstalowane jedna po drugiej. Jeśli proces wydaje się być zawieszony można kliknąć na przycisk "Pomiń" aby uniknąć oczekiwania na jego zakończenie. Może się to zdarzyć jeśli dezinstalator rozpocznie nowy proces ale nie zamknie go. Elementy z listy będą odinstalowane od góry w dół Lista dezinstalatorów Stan dezinstalacji Status Status... Uruchom dezinstalator teraz Pomiń Zakończ Otwórz lokalizację instalacji Właściwości Ustawienia Id Pomoc Odinstaluj recznie ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/UninstallProgressWindow.pt-BR.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Status... Cancelar Status Silencioso Nome Id Os desinstaladores selecionados serão executados um de cada vez. Se o processo parecer travado, você pode clicar no botão "Ignorar" para evitar aguardar a conclusão. Isso pode acontecer se o desinstalador falhar ou iniciar um novo processo que não fecha. Executar desinstalador Ignorar Finalizar Desinstalar manualmente Abrir local de instalação Propriedades Configurações Ajuda O conteúdo desta lista será desinstalado indo de cima para baixo. Lista dos desinstaladores Progresso da desinstalação Ignorar Finalizar Executar desinstalador agora Desinstalação manual Abrir diretório de instalação Propriedades Hibernar computador ao finalizar ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/UninstallProgressWindow.pt.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Estado... Cancelar Estado segundo plano Nome Id Os desinstaladores selecionadas serão executados um de cada vez. Se o processo lhe parecer ter bloqueado, pode clicar no botão "Ignorar" para evitar de esperar pela sua conclusão. Isto pode acontecer se o desinstalador falhar ou iniciar um novo processo e não o fechar. O conteúdo desta lista será desinstalado desde o topo à base. Lista dos desinstaladores Executar agora o desinstalador Passar à frente Concluir Abrir a localização da instalação Propriedades Configurações Ajuda Progresso da desinstalação Desinstalar manualmente 252, 17 17, 17 True ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/UninstallProgressWindow.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Fill 5, 5 4, 3, 4, 3 478, 26 0 progressBar1 System.Windows.Forms.ProgressBar, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel1 0 Fill 0, 36 4, 0, 4, 0 488, 33 1 Status... label1 System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel3 0 True 396, 3 4, 3, 4, 3 88, 27 2 Cancel buttonClose System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel2 0 Status 105 Quiet 47 Name 206 Id 25 17, 17 187, 22 Skip 187, 22 Terminate 184, 6 187, 22 Run uninstaller now 187, 22 Manual uninstall 184, 6 187, 22 Open install directory 187, 22 Properties 188, 148 contextMenuStrip1 System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 Fill 9, 72 4, 3, 4, 3 470, 187 2 objectListView1 BrightIdeasSoftware.ObjectListView, ObjectListView, Culture=neutral, PublicKeyToken=null groupBox1 0 True 59, 0 4, 0, 4, 0 12, 54 420, 60 0 Selected uninstallers will now be executed one at a time. If the process appears to be stuck you can click on the "Skip" button to avoid waiting for it to complete. This can happen if the uninstaller crashes or starts a new process and doesn't close it. label3 System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel1 0 172, 17 False Magenta 106, 22 Run uninstaller False Magenta 49, 22 Skip False Magenta 79, 22 Terminate Magenta 23, 22 Uninstall manually 6, 25 False Magenta 23, 22 Open install location False Magenta 23, 22 Properties 6, 25 Magenta 23, 22 Settings Magenta 23, 22 Help 9, 47 470, 25 1 toolStrip1 System.Windows.Forms.ToolStrip, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBox1 1 True Top 9, 25 4, 0, 4, 0 0, 0, 0, 7 351, 22 0 Contents of this list will be uninstalled going from top to bottom. label2 System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBox1 2 Fill 8, 143 4, 3, 4, 3 9, 9, 9, 9 488, 268 1 Uninstaller list groupBox1 System.Windows.Forms.GroupBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 1 277, 17 True 7, 15 504, 452 True GrowAndShrink True 221, 3 0, 4, 0, 0 168, 23 3 Put PC to sleep when done checkBoxFinishSleep System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel2 1 Bottom RightToLeft 8, 411 488, 33 3 flowLayoutPanel2 System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 2 Center NoControl 8, 8 4, 3, 4, 3 58, 58 10 pictureBox1 System.Windows.Forms.PictureBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 3 Top 0, 0 4, 3, 4, 3 5, 5, 5, 5 488, 36 0 panel1 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel3 1 Top 8, 74 4, 3, 4, 3 488, 69 0 panel3 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 4 True Top 8, 8 4, 3, 4, 3 55, 0, 0, 6 488, 66 0 flowLayoutPanel1 System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 5 4, 3, 4, 3 464, 398 8, 8, 8, 8 CenterParent Uninstall progress olvColumnStatus BrightIdeasSoftware.OLVColumn, ObjectListView, Culture=neutral, PublicKeyToken=null olvColumnIsSilent BrightIdeasSoftware.OLVColumn, ObjectListView, Culture=neutral, PublicKeyToken=null olvColumnName BrightIdeasSoftware.OLVColumn, ObjectListView, Culture=neutral, PublicKeyToken=null olvColumnId BrightIdeasSoftware.OLVColumn, ObjectListView, Culture=neutral, PublicKeyToken=null skipToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 terminateToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripSeparator3 System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 runNowToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 manualUninstallToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripSeparator4 System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 openInstallDirectoryToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 propertiesToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripButtonRun System.Windows.Forms.ToolStripButton, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripButtonSkip System.Windows.Forms.ToolStripButton, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripButtonTerminate System.Windows.Forms.ToolStripButton, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripButtonManualUninstall System.Windows.Forms.ToolStripButton, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripSeparator2 System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripButtonFolderOpen System.Windows.Forms.ToolStripButton, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripButtonProperties System.Windows.Forms.ToolStripButton, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripSeparator1 System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripButtonSettings System.Windows.Forms.ToolStripButton, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripButtonHelp System.Windows.Forms.ToolStripButton, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 usageTracker1 BulkCrapUninstaller.Functions.Tracking.UsageTracker, BCUninstaller, Culture=neutral, PublicKeyToken=null forceUpdateTimer System.Windows.Forms.Timer, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 sleepTimer System.Windows.Forms.Timer, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 UninstallProgressWindow System.Windows.Forms.Form, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 405, 17 554, 17 ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/UninstallProgressWindow.ru.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Статус... Отмена Статус Тихо Название Id Выбранные деинсталляторы будут выполняться по очереди. Если покажется, что процесс завис, Вы можете нажать на "Пропустить", чтобы не ждать его завершения. Такое происходит, если деинсталлятор дал сбой или запустил новый процесс и не закрыл его. Запустить деинсталлятор Пропустить Завершить Открыть папку установки Свойства Установки Содержание этого списка деинсталляции идёт сверху вниз. Список деинсталляции Прогресс деинсталляции Справка Удалить вручную Пропустить Завершить Запустить деинсталлятор Ручное удаление Открыть место установки Свойства Перевести компьютер в спящий режим после завершения операции 252, 17 17, 17 True ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/UninstallProgressWindow.sl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Stanje... Prekliči Stanje Tiho Ime Izbrani odstranjevalci bodo zdaj naenkrat izvedeni. Če se vam zdi, da se je postopek zataknil, lahko kliknite na gumb "Preskoči", da se boste izognili čakanju na njegovo dokončanje. To se lahko zgodi, če se odstranjevalec sesuje ali se začenja nov proces, in se ga ne da zapreti. Vsebina tega seznama bo odstranjena od zgoraj navzdol. Seznam odstranjevalcev Napredek odstranjevanja Preskoči Zaženi odstranjevalca Prekini Odpri mesto namestitve Lastnosti Nastavitve Id Pomoč Ročno odstrani 17, 17 True ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/UninstallProgressWindow.sv.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Status... Avbryt Status Tyst Namn Id Hoppa över Avsluta Kör avinstallerare nu Manuell avinstallation Öppna installationsmapp Egenskaper Valda avinstallationsprogram kommer nu att köras en åt gången. Om processen verkar fastna kan du klicka på knappen "Hoppa över" för att undvika att vänta på att den ska slutföras. Detta kan hända om avinstallationsprogrammet kraschar eller startar en ny process och inte stänger den. Kör avinstallation Hoppa över Avsluta Avinstallera manuellt Öppna installationsmapp Egenskaper Inställningar Hjälp Innehållet i denna lista kommer att avinstalleras från topp till botten. Avinstallationslista Sätt datorn i viloläge när den är klar Avinstallationsframsteg ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/UninstallProgressWindow.tr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Durum... Vazgeç Durum Sessiz Adı Id Seçilen kaldırıcılar artık tek seferde gerçekleştirilecek. İşlem sıkışmış gibi görünüyorsa, tamamlanmasını beklememek için "Atla" düğmesine tıklayabilirsiniz. Bu, kaldırıcı, yeni bir işlem başlatırsa veya yeni bir işlem başlatırsa ve kapatmazsa gerçekleşebilir. Kaldırıcıyı çalıştır Atla Sonlandır Manuel kaldır Kurulum konumunu aç Özellikler Ayarlar Yardım Bu listenin içeriği yukarıdan aşağıya doğru kaldırılacaktır. Kaldırılacaklar listesi Kaldırma ilerlemesi Atla Sonlandır Kaldırıcıyı şimdi çalıştırın Manuel kaldırma Yükleme dizinini açın Özellikler Bittiğinde bilgisayar uyku moduna geçsin ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/UninstallProgressWindow.vi.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Trạng thái... Huỷ Trạng thái Gỡ âm thầm Tên ID Bỏ qua Chấm dứt Khởi chạy ngay bây giờ Gỡ cài đặt thủ công Mở thư mục cài đặt Thuộc tính Các trình gỡ cài đặt đã chọn sẽ được chạy lần lượt. Nếu quá trình dường như bị kẹt, bạn có thể nhấp vào nút "Bỏ qua" để tránh phải đợi nó hoàn thành. Điều này có thể xảy ra nếu trình gỡ cài đặt bị lỗi hoặc khởi chạy một tiến trình mới và không đóng nó lại. Khởi chạy trình gỡ cài đặt Bỏ qua Chấm dứt Gỡ cài đặt thủ công Mở thư mục cài đặt Thuộc tính Cài đặt Trợ giúp Chúng sẽ được gỡ cài đặt theo thứ tự từ trên xuống. Danh sách trình gỡ cài đặt Thiết lập PC của bạn vào chế độ ngủ khi hoàn tất Tiến trình gỡ cài đặt ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/UninstallProgressWindow.zh-Hans.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 状态... 取消 状态 静默 名称 Id 跳过 终止 立即运行卸载程序 手动卸载 打开安装目录 属性 选中的卸载程序现在将一次执行一个。 如果进程似乎被卡住了,你可以点击“跳过”按钮,以避免等待它完成。如果卸载程序崩溃或启动新进程但未关闭它,则可能发生这种情况。 运行卸载程序 跳过 终止 手动卸载 打开安装位置 属性 设置 帮助 此列表的内容将自上而下卸载。 卸载程序列表 完成后将电脑置于睡眠状态 卸载进度 ================================================ FILE: source/BulkCrapUninstaller/Forms/Windows/UninstallProgressWindow.zh-Hant.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 狀態... 取消 狀態 安靜模式 名稱 ID 略過 中止 立即執行移除程式 手動解除安裝 開啟安裝目錄 屬性 選中的移除程式現在將一次執行一個。 如果過程似乎被卡住了,你可以點擊"略過"按鈕,以避免等待它完成。如果移除程式當機或啟動新程序但未關閉它,則可能發生這種情況。 執行移除程式 略過 中止 手動移除 開啟安裝位置 屬性 設定 幫助 此清單的內容將上而下移除。 移除程式清單 完成後將電腦睡眠 移除進度 ================================================ FILE: source/BulkCrapUninstaller/Forms/Wizards/BeginUninstallTaskWizard.Designer.cs ================================================ using BulkCrapUninstaller.Controls; namespace BulkCrapUninstaller.Forms { partial class BeginUninstallTaskWizard { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(BeginUninstallTaskWizard)); panelNavigation = new System.Windows.Forms.Panel(); labelProgress = new System.Windows.Forms.Label(); buttonExit = new System.Windows.Forms.Button(); buttonPrev = new System.Windows.Forms.Button(); panel4 = new System.Windows.Forms.Panel(); buttonNext = new System.Windows.Forms.Button(); panel1 = new System.Windows.Forms.Panel(); tabControl1 = new TabControlWithoutHeader(); tabPage1 = new System.Windows.Forms.TabPage(); relatedUninstallerAdder1 = new RelatedUninstallerAdder(); flowLayoutPanel5 = new System.Windows.Forms.FlowLayoutPanel(); p1Heading = new System.Windows.Forms.Label(); tabPage2 = new System.Windows.Forms.TabPage(); uninstallConfirmation1 = new UninstallConfirmation(); flowLayoutPanel4 = new System.Windows.Forms.FlowLayoutPanel(); label1 = new System.Windows.Forms.Label(); tabPage3 = new System.Windows.Forms.TabPage(); processWaiterControl1 = new Klocman.Forms.ProcessWaiterControl(); flowLayoutPanel3 = new System.Windows.Forms.FlowLayoutPanel(); label2 = new System.Windows.Forms.Label(); tabPage4 = new System.Windows.Forms.TabPage(); uninstallationSettings1 = new UninstallationSettings(); flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); label5 = new System.Windows.Forms.Label(); tabPage5 = new System.Windows.Forms.TabPage(); tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); labelOther = new System.Windows.Forms.Label(); label19 = new System.Windows.Forms.Label(); labelConcurrentEnabled = new System.Windows.Forms.Label(); label17 = new System.Windows.Forms.Label(); labelWillBeSilent = new System.Windows.Forms.Label(); label15 = new System.Windows.Forms.Label(); labelRestorePointCreated = new System.Windows.Forms.Label(); label13 = new System.Windows.Forms.Label(); labelFilesStillUsed = new System.Windows.Forms.Label(); label11 = new System.Windows.Forms.Label(); labelTotalSize = new System.Windows.Forms.Label(); label9 = new System.Windows.Forms.Label(); labelApps = new System.Windows.Forms.Label(); label7 = new System.Windows.Forms.Label(); button2 = new System.Windows.Forms.Button(); flowLayoutPanel2 = new System.Windows.Forms.FlowLayoutPanel(); label6 = new System.Windows.Forms.Label(); panelNavigation.SuspendLayout(); panel1.SuspendLayout(); tabControl1.SuspendLayout(); tabPage1.SuspendLayout(); flowLayoutPanel5.SuspendLayout(); tabPage2.SuspendLayout(); flowLayoutPanel4.SuspendLayout(); tabPage3.SuspendLayout(); flowLayoutPanel3.SuspendLayout(); tabPage4.SuspendLayout(); flowLayoutPanel1.SuspendLayout(); tabPage5.SuspendLayout(); tableLayoutPanel1.SuspendLayout(); flowLayoutPanel2.SuspendLayout(); SuspendLayout(); // // panelNavigation // panelNavigation.BackColor = System.Drawing.SystemColors.Control; panelNavigation.Controls.Add(labelProgress); panelNavigation.Controls.Add(buttonExit); panelNavigation.Controls.Add(buttonPrev); panelNavigation.Controls.Add(panel4); panelNavigation.Controls.Add(buttonNext); resources.ApplyResources(panelNavigation, "panelNavigation"); panelNavigation.Name = "panelNavigation"; // // labelProgress // resources.ApplyResources(labelProgress, "labelProgress"); labelProgress.ForeColor = System.Drawing.SystemColors.GrayText; labelProgress.Name = "labelProgress"; // // buttonExit // resources.ApplyResources(buttonExit, "buttonExit"); buttonExit.DialogResult = System.Windows.Forms.DialogResult.Cancel; buttonExit.Name = "buttonExit"; buttonExit.UseVisualStyleBackColor = true; // // buttonPrev // resources.ApplyResources(buttonPrev, "buttonPrev"); buttonPrev.Name = "buttonPrev"; buttonPrev.UseVisualStyleBackColor = true; buttonPrev.Click += buttonPrev_Click; // // panel4 // resources.ApplyResources(panel4, "panel4"); panel4.Name = "panel4"; // // buttonNext // resources.ApplyResources(buttonNext, "buttonNext"); buttonNext.Name = "buttonNext"; buttonNext.UseVisualStyleBackColor = true; buttonNext.Click += buttonNext_Click; // // panel1 // panel1.Controls.Add(tabControl1); resources.ApplyResources(panel1, "panel1"); panel1.Name = "panel1"; // // tabControl1 // tabControl1.Controls.Add(tabPage1); tabControl1.Controls.Add(tabPage2); tabControl1.Controls.Add(tabPage3); tabControl1.Controls.Add(tabPage4); tabControl1.Controls.Add(tabPage5); resources.ApplyResources(tabControl1, "tabControl1"); tabControl1.Multiline = true; tabControl1.Name = "tabControl1"; tabControl1.SelectedIndex = 0; tabControl1.TabStop = false; // // tabPage1 // tabPage1.Controls.Add(relatedUninstallerAdder1); tabPage1.Controls.Add(flowLayoutPanel5); resources.ApplyResources(tabPage1, "tabPage1"); tabPage1.Name = "tabPage1"; tabPage1.UseVisualStyleBackColor = true; // // relatedUninstallerAdder1 // resources.ApplyResources(relatedUninstallerAdder1, "relatedUninstallerAdder1"); relatedUninstallerAdder1.Name = "relatedUninstallerAdder1"; // // flowLayoutPanel5 // resources.ApplyResources(flowLayoutPanel5, "flowLayoutPanel5"); flowLayoutPanel5.Controls.Add(p1Heading); flowLayoutPanel5.Name = "flowLayoutPanel5"; // // p1Heading // resources.ApplyResources(p1Heading, "p1Heading"); p1Heading.Name = "p1Heading"; // // tabPage2 // tabPage2.Controls.Add(uninstallConfirmation1); tabPage2.Controls.Add(flowLayoutPanel4); resources.ApplyResources(tabPage2, "tabPage2"); tabPage2.Name = "tabPage2"; tabPage2.UseVisualStyleBackColor = true; // // uninstallConfirmation1 // resources.ApplyResources(uninstallConfirmation1, "uninstallConfirmation1"); uninstallConfirmation1.Name = "uninstallConfirmation1"; // // flowLayoutPanel4 // resources.ApplyResources(flowLayoutPanel4, "flowLayoutPanel4"); flowLayoutPanel4.Controls.Add(label1); flowLayoutPanel4.Name = "flowLayoutPanel4"; // // label1 // resources.ApplyResources(label1, "label1"); label1.Name = "label1"; // // tabPage3 // tabPage3.Controls.Add(processWaiterControl1); tabPage3.Controls.Add(flowLayoutPanel3); resources.ApplyResources(tabPage3, "tabPage3"); tabPage3.Name = "tabPage3"; tabPage3.UseVisualStyleBackColor = true; // // processWaiterControl1 // resources.ApplyResources(processWaiterControl1, "processWaiterControl1"); processWaiterControl1.Name = "processWaiterControl1"; processWaiterControl1.ShowIgnoreAndCancel = false; processWaiterControl1.AllProcessesClosed += processWaiterControl1_AllProcessesClosed; // // flowLayoutPanel3 // resources.ApplyResources(flowLayoutPanel3, "flowLayoutPanel3"); flowLayoutPanel3.Controls.Add(label2); flowLayoutPanel3.Name = "flowLayoutPanel3"; // // label2 // resources.ApplyResources(label2, "label2"); label2.Name = "label2"; // // tabPage4 // resources.ApplyResources(tabPage4, "tabPage4"); tabPage4.Controls.Add(uninstallationSettings1); tabPage4.Controls.Add(flowLayoutPanel1); tabPage4.Name = "tabPage4"; tabPage4.UseVisualStyleBackColor = true; // // uninstallationSettings1 // resources.ApplyResources(uninstallationSettings1, "uninstallationSettings1"); uninstallationSettings1.Name = "uninstallationSettings1"; // // flowLayoutPanel1 // resources.ApplyResources(flowLayoutPanel1, "flowLayoutPanel1"); flowLayoutPanel1.Controls.Add(label5); flowLayoutPanel1.Name = "flowLayoutPanel1"; // // label5 // resources.ApplyResources(label5, "label5"); flowLayoutPanel1.SetFlowBreak(label5, true); label5.Name = "label5"; // // tabPage5 // resources.ApplyResources(tabPage5, "tabPage5"); tabPage5.Controls.Add(tableLayoutPanel1); tabPage5.Controls.Add(button2); tabPage5.Controls.Add(flowLayoutPanel2); tabPage5.Name = "tabPage5"; tabPage5.UseVisualStyleBackColor = true; // // tableLayoutPanel1 // resources.ApplyResources(tableLayoutPanel1, "tableLayoutPanel1"); tableLayoutPanel1.Controls.Add(labelOther, 1, 6); tableLayoutPanel1.Controls.Add(label19, 0, 6); tableLayoutPanel1.Controls.Add(labelConcurrentEnabled, 1, 5); tableLayoutPanel1.Controls.Add(label17, 0, 5); tableLayoutPanel1.Controls.Add(labelWillBeSilent, 1, 4); tableLayoutPanel1.Controls.Add(label15, 0, 4); tableLayoutPanel1.Controls.Add(labelRestorePointCreated, 1, 3); tableLayoutPanel1.Controls.Add(label13, 0, 3); tableLayoutPanel1.Controls.Add(labelFilesStillUsed, 1, 2); tableLayoutPanel1.Controls.Add(label11, 0, 2); tableLayoutPanel1.Controls.Add(labelTotalSize, 1, 1); tableLayoutPanel1.Controls.Add(label9, 0, 1); tableLayoutPanel1.Controls.Add(labelApps, 1, 0); tableLayoutPanel1.Controls.Add(label7, 0, 0); tableLayoutPanel1.Name = "tableLayoutPanel1"; // // labelOther // resources.ApplyResources(labelOther, "labelOther"); labelOther.Name = "labelOther"; // // label19 // resources.ApplyResources(label19, "label19"); label19.Name = "label19"; // // labelConcurrentEnabled // resources.ApplyResources(labelConcurrentEnabled, "labelConcurrentEnabled"); labelConcurrentEnabled.Name = "labelConcurrentEnabled"; // // label17 // resources.ApplyResources(label17, "label17"); label17.Name = "label17"; // // labelWillBeSilent // resources.ApplyResources(labelWillBeSilent, "labelWillBeSilent"); labelWillBeSilent.Name = "labelWillBeSilent"; // // label15 // resources.ApplyResources(label15, "label15"); label15.Name = "label15"; // // labelRestorePointCreated // resources.ApplyResources(labelRestorePointCreated, "labelRestorePointCreated"); labelRestorePointCreated.Name = "labelRestorePointCreated"; // // label13 // resources.ApplyResources(label13, "label13"); label13.Name = "label13"; // // labelFilesStillUsed // resources.ApplyResources(labelFilesStillUsed, "labelFilesStillUsed"); labelFilesStillUsed.Name = "labelFilesStillUsed"; // // label11 // resources.ApplyResources(label11, "label11"); label11.Name = "label11"; // // labelTotalSize // resources.ApplyResources(labelTotalSize, "labelTotalSize"); labelTotalSize.Name = "labelTotalSize"; // // label9 // resources.ApplyResources(label9, "label9"); label9.Name = "label9"; // // labelApps // labelApps.AutoEllipsis = true; resources.ApplyResources(labelApps, "labelApps"); labelApps.Name = "labelApps"; // // label7 // resources.ApplyResources(label7, "label7"); label7.Name = "label7"; // // button2 // resources.ApplyResources(button2, "button2"); button2.Name = "button2"; button2.UseVisualStyleBackColor = true; button2.Click += button2_Click; // // flowLayoutPanel2 // resources.ApplyResources(flowLayoutPanel2, "flowLayoutPanel2"); flowLayoutPanel2.Controls.Add(label6); flowLayoutPanel2.Name = "flowLayoutPanel2"; // // label6 // resources.ApplyResources(label6, "label6"); flowLayoutPanel2.SetFlowBreak(label6, true); label6.Name = "label6"; // // BeginUninstallTaskWizard // AcceptButton = button2; resources.ApplyResources(this, "$this"); AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; BackColor = System.Drawing.SystemColors.ControlLightLight; CancelButton = buttonExit; Controls.Add(panel1); Controls.Add(panelNavigation); Name = "BeginUninstallTaskWizard"; FormClosed += BeginUninstallTaskWizard_FormClosed; panelNavigation.ResumeLayout(false); panelNavigation.PerformLayout(); panel1.ResumeLayout(false); tabControl1.ResumeLayout(false); tabPage1.ResumeLayout(false); tabPage1.PerformLayout(); flowLayoutPanel5.ResumeLayout(false); flowLayoutPanel5.PerformLayout(); tabPage2.ResumeLayout(false); tabPage2.PerformLayout(); flowLayoutPanel4.ResumeLayout(false); flowLayoutPanel4.PerformLayout(); tabPage3.ResumeLayout(false); tabPage3.PerformLayout(); flowLayoutPanel3.ResumeLayout(false); flowLayoutPanel3.PerformLayout(); tabPage4.ResumeLayout(false); tabPage4.PerformLayout(); flowLayoutPanel1.ResumeLayout(false); flowLayoutPanel1.PerformLayout(); tabPage5.ResumeLayout(false); tabPage5.PerformLayout(); tableLayoutPanel1.ResumeLayout(false); tableLayoutPanel1.PerformLayout(); flowLayoutPanel2.ResumeLayout(false); flowLayoutPanel2.PerformLayout(); ResumeLayout(false); } #endregion private System.Windows.Forms.Panel panelNavigation; private System.Windows.Forms.Label labelProgress; private System.Windows.Forms.Button buttonExit; private System.Windows.Forms.Button buttonPrev; private System.Windows.Forms.Panel panel4; private System.Windows.Forms.Button buttonNext; private System.Windows.Forms.TabPage tabPage2; private System.Windows.Forms.Panel panel1; private TabControlWithoutHeader tabControl1; private System.Windows.Forms.TabPage tabPage1; private RelatedUninstallerAdder relatedUninstallerAdder1; private UninstallConfirmation uninstallConfirmation1; private System.Windows.Forms.TabPage tabPage3; private Klocman.Forms.ProcessWaiterControl processWaiterControl1; private System.Windows.Forms.TabPage tabPage4; private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1; private UninstallationSettings uninstallationSettings1; private System.Windows.Forms.Label label5; private System.Windows.Forms.TabPage tabPage5; private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel2; private System.Windows.Forms.Label label6; private System.Windows.Forms.Button button2; private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; private System.Windows.Forms.Label labelOther; private System.Windows.Forms.Label label19; private System.Windows.Forms.Label labelConcurrentEnabled; private System.Windows.Forms.Label label17; private System.Windows.Forms.Label labelWillBeSilent; private System.Windows.Forms.Label label15; private System.Windows.Forms.Label labelRestorePointCreated; private System.Windows.Forms.Label label13; private System.Windows.Forms.Label labelFilesStillUsed; private System.Windows.Forms.Label label11; private System.Windows.Forms.Label labelTotalSize; private System.Windows.Forms.Label label9; private System.Windows.Forms.Label labelApps; private System.Windows.Forms.Label label7; private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel3; private System.Windows.Forms.Label label2; private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel5; private System.Windows.Forms.Label p1Heading; private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel4; private System.Windows.Forms.Label label1; } } ================================================ FILE: source/BulkCrapUninstaller/Forms/Wizards/BeginUninstallTaskWizard.ar.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 1 / 6 الغاء الامر للخلف استمرار التطبيقات ذات الصلة التي ترغب في الغاء تثبيتها ذات صلة تاكد من ان كل شيء ادناه امن لالغاء التثبيت التاكيد قد تحتاج بعض التطبيقات لتكون مغلقة قبل الغاء تثبيتها تشغيل انشاء نقطه استعاده قبل الغاء التثبيت يمكنك انشاء نقطه استعاده النظام الى تسجيل النسخ الاحتياطي ، وبعض الاعدادات والملفات. من المستحسن انشاء نقطه استعاده قبل ازاله برامج التشغيل وتطبيقات النظام الهامه. تحذير: يجب تمكين استعاده النظام لكي يعمل هذا! تغيير اعدادات الغاء التثبيت الاعدادات l l l l l l l غيرها/متفرقات تم تمكين الغاء التثبيت المتزامن الغاء التثبيت سيكون صامتا انشاء نقطه استعاده جديده لا تزال تستخدم الملفات من قبل تشغيل العمليات الحجم الإجمالي المقدر تطبيقات لالغاء التثبيت بدء الغاء التثبيت الرجاء التاكد من صحة المعلومات التالية قبل بدء عمليه الغاء التثبيت. هذه هي الفرصة الاخيره! نهائي بدء مهمة الغاء تثبيت جديده ================================================ FILE: source/BulkCrapUninstaller/Forms/Wizards/BeginUninstallTaskWizard.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; using BulkCrapUninstaller.Functions; using BulkCrapUninstaller.Functions.Tools; using BulkCrapUninstaller.Properties; using Klocman; using Klocman.Extensions; using Klocman.IO; using Klocman.Localising; using UninstallTools; using UninstallTools.Factory; using UninstallTools.Uninstaller; namespace BulkCrapUninstaller.Forms { public partial class BeginUninstallTaskWizard : Form { private bool _anyRelatedUninstallers; private List _otherUninstallers; private int _previousPageNumber; private bool _quiet; private ICollection _selectedUninstallers; public BeginUninstallTaskWizard() { InitializeComponent(); Icon = MessageBoxes.DefaultOwner.Icon; DialogResult = DialogResult.Cancel; tabControl1.TabIndex = 0; } private int PageNumber { get { return tabControl1.SelectedIndex; } set { tabControl1.SelectedIndex = value; UpdateState(); } } public IReadOnlyList Results { get; private set; } private void button2_Click(object sender, EventArgs e) { Results = uninstallConfirmation1.GetResults().ToArray(); DialogResult = DialogResult.OK; Close(); } private void buttonNext_Click(object sender, EventArgs e) { PageNumber = Math.Min(tabControl1.TabCount - 1, PageNumber + 1); } private void buttonPrev_Click(object sender, EventArgs e) { PageNumber = Math.Max(0, PageNumber - 1); } private List ConvertToTaskEntries(IEnumerable targets) { var targetList = new List(); foreach (var target in targets) { var tempStatus = UninstallStatus.Waiting; if (!target.IsValid) tempStatus = UninstallStatus.Invalid; else if (!Settings.Default.AdvancedDisableProtection && target.IsProtected) tempStatus = UninstallStatus.Protected; var silentPossible = _quiet && target.QuietUninstallPossible; targetList.Add(new BulkUninstallEntry(target, silentPossible, tempStatus)); } return targetList; } private static IEnumerable GetRelatedUninstallers( ApplicationUninstallerEntry thisUninstaller, IEnumerable other) { return other.Where(y => ApplicationEntryTools.AreEntriesRelated(thisUninstaller, y, -3)); } public void Initialize(ICollection selectedUninstallers, ICollection allUninstallers, bool quiet) { _quiet = quiet; _selectedUninstallers = selectedUninstallers; _otherUninstallers = allUninstallers .Except(_selectedUninstallers) .Where(x => !x.SystemComponent && !x.IsProtected) .ToList(); var relatedUninstallers = _otherUninstallers.Select( x => new { Entry = x, Related = GetRelatedUninstallers(x, _selectedUninstallers).ToList() }) .Where(x => x.Related.Any()).ToList(); relatedUninstallerAdder1.SetRelatedApps(relatedUninstallers .Select(x => new RelatedUninstallerAdder.RelatedApplicationEntry(x.Entry, x.Related))); _anyRelatedUninstallers = relatedUninstallers.Any(); if (!_anyRelatedUninstallers) PageNumber = 1; } private void processWaiterControl1_AllProcessesClosed(object sender, EventArgs e) { //if (PageNumber == 2) // PageNumber = 3; //todo show greeen text all closed? or skip when clicking next? slow } private static List SortTaskEntryList(List taskEntries) { return Settings.Default.AdvancedIntelligentUninstallerSorting ? AppUninstaller.SortIntelligently(taskEntries).ToList() : taskEntries.OrderBy(x => x.UninstallerEntry.DisplayName).ToList(); } private void UpdateState() { UseWaitCursor = true; Application.DoEvents(); switch (PageNumber) { case 0: break; case 1: { processWaiterControl1.StopUpdating(); var additionals = relatedUninstallerAdder1.GetResults(); var taskEntries = ConvertToTaskEntries(_selectedUninstallers.Concat(additionals)); taskEntries = SortTaskEntryList(taskEntries); uninstallConfirmation1.SetRelatedApps(taskEntries); } break; case 2: { /*if (taskEntries == null || taskEntries.Count == 0) return;*/ var selectedTaskEntries = uninstallConfirmation1.GetResults().ToList(); if (!selectedTaskEntries.Any()) { MessageBoxes.NoUninstallersSelectedInfo(); PageNumber = 1; return; } var relatedPids = AppUninstaller.GetRelatedProcessIds( selectedTaskEntries.Select(x => x.UninstallerEntry), !_quiet); if (relatedPids.Length == 0) { PageNumber = _previousPageNumber < 2 ? 3 : 1; return; } processWaiterControl1.Initialize(relatedPids, !_quiet); processWaiterControl1.StartUpdating(); } break; case 3: // Settings processWaiterControl1.StopUpdating(); break; case 4: // Final { var taskEntries = uninstallConfirmation1.GetResults().ToList(); labelApps.Text = string.Join(", ", taskEntries.Select(x => x.UninstallerEntry.DisplayName).OrderBy(x => x).ToArray()); labelTotalSize.Text = FileSize.SumFileSizes(taskEntries.Select(x => x.UninstallerEntry.EstimatedSize)).ToString(); labelConcurrentEnabled.Text = Settings.Default.UninstallConcurrency.ToYesNo(); labelFilesStillUsed.Text = processWaiterControl1.ProcessesStillRunning.ToYesNo(); labelRestorePointCreated.Text = (SysRestore.SysRestoreAvailable() ? Settings.Default.MessagesRestorePoints : YesNoAsk.No).GetLocalisedName(); labelWillBeSilent.Text = _quiet.ToYesNo(); labelOther.Text = Settings.Default.AdvancedSimulate ? "Simulating" : "-"; } break; } labelProgress.Text = PageNumber + 1 + " / " + tabControl1.TabCount; buttonPrev.Enabled = PageNumber > 0 && (PageNumber != 1 || _anyRelatedUninstallers); buttonNext.Enabled = PageNumber + 1 < tabControl1.TabCount; UseWaitCursor = false; _previousPageNumber = PageNumber; } private void BeginUninstallTaskWizard_FormClosed(object sender, FormClosedEventArgs e) { if (DialogResult != DialogResult.OK) SystemRestore.CancelSysRestore(); } } } ================================================ FILE: source/BulkCrapUninstaller/Forms/Wizards/BeginUninstallTaskWizard.cs.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 1 / 6 Zrušit Zpět Pokračovat Související aplikace, které budete chtít odinstalovat Související Potvrďte že všechno níže chcete bezpečně odinstalovat Potvrdit Před odinstalací může být nutné některé aplikace zavřít Spustit Před odinstalováním vytvořte bod obnovení Můžete vytvořit bod obnovení systému, zálohu registru, některá nastavení a soubory. Doporučujeme vytvořit bod obnovení před odebráním ovladačů a důležitých systémových aplikací. Upozornění: obnovení systému musí být povoleno, aby to fungovalo! Změnit nastavení odinstalace Nastavení l Ostatní / Různé l Souběžná odinstalace je povolena. l Tichá odinstalace l Vytvořit nový bod obnovení l Soubory jsou stále používány spuštěnými procesy. l Celková odhadovaná velikost l Aplikace k odinstalování ZAHÁJENÍ ODINSTALACE Před zahájením odinstalace se přesvědčte, zda jsou správné následující informace. Tohle je poslední šance! Závěr Zahájit novou odinstalační úlohu ================================================ FILE: source/BulkCrapUninstaller/Forms/Wizards/BeginUninstallTaskWizard.de.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 1/6 Abbruch Zurück Weiter Verwandte Anwendungen, die Sie möglicherweise deinstallieren möchten Verwandt Bestätigen Sie, dass alles, was unten aufgeführt ist, sicher deinstalliert werden kann Bestätigung Einige Anwendungen müssen geschlossen werden, bevor sie deinstalliert werden können Laufende Programme Wiederherstellungspunkt vor dem Deinstallieren erzeugen Sie können einen Systemwiederherstellungspunkt für die Backup-Registrierung, einigen Einstellungen und Dateien erstellen. Es wird empfohlen, vor dem Entfernen von Treibern und wichtigen Systemanwendungen einen Wiederherstellungspunkt zu erstellen. Achtung: Die Systemwiederherstellung muss aktiviert sein, damit dies funktioniert Ändere Uninstall Einstellungen Einstellungen l Anderes / Verschiedenes l Die gleichzeitige Deinstallation ist aktiviert l Die Installation wird "still" sein l Einen neuen Wiederherstellungspunkt setzen l Dateien werden weiterhin von laufenden Prozessen verwendet l Geschätzte Gesamtgröße l Anwendungen zum deinstallieren STARTE DEINSTALLATION Bitte stellen Sie sicher, dass die folgenden Informationen korrekt sind, bevor Sie mit der Deinstallation beginnen. Das ist die letzte Chance Ende Starte einen neuen Deinstallationstask ================================================ FILE: source/BulkCrapUninstaller/Forms/Wizards/BeginUninstallTaskWizard.es.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 1 / 6 Cancelar Atrás Continuar Aplicaciones relacionadas que quizás quieras desinstalar Relacionado Confirme que todo lo que se muestra a continuación sea seguro para desinstalar Confirmación Algunas aplicaciones pueden necesitar cerrarse antes de desinstalar Ejecutando Crear un punto de restauración antes de desinstalar Puede crear un punto de restauración del sistema para hacer una copia de seguridad del registro, algunas configuraciones y archivos. Se recomienda crear un punto de restauración antes de eliminar los controladores y las aplicaciones importantes del sistema. Advertencia: ¡La restauración del sistema debe estar habilitado para que esto funcione! Cambiar la configuración de desinstalación Configuración l Otros / Varios l La desinstalación simultánea está habilitada l La desinstalación será silenciosa l Crear un nuevo punto de restauración l Los archivos siguen siendo usados por los procesos en ejecución l Tamaño total estimado l Aplicaciones a desinstalar INICIAR LA DESINSTALACIÓN Asegúrese de que la siguiente información sea correcta antes de comenzar la desinstalación. ¡Esta es la última oportunidad! Finalización Iniciar nueva tarea de desinstalación ================================================ FILE: source/BulkCrapUninstaller/Forms/Wizards/BeginUninstallTaskWizard.fr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 1 / 6 Annuler Précédent Continuer Applications connexes que vous pouvez désinstaller Connexes Confirmez que tout ci-dessous est à désinstaller avec certitude Confirmation Certaines applications doivent peut-être être fermées avant désinstallation Applis en cours Changer les réglages de désinstallation Réglages | Autre / Divers | La désinstallation concurrence est activée | La désinstallation sera silencieuse | Créer un nouveau point de restauration | Des fichiers sont encore utilisés par des processus en cours | Taille totale estimée | Applications à désinstaller COMMENCER LA DESINSTALLATION Assurez-vous que les informations suivantes sont correctes avant de commencer la désinstallation. C'est la dernière chance ! Final Commencer une nouvelle tâche de désinstallation ================================================ FILE: source/BulkCrapUninstaller/Forms/Wizards/BeginUninstallTaskWizard.hu.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 1 / 6 Mégse Vissza Tovább Kapcsolódó Megerősítés Futó alkalmazások Beállítások l Egyéb l Egyidejű eltávolítás engedélyezve van l Csendes eltávolítás l Visszaállítási pont létrehozása l Futó programok használják a fájlokat l Becsült teljes méret l Eltávolítandó alkalmazások ELTÁVOLÍTÁS INDÍTÁSA Vége Hasonló alkalmazások, amelyeket esetleg érdemes eltávolítani Erősítse meg, hogy az alábbiak közül mindent biztonságosan el lehet távolítani Egyes alkalmazásokat az eltávolítás előtt lehet, hogy be kell zárni. Eltávolítási beállítások módosítása Az eltávolítás megkezdése előtt győződjön meg arról, hogy az alábbi adatok helyesek. Ez az utolsó lehetőség! Új eltávolítási feladat indítása ================================================ FILE: source/BulkCrapUninstaller/Forms/Wizards/BeginUninstallTaskWizard.it.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 1 / 6 Annulla Indietro Continua Applicazioni associate che potresti voler disinstallare Associato Conferma che ogni elemento in basso si può disinstallare in sicurezza Conferma Prima della disinstallazione potrebbe essere necessario chiudere le applicazioni In esecuzione Prima della disinstallazione crea un punto di ripristino Puoi creare un punto di ripristino del sistema per salvare il registro, alcune configurazioni e file. Ti raccomandiamo di creare un punto di ripristino prima di rimuovere le applicazioni. Attenzione: per funzionare il 'Ripristino di sistema' deve essere abilitato! Modifica impostazioni disinstallazione Impostazioni l Altro / varie l La disinstallazione simultanea è abilitata l La disinstallazione sarà silenziosa l Crea un nuovo punto di ripristino l I file sono ancora in uso da processi in esecuzione l Dimensione totale stimata l Applicazioni da disinstallare AVVIO DISINSTALLAZIONE Prima di avviare la disinstallazione assicurati che le seguenti informazioni siano corrette. Questa è l'ultima possibilità! Finale Avviamento nuova procedura di disinstallazione ================================================ FILE: source/BulkCrapUninstaller/Forms/Wizards/BeginUninstallTaskWizard.ja.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 1 / 6 l l l l l l l キャンセル 戻る 続ける 関連 確認 実行中のアプリ 設定 その他 同時アンインストールが有効になっています アンインストールはサイレントで行われます 新しい復元ポイントを作成 ファイルが実行中のプロセスによってまだ使用されています 推定合計サイズ アンインストールするアプリケーション アンインストールを開始 最終確認 アンインストールしたい関連アプリケーション 以下のすべてが安全にアンインストールできることを確認してください 一部のアプリケーションはアンインストール前に閉じる必要があります アンインストール設定を変更 アンインストールを開始する前に、以下の情報が正しいことを確認してください。これが最後のチャンスです! 新しいアンインストールタスクを開始 ================================================ FILE: source/BulkCrapUninstaller/Forms/Wizards/BeginUninstallTaskWizard.nl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 1 / 6 Annuleren Vorige Volgende Gerelateerde programma's die u wilt de-installeren Gerelateerd Bevestig dat alles hieronder veilig is om te de-installeren Bevestiging Sommige programma's moeten mogelijk worden afgesloten voor de-installatie Loopt nog Maak een herstelpunt alvorens te de-installeren U kunt een systeem herstelpunt maken voor een back-up van het register, sommige instellingen en bestanden. Het wordt aanbevolen om een herstelpunt te maken voor het verwijderen van stuurprogramma's en belangrijke systeem programma's. Waarschuwing: Systeemherstel moet ingeschakeld zijn om dit te laten werken! Wijzig de-installatie instellingen Instellingen l Anders / Divers l Gelijktijdig de-installeren is ingeschakeld l De-installatie zal 'stil' verlopen l Maak een nieuw herstelpunt Bestanden worden nog gebruikt door lopende processen l Totaal geschatte grootte l Programma's om te de-installeren START DE-INSTALLATIE Wees er van overtuigd dat de volgende informatie juist is, alvorens de de-installatie te starten. Dit is uw laatste kans! Finale Start nieuwe de-installatie taak l ================================================ FILE: source/BulkCrapUninstaller/Forms/Wizards/BeginUninstallTaskWizard.pl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 1 / 6 Anuluj Wstecz Dalej Powiązane aplikacje które możesz odinstalować Powiazane Potwierdź programy do odinstalowania Potwierdzenie Niektóre aplikacje moga wymagac zamkniecia przed odinstalowaniem Uruchomione Utwórz punkt przywracania przed odinstalowaniem Możesz utworzyć systemowy punkt przywracania systemu (zachowuje rejestr, niektóre ustawienia i pliki). Zaleca się utworzenie punktu przywracania przed usunięciem sterowników i ważnych aplikacji systemowych. Ostrzezenie: Przywracanie systemu musi byc wlaczone aby to dzialalo! Zmien ustawienia deinstalacji Ustawienia l Inne l Odinstalowuj kilka równocześnie l Deinstalacja będzie cicha l Utwórz nowy punkt przywracania l Pliki są nadal używane przez procesy l Całkowity szacowany rozmiar l Aplikacje do odinstalowania ROZPOCZNIJ DEZINSTALACJĘ Przed rozpoczęciem deinstalacji upewnij się, że poniższe informacje są poprawne. To jest ostatnia szansa! Final Rozpocznij nowe zadanie dezinstalacji ================================================ FILE: source/BulkCrapUninstaller/Forms/Wizards/BeginUninstallTaskWizard.pt-BR.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 1 / 6 Cancelar Voltar Continuar Relacionado Confirmação Aplicativos em execução Configuração | Outros / Misc | Desinstalação simultâmea ativada | Desinstalação será silenciosa | Criar novo ponto de restauração | Arquivos em uso por processos em execução | Tamanho total estimado | Aplicações para desinstalar COMEÇAR DESINSTALAÇÃO Final Aplicações relacionadas que talvez queira desinstalar Confirme que tudo abaixo é seguro para desinstalar Pode ser necessário fechar algumas aplicações antes de desinstalar Mudar configuração de desinstalação Por favor tenha certeza que as informações estão corretas antes de começar a desinstalação. Essa é a última chance! Iniciar uma nova tarefa de desinstalação ================================================ FILE: source/BulkCrapUninstaller/Forms/Wizards/BeginUninstallTaskWizard.pt.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 1 / 6 Cancelar Recuar Continuar Aplicações relacionadas que possa querer desinstalar Relacionado Confirme que é seguro desinstalar tudo o que é descrito abaixo Confirmação Algumas aplicacões poderão ter de ser fechadas antes de serem desinstaladas. A correr Criar um ponto de restauro antes de desinstalar Pode criar um ponto de restauro do sistema para o registo de backup, de algumas configurações e de arquivos. Recomenda-se criar um ponto de restauro antes de remover drivers e aplicativos importantes do sistema. Aviso: o restauro do sistema deve estar activo para que isto funcione! Alterar as configurações de desinstalação Configurações l Outros / Miscelânea l A desinstalação simultânea está activada l l l l l A desinstalação far-se-á em segundo plano Criar um novo ponto de restauro Os arquivos ainda são a ser usados pelos processos em curso Tamanho total estimado Aplicações para desinstalar COMEÇAR A DESINSTALAÇÃO Certifique-se de que a seguinte informação está correcta antes de iniciar a desinstalação. Esta é a última oportunidade! Final Inicie uma nova tarefa de desinstalação ================================================ FILE: source/BulkCrapUninstaller/Forms/Wizards/BeginUninstallTaskWizard.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Fill Microsoft Sans Serif, 9.75pt, style=Bold NoControl 123, 13 4, 0, 4, 0 210, 28 9 1 / 6 MiddleCenter labelProgress System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panelNavigation 0 True Left NoControl 13, 13 4, 3, 4, 3 110, 28 2 Cancel buttonExit System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panelNavigation 1 True Right False NoControl 333, 13 4, 3, 4, 3 88, 28 1 Back buttonPrev System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panelNavigation 2 Right 421, 13 4, 3, 4, 3 12, 28 3 panel4 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panelNavigation 3 True Right NoControl 433, 13 4, 3, 4, 3 88, 28 0 Continue buttonNext System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panelNavigation 4 Bottom 0, 487 4, 3, 4, 3 13, 13, 13, 13 534, 54 0 panelNavigation System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 1 Fill 4, 29 5, 3, 5, 3 7, 7, 7, 7 518, 427 1 relatedUninstallerAdder1 BulkCrapUninstaller.Forms.RelatedUninstallerAdder, BCUninstaller, Culture=neutral, PublicKeyToken=null tabPage1 0 True True Top Arial Black, 12pt, style=Bold NoControl 4, 0 4, 0, 4, 0 0, 0, 0, 3 437, 26 1 Related applications you might want to uninstall p1Heading System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel5 0 Top 4, 3 4, 3, 4, 3 518, 26 2 flowLayoutPanel5 System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tabPage1 1 4, 24 4, 3, 4, 3 4, 3, 4, 3 526, 459 0 Related tabPage1 System.Windows.Forms.TabPage, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tabControl1 0 Fill 4, 75 5, 3, 5, 3 7, 7, 7, 7 184, 0 0 uninstallConfirmation1 BulkCrapUninstaller.Forms.UninstallConfirmation, BCUninstaller, Culture=neutral, PublicKeyToken=null tabPage2 0 True True Top Arial Black, 12pt, style=Bold NoControl 4, 0 4, 0, 4, 0 0, 0, 0, 3 172, 72 12 Confirm that everything below is safe to uninstall label1 System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel4 0 Top 4, 3 4, 3, 4, 3 184, 72 12 flowLayoutPanel4 System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tabPage2 1 4, 44 4, 3, 4, 3 4, 3, 4, 3 192, 52 1 Confirmation tabPage2 System.Windows.Forms.TabPage, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tabControl1 1 Fill 4, 98 5, 3, 5, 3 7, 7, 7, 7 184, 0 13 processWaiterControl1 Klocman.Forms.ProcessWaiterControl, KlocTools, Culture=neutral, PublicKeyToken=null tabPage3 0 True True Top Arial Black, 12pt, style=Bold NoControl 4, 0 4, 0, 4, 0 0, 0, 0, 3 174, 95 13 Some applications might need to be closed before uninstalling label2 System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel3 0 Top 4, 3 4, 3, 4, 3 184, 95 14 flowLayoutPanel3 System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tabPage3 1 4, 44 4, 3, 4, 3 4, 3, 4, 3 192, 52 2 Running apps tabPage3 System.Windows.Forms.TabPage, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tabControl1 2 True True GrowAndShrink Top 51, 167 5, 3, 5, 3 7, 7, 7, 7 73, 433 1 uninstallationSettings1 BulkCrapUninstaller.Controls.UninstallationSettings, BCUninstaller, Culture=neutral, PublicKeyToken=null tabPage4 0 True GrowAndShrink True Top Arial Black, 12pt, style=Bold NoControl 4, 0 4, 0, 4, 0 0, 0, 0, 3 65, 164 3 Change uninstallation settings label5 System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel1 0 Top TopDown 51, 3 4, 3, 4, 3 73, 164 0 False flowLayoutPanel1 System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tabPage4 1 4, 44 4, 3, 4, 3 51, 3, 51, 3 192, 52 3 Settings tabPage4 System.Windows.Forms.TabPage, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tabControl1 3 True 300, 400 Single 2 True Left NoControl 154, 250 4, 0, 4, 0 10, 23 13 l MiddleLeft labelOther System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tableLayoutPanel1 0 True Right NoControl 72, 250 4, 0, 4, 0 73, 23 12 Other / Misc MiddleRight label19 System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tableLayoutPanel1 1 True Left NoControl 154, 226 4, 0, 4, 0 10, 23 11 l MiddleLeft labelConcurrentEnabled System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tableLayoutPanel1 2 True Right NoControl 10, 226 4, 0, 4, 0 135, 23 10 Concurrent uninstallation is enabled MiddleRight label17 System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tableLayoutPanel1 3 True Left NoControl 154, 202 4, 0, 4, 0 10, 23 9 l MiddleLeft labelWillBeSilent System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tableLayoutPanel1 4 True Right NoControl 28, 202 4, 0, 4, 0 117, 23 8 Uninstallation will be silent MiddleRight label15 System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tableLayoutPanel1 5 True Left NoControl 154, 178 4, 0, 4, 0 10, 23 7 l MiddleLeft labelRestorePointCreated System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tableLayoutPanel1 6 True Right NoControl 31, 178 4, 0, 4, 0 114, 23 6 Create a new restore point MiddleRight label13 System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tableLayoutPanel1 7 True Left NoControl 154, 154 4, 0, 4, 0 10, 23 5 l MiddleLeft labelFilesStillUsed System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tableLayoutPanel1 8 True Right NoControl 31, 154 4, 0, 4, 0 114, 23 4 Files are still used by running processes MiddleRight label11 System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tableLayoutPanel1 9 True Left NoControl 154, 130 4, 0, 4, 0 10, 23 3 l MiddleLeft labelTotalSize System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tableLayoutPanel1 10 True Right NoControl 36, 130 4, 0, 4, 0 109, 23 2 Total estimated size MiddleRight label9 System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tableLayoutPanel1 11 True Left NoControl 154, 14 4, 0, 4, 0 10, 115 1 l MiddleLeft labelApps System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tableLayoutPanel1 12 True Right NoControl 10, 14 4, 0, 4, 0 135, 115 0 Applications to uninstall MiddleRight label7 System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tableLayoutPanel1 13 Fill 45, 115 4, 3, 4, 3 0, 13, 0, 13 7 300, 267 1 tableLayoutPanel1 System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tabPage5 0 <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="labelOther" Row="6" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="label19" Row="6" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="labelConcurrentEnabled" Row="5" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="label17" Row="5" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="labelWillBeSilent" Row="4" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="label15" Row="4" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="labelRestorePointCreated" Row="3" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="label13" Row="3" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="labelFilesStillUsed" Row="2" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="label11" Row="2" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="labelTotalSize" Row="1" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="label9" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="labelApps" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="label7" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Percent,49.83923,Percent,50.16077" /><Rows Styles="Absolute,115,Absolute,23,Absolute,23,Absolute,23,Absolute,23,Absolute,23,Absolute,23" /></TableLayoutSettings> Bottom NoControl 45, 382 4, 3, 4, 3 300, 38 2 BEGIN UNINSTALLATION button2 System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tabPage5 1 True GrowAndShrink True Top Arial Black, 12pt, style=Bold NoControl 4, 0 4, 0, 4, 0 0, 0, 0, 3 288, 95 0 Please make sure the following information is correct before starting the uninstallation. This is the last chance! TopCenter label6 System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel2 0 Top 45, 20 4, 3, 4, 3 300, 95 0 flowLayoutPanel2 System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tabPage5 2 4, 44 4, 3, 4, 3 45, 20, 45, 20 192, 52 4 Final tabPage5 System.Windows.Forms.TabPage, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 tabControl1 4 Fill 0, 0 0, 0, 0, 0 534, 487 0 tabControl1 BulkCrapUninstaller.Controls.TabControlWithoutHeader, BCUninstaller, Culture=neutral, PublicKeyToken=null panel1 0 Fill 0, 0 4, 3, 4, 3 534, 487 0 panel1 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 0 True 7, 15 534, 541 4, 3, 4, 3 500, 400 CenterParent Begin new uninstallation task BeginUninstallTaskWizard System.Windows.Forms.Form, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 ================================================ FILE: source/BulkCrapUninstaller/Forms/Wizards/BeginUninstallTaskWizard.ru.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Отмена Назад Продолжить Связанные приложения, которые Вы, возможно, захотите удалить Связанные Убедитесь, что всё, что ниже, безопасно для удаления Подтверждение Некоторые приложения, возможно, потребуется закрыть перед удалением Запущенно Создание точки восстановления перед удалением Можно создать точку восстановления системы. Рекомендуется создать точку восстановления перед удалением драйверов и важных системных приложений. Предупреждение: для этого должно быть включено восстановление системы! Изменение параметров удаления Параметры Другое / Разное Одновременное удаление включено Удаление будет тихим Создание новой точки восстановления Файлы используются запущенными процессами Общий оценочный размер Приложения для удаления НАЧАТЬ УДАЛЕНИЕ Перед началом удаления убедитесь, что следующая информация верна. Это последний шанс! Завершение Начать новую задачу удаления | | | | | | | 1 / 6 ================================================ FILE: source/BulkCrapUninstaller/Forms/Wizards/BeginUninstallTaskWizard.sl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 1 / 6 Prekliči Nazaj Nadaljuj Povezane aplikacije, ki jih morda želite odstraniti Povezana Potrdite, da je vse spodaj varno odstraniti Potrditev Nekatere aplikacije je morda treba zapreti, preden jih odstranite Delovanje Preden odstranite program, ustvarite obnovitveno točko Ustvarite lahko obnovitveno točko sistema za varnostni kopirni register, nekatere nastavitve in datoteke. Pred odstranjevanjem gonilnikov in pomembnih sistemskih aplikacij priporočamo, da ustvarite obnovitveno točko. Opozorilo: Obnovitev sistema mora biti omogočena, da bo to delovalo! Spremeni nastavitve odstranitve Nastavitve l Drugo/Razno l Sočasna odstranitev je omogočena l Odstranitev bo tiha l Ustvari novo obnovitveno točko l Datoteke še vedno uporabljajo delujoči procesi l Skupna ocenjena velikost l Aplikacije za odstranitev ZAČETEK ODSTRANITVE Prepričajte se, da so naslednji podatki pravilni, preden začnete z odstranitvijo. To je zadnja priložnost! Končno Začni novo odstranjevanje ================================================ FILE: source/BulkCrapUninstaller/Forms/Wizards/BeginUninstallTaskWizard.sv.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 1 / 6 Avbryta Tillbaka Fortsätt Relaterat Bekräftelse Appar som körs Inställningar l Annat / Övrigt l Samtidig avinstallation är aktiverad l Avinstallationen kommer att vara tyst l Skapa ny återställningspunkt l Filer används fortfarande av körande processer l Totalt beräknad storlek l Appar att avinstallera PÅBÖRJA AVINSTALLATION Avslutningsvis Relaterade appar som du kanske vill avinstallera Bekräfta att allt nedan är säkert att avinstallera Vissa appar kanske behöver stängas innan avinstallation Ändra avinstallations-inställningar Kontrollera att följande information är korrekt innan du påbörjar avinstallationen. Detta är sista chansen! Börja ny avinstallationsuppgift Skapa en återställningspunkt innan avinstallationen Du kan skapa en systemåterställningspunkt för att säkerhetskopiera registret, vissa inställningar och filer. Det rekommenderas att skapa en återställningspunkt innan du tar bort drivrutiner och viktiga systemprogram. Notera: Systemåterställning måste vara aktiverat för att detta ska fungera ================================================ FILE: source/BulkCrapUninstaller/Forms/Wizards/BeginUninstallTaskWizard.tr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 1 / 6 Vazgeç Geri Devam Kaldırmak isteyebileceğiniz ilgili uygulamalar İlgili Aşağıdaki her şeyin kaldırılmasının güvenli olduğunu doğrulayın Onayla Bazı uygulamaların kaldırılmadan önce kapatılması gerekebilir Çalışan uygulamalar Kaldırmadan önce bir geri yükleme noktası oluşturun Kayıt defterini, bazı ayarları ve dosyaları yedeklemek için bir sistem geri yükleme noktası oluşturabilirsiniz. Sürücüleri ve önemli sistem uygulamalarını kaldırmadan önce bir geri yükleme noktası oluşturmanız önerilir. Uyarı: Bunun çalışması için sistem geri yüklemesi etkinleştirilmelidir! Kaldırma ayarlarının değiştirilmesi Ayarlar l Diğer / Çeşitli l Eşzamanlı kaldırma etkinleştirildi l Kaldırma işlemi sessiz olacak l Yeni bir geri yükleme noktası oluştur l Dosyalar hala çalışan işlemler tarafından kullanılıyor l Toplam tahmini boyut l Kaldırılacak uygulamalar KALDIRMA İŞLEMİNE BAŞLA Kaldırma işlemine başlamadan önce aşağıdaki bilgilerin doğru olduğundan emin olun. Bu son şans! Tamamlandı Yeni kaldırma görevine başla ================================================ FILE: source/BulkCrapUninstaller/Forms/Wizards/BeginUninstallTaskWizard.vi.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 1 / 6 Huỷ Trờ về Tiếp tục Có liên quan đến Xác nhận Các ứng dụng đang khởi chạy Cài đặt l Khác / Lặt vặt l Cho phép gỡ cài đặt đồng thời l Gỡ cài đặt âm thầm l Tạo một điểm khôi phục mới l Đang được sử dụng bởi tiến trình khác l Ước tính kích thước tổng l Các ứng dụng cần gỡ cài đặt BẮT ĐẦU QUÁ TRÌNH GỠ CÀI ĐẶT Phần cuối Các ứng dụng có liên quan mà bạn có thể muốn gỡ cài đặt Xác nhận rằng những mục dưới đây không có vấn đề gì khi gỡ cài đặt Một số ứng dụng có thể cần được đóng lại trước khi gỡ cài đặt Thay đổi cài đặt mặc định của bạn Vui lòng xác nhận rằng tất cả thông tin dưới đây là chính xác trước khi bắt đầu gỡ cài đặt. Đây là lần cơ hội cuối cùng của bạn! Bắt đầu quá trình gỡ cài đặt mới ================================================ FILE: source/BulkCrapUninstaller/Forms/Wizards/BeginUninstallTaskWizard.zh-Hans.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 1 / 6 取消 返回 继续 相关 确认 运行应用 更改卸载设置 设置 结束 你可能想卸载的相关应用程序 确认以下所有内容都可以安全卸载 某些应用程序可能需要在卸载前关闭 l 其他/杂项 l 同时卸载已启用 l 卸载将静默 l 创建新的还原点 l 文件仍被正在运行的进程使用 l 估计总大小 l 要卸载的应用程序 开始卸载 开始卸载前,请确保以下信息正确无误。这是最后的机会了! 开始新的卸载任务 ================================================ FILE: source/BulkCrapUninstaller/Forms/Wizards/BeginUninstallTaskWizard.zh-Hant.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 1/6 取消 返回 繼續 相關 確認 執行應用 設定 I 其他/雜項 I 同時移除已啟用 I 移除過程將最小化 l 建立新的還原點 l 檔案被在執行的程序使用 l 預估總大小 l 要移除的應用程式 開始解除安裝 結束 你可能想移除的相關應用程式 確認以下所有內容都可以安全解除安裝 某些應用程式可能需要在移除前關閉 更改移除設定 開始移除前,請確保以下資訊正確無誤。這是最後的機會了! 開始新的移除任務 ================================================ FILE: source/BulkCrapUninstaller/Forms/Wizards/FirstStartBox.Designer.cs ================================================ namespace BulkCrapUninstaller.Forms { partial class FirstStartBox { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { components = new System.ComponentModel.Container(); System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FirstStartBox)); panelNavigation = new System.Windows.Forms.Panel(); labelProgress = new System.Windows.Forms.Label(); buttonExit = new System.Windows.Forms.Button(); buttonPrev = new System.Windows.Forms.Button(); panel4 = new System.Windows.Forms.Panel(); buttonNext = new System.Windows.Forms.Button(); scrollPanel = new System.Windows.Forms.Panel(); panel3 = new System.Windows.Forms.Panel(); panel2 = new System.Windows.Forms.Panel(); page5 = new System.Windows.Forms.Panel(); panel12 = new System.Windows.Forms.Panel(); buttonMore = new System.Windows.Forms.Button(); buttonHelp = new System.Windows.Forms.Button(); buttonFinish = new System.Windows.Forms.Button(); flowLayoutPanel6 = new System.Windows.Forms.FlowLayoutPanel(); p5finishContact = new System.Windows.Forms.Label(); p5LinkContact = new System.Windows.Forms.LinkLabel(); p5finishHomepage = new System.Windows.Forms.Label(); p5LinkHomepage = new System.Windows.Forms.LinkLabel(); p5finishTitle = new System.Windows.Forms.Label(); spacer4 = new System.Windows.Forms.Panel(); pageNetwork = new System.Windows.Forms.Panel(); flowLayoutPanel2 = new System.Windows.Forms.FlowLayoutPanel(); p4netTitle = new System.Windows.Forms.Label(); p4netDesc = new System.Windows.Forms.Label(); p4netDesc1 = new System.Windows.Forms.Label(); p4netDesc2 = new System.Windows.Forms.Label(); p4netDesc3 = new System.Windows.Forms.Label(); p4netDesc4 = new System.Windows.Forms.Label(); p4netErrors = new System.Windows.Forms.Label(); checkBoxUpdateSearch = new System.Windows.Forms.CheckBox(); p4netUpdateAdd = new System.Windows.Forms.Label(); checkBoxSendStats = new System.Windows.Forms.CheckBox(); p4netUsageAdd = new System.Windows.Forms.Label(); checkBoxRatings = new System.Windows.Forms.CheckBox(); panel5 = new System.Windows.Forms.Panel(); pageCorrupted = new System.Windows.Forms.Panel(); flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); pCorTitle = new System.Windows.Forms.Label(); pCorDesc = new System.Windows.Forms.Label(); pCorViewInvalidTitle = new System.Windows.Forms.Label(); pCorViewInvalid = new System.Windows.Forms.Label(); checkBoxInvalidTest = new System.Windows.Forms.CheckBox(); pCorViewinvalidComment = new System.Windows.Forms.Label(); pCorOrphansTitle = new System.Windows.Forms.Label(); pCorOrphansMessage = new System.Windows.Forms.Label(); checkBoxOrphans = new System.Windows.Forms.CheckBox(); pCorOrphansComment = new System.Windows.Forms.Label(); spacer3 = new System.Windows.Forms.Panel(); page3 = new System.Windows.Forms.Panel(); flowLayoutPanel4 = new System.Windows.Forms.FlowLayoutPanel(); p3advTitle = new System.Windows.Forms.Label(); p3advDesc = new System.Windows.Forms.Label(); p3advSyscompTitle = new System.Windows.Forms.Label(); p3advSyscomp = new System.Windows.Forms.Label(); checkBoxListSysComp = new System.Windows.Forms.CheckBox(); p3advProtectTitle = new System.Windows.Forms.Label(); p3advProtect = new System.Windows.Forms.Label(); checkBoxListProtected = new System.Windows.Forms.CheckBox(); checkBoxDiisableProtection = new System.Windows.Forms.CheckBox(); p3advProtectAdd = new System.Windows.Forms.Label(); spacer2 = new System.Windows.Forms.Panel(); page2 = new System.Windows.Forms.Panel(); flowLayoutPanel3 = new System.Windows.Forms.FlowLayoutPanel(); p2viewTitle = new System.Windows.Forms.Label(); p2viewDetail = new System.Windows.Forms.Label(); p2viewDetail1 = new System.Windows.Forms.Label(); p2viewDetail2 = new System.Windows.Forms.Label(); p2viewDetail3 = new System.Windows.Forms.Label(); checkBoxGroups = new System.Windows.Forms.CheckBox(); checkBoxCheckboxes = new System.Windows.Forms.CheckBox(); p2viewCertsTitle = new System.Windows.Forms.Label(); p2viewCerts = new System.Windows.Forms.Label(); checkBoxCertTest = new System.Windows.Forms.CheckBox(); p2viewAdd = new System.Windows.Forms.Label(); spacer1 = new System.Windows.Forms.Panel(); page1 = new System.Windows.Forms.Panel(); flowLayoutPanel5 = new System.Windows.Forms.FlowLayoutPanel(); p1welcomeHeading = new System.Windows.Forms.Label(); p1welcomeSubheading = new System.Windows.Forms.Label(); p1languageHeading = new System.Windows.Forms.Label(); p1languageDesc = new System.Windows.Forms.Label(); panel9 = new System.Windows.Forms.Panel(); comboBoxLanguage = new System.Windows.Forms.ComboBox(); buttonLanguageApply = new System.Windows.Forms.Button(); p1languageExtradetails = new System.Windows.Forms.Label(); p1linkLabelContact = new System.Windows.Forms.LinkLabel(); panel1 = new System.Windows.Forms.Panel(); pictureBox1 = new System.Windows.Forms.PictureBox(); label2 = new System.Windows.Forms.Label(); timer1 = new System.Windows.Forms.Timer(components); panelNavigation.SuspendLayout(); scrollPanel.SuspendLayout(); page5.SuspendLayout(); panel12.SuspendLayout(); flowLayoutPanel6.SuspendLayout(); pageNetwork.SuspendLayout(); flowLayoutPanel2.SuspendLayout(); pageCorrupted.SuspendLayout(); flowLayoutPanel1.SuspendLayout(); page3.SuspendLayout(); flowLayoutPanel4.SuspendLayout(); page2.SuspendLayout(); flowLayoutPanel3.SuspendLayout(); page1.SuspendLayout(); flowLayoutPanel5.SuspendLayout(); panel9.SuspendLayout(); panel1.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)pictureBox1).BeginInit(); SuspendLayout(); // // panelNavigation // panelNavigation.BackColor = System.Drawing.SystemColors.Control; panelNavigation.Controls.Add(labelProgress); panelNavigation.Controls.Add(buttonExit); panelNavigation.Controls.Add(buttonPrev); panelNavigation.Controls.Add(panel4); panelNavigation.Controls.Add(buttonNext); resources.ApplyResources(panelNavigation, "panelNavigation"); panelNavigation.Name = "panelNavigation"; // // labelProgress // resources.ApplyResources(labelProgress, "labelProgress"); labelProgress.ForeColor = System.Drawing.SystemColors.GrayText; labelProgress.Name = "labelProgress"; // // buttonExit // resources.ApplyResources(buttonExit, "buttonExit"); buttonExit.DialogResult = System.Windows.Forms.DialogResult.Cancel; buttonExit.Name = "buttonExit"; buttonExit.UseVisualStyleBackColor = true; buttonExit.Click += CloseWizard; // // buttonPrev // resources.ApplyResources(buttonPrev, "buttonPrev"); buttonPrev.Name = "buttonPrev"; buttonPrev.UseVisualStyleBackColor = true; buttonPrev.Click += buttonPrev_Click; // // panel4 // resources.ApplyResources(panel4, "panel4"); panel4.Name = "panel4"; // // buttonNext // resources.ApplyResources(buttonNext, "buttonNext"); buttonNext.Name = "buttonNext"; buttonNext.UseVisualStyleBackColor = true; buttonNext.Click += buttonNext_Click; // // scrollPanel // resources.ApplyResources(scrollPanel, "scrollPanel"); scrollPanel.Controls.Add(panel3); scrollPanel.Controls.Add(panel2); scrollPanel.Controls.Add(page5); scrollPanel.Controls.Add(spacer4); scrollPanel.Controls.Add(pageNetwork); scrollPanel.Controls.Add(panel5); scrollPanel.Controls.Add(pageCorrupted); scrollPanel.Controls.Add(spacer3); scrollPanel.Controls.Add(page3); scrollPanel.Controls.Add(spacer2); scrollPanel.Controls.Add(page2); scrollPanel.Controls.Add(spacer1); scrollPanel.Controls.Add(page1); scrollPanel.Name = "scrollPanel"; // // panel3 // resources.ApplyResources(panel3, "panel3"); panel3.Name = "panel3"; // // panel2 // resources.ApplyResources(panel2, "panel2"); panel2.Name = "panel2"; // // page5 // page5.Controls.Add(panel12); page5.Controls.Add(flowLayoutPanel6); page5.Controls.Add(p5finishTitle); resources.ApplyResources(page5, "page5"); page5.Name = "page5"; // // panel12 // panel12.Controls.Add(buttonMore); panel12.Controls.Add(buttonHelp); panel12.Controls.Add(buttonFinish); resources.ApplyResources(panel12, "panel12"); panel12.Name = "panel12"; // // buttonMore // resources.ApplyResources(buttonMore, "buttonMore"); buttonMore.DialogResult = System.Windows.Forms.DialogResult.Cancel; buttonMore.Name = "buttonMore"; buttonMore.UseVisualStyleBackColor = true; buttonMore.Click += buttonMore_Click; // // buttonHelp // resources.ApplyResources(buttonHelp, "buttonHelp"); buttonHelp.DialogResult = System.Windows.Forms.DialogResult.Cancel; buttonHelp.Name = "buttonHelp"; buttonHelp.UseVisualStyleBackColor = true; buttonHelp.Click += buttonHelp_Click; // // buttonFinish // resources.ApplyResources(buttonFinish, "buttonFinish"); buttonFinish.DialogResult = System.Windows.Forms.DialogResult.Cancel; buttonFinish.Name = "buttonFinish"; buttonFinish.UseVisualStyleBackColor = true; buttonFinish.Click += CloseWizard; // // flowLayoutPanel6 // resources.ApplyResources(flowLayoutPanel6, "flowLayoutPanel6"); flowLayoutPanel6.Controls.Add(p5finishContact); flowLayoutPanel6.Controls.Add(p5LinkContact); flowLayoutPanel6.Controls.Add(p5finishHomepage); flowLayoutPanel6.Controls.Add(p5LinkHomepage); flowLayoutPanel6.Name = "flowLayoutPanel6"; // // p5finishContact // resources.ApplyResources(p5finishContact, "p5finishContact"); p5finishContact.Name = "p5finishContact"; // // p5LinkContact // resources.ApplyResources(p5LinkContact, "p5LinkContact"); p5LinkContact.Name = "p5LinkContact"; p5LinkContact.TabStop = true; p5LinkContact.LinkClicked += OpenContactForm; // // p5finishHomepage // resources.ApplyResources(p5finishHomepage, "p5finishHomepage"); p5finishHomepage.Name = "p5finishHomepage"; // // p5LinkHomepage // resources.ApplyResources(p5LinkHomepage, "p5LinkHomepage"); p5LinkHomepage.Name = "p5LinkHomepage"; p5LinkHomepage.TabStop = true; p5LinkHomepage.LinkClicked += OpenHomepage; // // p5finishTitle // resources.ApplyResources(p5finishTitle, "p5finishTitle"); p5finishTitle.Name = "p5finishTitle"; // // spacer4 // resources.ApplyResources(spacer4, "spacer4"); spacer4.Name = "spacer4"; // // pageNetwork // pageNetwork.Controls.Add(flowLayoutPanel2); resources.ApplyResources(pageNetwork, "pageNetwork"); pageNetwork.Name = "pageNetwork"; // // flowLayoutPanel2 // flowLayoutPanel2.Controls.Add(p4netTitle); flowLayoutPanel2.Controls.Add(p4netDesc); flowLayoutPanel2.Controls.Add(p4netDesc1); flowLayoutPanel2.Controls.Add(p4netDesc2); flowLayoutPanel2.Controls.Add(p4netDesc3); flowLayoutPanel2.Controls.Add(p4netDesc4); flowLayoutPanel2.Controls.Add(p4netErrors); flowLayoutPanel2.Controls.Add(checkBoxUpdateSearch); flowLayoutPanel2.Controls.Add(p4netUpdateAdd); flowLayoutPanel2.Controls.Add(checkBoxSendStats); flowLayoutPanel2.Controls.Add(p4netUsageAdd); flowLayoutPanel2.Controls.Add(checkBoxRatings); resources.ApplyResources(flowLayoutPanel2, "flowLayoutPanel2"); flowLayoutPanel2.Name = "flowLayoutPanel2"; // // p4netTitle // resources.ApplyResources(p4netTitle, "p4netTitle"); p4netTitle.Name = "p4netTitle"; // // p4netDesc // resources.ApplyResources(p4netDesc, "p4netDesc"); p4netDesc.Name = "p4netDesc"; // // p4netDesc1 // resources.ApplyResources(p4netDesc1, "p4netDesc1"); p4netDesc1.Name = "p4netDesc1"; // // p4netDesc2 // resources.ApplyResources(p4netDesc2, "p4netDesc2"); p4netDesc2.Name = "p4netDesc2"; // // p4netDesc3 // resources.ApplyResources(p4netDesc3, "p4netDesc3"); p4netDesc3.Name = "p4netDesc3"; // // p4netDesc4 // resources.ApplyResources(p4netDesc4, "p4netDesc4"); p4netDesc4.Name = "p4netDesc4"; // // p4netErrors // resources.ApplyResources(p4netErrors, "p4netErrors"); p4netErrors.Name = "p4netErrors"; // // checkBoxUpdateSearch // resources.ApplyResources(checkBoxUpdateSearch, "checkBoxUpdateSearch"); checkBoxUpdateSearch.Name = "checkBoxUpdateSearch"; checkBoxUpdateSearch.UseVisualStyleBackColor = true; // // p4netUpdateAdd // resources.ApplyResources(p4netUpdateAdd, "p4netUpdateAdd"); p4netUpdateAdd.Name = "p4netUpdateAdd"; // // checkBoxSendStats // resources.ApplyResources(checkBoxSendStats, "checkBoxSendStats"); checkBoxSendStats.Name = "checkBoxSendStats"; checkBoxSendStats.UseVisualStyleBackColor = true; // // p4netUsageAdd // resources.ApplyResources(p4netUsageAdd, "p4netUsageAdd"); p4netUsageAdd.Name = "p4netUsageAdd"; // // checkBoxRatings // resources.ApplyResources(checkBoxRatings, "checkBoxRatings"); checkBoxRatings.Name = "checkBoxRatings"; checkBoxRatings.UseVisualStyleBackColor = true; // // panel5 // resources.ApplyResources(panel5, "panel5"); panel5.Name = "panel5"; // // pageCorrupted // pageCorrupted.Controls.Add(flowLayoutPanel1); resources.ApplyResources(pageCorrupted, "pageCorrupted"); pageCorrupted.Name = "pageCorrupted"; // // flowLayoutPanel1 // flowLayoutPanel1.Controls.Add(pCorTitle); flowLayoutPanel1.Controls.Add(pCorDesc); flowLayoutPanel1.Controls.Add(pCorViewInvalidTitle); flowLayoutPanel1.Controls.Add(pCorViewInvalid); flowLayoutPanel1.Controls.Add(checkBoxInvalidTest); flowLayoutPanel1.Controls.Add(pCorViewinvalidComment); flowLayoutPanel1.Controls.Add(pCorOrphansTitle); flowLayoutPanel1.Controls.Add(pCorOrphansMessage); flowLayoutPanel1.Controls.Add(checkBoxOrphans); flowLayoutPanel1.Controls.Add(pCorOrphansComment); resources.ApplyResources(flowLayoutPanel1, "flowLayoutPanel1"); flowLayoutPanel1.Name = "flowLayoutPanel1"; // // pCorTitle // resources.ApplyResources(pCorTitle, "pCorTitle"); pCorTitle.Name = "pCorTitle"; // // pCorDesc // resources.ApplyResources(pCorDesc, "pCorDesc"); pCorDesc.Name = "pCorDesc"; // // pCorViewInvalidTitle // resources.ApplyResources(pCorViewInvalidTitle, "pCorViewInvalidTitle"); pCorViewInvalidTitle.Name = "pCorViewInvalidTitle"; // // pCorViewInvalid // resources.ApplyResources(pCorViewInvalid, "pCorViewInvalid"); pCorViewInvalid.Name = "pCorViewInvalid"; // // checkBoxInvalidTest // resources.ApplyResources(checkBoxInvalidTest, "checkBoxInvalidTest"); checkBoxInvalidTest.Name = "checkBoxInvalidTest"; checkBoxInvalidTest.UseVisualStyleBackColor = true; // // pCorViewinvalidComment // resources.ApplyResources(pCorViewinvalidComment, "pCorViewinvalidComment"); pCorViewinvalidComment.Name = "pCorViewinvalidComment"; // // pCorOrphansTitle // resources.ApplyResources(pCorOrphansTitle, "pCorOrphansTitle"); pCorOrphansTitle.Name = "pCorOrphansTitle"; // // pCorOrphansMessage // resources.ApplyResources(pCorOrphansMessage, "pCorOrphansMessage"); pCorOrphansMessage.Name = "pCorOrphansMessage"; // // checkBoxOrphans // resources.ApplyResources(checkBoxOrphans, "checkBoxOrphans"); checkBoxOrphans.Name = "checkBoxOrphans"; checkBoxOrphans.UseVisualStyleBackColor = true; // // pCorOrphansComment // resources.ApplyResources(pCorOrphansComment, "pCorOrphansComment"); pCorOrphansComment.Name = "pCorOrphansComment"; // // spacer3 // resources.ApplyResources(spacer3, "spacer3"); spacer3.Name = "spacer3"; // // page3 // page3.Controls.Add(flowLayoutPanel4); resources.ApplyResources(page3, "page3"); page3.Name = "page3"; // // flowLayoutPanel4 // flowLayoutPanel4.Controls.Add(p3advTitle); flowLayoutPanel4.Controls.Add(p3advDesc); flowLayoutPanel4.Controls.Add(p3advSyscompTitle); flowLayoutPanel4.Controls.Add(p3advSyscomp); flowLayoutPanel4.Controls.Add(checkBoxListSysComp); flowLayoutPanel4.Controls.Add(p3advProtectTitle); flowLayoutPanel4.Controls.Add(p3advProtect); flowLayoutPanel4.Controls.Add(checkBoxListProtected); flowLayoutPanel4.Controls.Add(checkBoxDiisableProtection); flowLayoutPanel4.Controls.Add(p3advProtectAdd); resources.ApplyResources(flowLayoutPanel4, "flowLayoutPanel4"); flowLayoutPanel4.Name = "flowLayoutPanel4"; // // p3advTitle // resources.ApplyResources(p3advTitle, "p3advTitle"); p3advTitle.Name = "p3advTitle"; // // p3advDesc // resources.ApplyResources(p3advDesc, "p3advDesc"); p3advDesc.Name = "p3advDesc"; // // p3advSyscompTitle // resources.ApplyResources(p3advSyscompTitle, "p3advSyscompTitle"); p3advSyscompTitle.Name = "p3advSyscompTitle"; // // p3advSyscomp // resources.ApplyResources(p3advSyscomp, "p3advSyscomp"); p3advSyscomp.Name = "p3advSyscomp"; // // checkBoxListSysComp // resources.ApplyResources(checkBoxListSysComp, "checkBoxListSysComp"); checkBoxListSysComp.Name = "checkBoxListSysComp"; checkBoxListSysComp.UseVisualStyleBackColor = true; // // p3advProtectTitle // resources.ApplyResources(p3advProtectTitle, "p3advProtectTitle"); p3advProtectTitle.Name = "p3advProtectTitle"; // // p3advProtect // resources.ApplyResources(p3advProtect, "p3advProtect"); p3advProtect.Name = "p3advProtect"; // // checkBoxListProtected // resources.ApplyResources(checkBoxListProtected, "checkBoxListProtected"); checkBoxListProtected.Name = "checkBoxListProtected"; checkBoxListProtected.UseVisualStyleBackColor = true; // // checkBoxDiisableProtection // resources.ApplyResources(checkBoxDiisableProtection, "checkBoxDiisableProtection"); checkBoxDiisableProtection.Name = "checkBoxDiisableProtection"; checkBoxDiisableProtection.UseVisualStyleBackColor = true; // // p3advProtectAdd // resources.ApplyResources(p3advProtectAdd, "p3advProtectAdd"); p3advProtectAdd.Name = "p3advProtectAdd"; // // spacer2 // resources.ApplyResources(spacer2, "spacer2"); spacer2.Name = "spacer2"; // // page2 // page2.Controls.Add(flowLayoutPanel3); resources.ApplyResources(page2, "page2"); page2.Name = "page2"; // // flowLayoutPanel3 // flowLayoutPanel3.Controls.Add(p2viewTitle); flowLayoutPanel3.Controls.Add(p2viewDetail); flowLayoutPanel3.Controls.Add(p2viewDetail1); flowLayoutPanel3.Controls.Add(p2viewDetail2); flowLayoutPanel3.Controls.Add(p2viewDetail3); flowLayoutPanel3.Controls.Add(checkBoxGroups); flowLayoutPanel3.Controls.Add(checkBoxCheckboxes); flowLayoutPanel3.Controls.Add(p2viewCertsTitle); flowLayoutPanel3.Controls.Add(p2viewCerts); flowLayoutPanel3.Controls.Add(checkBoxCertTest); flowLayoutPanel3.Controls.Add(p2viewAdd); resources.ApplyResources(flowLayoutPanel3, "flowLayoutPanel3"); flowLayoutPanel3.Name = "flowLayoutPanel3"; // // p2viewTitle // resources.ApplyResources(p2viewTitle, "p2viewTitle"); p2viewTitle.Name = "p2viewTitle"; // // p2viewDetail // resources.ApplyResources(p2viewDetail, "p2viewDetail"); p2viewDetail.Name = "p2viewDetail"; // // p2viewDetail1 // resources.ApplyResources(p2viewDetail1, "p2viewDetail1"); p2viewDetail1.Name = "p2viewDetail1"; // // p2viewDetail2 // resources.ApplyResources(p2viewDetail2, "p2viewDetail2"); p2viewDetail2.Name = "p2viewDetail2"; // // p2viewDetail3 // resources.ApplyResources(p2viewDetail3, "p2viewDetail3"); p2viewDetail3.Name = "p2viewDetail3"; // // checkBoxGroups // resources.ApplyResources(checkBoxGroups, "checkBoxGroups"); checkBoxGroups.Name = "checkBoxGroups"; checkBoxGroups.UseVisualStyleBackColor = true; // // checkBoxCheckboxes // resources.ApplyResources(checkBoxCheckboxes, "checkBoxCheckboxes"); checkBoxCheckboxes.Name = "checkBoxCheckboxes"; checkBoxCheckboxes.UseVisualStyleBackColor = true; // // p2viewCertsTitle // resources.ApplyResources(p2viewCertsTitle, "p2viewCertsTitle"); p2viewCertsTitle.Name = "p2viewCertsTitle"; // // p2viewCerts // resources.ApplyResources(p2viewCerts, "p2viewCerts"); p2viewCerts.Name = "p2viewCerts"; // // checkBoxCertTest // resources.ApplyResources(checkBoxCertTest, "checkBoxCertTest"); checkBoxCertTest.Name = "checkBoxCertTest"; checkBoxCertTest.UseVisualStyleBackColor = true; // // p2viewAdd // resources.ApplyResources(p2viewAdd, "p2viewAdd"); p2viewAdd.Name = "p2viewAdd"; // // spacer1 // resources.ApplyResources(spacer1, "spacer1"); spacer1.Name = "spacer1"; // // page1 // page1.Controls.Add(flowLayoutPanel5); page1.Controls.Add(panel1); resources.ApplyResources(page1, "page1"); page1.Name = "page1"; // // flowLayoutPanel5 // flowLayoutPanel5.Controls.Add(p1welcomeHeading); flowLayoutPanel5.Controls.Add(p1welcomeSubheading); flowLayoutPanel5.Controls.Add(p1languageHeading); flowLayoutPanel5.Controls.Add(p1languageDesc); flowLayoutPanel5.Controls.Add(panel9); flowLayoutPanel5.Controls.Add(p1languageExtradetails); flowLayoutPanel5.Controls.Add(p1linkLabelContact); resources.ApplyResources(flowLayoutPanel5, "flowLayoutPanel5"); flowLayoutPanel5.Name = "flowLayoutPanel5"; // // p1welcomeHeading // resources.ApplyResources(p1welcomeHeading, "p1welcomeHeading"); p1welcomeHeading.Name = "p1welcomeHeading"; // // p1welcomeSubheading // resources.ApplyResources(p1welcomeSubheading, "p1welcomeSubheading"); p1welcomeSubheading.Name = "p1welcomeSubheading"; // // p1languageHeading // resources.ApplyResources(p1languageHeading, "p1languageHeading"); p1languageHeading.Name = "p1languageHeading"; // // p1languageDesc // resources.ApplyResources(p1languageDesc, "p1languageDesc"); p1languageDesc.Name = "p1languageDesc"; // // panel9 // panel9.Controls.Add(comboBoxLanguage); panel9.Controls.Add(buttonLanguageApply); resources.ApplyResources(panel9, "panel9"); panel9.Name = "panel9"; // // comboBoxLanguage // comboBoxLanguage.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; comboBoxLanguage.FormattingEnabled = true; resources.ApplyResources(comboBoxLanguage, "comboBoxLanguage"); comboBoxLanguage.Name = "comboBoxLanguage"; // // buttonLanguageApply // resources.ApplyResources(buttonLanguageApply, "buttonLanguageApply"); buttonLanguageApply.Name = "buttonLanguageApply"; buttonLanguageApply.UseVisualStyleBackColor = true; buttonLanguageApply.Click += buttonLanguageApply_Click; // // p1languageExtradetails // resources.ApplyResources(p1languageExtradetails, "p1languageExtradetails"); p1languageExtradetails.Name = "p1languageExtradetails"; // // p1linkLabelContact // resources.ApplyResources(p1linkLabelContact, "p1linkLabelContact"); p1linkLabelContact.Name = "p1linkLabelContact"; p1linkLabelContact.TabStop = true; p1linkLabelContact.LinkClicked += OpenContactForm; // // panel1 // panel1.Controls.Add(pictureBox1); panel1.Controls.Add(label2); resources.ApplyResources(panel1, "panel1"); panel1.Name = "panel1"; // // pictureBox1 // resources.ApplyResources(pictureBox1, "pictureBox1"); pictureBox1.Image = Properties.Resources._bcu_logo; pictureBox1.Name = "pictureBox1"; pictureBox1.TabStop = false; // // label2 // resources.ApplyResources(label2, "label2"); label2.ForeColor = System.Drawing.Color.FromArgb(64, 64, 64); label2.Name = "label2"; // // timer1 // timer1.Interval = 15; timer1.Tick += timer1_Tick; // // FirstStartBox // AcceptButton = buttonNext; resources.ApplyResources(this, "$this"); AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; BackColor = System.Drawing.SystemColors.ControlLightLight; CancelButton = buttonExit; ControlBox = false; Controls.Add(panelNavigation); Controls.Add(scrollPanel); FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; MaximizeBox = false; MinimizeBox = false; Name = "FirstStartBox"; ShowInTaskbar = false; SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; TopMost = true; FormClosed += FirstStartBox_FormClosed; Load += FirstStartBox_Load; panelNavigation.ResumeLayout(false); panelNavigation.PerformLayout(); scrollPanel.ResumeLayout(false); page5.ResumeLayout(false); page5.PerformLayout(); panel12.ResumeLayout(false); flowLayoutPanel6.ResumeLayout(false); flowLayoutPanel6.PerformLayout(); pageNetwork.ResumeLayout(false); flowLayoutPanel2.ResumeLayout(false); flowLayoutPanel2.PerformLayout(); pageCorrupted.ResumeLayout(false); flowLayoutPanel1.ResumeLayout(false); flowLayoutPanel1.PerformLayout(); page3.ResumeLayout(false); flowLayoutPanel4.ResumeLayout(false); flowLayoutPanel4.PerformLayout(); page2.ResumeLayout(false); flowLayoutPanel3.ResumeLayout(false); flowLayoutPanel3.PerformLayout(); page1.ResumeLayout(false); flowLayoutPanel5.ResumeLayout(false); flowLayoutPanel5.PerformLayout(); panel9.ResumeLayout(false); panel1.ResumeLayout(false); ((System.ComponentModel.ISupportInitialize)pictureBox1).EndInit(); ResumeLayout(false); } #endregion private System.Windows.Forms.Panel panelNavigation; private System.Windows.Forms.Button buttonExit; private System.Windows.Forms.Button buttonPrev; private System.Windows.Forms.Button buttonNext; private System.Windows.Forms.Panel scrollPanel; private System.Windows.Forms.Panel page3; private System.Windows.Forms.Panel spacer3; private System.Windows.Forms.Panel page2; private System.Windows.Forms.Panel spacer2; private System.Windows.Forms.Panel pageNetwork; private System.Windows.Forms.Panel spacer1; private System.Windows.Forms.Panel page1; private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel2; private System.Windows.Forms.Label p4netTitle; private System.Windows.Forms.Label p4netDesc; private System.Windows.Forms.Label p4netDesc1; private System.Windows.Forms.Label p4netDesc2; private System.Windows.Forms.Label p4netDesc3; private System.Windows.Forms.Label p4netErrors; private System.Windows.Forms.CheckBox checkBoxUpdateSearch; private System.Windows.Forms.Label p4netUpdateAdd; private System.Windows.Forms.CheckBox checkBoxSendStats; private System.Windows.Forms.Label p4netUsageAdd; private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel3; private System.Windows.Forms.Label p2viewTitle; private System.Windows.Forms.Label p2viewDetail; private System.Windows.Forms.Label p2viewAdd; private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel5; private System.Windows.Forms.Label p1languageHeading; private System.Windows.Forms.Label p1languageDesc; private System.Windows.Forms.Panel panel9; private System.Windows.Forms.ComboBox comboBoxLanguage; private System.Windows.Forms.Button buttonLanguageApply; private System.Windows.Forms.Label p1languageExtradetails; private System.Windows.Forms.LinkLabel p1linkLabelContact; private System.Windows.Forms.Label p2viewDetail1; private System.Windows.Forms.Label p2viewDetail2; private System.Windows.Forms.Label p2viewDetail3; private System.Windows.Forms.Label p2viewCerts; private System.Windows.Forms.CheckBox checkBoxCertTest; private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel4; private System.Windows.Forms.Label p3advTitle; private System.Windows.Forms.Label p3advDesc; private System.Windows.Forms.Label p3advSyscomp; private System.Windows.Forms.Label p3advProtect; private System.Windows.Forms.CheckBox checkBoxListSysComp; private System.Windows.Forms.CheckBox checkBoxListProtected; private System.Windows.Forms.CheckBox checkBoxDiisableProtection; private System.Windows.Forms.Label p3advProtectAdd; private System.Windows.Forms.Panel page5; private System.Windows.Forms.Panel panel12; private System.Windows.Forms.Button buttonFinish; private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel6; private System.Windows.Forms.Label p5finishContact; private System.Windows.Forms.LinkLabel p5LinkContact; private System.Windows.Forms.Label p5finishHomepage; private System.Windows.Forms.LinkLabel p5LinkHomepage; private System.Windows.Forms.Label p5finishTitle; private System.Windows.Forms.Panel spacer4; private System.Windows.Forms.Timer timer1; private System.Windows.Forms.Panel panel1; private System.Windows.Forms.Label p1welcomeHeading; private System.Windows.Forms.Label p1welcomeSubheading; private System.Windows.Forms.Label label2; private System.Windows.Forms.Label p2viewCertsTitle; private System.Windows.Forms.Label p3advSyscompTitle; private System.Windows.Forms.Label p3advProtectTitle; private System.Windows.Forms.PictureBox pictureBox1; private System.Windows.Forms.Panel panel5; private System.Windows.Forms.Panel pageCorrupted; private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1; private System.Windows.Forms.Label pCorTitle; private System.Windows.Forms.Label pCorDesc; private System.Windows.Forms.Label pCorViewInvalidTitle; private System.Windows.Forms.Label pCorViewInvalid; private System.Windows.Forms.CheckBox checkBoxInvalidTest; private System.Windows.Forms.Label pCorViewinvalidComment; private System.Windows.Forms.Label pCorOrphansTitle; private System.Windows.Forms.Label pCorOrphansMessage; private System.Windows.Forms.CheckBox checkBoxOrphans; private System.Windows.Forms.Label pCorOrphansComment; private System.Windows.Forms.Panel panel3; private System.Windows.Forms.Panel panel2; private System.Windows.Forms.CheckBox checkBoxGroups; private System.Windows.Forms.CheckBox checkBoxCheckboxes; private System.Windows.Forms.Button buttonMore; private System.Windows.Forms.Label p4netDesc4; private System.Windows.Forms.CheckBox checkBoxRatings; private System.Windows.Forms.Button buttonHelp; private System.Windows.Forms.Label labelProgress; private System.Windows.Forms.Panel panel4; } } ================================================ FILE: source/BulkCrapUninstaller/Forms/Wizards/FirstStartBox.ar.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 1 / 6 خروج من المعالج للخلف مواصله تم الانتهاء من الاعداد الوصول الى الشبكة يمكن ل "المثبت" محاولة الاتصال بالانترنت للاسباب التالية: ? للبحث عن تحديثات البرنامج. ? لتحميل تقارير الخطا. ? لارسال احصاءات الاستخدام المجهول. ? لجلب وتحميل تصنيفات التطبيق "اظهار المثبتات التي تم وضع علامة عليها على انها "مكونات النظام المثبتات المحمية "اظهار المثبتات التي تم وضع علامة عليها على انها "محمية "تعطيل حماية غير المثبتات التي تم وضع علامة عليها بانها "محمية سيسمح لك هذا بالغاء تثبيت العناصر المحمية. عرض قائمه الغاء التثبيت جميع المثبتات التي وجدت في نظامك هي في قائمة العرض الرئيسية. فيما يلي بعض الطرق لاستعراض هذه البيانات: ? (استخدام الفلاتر والبحث عن الكلمات الرئيسية (في جميع الاعمده ? فرز غير التركيب من قبل اي عمود. اعاده ترتيب الاعمده بحريه. ? مجموعه المثبتات المماثله اظهار الغاء التثبيت في مجموعات تحديد استخدام مربعات الاختيار المثبتات المعتمدة فتح نموذج جهة الاتصال اعدادات اضافيه عرض التعليمات انهاء الاعداد يمكنك الان البدء باستخدام المثبت. اذا كان لديك اي اسئله او ترغب في اقتراح ميزه جديده زيارة الرابط ادناه. فتح نموذج جهة الاتصال يمكنك قراءه سجلات التغيير التفصيلي والتحقق من المزيد من برمجياتي علي الصفحة الرئيسية. افتح الصفحة الرئيسية تطبيق ulk crap uninstaller The missing B is in an image next to the text BCUninstaller فتحي الداودية يرحبا بكم في البحث تلقائيا عن التحديثات عند بدء تشغيل التطبيق يمكنك البحث عن التحديثات يدويا من شريط القوائم. ارسال احصائيات الاستخدام المجهول تلقائيا سيساعد ارسال هذه الاحصاءات على تحسين المثبت. تمكين تصنيفات المستخدم للتطبيقات الغاء التثبيت معطوب تمييز التثبيت غير صالح يتم وضع علامة التثبيت غير صالح باللون الرمادي. التطبيقات غير مسجلة BCUninstaller فتحي الداودية يرحبا بكم في ! سيوفر لك هذا المعالج جولة سريعة ويساعد في تكوين التطبيق. اللغة المحددة الخاصة بهم في دليل المثبت. لا يتم مشاركه البيانات المرسلة مع اي اطراف ثالثه.XML في كل مره يحدث فيها خطا سيتم سؤالك عما اذا كنت تريد ارساله. يمكنك التحقق من البيانات التي يتم ارسالها في تقارير الخطا والاستخدام عن طريق فحص ملفات مع مرور الوقت قد تجد ان بعض التطبيقات سوف ترفض الغاء التثبيت ، او سوف تختفي فقط من معظم مديري الغاء التثبيت. المثبتات التالفة او المفقودة "في بعض الحالات يمكن الحصول علي المثبتات معطوبة ، مما يجعلها من المستحيل الغاء تثبيتها. يمكن ان تزيل هذه المداخل بسهوله باستخدام الخيار "الغاء التثبيت يدويا. في بعض الاحيان يمكن ان تترك التطبيقات باكملها على محركاتك حتى بعد الغاء تثبيت. ويمكن ان يحدث هذا ايضا اذا تمت ازاله الغاء التثبيت فقط. اظهار التطبيقات الغير مسجلة في القائمة يتم وضع علامة على التطبيقات الغير مسجلة باللون اللحمر. لذا لم يتم العثور على الغاء التثبيت الاصلي سيكون لديك لاستخدام "للالغاء يدويا" الخيار للازاله. المستخدمون المتقدمون في حين يمكن استخدام المثبت بمثابه الغاء التثبيت الاساسيه ، ومعظم وظائفها تهدف الى مستخدمي السلطة. المضي قدما بحذر! مكونات النظام التطبيقات التي تحمل علامة "مكونات النظام" مخفيه عن معظم مديري الغاء التثبيت الاساسيه. لا تعني هذه العلامة ان التطبيق هو جزء من نظام التشغيل. يتم وضع علامة على العناصر المحمية بعلامة "عدم الازاله" ، مما يعني ان الناشر لا يريد منك ازالتها. غالبا ما يتم استخدام هذه العلامة من قبل حزم البرامج الكبيرة لمنعك من الغاء تثبيت الاجزاء الفردية الخاصة بهم. ويمكن التوقيع على المثبتات بالشهادات الصادرة عن السلطات المختصة. اذا اجتازت الشهادة التحقق من صحة حزمه البرامج لم يتم تغييرها والسمعة. تمييز المثبتات المعتمدة يتم وضع علامة التثبيت المثبتة باللون الاخضر ، غير المتحقق منها باللون الازرق. تحذير: يمكن ان يستغرق التحقق وقتا طويلا. يمكنك اجبار المثبت على استخدام تعريب معين اذا كانت اللغة الافتراضية غير صحيحه. سيتم تنفيذ اعاده التشغيل لتطبيق اللغة الجديدة. اذا كنت على استعداد للمساعدة في ترجمه المثبت الى لغتك ، انقر على الرابط ادناه للاتصال بي. كل مساعده هو موضع تقدير كبير! ================================================ FILE: source/BulkCrapUninstaller/Forms/Wizards/FirstStartBox.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Globalization; using System.Linq; using System.Windows.Forms; using BulkCrapUninstaller.Functions; using BulkCrapUninstaller.Properties; using Klocman.Binding.Settings; using Klocman.Forms.Tools; namespace BulkCrapUninstaller.Forms { public partial class FirstStartBox : Form { private readonly Panel[] _pages; private readonly int _pageWidth; private readonly SettingBinder _settings = Settings.Default.SettingBinder; private int _pageNumber; private int _targetXPos; public FirstStartBox(bool canExit) { InitializeComponent(); if (DesignMode) return; if (!canExit) { buttonExit.Enabled = false; buttonExit.Visible = false; } Icon = Resources.Icon_Logo; p1linkLabelContact.TabStop = false; p5LinkHomepage.TabStop = false; p5LinkContact.TabStop = false; _pages = new[] { page1, page2, page3, pageCorrupted, pageNetwork, page5 }; _pageWidth = page1.Width + spacer4.Width; // List view _settings.BindControl(checkBoxCheckboxes, x => x.UninstallerListUseCheckboxes, this); _settings.BindControl(checkBoxGroups, x => x.UninstallerListUseGroups, this); _settings.BindControl(checkBoxCertTest, x => x.AdvancedTestCertificates, this); // Advanced _settings.BindControl(checkBoxDiisableProtection, x => x.AdvancedDisableProtection, this); _settings.BindControl(checkBoxListProtected, x => x.FilterShowProtected, this); _settings.BindControl(checkBoxListSysComp, x => x.FilterShowSystemComponents, this); // Corrupted _settings.BindControl(checkBoxInvalidTest, x => x.AdvancedTestInvalid, this); _settings.BindControl(checkBoxOrphans, x => x.AdvancedDisplayOrphans, this); // Network _settings.BindControl(checkBoxSendStats, x => x.MiscSendStatistics, this); _settings.BindControl(checkBoxUpdateSearch, x => x.MiscCheckForUpdates, this); _settings.BindControl(checkBoxRatings, x => x.MiscUserRatings, this); comboBoxLanguage.Items.Add(Localisable.DefaultLanguage); foreach (var languageCode in CultureConfigurator.SupportedLanguages.OrderBy(x => x.DisplayName)) { comboBoxLanguage.Items.Add(new ComboBoxWrapper(languageCode, x => x.DisplayName)); } var selectedItem = comboBoxLanguage.Items.OfType>() .FirstOrDefault(x => x.WrappedObject.Name.Equals(_settings.Settings.Language)); if (selectedItem != null) { comboBoxLanguage.SelectedItem = selectedItem; } else { comboBoxLanguage.SelectedIndex = 0; } _settings.SendUpdates(this); UpdatePageEnabledState(); } private void buttonLanguageApply_Click(object sender, EventArgs e) { _settings.Settings.Language = comboBoxLanguage.SelectedIndex == 0 ? string.Empty : ((ComboBoxWrapper)comboBoxLanguage.SelectedItem).WrappedObject.Name; _settings.Settings.Save(); EntryPoint.Restart(); } private void buttonNext_Click(object sender, EventArgs e) { TopMost = false; _pageNumber++; if (_pageNumber >= _pages.Length) _pageNumber = _pages.Length - 1; UpdateScrollPosition(); } private void buttonPrev_Click(object sender, EventArgs e) { _pageNumber--; if (_pageNumber < 0) _pageNumber = 0; UpdateScrollPosition(); } private void CloseWizard(object sender, EventArgs e) { try { _settings.Settings.MiscFirstRun = false; _settings.Settings.Save(); } catch (Exception ex) { PremadeDialogs.GenericError(ex); } Close(); } private void FirstStartBox_FormClosed(object sender, FormClosedEventArgs e) { _settings.RemoveHandlers(this); } private void OpenContactForm(object sender, LinkLabelLinkClickedEventArgs e) { PremadeDialogs.StartProcessSafely(Resources.ContactUrl); } private void OpenHomepage(object sender, LinkLabelLinkClickedEventArgs e) { PremadeDialogs.StartProcessSafely(Resources.HomepageUrl); } private void timer1_Tick(object sender, EventArgs e) { int resultXPos; var currentXPos = scrollPanel.HorizontalScroll.Value; var difference = Math.Abs(_targetXPos - currentXPos); var change = Math.Max(1, (int)Math.Round(Math.Pow(difference / 5f, 1.03f), MidpointRounding.ToEven)); if (currentXPos > _targetXPos) { resultXPos = currentXPos - change; resultXPos = Math.Max(resultXPos, _targetXPos); } else if (currentXPos < _targetXPos) { resultXPos = currentXPos + change; resultXPos = Math.Min(resultXPos, _targetXPos); } else { resultXPos = _targetXPos; } //Console.WriteLine(string.Format("{0,5}{1,5}{2,5}", currentXPos, change, resultXPos)); resultXPos = Math.Clamp(resultXPos, scrollPanel.HorizontalScroll.Minimum, scrollPanel.HorizontalScroll.Maximum); // Double assign is needed because of a bug in the control scrollPanel.HorizontalScroll.Value = resultXPos; scrollPanel.HorizontalScroll.Value = resultXPos; if (resultXPos == _targetXPos) { timer1.Enabled = false; if (_pageNumber == _pages.Length) buttonFinish.Focus(); } } private void UpdateScrollPosition() { labelProgress.Text = $"{_pageNumber + 1} / {_pages.Length + 1}"; _targetXPos = _pageNumber * _pageWidth; timer1.Enabled = false; // Not actually needed var currentValue = scrollPanel.HorizontalScroll.Value; // Bug in the control: Scroll bar resets when the Enabled property is set to false buttonNext.Enabled = _pageNumber < _pages.Length - 1; buttonPrev.Enabled = _pageNumber > 0; // Double assign is needed because of a bug in the control scrollPanel.HorizontalScroll.Value = currentValue; scrollPanel.HorizontalScroll.Value = currentValue; UpdatePageEnabledState(); timer1.Enabled = true; } private void UpdatePageEnabledState() { for (var index = 0; index < _pages.Length; index++) { var page = _pages[index]; var current = index == _pageNumber; page.Enabled = current; if (current) page.Focus(); } } private void buttonMore_Click(object sender, EventArgs e) { using (var sw = new SettingsWindow()) sw.ShowDialog(this); DialogResult = DialogResult.None; } private void buttonHelp_Click(object sender, EventArgs e) { MessageBoxes.DisplayHelp(); } private void FirstStartBox_Load(object sender, EventArgs e) { } } } ================================================ FILE: source/BulkCrapUninstaller/Forms/Wizards/FirstStartBox.cs.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Ukončit průvodce Zpět Pokračovat Další nastavení Ukončete průvodce Nyní můžete začít používat BCUninstaller. Máte-li jakékoli dotazy nebo chcete-li navrhnout novou funkci navštivte odkaz níže. Otevřete kontaktní formulář Můžete si přečíst podrobné protokoly změn a podívejte se na více mého softwaru na domovské stránce. Otevřete domovskou stránku Instalační program byl dokončen Přístup k síti BCUninstaller se může připojit k internetu z následujících důvodů: ● Chcete-li hledat aktualizací programu. ● Chcete-li nahrát chybové hlášení. ● Chcete-li poslat anonymní statistiku používání. Pokaždé, když dojde k chybě, budete dotázáni, zda ji chcete odeslat. Můžete zkontrolovat, jaké údaje jsou odesílány ve zprávách o chybách a používání programu, kontrolou XML soubory v adresáři BCUninstaller .Odeslaná data nejsou poskytována třetími stranám. Automaticky hledat aktualizace při startu aplikace Můžete vyhledávat aktualizace ručně na liště nabídky. Automaticky posílat anonymní statistiku používání programu Odesláním této statistiky pomůže zlepšit BCUninstaller. Poškozený odinstalátor Časem možná zjistíte, že některé aplikace se odmítnou odinstalovat, nebo si jen tak zmizí z většiny manažerů pro odinstalování. Poškozený nebo chybějící odinstalátor V některých případech odinstalátor může být poškozen, a není nemožná odinstalace. BCUninstaller umožňuje odebrat tyto položky snadno pomocí volby "Odinstalovat ručně". Zvýraznit neplatné odinstalátory Neplatné odinstalátory jsou označeny šedě. Neregistrované aplikace Někdy celé aplikace mohou být ponechána na disku, i poté, co byl odinstalovány. To se také může stát, když se pouze program na odinstalaci odstraní. Zobrazit neregistrované aplikace v seznamu Neregistrované aplikace jsou označeny červeně. Pokud původní odinstalátor není nalezen, budete muset použít volbu "Odinstalovat ručně", k jejich odstranění. Zkušení uživatelé Zatímco BCUninstaller může být použit jako základní odinstalátor, většina z jeho funkcí jsou zaměřeny pro zkušené uživatele. Postupujte opatrně! Systémové součásti Aplikace označené jako "součásti systému", jsou skryty pro většinu základních manažerů pro odinstalování. Tato značka Neznamená, že aplikace je součástí operačního systému. Zobrazit odinstalátory označené jako "součástí systému" Chráněné odinstalátory Chráněné položky jsou označeny "NoRemove" značka, což znamená, že vydavatel nechce jejich odstranění. Tato značka je často používána u velkých softwarových balíčků, aby vám zabránila odinstalování jejich jednotlivých částí. Zobrazit odinstalátory označené jako "chráněné" Zakázat ochranu odinstalátorů označených jako "chráněné" To vám umožní odinstalovat chráněné položky. Odinstalátor zobrazení seznamu Všechny odinstalátory nalezené ve vašem systému jsou v hlavním zobrazení seznamu. Zde jsou některé způsoby, jak procházet tyto údaje: ● Pomocí filtrů a hledání klíčových slov (ve všech sloupcích) ● Řadit odinstalátory podle libovolného sloupce. Volně uspořádání sloupců. ● Seskupení podobných odinstalátorů Zobrazit odinstalátory ve skupinách Vyberte pomocí zaškrtávacích políček Certifikované odinstalátory Odinstalátory mohou být podepsána certifikáty vydanými příslušnými orgány. Pokud certifikát projde validace, softwarový balík nebyl změněn a je seriózní. Zvýraznit certifikované odinstalátory Ověřené odinstalátory jsou označeny zeleně, neověřené jsou v modré barvě. Upozornění: Ověření může trvat delší dobu. Vítejte v BCUninstaller! Tento průvodce umožní rychlou prohlídku a pomůže s konfiguraci aplikace. Výběr jazyka Můžete vynutit BCUninstaller použít konkrétní lokalizaci, pokud výchozí jazyk je nesprávný. Po restartu bude aplikován nový jazyk. Použít Pokud jste ochotni pomoci s překladem BCUninstaller do Vašeho jazyka, klikněte na odkaz níže, aby jste mě kontaktovali. Veškerou pomoc velmi ocenim! Otevřete kontaktní formulář Vítejte v BCUninstaller ● Chcete-li načíst a nahrajte aplikační ratingy Aktivovat uživatelských ratingy aplikací ulk crap uninstaller The missing B is in an image next to the text Zobrazit nápovědu 1 / 6 ================================================ FILE: source/BulkCrapUninstaller/Forms/Wizards/FirstStartBox.de.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Verlassen Zurück Weiter Assistenten verlassen Sie können nun den BCUninstaller starten. Wenn Sie Fragen haben oder ein neues Feature vorschlagen möchten, verwenden Sie bitte den unten stehenden Link. Kontaktformular öffnen Detaillierte Änderungsprotokolle finden Sie auf der Homepage ebenso wie weitere Software von mir. Homepage öffnen Setup wurde abgeschlossen Netzwerkzugriff BCUninstaller kann versuchen, aus folgenden Gründen eine Verbindung mit dem Internet herzustellen: ● zur Suche nach Updates ● zur Fehlerberichterstattung. ● zum Senden anonymer Nutzerstatistiken Wenn ein Fehler auftritt, werden Sie gefragt, ob Sie einen Fehlerbericht senden möchten. Sie können jederzeit überprüfen, welche Daten in Fehler- und Nutzungsreports gesendet werden. Überprüfen Sie dazu die jeweiligen XML-Dateien im BCUninstaller Verzeichnis. Gesendeten Daten werden nicht an Dritte weitergegeben. Beim Start automatisch nach Updates suchen Aus der Menüleiste können Sie manuell nach Aktualisierungen suchen. Automatisch anonyme Nutzungsstatistiken senden Diese Statistiken helfen mir, BCUninstaller zu verbessern. Beschädigte Uninstaller Zeitweise kann es vorkommen, dass eine Anwendung sich weigert, deinstalliert zu werden, oder einfach aus den meisten Uninstall-Programmen verschwindet. Beschädigte oder fehlende Uninstaller In einigen Fällen können Uninstaller beschädigt sein, so dass man nicht deinstallieren kann. BCUninstaller kann diese Einträge mit der Option "Manuell deinstallieren" entfernen. Beschädigte Uninstaller hervorheben Beschädigte Uninstaller werden grau angezeigt Nicht registrierte Anwendung Manchmal können nach einer Deinstallation vollständige Anwendungen auf dem Laufwerk zurück bleiben. Das kann auch passieren, wenn der Uninstaller selbst entfernt wurde. Nicht registrierte Anwendungen in der Liste anzeigen Nicht registrierte Anwendungen werden rot dargestellt. Fehlt der originäre Uninstaller, können Sie die Option "Manuell deinstallieren" verwenden, um die Anwendung zu entfernen. Erfahrene Anwender Obwohl BCUninstaller als Standard-Uninstaller verwendet werden kann, richten sich die meisten Funktionen an erfahrene Anwender. Lassen Sie Vorsicht walten! Systemkomponenten Anwendungen, die als "Systemkomponenten" gekennzeichnet sind, werden von den meisten einfachen Uninstallern ausgeblendet. Diese Kennzeichnung bedeutet NICHT, dass die Anwendung zum Betriebssystem gehört. Als "Systemkomponente" markierte Uninstaller anzeigen Geschützte Uninstaller Geschützte Elemente werden als "NoRemove" gekennzeichnet, was bedeutet, dass der Herausgeber nicht will, dass Sie sie entfernen. Das Kennzeichen wird häufig von umfangreicher Software verwendet, um zu verhindern, dass Sie ihre Einzelteile deinstallieren. "Geschützte" Uninstaller anzeigen Den Schutz "geschützter" Uninstaller entfernen Damit können Sie geschützte Elemente deinstallieren Uninstaller Liste Alle in Ihrem System gefundenen Uninstaller befinden sich in der Hauptliste. Einige Möglichkeiten, um diese Daten zu durchsuchen: ● Filter verwenden und nach Schlüsselwörtern (in allen Spalten) suchen ● Sortieren Sie Uninstaller nach beliebigen Spalten. Sie können alle Spalten neu anordnen. ● Gruppieren von ähnlichen Uninstallern Elemente gruppieren Auswahl mit Checkboxen Zertifizierte Uninstaller Uninstaller können mit von zuständigen Behörden ausgestellten Zertifikaten signiert sein. Wurde das Zertifikat erfolgreich validiert, ist das Softwarepaket unverändert und als seriös eingestuft. Zertifizierte Uninstaller hervorheben Verifizierte Uninstaller sind grün, nicht verifizierte blau markiert. Achtung: die Überprüfung kann lange dauern. Willkommen beim BCUninstaller! Dieser Assistent gibt Ihnen einen kurzen Überblick und soll Ihnen helfen, die Anwendung zu konfigurieren. Sprache Wählen Sie für BCUninstaller Ihre Landessprache. Nach einem Neustart wird die neue Sprache übernommen. Anwenden Kontaktieren Sie mich gerne, wenn Sie helfen möchten, BCUninstaller in Ihre Sprache zu übersetzen. Klicken Sie dafür auf den Link unten. Jede Hilfe ist willkommen! Kontaktformular öffnen ulk crap uninstaller The missing B is in an image next to the text Willkommen beim BCUninstaller Weitere Einstellungen ● Um abzurufen und laden Sie Anwendungs Wertungen Aktivieren nutzerbewertungen von Applikationen 1 / 6 Zeige Hilfe ================================================ FILE: source/BulkCrapUninstaller/Forms/Wizards/FirstStartBox.es.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ¡Bienvenido a BCUninstaller! Ver ayuda Si usted está dispuesto a ayudar a traducir BCUninstaller a su idioma, haga clic en el enlace de abajo para ponerse en contacto conmigo. ¡Toda ayuda es muy apreciada! ● Para capturar y cargar puntuaciones de aplicaciones Continuar Desinstaladores corruptos Los elementos protegidos están marcados con la etiqueta "No Eliminar", lo que significa que el editor no quiere que los elimine. Esta etiqueta es utilizada a menudo en los grandes paquetes de software para evitar la desinstalación de sus partes individuales. Acceso a Internet ● Para enviar estadísticas de uso anónimas. Todos los desinstaladores que se encuentran en el sistema están en la lista principal. Estas son algunas formas de navegar por estos datos: Los desinstaladores inválidos están marcados en gris. Abrir la página de inicio ● Para buscar actualizaciones del programa. BCUninstaller puede forzar el uso de una localización específica si el idioma por defecto es incorrecto. Se realizará un reinicio para aplicar el nuevo idioma. Resaltar desinstaladores inválidos Puede buscar actualizaciones de forma manual desde la barra de menú. Las aplicaciones no registradas están marcadas en rojo. Si no está el desinstalador original tendrá que utilizar la opción "Desinstalar manualmente" para eliminarlas. Bienvenido a BCUninstaller Finalizar configuración Mostrar desinstaladores marcados como "protegidos" Habilitar puntuación de las aplicaciones Aplicar Aplicación no registrada Componentes del sistema Volver BCUninstaller puede intentar conectarse a Internet por las siguientes razones: Cada vez que se produzca un error se le preguntará si desea enviarlo. Puede comprobar los datos que se están enviando en los informes de errores y uso mediante la inspección de sus respectivos archivos XML en el directorio de BCUninstaller. Los datos enviados no se comparten con terceros. El envío de estas estadísticas ayudará a mejorar BCUninstaller. Ahora puede comenzar a utilizar BCUninstaller. Si tiene alguna pregunta o desea sugerir una nueva característica visite el siguiente enlace. Mostrar desinstaladores en grupos Desinstaladores certificados Esto le permitirá desinstalar elementos protegidos. Más ajustes Este asistente le dará un recorrido rápido y ayudará a configurar la aplicación. Las aplicaciones marcadas como "componentes del sistema" se ocultan de la mayor parte de los gestores básicos de desinstalación. Esta etiqueta NO significa que la aplicación es una parte del sistema operativo. Desactivar la protección de los desinstaladores marcados como "protegidos" Usuarios avanzados Desinstaladores corrompidos o que faltan Resaltar desinstaladores certificados Desinstaladores protegidos Vista de la lista del desinstalador Con el tiempo encontrará que algunas aplicaciones se niegan a desinstalarse, o simplemente desaparecerán de la mayoría de los gestores de desinstalación. Mostrar aplicaciones no registradas en la lista En algunos casos los desinstaladores pueden corromperse, haciendo imposible su desinstalación. BCUninstaller puede quitar estas entradas fácilmente utilizando la opción "Desinstalar manualmente". A veces las aplicaciones enteras pueden dejar restos en su unidad, incluso después de haber sido desinstaladas. Esto también puede ocurrir si solamente se quita el desinstalador. Los desinstaladores pueden ser firmados con certificados emitidos por las autoridades pertinentes. Si el certificado pasa la validación, y el paquete de software no ha sido alterado y tiene buena reputación. BCUninstaller puede ser utilizado como un desinstalador básico, la mayoría de sus funciones se dirigen a los usuarios más avanzados. ¡Proceda con precaución! Seleccionar usando checkboxes Enviar automáticamente estadísticas de uso anónimas La instalación ha terminado Buscar actualizaciones automáticamente al iniciar la aplicación Abrir el formulario de contacto Los desinstaladores verificados están marcados en verde, los no verificados están en azul. Advertencia: La verificación puede tardar mucho tiempo. ● Ordenar desinstaladores por cualquier columna. Reorganizar las columnas libremente. ● Agrupar desinstaladores similares ulk Crap Uninstaller The missing B is in an image next to the text ● Utilizar filtros y búsqueda de palabras clave (en todas las columnas) Abrir el formulario de contacto Salir del asistente Mostrar desinstaladores marcados como "componentes del sistema" ● Para cargar los informes de errores. Idioma seleccionado Usted puede leer los registros de cambios detallados y echar un mejor vistazo de mi software en la página de inicio. 1 / 6 ================================================ FILE: source/BulkCrapUninstaller/Forms/Wizards/FirstStartBox.fr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Quitter l'assistant Précédent Continuer Terminer l'installation Vous pouvez maintenant utiliser BCUninstaller. Si vous des questions ou souhaiteriez suggérer une nouvelle fonction, visitez le lien ci-dessous. Ouvrir le formulaire de contact Vous pouvez lire le journal détaillé des changements et voir davantage de mes logiciels sur la page d'accueil. Ouvrir la page d'accueil L'installation est terminée Accès réseau BCUninstaller peut tenter de se connecter à internet pour les raisons suivantes : ● Pour chercher des mises à jour du programme. ● Pour télécharger des rapports d'erreurs. ● Pour envoyer des statistiques anonymes d'utilisation. Chaque fois qu'une erreur survient, il vous sera demandé si vous voulez l'envoyer. Vous pouvez vérifier quelle donnée est envoyée dans les rapports d'erreur et d'utilisation en inspectant leurs fichiers XML respectifs dans le dossier de BCUninstaller. Les données envoyées ne sont partagées avec aucune tierce partie. Chercher automatiquement les mises à jour au démarrage de l'application Vous pouvez chercher manuellement les mises à jour depuis la barre de menus. Envoyer automatiquement les statistiques anonymes d'utilisation L'envoi de ces statistiques aidera à améliorer BCUninstaller. Désinstalleurs corrompus Au fil du temps, vous pouvez découvrir que certaines applications refuseront de se désinstaller, ou disparaitront juste de la plupart des gestionnaires de désinstallation. Désinstalleurs corrompus ou manquants Dans quelques cas, les désinstalleurs peuvent être corrompus, rendant impossible la désinstallation. BCUninstaller peut supprimer facilement ces entrées en utilisant l'option "Désinstaller manuellement". Surligner les désinstalleurs invalides Les désinstalleurs invalides sont marqués en gris. Applications non enregistrées Parfois, des applications entières peuvent être laissées sur votre lecteur après avoir été désinstallées. Cela peut aussi arriver si seul le désinstalleur est supprimé. Montrer les applications non enregistrées dans la liste Les applications non enregistrées sont marquées en rouge. Si le désinstalleur d'origine est introuvable, vous devrez utiliser l'option "Désinstaller manuellement" pour les supprimer. Utilisateurs avancés Quoique BCUninstaller puisse être utilisé comme un désinstalleur basique, la plupart de ses fonctions sont destinées aux utilisateurs avancés. Procédez avec précaution ! Composants système Les applications marquées comme "composants système" sont cachées de la plupart des gestionnaires basiques de désinstallation. Cette balise ne signifie PAS que l'application fait partie du système d'exploitation. Afficher les désinstalleurs marqués comme "composants système" Désinstalleurs protégés Les éléments protégés sont marqués avec la balise "NoRemove", qui signifie que l'éditeur ne veut pas que vous les supprimiez. Cette balise est souvent utilisée par des grands ensembles de logiciels pour vous empêcher de désinstaller leurs parties individuelles. Afficher les désinstalleurs marqués comme "protégés" Désactiver la protection des désinstalleurs marqués comme "protégés" Cela vous laissera désinstaller les éléments protégés. Vue liste du désinstalleur Tous les désinstalleurs trouvés dans votre système sont dans la vue liste principale. Voici quelques façons de parcourir ces données : ● Utiliser des filtres et chercher des mots-clés (dans toutes les colonnes). ● Trier les désinstalleurs par toute colonne. Réarranger librement les colonnes. ● Grouper les désinstalleurs similaires. Afficher les désinstalleurs en groupes Sélectionnner par cases à cocher Désinstalleurs certifiés Les désinstalleurs peuvent être signés avec des certificats publiés par les autorités compétentes. Si le certificat passe la validation, le progiciel n'a pas été altéré et est réputé. Surligner les désinstalleurs certifiés Les désinstalleurs vérifiés sont marqués en vert, non vérifiés en bleu. Attention : la vérification peut mettre longtemps. Bienvenue à BCUninstaller ! Cet assistant vous fera faire un tour rapide et aidera à configurer l'application. Langue sélectionnée Vous pouvez forcer BCUninstaller à utiliser une localisation spécifique si la langue par défaut est incorrecte. Un redémarrage sera réalisé pour appliquer la nouvelle langue. Appliquer Si vous souhaitez aider à traduire BCUninstaller dans votre langue, cliquez sur le lien ci-dessous pour me contacter. Toute aide est grandement appréciée ! Ouvrir le formulaire de contact Bienvenue dans BCUninstaller ulk crap uninstaller The missing B is in an image next to the text Plus de réglages ● Pour récupérer et envoyer les notes d'application. Activer les notes utilisateur des applications Voir l'aide 1 / 6 ================================================ FILE: source/BulkCrapUninstaller/Forms/Wizards/FirstStartBox.hu.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Kilépés Vissza Tovább További beállítások Súgó Befejezés Most már használhatja a BCUninstaller-t. Ha kérdése lenne, vagy egy újabb funkciót szeretne javasolni kattintson a lenti hivatkozásra. Kapcsolat űrlap megnyitása A módosítások részleteit elolvashatja a honlapunkon, illetve ott további információkat kaphat. Honlap megnyitása A telepítés befejeződött Hálózati hozzáférés A BCUninstaller a következők miatt, adott esetekben csatlakozhat az Internethez: ● Programfrissítések keresése. ● Hibajelentések elküldése. ● Névtelen használati statisztika elküldése. ● Alkalmazás minősítések fel- és letöltése. Amikor hiba történik a program megkérdi önt, hogy szeretne-e arról jelentést küldeni. Csak jelölje ki az elküldendő jelentéseket, amelyek a BCUninstaller könyvtárában levő XML fájlokban találhatók. Az elküldött adatokat nem osztjuk meg semmilyen harmadik féllel. Frissítések automatikus keresése a program indításakor A frissítéseket kézzel is megkeresheti a menüsorban. Névtelen használati statisztika elküldése Ezeknek a statisztikáknak az elküldésével segíthet a program jobbá tételében. Alkalmazások minősítésének engedélyezése Sérült eltávolítók Idővel előfordulhat, hogy néhány alkalmazást már nem tud eltávolítani, vagy azok eltűnnek a legtöbb eltávolításkezelő elől. Sérült vagy hiányzó eltávolítók Néha az eltávolítók megsérülhetnek, így ezekkel nem lehetséges az eltávolítás. A BCUninstaller az ilyen jellegű bejegyzéseket is eltávolítja a "Kézi eltávolítás" opcióval. Érvénytelen eltávolítók jelölése Az érvénytelen eltávolítók szürkével lesznek megjelölve. Nem regisztrált alkalmazás Néha teljes alkalmazások maradhatnak vissza a lemezén egy eltávolítást követően. Ez akkor is előfordulhat, ha csak az eltávolító kerül törlésre. Nem regisztrált mutatása a listában Az nem regisztrált alkalmazások pirossal vannak jelölve. Ha az eredeti eltávolító nem található meg, ezekhez használhatja a "Kézi eltávolítás" lehetőséget. Speciális felhasználók A BCUninstaller ugyan egy alap eltávolítóként használható, azonban számos funkciója szakértő felhasználóknak ajánlott. Óvatosan menjen tovább! Rendszerelemek A programok által "rendszerelemként" jelöltek nem láthatók az alap eltávolításkezelőkben. Ez a címke NEM jelenti azt, hogy az alkalmazás az operációs rendszer része lenne. "Rendszerelemként" megjelölt eltávolítók mutatása Védett eltávolítók Védett elemek, amelyek "NoRemove" címkével vannak ellátva. Ebben az esetben a kiadó nem akarja, hogy eltávolítsa ezeket. Ezt általában nagy szoftvercsomagok használják, hogy megakadályozzák az egyes részeik eltávolítását. "Védettként" megjelölt eltávolítók mutatása "Védettként" megjelölt eltávolítók védelmének kikapcsolása Ezzel eltávolíthatja a védett elemeket. Eltávolító lista-nézet A rendszerében levő összes eltávolító megnézhető a fő listanézetben. Néhány módszer az adatok áttekintéséhez: ● Szűrőhasználat és kulcsszavas keresés (az összes oszlopban) ● Rendezés bármely oszlop szerint. Az oszlopok átrendezhetők. ● Hasonló eltávolítók csoportosítása Elemek csoportosítása Kijelölés jelölőnégyzetekkel Hitelesített eltávolítók Az eltávolítók aláírásra kerülhetnek a fejlesztők által kiadott tanúsítványokkal. Ha a tanúsítvány átment a hitelesítésen, a programcsomag nem lett módosítva és megbízható. Hitelesítettek megjelölése A hitelesített eltávolítók zölddel, egyébként kékkel lesznek jelölve. Figyelem: Az ellenőrzés hosszabb ideig is eltarthat. Üdvözli Önt a BCUninstaller! A varázslóban gyors segítséget kap az alkalmazás megfelelő beállításához. Kiválasztott nyelv Kényszerítheti a BCUninstaller-t, egy adott nyelv használatára, ha az alap nyelv nem felel meg. Az új nyelv alkalmazásához újra kell indítani a programot. Alkalmaz Ha lefordítaná a saját nyelvére a BCUninstaller-t, kattintson az alábbi hivatkozásra a kapcsolatfelvételhez. Minden segítséget szívesen fogadunk! Kapcsolat űrlap megnyitása ulk crap uninstaller The missing B is in an image next to the text Üdvözli a BCUninstaller 1 / 6 ================================================ FILE: source/BulkCrapUninstaller/Forms/Wizards/FirstStartBox.it.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Esci dalla procedura guidata Indietro Continua Altre opzioni Visualizza guida in linea Fine impostazione Ora puoi iniziare ad usare BCUninstaller. Per qualunque domanda o suggerimenti di nuove funzionalità usa i collegamenti in basso. Apri il modulo di contatto Nella pagina web puoi leggere il dettaglio delle novità del programma e dare uno sguardo ad altre informazioni. Apri la pagina web del programma Configurazione programma completata Accesso alla rete BCUninstaller cercherà di collegarsi ad internet per i seguenti motivi: ● Cercare aggiornamenti del programma. ● Inviare segnalazioni di errori ● Inviare statistiche di uso anonime. ● Recuperare e inviare valutazioni sull'applicazione Quando si verificherà un errore verrà chiesto se segnalarlo. Puoi controllare quali dati vengono inviati nelle segnalazioni di errori e di uso controllando i relativi file XML nella cartella di BCUninstaller. I dati inviati non saranno condivisi con nessuno. All'avvio controlla automaticamente la disponibilità di aggiornamenti Puoi cercare manualmente gli aggiornamenti dalla barra dei menù. Invia automaticamente statistiche d'uso anonime. L'invio delle statistiche contribuirà al miglioramento di BCUninstaller. Abilita le valutazioni utente dell'applicazione Disinstallatori corrotti Nel tempo può capitare che alcune applicazioni si rifiuteranno di essere disinstallate, o scompariranno dalla maggiori parte dei gestori di disinstallazione. Disinstallatori corrotti o mancanti In alcuni casi i disinstallatori possono corrompersi, rendendo impossibile la disinstallazione. BCUninstaller può facilmente rimuovere queste voci usando l'opzione "Disinstalla manualmente". Evidenzia disinstallatori non validi I disinstallatori non validi sono evidenziati in grigio. Applicazione non registrata A volte intere applicazioni posso restare nel disco persino dopo la disinstallazione. Può accadere se viene rimosso il solo disinstallatore. Visualizza nell'elenco le applicazioni non registrate Le applicazioni non registrate sono evidenziate in rosso. Se il disinstallatore originale non viene rilevato per rimuoverle bisogna usare l'opzione "Disinstalla manualmente". Utenti avanzati Anche se BCUninstaller può essere usato come semplice disinstallatore, la maggior parte delle sue funzioni sono rivolte agli utenti esperti. Procedi con cautela! Componenti di sistema Le applicazioni evidenziate come 'Componenti di sistema' sono invisibili alla maggior parte dei gestori di disinstallazione standard. Questo attributo NON indica che l'applicazione è parte del sistema operativo. Visualizza disinstallatori evidenziati come "componenti di sistema" Disinstallatori protetti Gli elementi protetti sono segnati con l'attributo "NoRemove", che indica che il produttore non vuole che vengano rimossi. Questo attributo è spesso usato da svariati pacchetti software per evitare che vengano disinstallate parti di esso. Visualizza disinstallatori evidenziati come "protetti" Disabilita la protezione dei disinstallatori evidenziati come "protetti" Questo permetterà di disinstallare gli elementi protetti. Vista elenco disinstallatore Tutti i disinstallatori trovati nel sistema sono visualizzati nell'elenco principale. Qui ci sono alcune modalità di visualizzazione di queste informazioni: ● Usa i filtri e cerca per parole chiave (in tutte le colonne) ● Ordina i disinstallatori per tutte le colonne. Riordina le colonne liberamente. ● Raggruppa disinstallatori simili Visualizza disinstallatori in gruppi Seleziona tramite riquadri di controllo Disinstallatori certificati I disinstallatori possono essere firmati con certificati emessi da autorità attendibili. Se il certificato supera la validazione significa che il pacchetto software non è stato alterato ed è affidabile. Evidenzia disinstallatori certificati I disinstallatori verificati sono evidenziati in verde, quelli non verificati in blu. Attenzione: la verifica può durare a lungo. Benvenuto in BCUninstaller! Questa procedura guidata visualizzerà una breve introduzione e aiuterà a configurare l'applicazione. Lingua selezionata Se la lingua predefinita non è corretta puoi forzare BCUninstaller ad usare un'altra lingua. Per usare la nuova lingua sarà necessario riavviare l'applicazione. Applica Se sei disposto ad aiutarci nella traduzione di BCUninstaller nella tua lingua fai clic sul collegamento in basso per contattarmi. Ogni aiuto è fortemente apprezzato! Apri il modulo dei contatti ulk crap uninstaller The missing B is in an image next to the text Benvenuto in BCUninstaller 1 / 6 ================================================ FILE: source/BulkCrapUninstaller/Forms/Wizards/FirstStartBox.ja.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 1月6日 ウィザードを終了 戻る 続ける さらなる設定 ヘルプを見る セットアップを完了 これでBCUninstallerを使用開始できます。質問がある場合や新機能を提案したい場合は、以下のリンクを参照ください。 お問い合わせフォームを開く 詳細な変更履歴を読み、ホームページで他のソフトウェアを確認できます。 ホームページを開く セットアップが完了しました ネットワークアクセス BCUninstallerは以下の理由でインターネットに接続を試みることがあります: ● プログラムの更新を検索するため。 ● エラーレポートをアップロードするため。 ● 匿名の使用統計を送信するため。 ● アプリケーションの評価を取得しアップロードするため。 エラーが発生するたびに送信するかどうか尋ねられます。 BCUninstallerのディレクトリ内のそれぞれのXMLファイルを調べることで、エラーと使用報告に送信されるデータを確認できます。 送信されたデータは第三者と共有されることはありません。 アプリケーション起動時に自動的に更新を探す メニューバーから手動で更新を検索できます。 匿名の使用統計を自動的に送信する これらの統計を送信することで、BCUninstallerの改善に役立ちます。 アプリケーションのユーザー評価を有効にする 壊れたアンインストーラー 時間が経つにつれ、いくつかのアプリケーションがアンインストールを拒否したり、ほとんどのアンインストールマネージャーから消えてしまうことがあります。 壊れたまたは存在しないアンインストーラー 場合によっては、アンインストーラーが壊れ、アンインストールできなくなることがあります。 BCUninstallerは「手動でアンインストール」オプションを使用してこれらのエントリを簡単に削除できます。 無効なアンインストーラーを強調表示 無効なアンインストーラーは灰色で表示されます。 登録されていないアプリケーション 時には、アンインストールされた後でも、ドライブにアプリケーション全体が残ることがあります。これは、アンインストーラーだけが削除された場合にも起こります。 リストに登録されていないアプリケーションを表示 登録されていないアプリケーションは赤で表示されます。 元のアンインストーラーが見つからない場合は、「手動でアンインストール」オプションを使用して削除する必要があります。 上級者 BCUninstallerは基本的なアンインストーラーとして使用できますが、そのほとんどの機能は上級ユーザー向けです。慎重に進めてください! システムコンポーネント 「システムコンポーネント」としてマークされたアプリケーションは、ほとんどの基本的なアンインストールマネージャーから隠されています。 このタグは、アプリケーションがオペレーティングシステムの一部であることを意味するものではありません。 「システムコンポーネント」としてマークされたアンインストーラーを表示 保護されたアンインストーラー 保護されたアイテムは「NoRemove」タグでマークされており、発行者がそれらを削除させたくないことを意味します。 このタグは、大規模なソフトウェアパッケージによって、個々の部分をアンインストールさせないように使用されることがよくあります。 「保護された」とマークされたアンインストーラーを表示 「保護された」とマークされたアンインストーラーの保護を無効にする これにより、保護されたアイテムをアンインストールできるようになります。 アンインストーラーリストビュー システム内で見つかったすべてのアンインストーラーは、メインリストビューにあります。以下はこのデータをブラウズする方法です: ● フィルターを使用し、キーワードを検索(すべての列で) ● 任意の列でアンインストーラーをソートします。列を自由に並べ替えます。 ● 類似のアンインストーラーをグループ化 グループ内にアンインストーラーを表示 チェックボックスを使用して選択 認定アンインストーラー アンインストーラーは、関連当局から発行された証明書で署名されることがあります。 証明書が検証に合格した場合、そのソフトウェアパッケージは変更されておらず、信頼性があります。 認定アンインストーラーを強調表示 検証済みのアンインストーラーはグリーンで、未検証のものはブルーで表示されます。 警告:検証には時間がかかることがあります。 BCUninstallerへようこそ! このウィザードでは、簡単なツアーを行い、アプリケーションの設定を手伝います。 選択された言語 デフォルトの言語が正しくない場合、BCUninstallerに特定のローカリゼーションを強制することができます。新しい言語を適用するために再起動が行われます。 適用 BCUninstallerをあなたの言語に翻訳するのを手伝っていただける場合は、以下のリンクをクリックして私に連絡してください。 どんな助けでも歓迎します! お問い合わせフォームを開く バルク・クラップ・アンインストーラー The missing B is in an image next to the text BCUninstallerへようこそ ================================================ FILE: source/BulkCrapUninstaller/Forms/Wizards/FirstStartBox.nl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Assistent sluiten Vorige Volgende Meer instellingen Help tonen Setup voltooien U kunt de BCUninstaller nu starten. Als u vragen hebt of een nieuwe functie wilt voorstellen, gelieve onderstaande link te gebruiken. Contactformulier openen Gedetailleerde verslagen van programma wijzigingen en mijn andere software vindt u op mijn homepagina. Homepagina openen Setup is voltooid. Netwerk toegang BCUninstaller kan proberen om verbinding te maken met het internet, om de volgende redenen: ● Voor het zoeken naar programma updates ● Voor het uploaden van foutrapportages ● Voor het versturen van anonieme gebruikers statistieken. ● Voor het ophalen en uploaden van toepassings waarderingen Wanneer er een fout optreedt vraag ik u, om mij daarvan een foutbericht te sturen. U kunt telkens controleren, welke gegevens in fout- en gebruiksrapportages gestuurd moeten worden. Controleer daarvoor de betreffende XML-bestanden in de BCUinstaller map. Tijdens het starten automatisch naar updates zoeken. In de menubalk kunt u ook handmatig naar updates zoeken. Automatisch anonieme gebruiks statistieken versturen Deze statistieken helpen om BCUninstaller te verbeteren. Inschakelen gebruikers beoordelingen voor programma's. Beschadigde de-installer Van tijd tot tijd kan het voorkomen, dat een programma weigert te de-installeren of eenvoudigweg uit de meeste de-installer programma's verdwijnt. Beschadigde of ontbrekende de-installer(s) In sommige gevallen kunnen de-installers beschadigd zijn, zodat men niet kan de-installeren. BCUninstaller kan deze registraties met de optie "Handmatig de-installeren" verwijderen. Beschadigde de-installers accentueren Beschadigde de-installers worden grijs weergegeven Niet geregistreerde toepassing Soms kunnen volledige programma's na de-installatie op de harde schijf achterblijven. Dit kan ook gebeuren als de de-installer zelf werd verwijderd. Niet geregistreerde toepassingen in de lijst tonen Niet geregistreerde toepassingen worden in het rood weergegeven. Ontbreekt de originele de-installer, dan kunt u de optie "Handmatig de-instaleren" gebruiken, om het programma te verwijderen. Ervaren gebruikers Hoewel BCUninstaller als standaard de-installer kan worden gebruikt, zijn de meeste functies bedoeld voor ervaren gebruikers. Handel met voorzichtigheid! Systeem componenten Programma's die als 'systeem component(en)' zijn aangeduid, worden door de meeste de-installers verborgen. Deze aanduiding betekent NIET, dat het programma tot het besturingssysteem behoort. Als 'systeem componenten' aangeduide de-installers tonen Beveiligde de-installers Beveiligde onderdelen worden met het "Niet Verwijderen" label aangeduid hetgeen betekent, dat de uitgever niet wil dat u deze verwijderd. Deze aanduiding wordt vaak bij softwarepakketten gebruikt, om te voorkomen dat u daarvan onderdelen de-installeert. "Beveiligde" de-installers tonen De beveiliging van "beveiligde" de-installers uitschakelen Hierdoor kunt u beveiligde onderdelen de-installeren De-installer lijst Alle op uw systeem gevonden de-installers bevinden zich in de hoofdlijst. Enkele mogelijkheden om deze gegevens te doorzoeken: ● Filters gebruiken en naar sleutelwoorden zoeken (in alle kolommen) ● Sorteer de-installers volgens willekeurige kolommen. U kunt alle kolommen opnieuw ordenen. Groeperen van soortgelijke uninstallers Onderdelen groeperen Keuze met checkboxen Gecertificeerde de-installers De-installers kunnen ondertekend zijn met certificaten van erkende autoriteiten. Werd het certificaat succesvol gevalideerd, dan is het softwarepakket onveranderd en deugdelijk. Geverifieërde de-installers accentueren Geverifieerde de-installers worden groen, niet geverifieerde worden blauw aangeduid. Let op: de verificatie kan lang duren. Welkom bij BCUninstaller! Deze assistent geeft u een kort overzicht en helpt u bij het configureren van dit programma. Gekozen taal Kies voor BCUninstaller uw taal. Na een herstart wordt de gekozen taal overgenomen. Toepassen Als u wilt helpen met de vertaling van BCUninstaller in uw taal, klik dan op de link hieronder om contact met mij op te nemen. Alle hulp is welkom! Contactformulier openen ulk crap uninstaller The missing B is in an image next to the text Welkom bij BCUninstaller 1 / 6 ================================================ FILE: source/BulkCrapUninstaller/Forms/Wizards/FirstStartBox.pl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Wyjdź z kreatora Cofnij Kontynuuj Zakończ konfigurację Teraz możesz zacząć używać BCUninstaller. Jeśli masz jakieś pytania lub sugestie dotyczące nowych funkcji programu kliknij poniższy link. Otwórz formularz kontaktowy Możesz przeczytać szczegółowy dziennik zmian i sprawdzić inne moje programy na stronie głównej. Otwórz stronę główną Konfiguracja została zakończona Dostęp do sieci BCUninstaller może próbować połączyć się z Internetem z następujących powodów: ● Aby wyszukać aktualizacje. ● Aby przesłać raporty o błędach. ● Aby wysłać anonimowe dane statystyczne. Za każdym razem po wystąpieniu błędu wystąpi zapytanie o przesłanie raportu. Możesz sprawdzić jakie dane przesyłane są w raportach o błędach i w danych statystycznych sprawdzając pliki XML w katalogu BCUninstaller. Przesyłane dane nie są udostępnianie osobom trzecim. Automatycznie sprawdź aktualizacje przy starcie aplikacji Możesz ręcznie sprawdzać aktualizacje na Pasku Menu Automatycznie przesyłaj dane statystyczne Wysyłanie tych statystyk pomoże usprawnić działanie BCUninstaller. Uszkodzone dezinstalatory Z czasem niektóre aplikacje mogą odmówić dezinstalacji, lub mogą po prostu zniknąć z większości menedżerów dezinstalacji. Uszkodzone lub zaginione dezinstalatory W niektórych przypadkach dezinstalatory mogą zostać uszkodzone, przez co odinstalowanie aplikacji staje się niemożliwe. Można usunąć je poprzez funkcję "Odinstaluj ręcznie". Zaznacz nieprawidłowe dezinstalatory Nieprawidłowe dezinstalatory są zaznaczone na szaro Niezarejestrowana aplikacje Czasem całe aplikacje mogą być pozostawione na dysku nawet po odinstalowaniu. Może się to zdarzyć, jeśli tylko dezinstalator jest usunięty. Pokaż niezarejestrowane aplikacje na liście Niezarejestrowane aplikacje są zaznaczone na czerwono. Jeśli oryginalny dezinstalator nie zostanie znaleziony będziesz musiał skorzystać z opcji "Odinstaluj ręcznie", aby je usunąć. Użytkownicy zaawansowani BCUninstaller może być używany jako podstawowy dezinstalator. Większość jego funkcji przeznaczona jest dla użytkowników zaawansowanych. Postępuj ostrożnie! Komponenty systemu Aplikacje oznaczone jako "składniki systemu" są ukryte w większości podstawowych menedżerów dezinstalacji. Znacznik ten NIE oznacza, że aplikacja jest częścią systemu operacyjnego. Pokaż dezinstalatory oznaczone jako "komponenty systemu" Chronione dezinstalatory Chronione elementy są oznaczone jako "Nieusuwalne", co oznacza, że wydawca nie chce, by je usunąć. To oznaczenie często jest wykorzystywane przez duże pakiety oprogramowania aby uniemożliwić odinstalowanie poszczególnych ich części. Pokaż dezinstalatory oznaczone jako "chronione" Wyłącz ochronę dla dezinstalatorów oznaczonych jako "chronione" To pozwoli ci odinstalować elementy chronione. Lista dezinstalatorów Wszystkie dezinstalatory znalezione w systemie widoczne są w głównym widoku listy. Oto kilka sposobów, aby przeglądać te dane: ● Użyj filtrów i wyszukiwania słów kluczowych (we wszystkich kolumnach) ● Sortuj dezinstalatory według dowolnej kolumny. Dowolnie zmieniaj układ kolumn. ● Grupuj podobne dezinstalatory. Pokaż dezinstalatory w grupach Zaznaczaj polami wyboru Dezinstalatory certyfikowane Dezinstalatory mogą mieć podpisane certyfikaty wydane przez odpowiednie władze. Jeśli certyfikat przeszedł walidację pakiet oprogramowania nie został zmieniony i jest godny zaufania. Zaznacz dezinstalatory certyfikowane Zweryfikowane dezinstalatory są zaznaczone na zielone, niezweryfikowane na niebiesko. Uwaga: Weryfikacja może zając dużo czasu. Witaj w BCUninstaller! Ten kreator pomoże ci w szybkiej konfiguracji programu. Wybrany język Możesz zmienić język, jeśli domyślna lokalizacja sprzętu jest nieprawidłowa. Aby zastosować wybrany język nastąpi ponowne uruchomienie programu. Zastosuj Jeśli chcesz pomóc w tłumaczeniu BCUninstaller na swój język, kliknij na link poniżej i skontaktuj się ze mną. Każda pomoc jest mile widziana! Otwórz formularz kontaktowy Witaj w BCUninstaller ulk crap uninstaller The missing B is in an image next to the text Więcej ustawień ● Aby pobrać i wysłać oceny aplikacji Włącz oceny użytkowników dla aplikacji Pokaż pomoc 1 / 6 ================================================ FILE: source/BulkCrapUninstaller/Forms/Wizards/FirstStartBox.pt-BR.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 1 / 6 Sair do assistente Voltar Continuar A instalação finalizou Acesso à rede BCUninstaller pode tentar se conectar à Internet pelas seguintes razões: ● Para procurar atualizações do programa ● Enviar relatórios de erros. ● Para enviar estatísticas anônimas de utilização. ● Para obter e fazer upload de classificações de aplicativos Toda vez que ocorrer um erro, será perguntado se deseja enviá-lo. Você pode verificar quais dados estão sendo enviados com os relatórios de erros e de uso, inspecionando seus respectivos arquivos XML no diretório do BCUninstaller. Os dados enviados não são compartilhados com terceiros. Procurar automaticamente atualizações ao iniciar o aplicativo Você pode procurar atualizações manualmente na barra de menus. Enviar automaticamente estatísticas de uso anônimo O envio dessas estatísticas ajudará a melhorar o BCUninstaller. Habilitar classificações de usuários de aplicativos Desinstaladores corrompidos Ao longo do tempo, você pode achar que algumas aplicações se recusarão a desinstalar ou simplesmente desaparecerão da maioria dos gerenciadores de desinstalação. Desinstaladores corrompidos ou em falta Em alguns casos, os desinstaladores podem ficar corrompidos, tornando-os impossíveis de desinstalar. BCUninstaller pode remover essas entradas facilmente usando a opção "Desinstalar manualmente". Destacar Desinstaladores inválidos Desinstaladores inválidos são marcados em cinza. Aplicações não registradas Às vezes, aplicativos inteiros podem ser deixados na sua unidade, mesmo depois de serem desinstalados. Isso também pode ocorrer se apenas o desinstalador for removido. Mostrar aplicativos não registrados na lista Os aplicativos não registrados estão marcados em vermelho. Se o desinstalador original não for encontrado, você terá que usar a opção "Desinstalar manualmente" para removê-los. Usuários avançados Enquanto o BCUninstaller pode ser usado como um desinstalador básico, a maioria de suas funções são destinadas aos usuários avançados. Prossiga com cuidado! Componentes do sistema Os aplicativos marcados como "componentes do sistema" estão ocultos da maioria dos gerenciadores básicos de desinstalação. Esta etiqueta NÃO significa que o aplicativo seja parte do sistema operacional. Mostrar desinstaladores marcados como "componentes do sistema" Desinstaladores protegidos Os itens protegidos são marcados com a tag "NoRemove", o que significa que o editor não deseja que você os remova. Esta etiqueta é frequentemente usada por grandes pacotes de software para evitar que você desinstale suas partes individuais. Mostrar desinstaladores marcados como "protegidos" Desativar proteção de desinstaladores marcados como "protegidos" Isso permitirá que você desinstale itens protegidos. Visualização da lista do desinstalador Todos os desinstaladores encontrados em seu sistema estão na lista principal. Aqui estão algumas maneiras de procurar esses dados: ● Use filtros e procure por palavras-chave (em todas as colunas) ● Classifique os desinstaladores por qualquer coluna. Colunas de rearranjo livre. ● Agrupar desinstaladores similares. Mostrar desinstaladores em grupos Selecione usando caixas de seleção Desinstaladores certificados Os desinstaladores podem ser assinados com certificados emitidos pelas autoridades relevantes. Se o certificado passar na validação, o pacote de software não foi alterado e é respeitável. Destacar desinstaladores certificados Os desinstaladores verificados são marcados em verde, não verificados estão em azul. Atenção: a verificação pode demorar muito. Bem-vindo ao BCUninstaller! Este assistente lhe dará um rápido passeio e ajudará a configurar o aplicativo. Idioma selecionado Você pode forçar o BCUninstaller a usar uma localização específica se o idioma padrão estiver incorreto. Um reinício será executado para aplicar o novo idioma. Se você está disposto a ajudar a traduzir BCUninstaller para o seu idioma, clique no link abaixo para entrar em contato comigo. Toda ajuda é bem-vinda! Abrir o formulário de contato Mais configurações Ver ajuda Concluir a configuração Agora você pode começar a usar o BCUninstaller. Se você tiver alguma dúvida ou gostaria de sugerir um novo recurso, visite o link abaixo. Abrir o formulário de contato Você pode ler os logs de mudanças detalhadas e confira mais do meu software na página inicial. Abrir a homepage Aplicar ulk crap uninstaller Bem-vindo ao BCUninstaller ================================================ FILE: source/BulkCrapUninstaller/Forms/Wizards/FirstStartBox.pt.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Bem-vindo ao BCUninstaller! Ver ajuda Se estiver disposto a ajudar a traduzir o BCUninstaller para o seu idioma, clique no link abaixo para entrar em contato comigo. Toda a ajuda é bem-vinda! ● Para pesquisar e baixar avaliações de aplicativos. Continuar Desinstaladores corrompidos Os itens protegidos estão nomeados como "NoRemove (NãoRemover)", o que significa que o autor não quer que sejam removidos. Esta condição é muitas vezes imposta a grandes conjuntos de software para evitar que você desinstale partes individuais dele. Acesso à rede ● Para enviar estatísticas anónimas de utilização. Todos os desinstaladores encontrados no seu sistema estão na vista lista principal. Eis algumas maneiras de procurar esses dados: Os desinstaladores inválidos estão assinalados a cinzento Abrir a homepage ● Para procurar actualizações do sistema Pode obrigar o BCUninstaller a usar uma localização específica se o idioma instalado por defeito for o incorreto. Será realizada uma reinicialização para aplicar o novo idioma. Destacar Desinstaladores inválidos Pode procurar manualmente por atualizações usando a barra de menu. As aplicações não registada estão assinaladas a vermelho. Se o desinstalador original não for encontrado terá de usar a opção "Desinstalar manualmente" para os remover. Bem-vindo ao BCUninstaller Terminar a configuração Mostrar desinstaladores designados como "protegidos". Permitir avaliações do utilizaddor das aplicações Aplicar Aplicação não registada Componentes do sistema Anterior O BCUninstaller pode tentar ligar-se à internet, pelas seguintes razões:: Sempre que ocorrer um erro, ser-lhe-á perguntado se deseja enviar um relatório. Poderá verificar se os dados estão a ser enviados em relatórios de erros e utilização examinando os arquivos XML no directório do BCUninstaller. Os dados enviados não são participados a terceiros. Enviando estas estatísticas está a contribuir para melhorar o BCUninstaller. Agora pode começar a usar o BCUninstaller. Se tiver alguma dúvida ou se quiser sugerir um novo recurso visite o link abaixo. Apresentar os desinstaladores dispostos em grupos Desinstaladores certificados Isto permite-lhe desinstalar itens protegidos. Mais configuirações Este assistente permite-lhe fazer uma rápida ronda pelo programa e ajudá-lo-á a configurar a aplicação. As aplicações denominadas como "Componentes do sistema" são invisíveis à maior parte dos gestores básicos de desinstalação. Esta indicação NÃO significa que a aplicação faça parte do sistema operativo. Desactiva a protecção dos desinstaladores designados como "Protegidos". Utilizadores experientes Desinstaladores corrompidos ou em falta Destacar desinstaladores certificadosHighlight certified uninstallers Desinstaladores protegidos Exibição da lista de desinstalador. Ao longo do tempo irá constatar que alguns aplicativos se recusarão a desinstalar ou que vão simplesmente desaparecer da maioria dos gestores de desinstalação. Mostrar na lista as aplicações não registada Em certos casos, alguns desinstaladores podem estar corrompidos, sendo impossível desinstalá-los. O BCUninstaller pode remover essas entradas facilmente usando a opção "Desinstalar manualmente". Sometimes whole applications can be left on your drive even after being uninstalled. This can also happen if only the uninstaller is removed. Os desinstaladores podem ser reconhecidos por certificados emitidos pelas autoridades competentes. Se o certificado legitima a validação, o software não foi alterado e é credível. Se bem que o BCUninstaller possa ser utilizado como um desinstalador básico, a maior parte das suas funções são destinadas aos utilizadores experientes. Proceda com precaução! Seleccionar usando as caixas de selecção Enviar automaticamente estatísticas anónimas de utilização. A instalação terminou Procurar automaticamente por atualizações no arranque da aplicação. Abrir o formulário de contacto Os desinstaladores comprovados estão assinalados a verde, os não comprovados estão a azul. Aviso: A verificação pode levar bastante tempo. ● Ordenar os desinstaladores em qualquer coluna. Reorganize livremente as colunas. ● Agrupar desinstaladores similares. ulk crap uninstaller The missing B is in an image next to the text ● Utilizar os filtros e pesquise por palavras-chave (em todas as colunas). Abra o formulário de contacto Sair do assistente Mostrar desinstaladores assinalados como "componentes do sistema" ● Enviar relatórios de erros. Idioma seleccionado Pode ler o rol detalhado das alterações e inteirar-se mais acerca do meu software na página inicial. 1 / 6 True 17, 17 ru ================================================ FILE: source/BulkCrapUninstaller/Forms/Wizards/FirstStartBox.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Fill Microsoft Sans Serif, 9.75pt, style=Bold 123, 13 4, 0, 4, 0 89, 28 2 1 / 6 MiddleCenter labelProgress System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panelNavigation 0 True Left 13, 13 4, 3, 4, 3 110, 28 3 Exit wizard buttonExit System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panelNavigation 1 True Right False 212, 13 4, 3, 4, 3 88, 28 1 Back buttonPrev System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panelNavigation 2 Right 300, 13 4, 3, 4, 3 12, 28 10 panel4 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panelNavigation 3 True Right 312, 13 4, 3, 4, 3 88, 28 0 Continue buttonNext System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panelNavigation 4 Bottom 0, 409 4, 3, 4, 3 13, 13, 13, 13 413, 54 7 panelNavigation System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 0 True Left 2551, 7 4, 3, 4, 3 26, 432 17 panel3 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 scrollPanel 0 Left 2525, 7 4, 3, 4, 3 26, 432 16 panel2 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 scrollPanel 1 Top NoControl 125, 42 4, 3, 4, 3 148, 27 0 More settings buttonMore System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel12 0 Top NoControl 125, 75 4, 3, 4, 3 148, 27 1 View help buttonHelp System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel12 1 Bottom NoControl 125, 130 4, 3, 4, 3 148, 27 2 Finish setup buttonFinish System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel12 2 Top 0, 193 4, 3, 4, 3 386, 171 1 panel12 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 page5 0 True True 9, 5 4, 0, 4, 0 0, 9, 0, 5 364, 44 0 You can now start using BCUninstaller. If you have any questions or would like to suggest a new feature visit the link below. p5finishContact System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel6 0 True 9, 49 4, 0, 4, 0 128, 15 1 Open the contact form p5LinkContact System.Windows.Forms.LinkLabel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel6 1 True 9, 64 4, 0, 4, 0 0, 9, 0, 5 333, 44 2 You can read detailed change logs and check out more of my software on the homepage. p5finishHomepage System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel6 2 True 9, 108 4, 0, 4, 0 116, 15 3 Open the homepage p5LinkHomepage System.Windows.Forms.LinkLabel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel6 3 Top 0, 65 4, 3, 4, 3 5, 5, 5, 5 386, 128 8 flowLayoutPanel6 System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 page5 1 Top Arial Black, 12pt, style=Bold 0, 0 4, 0, 4, 0 0, 0, 0, 7 386, 65 0 Setup has been finished BottomCenter p5finishTitle System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 page5 2 Left 2127, 7 4, 3, 4, 3 0, 0, 12, 0 398, 432 14 page5 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 scrollPanel 2 Left 2101, 7 4, 3, 4, 3 26, 432 15 spacer4 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 scrollPanel 3 True Arial Black, 12pt, style=Bold 9, 5 4, 0, 4, 0 0, 0, 0, 3 155, 26 0 Network access p4netTitle System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel2 0 True 9, 31 4, 0, 4, 0 0, 0, 0, 3 377, 33 1 BCUninstaller can attempt to connect to the internet for the following reasons: p4netDesc System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel2 1 True 9, 64 4, 0, 4, 0 5, 0, 0, 2 186, 17 3 ● To search for program updates. p4netDesc1 System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel2 2 True 9, 81 4, 0, 4, 0 5, 0, 0, 2 145, 17 4 ● To upload error reports. p4netDesc2 System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel2 3 True 9, 98 4, 0, 4, 0 5, 0, 0, 2 213, 17 5 ● To send anonymous usage statistics. p4netDesc3 System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel2 4 True NoControl 9, 115 4, 0, 4, 0 5, 0, 0, 2 228, 17 6 ● To fetch and upload application ratings p4netDesc4 System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel2 5 True 9, 132 4, 0, 4, 0 0, 9, 0, 9 380, 78 7 Every time an error occurs you will be asked if you want to send it. You can check what data is being sent in error and usage reports by inspecting their respective XML files in BCUninstaller's directory. The sent data is not shared with any third parties. p4netErrors System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel2 6 True NoControl 9, 213 4, 3, 4, 2 5, 0, 0, 0 299, 19 8 Automatically look for updates on application start checkBoxUpdateSearch System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel2 7 True Microsoft Sans Serif, 8.25pt, style=Italic 9, 234 4, 0, 4, 0 7, 0, 0, 7 280, 20 9 You can search for updates manually from the menu bar. p4netUpdateAdd System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel2 8 True NoControl 9, 257 4, 3, 4, 2 5, 0, 0, 0 281, 19 10 Automatically send anonymous usage statistics checkBoxSendStats System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel2 9 True Microsoft Sans Serif, 8.25pt, style=Italic 9, 278 4, 0, 4, 0 7, 0, 0, 7 274, 20 11 Sending these statistics will help improve BCUninstaller. p4netUsageAdd System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel2 10 True NoControl 9, 301 4, 3, 4, 2 5, 0, 0, 0 211, 19 11 Enable user ratings of applications checkBoxRatings System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel2 11 Fill TopDown 0, 0 4, 3, 4, 3 5, 5, 5, 5 398, 432 1 flowLayoutPanel2 System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 pageNetwork 0 Left 1703, 7 4, 3, 4, 3 398, 432 8 pageNetwork System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 scrollPanel 4 Left 1677, 7 4, 3, 4, 3 26, 432 19 panel5 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 scrollPanel 5 True Arial Black, 12pt, style=Bold NoControl 9, 5 4, 0, 4, 0 0, 0, 0, 3 209, 26 0 Corrupted uninstallers pCorTitle System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel1 0 True NoControl 9, 31 4, 0, 4, 0 0, 0, 0, 3 379, 33 1 Over time you may find that some applications will refuse to uninstall, or will just disappear from most of the uninstall managers. pCorDesc System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel1 1 True Arial, 9.75pt, style=Bold NoControl 9, 64 4, 0, 4, 0 0, 9, 0, 3 216, 28 2 Corrupted or missing uninstallers pCorViewInvalidTitle System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel1 2 True NoControl 9, 92 4, 0, 4, 0 0, 0, 0, 3 380, 48 3 In some cases uninstallers can get corrupted, making them impossible to uninstall. BCUninstaller can remove these entries easily using the "Uninstall manually" option. pCorViewInvalid System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel1 3 True NoControl 9, 143 4, 3, 4, 2 5, 0, 0, 0 182, 19 4 Highlight invalid uninstallers checkBoxInvalidTest System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel1 4 True Microsoft Sans Serif, 8.25pt, style=Italic NoControl 9, 164 4, 0, 4, 0 7, 0, 0, 0 193, 13 5 Invalid uninstallers are marked in grey. pCorViewinvalidComment System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel1 5 True Arial, 9.75pt, style=Bold NoControl 9, 177 4, 0, 4, 0 0, 9, 0, 3 169, 28 6 Unregistered applications pCorOrphansTitle System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel1 6 True NoControl 9, 205 4, 0, 4, 0 0, 0, 0, 3 357, 48 7 Sometimes whole applications can be left on your drive even after being uninstalled. This can also happen if only the uninstaller is removed. pCorOrphansMessage System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel1 7 True NoControl 9, 256 4, 3, 4, 2 5, 0, 0, 0 247, 19 8 Show unregistered applications in the list checkBoxOrphans System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel1 8 True Microsoft Sans Serif, 8.25pt, style=Italic NoControl 9, 277 4, 0, 4, 0 7, 0, 0, 0 340, 39 9 Unregistered applications are marked in red. If the original uninstaller isn't found you will have to use the "Uninstall manually" option to remove them. pCorOrphansComment System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel1 9 Fill TopDown 0, 0 4, 3, 4, 3 5, 5, 5, 5 398, 432 1 flowLayoutPanel1 System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 pageCorrupted 0 Left 1279, 7 4, 3, 4, 3 398, 432 18 pageCorrupted System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 scrollPanel 6 Left 1253, 7 4, 3, 4, 3 26, 432 13 spacer3 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 scrollPanel 7 True Arial Black, 12pt, style=Bold 9, 5 4, 0, 4, 0 0, 0, 0, 3 152, 26 0 Advanced users p3advTitle System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel4 0 True 9, 31 4, 0, 4, 0 353, 30 1 While BCUninstaller can be used as a basic uninstaller, most of its functions are aimed at power users. Proceed with caution! p3advDesc System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel4 1 True Arial, 9.75pt, style=Bold 9, 61 4, 0, 4, 0 0, 9, 0, 3 134, 28 2 System components p3advSyscompTitle System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel4 2 True 9, 89 4, 0, 4, 0 0, 0, 0, 3 371, 48 3 Applications marked as "system components" are hidden from most of the basic uninstall managers. This tag does NOT mean that the application is a part of the operating system. p3advSyscomp System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel4 3 True NoControl 9, 140 4, 3, 4, 2 5, 0, 0, 0 300, 19 4 Show uninstallers marked as "system components" checkBoxListSysComp System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel4 4 True Arial, 9.75pt, style=Bold 9, 161 4, 0, 4, 0 0, 5, 0, 3 145, 24 5 Protected uninstallers p3advProtectTitle System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel4 5 True 9, 185 4, 0, 4, 0 0, 0, 0, 3 378, 63 6 Protected items are marked with the "NoRemove" tag, which means that the publisher doesn't want you to remove them. This tag is often used by large software packages to prevent you from uninstalling their individual parts. p3advProtect System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel4 6 True NoControl 9, 251 4, 3, 4, 2 5, 0, 0, 0 244, 19 7 Show uninstallers marked as "protected" checkBoxListProtected System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel4 7 True NoControl 9, 275 4, 3, 4, 2 5, 0, 0, 0 325, 19 8 Disable protection of uninstallers marked as "protected" checkBoxDiisableProtection System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel4 8 True Microsoft Sans Serif, 8.25pt, style=Italic 9, 296 4, 0, 4, 0 7, 0, 0, 0 204, 13 9 This will let you uninstall protected items. p3advProtectAdd System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel4 9 Fill TopDown 0, 0 4, 3, 4, 3 5, 5, 5, 5 398, 432 0 flowLayoutPanel4 System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 page3 0 Left 855, 7 4, 3, 4, 3 398, 432 12 page3 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 scrollPanel 8 Left 829, 7 4, 3, 4, 3 26, 432 11 spacer2 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 scrollPanel 9 True Arial Black, 12pt, style=Bold 9, 5 4, 0, 4, 0 0, 0, 0, 3 184, 26 0 Uninstaller list view p2viewTitle System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel3 0 True 9, 31 4, 0, 4, 0 0, 0, 0, 3 366, 33 1 All of the uninstallers found in your system are in the main list view. Here are some ways to browse this data: p2viewDetail System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel3 1 True 9, 64 4, 0, 4, 0 5, 0, 0, 2 289, 17 2 ● Use filters and search for keywords (in all columns) p2viewDetail1 System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel3 2 True 9, 81 4, 0, 4, 0 5, 0, 0, 2 330, 17 4 ● Sort uninstallers by any column. Freely rearrange columns. p2viewDetail2 System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel3 3 True 9, 98 4, 0, 4, 0 5, 0, 0, 5 156, 20 5 ● Group similar uninstallers p2viewDetail3 System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel3 4 True NoControl 9, 121 4, 3, 4, 2 5, 0, 0, 0 176, 19 6 Show uninstallers in groups checkBoxGroups System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel3 5 True NoControl 9, 145 4, 3, 4, 2 5, 0, 0, 0 159, 19 7 Select using checkboxes checkBoxCheckboxes System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel3 6 True Arial, 9.75pt, style=Bold 9, 166 4, 0, 4, 0 0, 9, 0, 3 138, 28 8 Certified uninstallers p2viewCertsTitle System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel3 7 True 9, 194 4, 0, 4, 0 0, 0, 0, 3 379, 48 9 Uninstallers can be signed with certificates issued by relevant authorities. If the certificate passes validation the software package has not been altered and is reputable. p2viewCerts System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel3 8 True NoControl 9, 245 4, 3, 4, 2 5, 0, 0, 0 190, 19 10 Highlight certified uninstallers checkBoxCertTest System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel3 9 True Microsoft Sans Serif, 8.25pt, style=Italic 9, 266 4, 0, 4, 0 7, 0, 0, 0 308, 26 10 Verified uninstallers are marked in green, unverified are in blue. Warning: Verification can take a long time. p2viewAdd System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel3 10 Fill TopDown 0, 0 4, 3, 4, 3 5, 5, 5, 5 398, 432 0 flowLayoutPanel3 System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 page2 0 Left 431, 7 4, 3, 4, 3 398, 432 10 page2 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 scrollPanel 10 Left 405, 7 4, 3, 4, 3 26, 432 9 spacer1 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 scrollPanel 11 True Arial Black, 12pt, style=Bold 9, 5 4, 0, 4, 0 0, 9, 0, 3 244, 35 0 Welcome to BCUninstaller! p1welcomeHeading System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel5 0 True 9, 40 4, 0, 4, 0 326, 30 1 This wizard will give you a quick tour and help configure the application. p1welcomeSubheading System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel5 1 True Arial Black, 12pt, style=Bold 9, 70 4, 0, 4, 0 0, 9, 0, 3 176, 35 2 Selected language p1languageHeading System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel5 2 True 9, 105 4, 0, 4, 0 0, 0, 0, 5 376, 50 3 You can force BCUninstaller to use a specific localization if the default language is incorrect. A restart will be performed to apply the new language. p1languageDesc System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel5 3 9, 3 4, 7, 4, 3 268, 23 0 comboBoxLanguage System.Windows.Forms.ComboBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel9 0 Top, Right 284, 2 4, 3, 4, 3 88, 27 1 Apply buttonLanguageApply System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel9 1 Top 9, 158 4, 3, 4, 3 379, 31 4 panel9 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel5 4 True 9, 192 4, 0, 4, 0 0, 2, 0, 5 379, 37 5 If you are willing to help translate BCUninstaller to your language, click on the link below to contact me. All help is greatly appreciated! p1languageExtradetails System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel5 5 True 9, 229 4, 0, 4, 0 128, 15 6 Open the contact form p1linkLabelContact System.Windows.Forms.LinkLabel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel5 6 Fill TopDown 0, 118 4, 3, 4, 3 5, 5, 5, 5 398, 314 1 flowLayoutPanel5 System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 page1 0 Right 40, 0 4, 3, 4, 3 114, 118 Zoom 8 pictureBox1 System.Windows.Forms.PictureBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel1 0 Right Calibri, 27.75pt, style=Bold 154, 0 0, 0, 0, 0 244, 118 7 ulk crap uninstaller MiddleLeft label2 System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel1 1 Top 0, 0 4, 3, 4, 3 398, 118 0 panel1 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 page1 1 Left 7, 7 4, 3, 4, 3 398, 432 7 page1 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 scrollPanel 12 Fill 0, 0 4, 3, 4, 3 7, 7, 7, 7 413, 463 1 scrollPanel System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 1 17, 17 True 7, 15 413, 463 4, 3, 4, 3 CenterParent Welcome to BCUninstaller timer1 System.Windows.Forms.Timer, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 FirstStartBox System.Windows.Forms.Form, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 ================================================ FILE: source/BulkCrapUninstaller/Forms/Wizards/FirstStartBox.ru.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Отмена Назад Далее Больше настроек Просмотр справки Готово Теперь Вы можете начать использовать BCUninstaller. Если у Вас есть вопросы или вы хотите предложить новую функцию — посетите ссылку ниже. Написать разработчику Вы можете посмотреть новости и другие мои программы на домашней странице. Домашняя страница Установка завершена Доступ к сети BCUninstaller может попытаться подключиться к Интернету по следующим причинам: ● Для поиска обновлений программы. ● Для отправки отчётов об ошибках. ● Для отправки анонимной статистики. ● Для получения и загрузки рейтинга программ Каждый раз, когда возникает ошибка, Вам будет предложено отправить отчёт. Вы можете проверить, какие данные передаются в отчёте, просмотрев XML-файлы в каталоге BCUninstaller. Передаваемые данные не передаются третьим сторонам. Искать обновления при запуске приложения Вы можете искать обновления вручную в строке меню. Отправлять анонимную статистику использования Эти статистические данные помогут улучшить BCUninstaller. Включить пользовательские оценки приложений Повреждённые деинсталляторы Со временем Вы можете обнаружить, что некоторые приложения отказываются удаляться или просто исчезли из большинства менеджеров деинсталляции программ. Повреждённые или отсутствующие деинсталляторы В некоторых случаях деинсталляторы могут быть повреждены, что делает невозможным их удаление. BCUninstaller может удалить эти записи с помощью опции "Удалить вручную". Подсветка недопустимых деинсталляторов Недействительные деинсталляторы помечаются серым. Незарегистрированные приложения Иногда целые приложения остаются на винчестере даже после удаления. Это обычно происходит, если деинсталлятор удалён. Показывать незарегистрированные в списке Незарегистрированные приложения помечены красным. Их деинсталлятор не обнаружен и Вам надо использовать параметр "Удалить вручную" для их удаления. Опытные пользователи BCUninstaller может использоваться как основной деинсталлятор, но многие его функции предназначены для опытных пользователей. Соблюдайте осторожность! Системные компоненты Приложения, помеченные как "системные", скрыты от большинства основных менеджеров деинсталляции программ. Этот тег не означает, что приложение является частью операционной системы. Показывать деинсталляторы с тегом "системные" Защищённые деинсталляторы Защищённые элементы помечены тегом "NoRemove", это означает, что издатель не хочет, чтобы их удаляли. Этот тег часто используется крупными пакетами программного обеспечения, чтобы помешать Вам удалить их отдельные части. Показывать деинсталляторы с тегом "NoRemove" Отключить защиту деинсталляторов с тегом "NoRemove" Это позволит Вам деинсталлировать защищённые элементы. Вид списка деинсталяции Все деинсталляторы, найденные в вашей системе, находятся в главном списке. Вот несколько способов, как просматривать эти данные: ● Используйте фильтры и поиск по ключевым словам (во всех колонках) ● Сортировка деинсталляторов по любой колонке. Можно переставлять столбцы. ● Группировка похожих деинсталляторов Показывать деинсталляторы в группах Использовать для выбора флажки Сертифицированные деинсталляторы Деинсталлятор может быть подписан с помощью доверенных сертификатов. Если сертификат проходит проверку подлинности — означает, что программный пакет не был изменён и заслуживает доверия. Подсвечивать проверенные деинсталляторы Проверенные деинсталляторы выделяются зелёным, непроверенные — синим. Внимание: Проверка может занимать длительное время. Добро пожаловать в BCUninstaller! Этот мастер проведёт краткий обзор и поможет настроить приложение. Выбранный язык BCUninstaller может использовать указанную локализацию. Чтобы применить новый язык, будет выполнена перезагрузка программы. Применить Если Вы готовы помочь в переводе BCUninstaller на Ваш язык, нажмите на ссылку ниже, чтобы связаться со мной. Любая помощь будет принята с благодарностью! Открыть форму связи Добро пожаловать в BCUninstaller ulk crap uninstaller The missing B is in an image next to the text 1 / 6 ================================================ FILE: source/BulkCrapUninstaller/Forms/Wizards/FirstStartBox.sl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Dobrodošli v BCUninstaller! Zaščitene vnosi so označeni z oznako "NeOdstrani", kar pomeni, da izdajatelj ne želi, da jih odstranite. Ta oznaka se pogosto uporablja v velikih programskih paketih, da vam preprečuje odstranjevanje njihovih posameznih delov. Omrežni dostop ● Za pošiljanje anonimne statistike o uporabi. Vsi najdeni odstranjevalci v vašem sistemu so v glavnem pogledu seznama. Tukaj je nekaj načinov za brskanje teh podatkov: Neveljavni odstranjevalci so označeni v sivi barvi. Prikaži neregistrirane aplikacije na seznamu Zaščiteni odstranjevalci Odpri domačo stran ● Za iskanje posodobitev programa. BCUninstaller lahko prisilite, da uporablja določen jezik, če je privzeti jezik napačen. Za začetek uporabe novega jezika bo opravljen ponovni zagon programa. Zdaj lahko začnete uporabljati BCUninstaller. Če imate kakršna koli vprašanja ali, če želite predlagati nove funkcije, obiščite spodnjo povezavo. Označi neveljavne odstranjevalce Iz menijske vrstice lahko ročno poiščete posodobitve. Dobrodošli v BCUninstallerju Končaj namestitev Nadaljuj Prikaži odstranjevalce, ki so označene kot "zaščiteni" Uporabi Neregistrirane aplikacije Sestavine sistema Nazaj Prikaži odstranjevalce, ki so označene kot "sistemske sestavine" Lahko preberete podrobne dnevnike sprememb in preverite več mojih programov na domači spletni strani. Vsakič, ko pride do napake boste vprašani, če želite poslati sporočilo o napaki. Lahko preverite kateri podatki bodo poslani v poročilu o napaki in v poročilu o uporabi, z upogledom v njune XML datoteke (v imeniku BCUninstallerja). Poslani podatki ne bodo dostopni drugim osebam. Pošiljanje teh statistik nam bo pomagalo izboljšati BCUninstaller. Ta čarovnik vam bo nudil hiter ogled in pomagal nastaviti aplikacijo. Prikaži odstranjevalce v skupinah Zapri čarovnika Overjeni odstranjevalci To vam bo dovolilo odstraniti zaščitene vnose. Več nastavitev Aplikacije, ki so označene kot "sistemske sestavine", so skrite za večino osnovnih upraviteljev odstranjevanj. Ta oznaka NE pomeni, da je aplikacija del operacijskega sistema. Onemogoči zaščito odstranjevalcev, ki so označeni kot "zaščiteni" Napredni uporabniki Poškodovani ali manjkajoči odstranjevalci Označi overjene odstranjevalce Pogled seznama odstranjevalcev Poškodovani odstranjevalci Sčasoma boste morda ugotovili, da bodo nekatere aplikacije zavrnile odstranjevanje, ali bodo samo izginile iz večine upraviteljev odstranjevanja. V nekaterih primerih lahko prejmete poškodovane odstranjevalce, zaradi česar ni možno odstranjevanje aplikacij. BCUninstaller lahko preprosto odstrani te vnose z uporabo možnosti "Odstrani ročno". Včasih cele aplikacije lahko ostanejo na vašem pogonu, tudi po odstranitvi. To se lahko zgodi tudi, če je odstranjen samo odstranjevalec. Odstranjevalci so lahko podpisani s potrdili, ki so jih izdali pomembni organi. Če potrdila opravijo potrditev, programski paket ni bil spreminjan in je pristen. BCUninstaller se lahko poskuša povezati z internetom iz naslednjih razlogov: Medtem, ko se BCUninstaller lahko uporablja kot osnovni odstranjevalec, je večina njegovih funkcij namenjenih naprednejšim uporabnikom. Nadaljujte previdno! Izberi s pomočjo potrditvenih polj Samodejno pošlji anonimno statistiko uporabe Namestitev je končana Ob zagonu aplikacije, samodejno preveri obstoj posodobitev Neregistrirane aplikacije so označene z rdečo barvo. Če ni mogoče najti izvirnega odstranjevalca, boste morali uporabiti možnost "Odstrani ročno", da jih odstranite. Odpri obrazec za stik Preverjeni odstranjevalci so označeni z zeleno barvo, nepreverjeni pa so v modri barvi. Opozorilo: Preverjanje lahko traja dlje časa. ● Razvrstite odstranjevalce po vsakem stolpcu. Prosto preuredite stolpce. ● Grupiraj podobne odstranjevalce ulk crap uninstaller The missing B is in an image next to the text ● Uporabite filtre in poiščite ključne besede (v vseh stolpcih) Odpri obrazec za stik Če ste pripravljeni pomagati prevesti BCUninstaller v vaš jezik, kliknite na spodnjo povezavo, da stopite v stik z mano. Vsa pomoč je zelo cenjena! ● Za pošiljanje poročil o napakah. Izbran jezik ● Za pridobivanje in nalaganje ocen aplikacije Omogoči uporabnikovo ocenjevanje aplikacije Prikaz pomoči 1/6 True 17, 17 cs ================================================ FILE: source/BulkCrapUninstaller/Forms/Wizards/FirstStartBox.sv.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 1 / 6 Avsluta guiden Tillbaka Fortsätt Fler inställningar Visa hjälp Slutför Nu kan du börja använda BCUninstaller. Om du har några frågor eller vill föreslå en ny funktion, besök länken nedan. Öppna kontaktformuläret Du kan läsa detaljerade ändringsloggar och kolla in mer av min programvara på hemsidan. Öppna hemsidan Installationen har slutförts Nätverksåtkomst BCUninstaller kan försöka ansluta till internet av följande skäl: ● För att söka efter uppdateringar. ● För att ladda upp felrapporter. ● För att skicka anonym användarstatistik. ● För att hämta och ladda upp appbetyg Varje gång ett fel inträffar kommer du att bli ombedd att rapportera det. Du kan kontrollera vilka data som skickas i fel- och användningsrapporter genom att inspektera deras respektive XML-filer i BCUninstallers mapp. Uppladdad data delas inte med några tredje parter. Sök efter uppdateringar automatiskt vid varje uppstart Du kan söka efter uppdateringar manuellt från menyraden. Skicka anonym användningsstatistik automatiskt Att skicka denna statistik hjälper till att förbättra BCUninstaller. Aktivera användarbetyg för appar Korrupta avinstallationsprogram Över tid kan du märka att vissa appar vägrar att avinstallera sig, eller helt enkelt försvinner från de flesta avinstallationshanterare. Korrupta eller saknade avinstallationsprogram I vissa fall kan avinstallationsprogram bli korrupta, vilket gör dem omöjliga att avinstallera. BCUninstaller kan ta bort dessa poster med hjälp av alternativet "Avinstallera manuellt". Märk ogiltiga avinstallationsprogram Ogiltiga avinstallationsprogram är markerade i grått. Oregistrerade appar Ibland kan fullständiga appar lämnas kvar på din enhet trots att de har avinstallerats. Detta kan också hända om endast avinstallationsprogrammet tas bort. Visa oregistrerade appar i listan Oregistrerade appar är markerade i rött. Om det ursprungliga avinstallationsprogrammet inte hittas måste du använda alternativet "Avinstallera manuellt" för att ta bort dem. Avancerade användare Även om BCUninstaller kan användas som en grundläggande avinstallerare, är de flesta av dess funktioner riktade mot avancerade användare. Använd med försiktighet! Systemkomponenter Appar markerade som 'systemkomponenter' är dolda från de flesta avinstallationshanterare. Denna tagg innebär INTE att appen är en del av operativsystemet. Visa avinstallationsprogram markerade som 'systemkomponenter' Skyddade avinstallationsprogram Skyddade objekt är markerade med taggen "NoRemove", vilket innebär att utgivaren inte vill att du ska ta bort dem. Denna tagg används ofta av stora programvarupaket för att förhindra att du avinstallerar deras enskilda delar. Visa avinstallationsprogram markerade som "skyddade" Inaktivera skyddet av avinstallationsprogram markerade som 'skyddade' Detta tillåter dig att avinstallera skyddade objekt. Avinstallationer listvy Alla avinstallationsprogram som hittats på din dator finns i huvudlistvyn. Här är några sätt att bläddra bland denna data: ● Använd filter och sök efter nyckelord (i alla kolumner) ● Sortera avinstallationsprogram efter valfri kolumn. Flytta kolumner fritt. ● Gruppera liknande avinstallationsprogram Visa avinstallationsprogram i grupper Välj med hjälp av kryssrutor Certifierade avinstallationsprogram Avinstallationsprogram kan signeras med certifikat utfärdade av relevanta myndigheter. Om certifikatet passerar valideringen har programvarupaketet inte ändrats och är betrodd. Markera certifierade avinstallationsprogram Verifierade avinstallationsprogram är markerade i grönt, ej verifierade är i blått. Varning: Verifiering kan ta lång tid. Välkommen till BCUninstaller! Den här guiden kommer att ge dig en snabb översikt och hjälpa dig att konfigurera appen. Språkval Du kan tvinga BCUninstaller att använda en specifik språkversion om standardspråket är felaktigt. En omstart kommer att utföras för att tillämpa det nya språket. Verkställ Om du är villig att hjälpa till med att översätta BCUninstaller till ditt språk, klicka på länken nedan för att kontakta mig. All hjälp uppskattas mycket! Öppna kontaktformuläret ulk crap uninstaller The missing B is in an image next to the text Välkommen till BCUninstaller ================================================ FILE: source/BulkCrapUninstaller/Forms/Wizards/FirstStartBox.tr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 1 / 6 Sihirbazdan çık Geri Devam Diğer ayarlar Yardımı görüntüle Kurulumu bitir Artık BCUninstaller'ı kullanmaya başlayabilirsiniz. Herhangi bir sorunuz varsa veya yeni bir özellik önermek istiyorsanız, aşağıdaki bağlantıyı ziyaret edin. İletişim formunu aç Ayrıntılı değişiklik kayıtlarını okuyabilir ve ana sayfamdaki yazılımımdan daha fazlasını kontrol edebilirsiniz. Ana sayfayı aç Kurulum bitti Ağ Girişi BCUninstaller aşağıdaki nedenlerle internete bağlanmayı deneyebilir: ● Program güncellemelerini ara. ● Hata raporlarını yükle. ● Anonim kullanım istatistiklerini gönder. ● Uygulama puanlarını almak ve yükle. Bir hata oluştuğunda, göndermek istediğiniz zaman size sorulur. BCUninstaller dizinindeki ilgili XML dosyalarını inceleyerek hata ve kullanım raporlarında hangi verilerin gönderildiğini kontrol edebilirsiniz. Gönderilen veriler üçüncü taraflarla paylaşılmaz. Uygulama başlangıcında güncellemeleri otomatik olarak arayın Güncellemeleri menü çubuğundan elle arayabilirsiniz. Anonim kullanım istatistiklerini otomatik olarak gönder Bu istatistikleri göndermek BCUninstaller'ı iyileştirmeye yardımcı olacaktır. Uygulamaların kullanıcı derecelendirmelerini etkinleştir Bozulmuş kaldırıcılar Zamanla bazı uygulamaların kaldırmayı reddedeceğini veya yalnızca kaldırılan yöneticilerin çoğundan kaybolduğunu görebilirsiniz. Bozuk veya eksik kaldırıcılar Bazı durumlarda, kaldırma araçları bozulabilir ve bunları kaldırmak imkansız hale getirir. BCUninstaller bu girdileri "Manuel kaldır" seçeneğini kullanarak kolayca kaldırabilir. Geçersiz kaldırıcıları vurgula Geçersiz kaldırıcılar gri ile işaretlenmiştir. Kayıtsız başvurular Bazen tüm uygulamalar kaldırıldıktan sonra bile sürücünüzde bırakılabilir. Bu, yalnızca kaldırıcı kaldırılırsa da gerçekleşebilir. Kayıtlı olmayan uygulamaları listede göster Kayıtlı olmayan uygulamalar kırmızı olarak işaretlenmiştir. Orijinal kaldırıcı bulunamadıysa, kaldırmak için "El ile kaldır" seçeneğini kullanmanız gerekecektir. Ileri düzey kullanıcılar BCUninstaller temel bir kaldırıcı olarak kullanılabilirken, işlevlerinin çoğu deneyimli kullanıcılara yöneliktir. Dikkatli ilerle! Sistem bileşenleri "Sistem bileşenleri" olarak işaretlenmiş uygulamalar, temel kaldırma yöneticilerinin çoğundan gizlenmiştir. Bu etiket, uygulamanın işletim sisteminin bir parçası olduğu anlamına gelmez. Show uninstallers marked as "system components" Korumalı kaldırıcılar Korunan öğeler "NoRemove" etiketi ile işaretlenir, yani yayıncı bunları kaldırmanızı istemez. Bu etiket genellikle bireysel parçalarını kaldırmanızı önlemek için büyük yazılım paketleri tarafından kullanılır. "Korumalı" olarak işaretlenmiş kaldırıcıları göster "Korumalı" olarak işaretlenmiş kaldırıcıların korumasını devre dışı bırak Bu korumalı öğeleri kaldırmanıza izin verecektir. Kaldırıcı listesi görünümü Sisteminizde bulunan tüm kaldırma programları ana liste görünümündedir. Bu verilere göz atmanın bazı yolları: ● Filtreleri kullanın ve anahtar kelimeleri arayın (tüm sütunlarda) ● Filtreleri kullanın ve anahtar kelimeleri arayın (tüm sütunlarda)... ● Benzer kaldırıcılar gruplandır Gruplardaki kaldırıcıları göster Onay kutularını kullanarak seçin Sertifikalı kaldırıcılar Kaldırma yetkilileri ilgili yetkililer tarafından verilen sertifikalarla imzalanabilir. Sertifika geçerliliğini geçerse, yazılım paketi değiştirilmemiştir ve saygındır. Sertifikalı kaldırıcıları vurgulayın Doğrulanmış kaldırıcılar yeşil olarak işaretlenmiş, doğrulanmamış mavi renktedir. Uyarı: Doğrulama uzun sürebilir. Bu sihirbaz size hızlı bir tur verir ve uygulamayı yapılandırmaya yardımcı olur. Seçilen dil Varsayılan dil yanlışsa BCUninstaller'ı belirli bir yerelleştirmeyi kullanmaya zorlayabilirsiniz. Yeni dili uygulamak için bir yeniden başlatma yapılacaktır. Uygula BCUninstaller'ı kendi dilinize çevirmeye yardımcı olmak istiyorsanız, bana ulaşmak için aşağıdaki bağlantıya tıklayın. Tüm yardımlar büyük beğeni topluyor! İletişim formunu aç ulk crap uninstaller The missing B is in an image next to the text BCUninstaller'e hoş geldiniz ================================================ FILE: source/BulkCrapUninstaller/Forms/Wizards/FirstStartBox.vi.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 1 / 6 Thoát thiết lập Trở về Tiếp tục Xem thêm cài đặt Xem trợ giúp Hoàn thành thiết lập Bạn có thể bắt đầu sử dụng BCUninstaller ngay bây giờ. Nếu bạn có bất kỳ câu hỏi nào hay muốn đề xuất một tính năng mới, hãy truy cập vào liên kết dưới đây. Mở biểu mẫu liên hệ Bạn có thể xem chi tiết nhật ký thay đổi và khám phá thêm các phần mềm khác của tôi trên trang chủ. Mở trang chủ Thiết lập đã hoàn tất Truy cập mạng BCUninstaller có thể cố gắng kết nối Internet vì những lý do sau: ● Để kiểm tra các bản cập nhật. ● Để tải lên các báo cáo lỗi. ● Để gửi số liệu thống kê sử dụng ẩn danh. ● Để tìm và tải lên các đánh giá ứng dụng. Mỗi khi xảy ra lỗi, bạn sẽ được hỏi xem có muốn gửi báo cáo lỗi đó không. Bạn có thể kiểm tra dữ liệu nào đang được gửi trong các báo cáo lỗi và sử dụng bằng cách kiểm tra các file XML tương ứng trong thư mục của BCUninstaller. Dữ liệu được gửi đi không được chia sẻ với bất kỳ bên thứ ba nào. Tự động kiểm tra các bản cập nhật khi khởi động ứng dụng Bạn có thể kiểm tra cập nhật thủ công từ thanh menu. Tự động gửi số liệu thống kê sử dụng ẩn danh Gửi những số liệu thống kê này có thể giúp cải thiện BCUninstaller. Bật tính năng đánh giá ứng dụng của người dùng Trình gỡ cài đặt bị hỏng Theo thời gian, bạn có thể gặp phải tình trạng một số ứng dụng không thể gỡ cài đặt theo cách thông thường, hoặc chúng biến mất khỏi danh sách của hầu hết các công cụ gỡ cài đặt. Trình gỡ cài đặt bị hỏng hoặc bị thiếu Đôi khi trình gỡ cài đặt có thể bị lỗi, khiến bạn không thể gỡ cài đặt phần mềm theo cách thông thường. BCUninstaller có thể dễ dàng loại bỏ các chương trình này bằng cách sử dụng tùy chọn "Gỡ cài đặt thủ công". Đánh dấu các trình gỡ cài đặt không hợp lệ Trình gỡ cài đặt không hợp lệ được đánh dấu bằng màu xám. Ứng dụng chưa đăng ký Đôi khi toàn bộ ứng dụng vẫn có thể còn sót lại trên ổ đĩa của bạn ngay cả sau khi gỡ cài đặt. Điều này cũng có thể xảy ra khi chỉ có mỗi trình gỡ cài đặt được xoá. Hiển thị các ứng dụng chưa đăng ký Các ứng dụng chưa đăng ký được đánh dấu bằng màu đỏ. Nếu bạn không thể tìm thấy trình gỡ cài đặt gốc, bạn sẽ cần xóa chúng bằng tùy chọn "Gỡ cài đặt thủ công". Dành cho người dùng nâng cao Mặc dù BCUninstaller có thể được sử dụng như một trình gỡ cài đặt cơ bản, nhưng hầu hết các chức năng của nó đều hướng đến người dùng chuyên sâu. Hãy cẩn thận khi sử dụng! Thành phần hệ thống Các ứng dụng được đánh dấu là "thành phần hệ thống" thường bị ẩn khỏi hầu hết các trình gỡ cài đặt cơ bản. Tuy nhiên, điều này KHÔNG CÓ NGHĨA là ứng dụng đó là một phần của hệ điều hành. Hiển thị các trình gỡ cài đặt được đánh dấu là "thành phần hệ thống" Trình gỡ cài đặt được bảo vệ Các mục được bảo vệ được đánh dấu bằng thẻ "NoRemove", có nghĩa là nhà phát hành không muốn bạn xóa chúng. Thẻ này thường được các gói phần mềm lớn sử dụng để ngăn bạn gỡ cài đặt các phần riêng lẻ của chúng. Hiển thị các trình gỡ cài đặt được đánh dấu là "được bảo vệ" Tắt tính năng bảo vệ của các trình gỡ cài đặt được đánh dấu là "được bảo vệ" Tính năng này sẽ cho phép bạn gỡ cài đặt các mục được bảo vệ. Chế độ xem danh sách trình gỡ cài đặt Tất cả các trình gỡ cài đặt được tìm thấy trong hệ thống của bạn đều có trong danh sách chính. Dưới đây là một số cách để duyệt qua dữ liệu này: ● Sử dụng bộ lọc và tìm kiếm theo từ khóa (tất cả các cột) ● Sắp xếp các trình gỡ cài đặt theo bất kỳ cột nào và bạn có thể sắp xếp lại các cột theo ý muốn. ● Nhóm các trình gỡ cài đặt tương tự lại với nhau. Hiển thị các trình gỡ cài đặt theo nhóm Chọn bằng cách tích vào hộp kiểm Trình gỡ cài đặt đã đạt chứng chỉ Trình gỡ cài đặt có thể được ký bằng chứng chỉ do các tổ chức uy tín cấp. Nếu chứng chỉ vượt qua xác thực, thì gói phần mềm chưa bị can thiệp và có uy tín. Đánh dấu các trình gỡ cài đặt đạt chứng chỉ Trình gỡ cài đặt được xác minh được đánh dấu màu xanh lục, trình gỡ cài đặt chưa được xác minh được đánh dấu màu xanh lam. Cảnh báo: Việc xác minh có thể mất nhiều thời gian. Chào mừng bạn đến với BCUninstaller! Trình hướng dẫn này sẽ cung cấp cho bạn một bản tóm tắt nhanh và hỗ trợ cấu hình ứng dụng. Ngôn ngữ đã chọn Bạn có thể buộc BCUninstaller sử dụng một cụ thể nếu ngôn ngữ mặc định không chính xác. Để áp dụng ngôn ngữ mới, chương trình cần sẽ cần phải khởi động lại. Chấp nhận Nếu bạn sẵn lòng giúp đỡ dịch BCUninstaller sang ngôn ngữ mẹ đẻ của bạn, hãy nhấp vào liên kết bên dưới để liên hệ với tôi. Mọi sự trợ giúp đều được trân trọng! Mở biểu mẫu liên hệ ulk crap uninstaller The missing B is in an image next to the text Chào mừng đến với BCUninstaller! ================================================ FILE: source/BulkCrapUninstaller/Forms/Wizards/FirstStartBox.zh-Hans.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 1 / 6 退出向导 返回 继续 更多设置 查看帮助 完成设置 现在可以开始使用BCUninstaller。如果你有任何问题或想建议一个新功能,请访问下面的链接。 打开联系窗体 你可以查看详细的更新日志,并在主页上查看我的其他软件。 打开主页 设置已完成 网络访问 BCUninstaller会尝试连接到互联网,原因如下: ● 搜索应用程序更新。 ● 上传错误报告。 ● 发送匿名使用情况统计信息。 ● 获取和上传应用程序评分 每次发生错误时,系统都会询问你是否要发送错误。通过检查BCUninstaller目录中相应的XML文件,可以检查错误和使用情况报告中发送的数据。发送的数据不与任何第三方共享。 在应用程序启动时自动查找更新 你可以从菜单栏手动搜索更新。 自动发送匿名使用情况统计信息 发送这些统计信息将有助于改进BCUninstaller 启用应用程序的用户评分 已损坏的卸载程序 随着时间推移,你可能会发现一些应用程序会拒绝卸载,或者只是从大多数卸载管理器中消失。 已损坏或丢失的卸载程序 在某些情况下,卸载程序可能会损坏,导致无法卸载。BCUninstaller可以使用"手动卸载"选项轻松删除这些条目。 突出显示无效的卸载程序 无效的卸载程序标记为灰色。 未注册的应用程序 有时,即使卸载后,整个应用程序也可能留在驱动器上。如果只删除卸载程序,也可能发生这种情况。 在列表中显示未注册的应用程序 未注册的应用程序以红色标记。 如果找不到原始的卸载程序,则必须使用“手动卸载”选项来删除它们。 高级用户 虽然BCUninstaller可以用作基本的卸载程序,但它的大部分功能都是针对高级用户的。小心行事! 系统组件 标记为"系统组件"的应用程序对大多数基本卸载管理器都是隐藏的。此标记并不意味着应用程序是操作系统的一部分。 显示标记为“系统组件”的卸载程序 受保护的卸载程序 受保护的项目用"不要删除"标记,这意味着发布者不希望你删除它们。大型软件包经常使用此标记来阻止你卸载其各个部分。 显示标记为"受保护"的卸载程序 禁用标记为"受保护"的卸载程序的保护 这将允许你卸载受保护的项目。 卸载程序列表视图 在系统中找到的所有卸载程序都在主列表视图中。以下是浏览这些数据的一些方法: 如果你愿意帮助将BCUninstaller翻译成你的语言,请单击下面的链接与我联系。非常感谢你的帮助! 打开联系窗体 ulk crap The missing B is in an image next to the text 欢迎使用BCUninstaller ●使用筛选器并搜索关键字(在所有列中) ●按任意列对卸载程序排序。自由地重新安排列。 ●将相似卸载程序分组 分组显示卸载程序 使用复选框选择 已验证卸载程序 卸载程序可以使用相关机构颁发的证书进行签名。如果证书通过验证,则软件包未被更改,且信誉良好。 突出显示已验证卸载程序 已验证的卸载程序以绿色标记,未验证的卸载程序以蓝色标记。 警告:验证可能需要很长时间。 欢迎使用BCUninstaller! 此向导将为你提供快速教程并帮助你配置应用程序。 选择语言 如果默认语言不正确,可以强制BCUninstaller使用特定的本地化。将重新启动以应用新语言。 应用 ================================================ FILE: source/BulkCrapUninstaller/Forms/Wizards/FirstStartBox.zh-Hant.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 1/6 關閉精靈 返回 繼續 更多設定 查看幫助 完成設定 現在可以開始使用BCUninstaller。如果你有任何問題或想建議一個新功能,請透過下面的連結。 開啟聯絡表單 你可以查看詳細的更新日誌,並在官網上查看我的其他軟體。 開啟官網 設定已完成 訪問網路 BCUninstaller會嘗試連結到網路,原因如下: ● 搜尋應用程式更新。 ● 上傳錯誤報告。 ● 傳送匿名使用情況統計資訊。 ● 獲取和上傳應用程式評分 每次發生錯誤時,系統都會詢問你是否要傳送錯誤。通過檢查BCUninstaller目錄中相應的XML文件,可以檢查錯誤和使用情況報告中傳送的資料。傳送的資料不與任何第三方共享 在應用程式啟動時自動檢查更新 你可以從選單列手動搜尋更新 自動傳送匿名使用情況統計資訊 發送這些統計資訊將有助於改進BCUninstaller 啟用應用程式的使用者評分 已毀損的移除程式 隨著時間,你可能會發現一些應用程式會拒絕移除,或者只是從大多數移除管理程式中消失。 已毀損或遺失的移除程式 在某些情況下,移除程式可能會毀損,導致無法移除。BCUninstaller可以使用"手動移除選項輕鬆刪除這些項目。 提高顯示無效的移除程式 無效的移除程式標記為灰色。 未註冊的應用程式 有時,即使移除後,整個應用程式也可能留在硬碟上。如果只刪除應用程式,也可能發生這種情況。 在清單中顯示未註冊的應用程式 未註冊的應用程式以紅色標記。 如果找不到原始的移除程式,則必須使用"手動移除"選項來刪除它們。 進階使用者 雖然BCUninstaller可以用作基本的移除程式,但它的大部分功能都是針對進階使用者的。請小心使用! 系統元件 標記為"系統元件"的應用程式對大多數基本移除管理員都是隱藏的。此標記並不意味著應用程式式操作系統的一部份。 顯示標記為"系統元件"的移除程式 受保護的移除程式 受保護的項目用"不要刪除標記,這意味著發布者不希望你刪除它們。大型軟體經常使用此標記來阻止你移除其他各個部分。 顯示標記為"受保護"的移除程式 隱藏標記為''受保護"的移除程式的保護 這將允許你移除受保護的項目。 移除程式清單顯示 在喜桶中找到的所有移除程式都在主清單顯示中。以下式瀏覽這些資料的一些方法: ●篩選並搜尋關鍵字(在所有列中) ●按任意列對應用程式排序。自由重新安排列。 ●將相似應用程式分組 分組顯示移除程式 使用複選框選擇 已驗證移除程式 移除程序可以使用相關機構頒發的憑證進行簽名。如果憑證通過驗證,則軟體包未被更改,且信譽良好。 提高顯示已驗證的移除程式 已驗證的移除程式已綠色標記,未驗證的移除程式已藍色標記。 警告:驗證可能需要很長時間。 歡迎使用BCUninstaller! 此精靈將為你提供快速教學並幫助你設置應用程式。 選擇語言 如果預設語言不正確,可以強制BCUninstaller使用特定的本地化。將重新啟動以套用新語言。 套用 如果願意幫助將BCUninstaller翻譯成你的語言,請點擊下面的連結與我聯繫。非常感謝你的幫助! 開啟聯絡視窗 ulk crap The missing B is in an image next to the text 歡迎使用BCUninstaller ================================================ FILE: source/BulkCrapUninstaller/Functions/AppPropertiesGatherer.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections; using System.Collections.Generic; using System.Data; using System.Globalization; using System.IO; using System.Linq; using BulkCrapUninstaller.Functions.Tools; using BulkCrapUninstaller.Properties; using Klocman.Extensions; using Klocman.IO; using Klocman.Localising; using UninstallTools; namespace BulkCrapUninstaller.Functions { using SingleProperty = KeyValuePair; internal enum InfoType { Invalid = 0, Overview, FileInfo, Certificate, Registry } internal static class AppPropertiesGatherer { public static DataTable GetInfo(ApplicationUninstallerEntry entry, InfoType infoType) { try { switch (infoType) { case InfoType.Overview: return ExtractOverview(entry); case InfoType.FileInfo: return ExtractFileInfo(entry); case InfoType.Registry: return ExtractRegistryInfo(entry); case InfoType.Certificate: return ExtractCertificateInfo(entry); default: throw new InvalidOperationException("Selected tab is invalid or not supported."); } } catch (Exception ex) { return GetError(ex.Message); } } private static void ConvertPropertiesIntoDataTable(IEnumerable lq, DataTable dt) { foreach (var kvp in lq.OrderBy(x => x.Key)) { if (kvp.Value == null) continue; if (kvp.Value is Guid guid && guid.IsEmpty()) continue; if (kvp.Value is DateTime time && time.IsDefault()) continue; if ((kvp.Value as Version)?.IsZeroOrNull() ?? false) continue; string result; if (kvp.Value is bool b) result = b.ToYesNo(); else if (kvp.Value is Enum e) result = e.GetLocalisedName(); else if (kvp.Value is ICollection c) result = string.Join(" | ", c.Cast().Select(x => x.ToString()).ToArray()); else result = kvp.Value.ToString(); if (!string.IsNullOrEmpty(result)) dt.Rows.Add(kvp.Key, result); } } private static DataTable ExtractCertificateInfo(ApplicationUninstallerEntry tag) { var cert = tag.GetCertificate(); if (cert == null) return GetError(Localisable.PropertiesWindow_Table_ErrorNoCertificate); var localizedCert = new LocalizedX509Certificate2(cert); // Extract required data var lq = from property in typeof(LocalizedX509Certificate2).GetProperties() select new SingleProperty(property.GetLocalisedName(), property.GetValue(localizedCert, new object[] { })); // Create and return the table var dt = GetCleanDataTable(); ConvertPropertiesIntoDataTable(lq.ToList(), dt); return dt; } private static DataTable ExtractFileInfo(ApplicationUninstallerEntry tag) { if (string.IsNullOrEmpty(tag.UninstallerFullFilename)) throw new InvalidOperationException(Localisable.PropertiesWindow_Table_ErrorMissingUninstaller); if (!File.Exists(tag.UninstallerFullFilename)) { if (tag.UninstallerKind == UninstallerType.Msiexec) throw new NotSupportedException(Localisable.PropertiesWindow_Table_ErrorMsi); throw new IOException(Localisable.PropertiesWindow_Table_ErrorDoesntExist); } var fi = AdvancedFileInfo.FromPath(tag.UninstallerFullFilename); var lq = from property in typeof(AdvancedFileInfo).GetProperties() select new SingleProperty(property.GetLocalisedName(), property.GetValue(fi, new object[] { })); // Create and return the table var dt = GetCleanDataTable(); ConvertPropertiesIntoDataTable(lq, dt); return dt; } private static DataTable ExtractOverview(ApplicationUninstallerEntry tag) { var lq = from property in typeof(ApplicationUninstallerEntry).GetProperties() select new SingleProperty(property.GetLocalisedName(), property.GetValue(tag, new object[] { })); // Create and return the table var dt = GetCleanDataTable(); ConvertPropertiesIntoDataTable(lq, dt); return dt; } private static DataTable ExtractRegistryInfo(ApplicationUninstallerEntry tag) { if (!tag.IsRegistered) throw new InvalidOperationException(Localisable.PropertiesWindow_Table_ErrorMissingRegistry); var targetKey = tag.OpenRegKey(); var dt = GetCleanDataTable(); var valueNames = targetKey.GetValueNames(); foreach (var valueName in valueNames) { dt.Rows.Add(valueName, targetKey.GetValue(valueName)); } targetKey.Close(); return dt; } private static DataTable GetCleanDataTable() { var dt = new DataTable {Locale = CultureInfo.InvariantCulture}; dt.Columns.Add(Localisable.PropertiesWindow_Table_Name, typeof(string)); dt.Columns.Add(Localisable.PropertiesWindow_Table_Value, typeof(string)); return dt; } private static DataTable GetError(string message) { return GetMessage(Localisable.PropertiesWindow_Table_Error, message); } private static DataTable GetMessage(string name, string message) { var dt = GetCleanDataTable(); dt.Rows.Add(name, message); return dt; } } } ================================================ FILE: source/BulkCrapUninstaller/Functions/AppUninstaller.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Threading; using System.Windows.Forms; using BulkCrapUninstaller.Forms; using BulkCrapUninstaller.Functions.Tools; using BulkCrapUninstaller.Properties; using Klocman; using Klocman.Extensions; using Klocman.Forms; using Klocman.Forms.Tools; using Klocman.Native; using Klocman.Tools; using UninstallTools; using UninstallTools.Factory; using UninstallTools.Factory.InfoAdders; using UninstallTools.Junk; using UninstallTools.Junk.Containers; using UninstallTools.Uninstaller; namespace BulkCrapUninstaller.Functions { internal class AppUninstaller { private readonly Action _initiateListRefresh; private readonly Action _lockApplication; private readonly Action _visibleCallback; private readonly Settings _settings = Settings.Default; private readonly object _uninstallLock = new(); /// /// Uninstall tasks will wait until this is released to continue. Keep it short to prevent ui unresponsiveness. /// public readonly object PublicUninstallLock = new(); private static readonly int MyProcessId = Environment.ProcessId; /// One of arguments is . internal AppUninstaller(Action listRefreshCallback, Action applicationLockCallback, Action visibleCallback) { _initiateListRefresh = listRefreshCallback ?? throw new ArgumentNullException(nameof(listRefreshCallback)); _lockApplication = applicationLockCallback ?? throw new ArgumentNullException(nameof(applicationLockCallback)); _visibleCallback = visibleCallback; } /// /// Returns false if export failed, else true. /// /// What to export /// Full path with filename and extension to write the export result to. /// public static bool ExportUninstallers(IEnumerable itemsToExport, string filename) { var applicationUninstallerEntries = itemsToExport as List ?? itemsToExport.ToList(); if (applicationUninstallerEntries.Count <= 0) return false; try { ApplicationEntrySerializer.SerializeApplicationEntries(filename, applicationUninstallerEntries); } catch (Exception ex) { MessageBoxes.ExportFailed(ex.Message, null); return false; } return true; } internal static int[] GetRelatedProcessIds(IEnumerable entries, bool doNotKillSteam) { var filters = entries.SelectMany(e => new[] { e.InstallLocation, e.UninstallerLocation }) .Where(s => !string.IsNullOrEmpty(s)).Distinct().ToArray(); return GetRelatedProcessIds(filters, doNotKillSteam); } private static bool CheckForRunningProcessesBeforeUninstall(IEnumerable entries, bool doNotKillSteam) { var filters = entries.SelectMany(e => new[] { e.InstallLocation, e.UninstallerLocation }) .Where(s => !string.IsNullOrEmpty(s)).Distinct().ToArray(); return CheckForRunningProcesses(filters, doNotKillSteam); } private static bool CheckForRunningProcessesBeforeCleanup(IEnumerable entries) { var filters = entries.OfType() .Select(x => x.Path.FullName) .Distinct().ToArray(); return CheckForRunningProcesses(filters, false); } public static IEnumerable GetApplicationsFromProcess( IEnumerable allApplications, Process targetProcess) { if (targetProcess == null) throw new ArgumentNullException(nameof(targetProcess)); if (targetProcess.MainModule?.FileName == null) throw new ArgumentException("MainModule is null"); var mainFilename = targetProcess.MainModule.FileName; return from app in allApplications where (app.IsInstallLocationValid() && mainFilename.Contains(app.InstallLocation, StringComparison.InvariantCultureIgnoreCase)) || (!string.IsNullOrEmpty(app.UninstallerLocation) && mainFilename.Contains(app.UninstallerLocation, StringComparison.InvariantCultureIgnoreCase)) select app; } internal static bool CheckForRunningProcesses(string[] filters, bool doNotKillSteam, Form parentForm = null) { var idsToCheck = GetRelatedProcessIds(filters, doNotKillSteam); if (idsToCheck.Length > 0) { if (!ProcessWaiter.ShowDialog(parentForm ?? MessageBoxes.DefaultOwner, idsToCheck.ToArray(), false)) return false; } return true; } private static int[] GetRelatedProcessIds(string[] filters, bool doNotKillSteam) { var idsToCheck = new List(); foreach (var pr in Process.GetProcesses()) { try { if (pr.Id == MyProcessId || pr.HasExited) continue; if (doNotKillSteam && pr.ProcessName.Equals("steam", StringComparison.OrdinalIgnoreCase)) continue; if (string.IsNullOrEmpty(pr.MainModule?.FileName) || pr.MainModule.FileName.StartsWith(WindowsTools.GetEnvironmentPath(CSIDL.CSIDL_SYSTEM), StringComparison.OrdinalIgnoreCase)) continue; var filenames = pr.Modules.Cast() .Select(x => x.FileName) .Where(s => !string.IsNullOrEmpty(s)) .Distinct(); if (filenames.Any(filename => filters.Any(filter => { if (string.IsNullOrEmpty(filename)) return false; if (!Path.IsPathRooted(filename)) return false; return filename.StartsWith(filter, StringComparison.OrdinalIgnoreCase); }))) { idsToCheck.Add(pr.Id); } } catch { // Ignore invalid processes } } return idsToCheck.ToArray(); } public void RunUninstall(IEnumerable selectedUninstallers, IEnumerable allUninstallers, bool quiet) { if (!TryGetUninstallLock()) return; var listRefreshNeeded = false; try { var targetList = new List(selectedUninstallers); var allUninstallerList = allUninstallers as IList ?? allUninstallers.ToList(); if (!_settings.AdvancedDisableProtection) { var protectedTargets = targetList.Where(x => x.IsProtected).ToList(); if ( MessageBoxes.ProtectedItemsWarningQuestion(protectedTargets.Select(x => x.DisplayName).ToArray()) == MessageBoxes.PressedButton.Cancel) return; targetList.RemoveAll(protectedTargets); } if (targetList.Any()) { _lockApplication(true); IReadOnlyList taskEntries; using (var wizard = new BeginUninstallTaskWizard()) { wizard.Initialize(targetList, allUninstallerList.ToList(), quiet); wizard.StartPosition = FormStartPosition.CenterParent; if (wizard.ShowDialog(MessageBoxes.DefaultOwner) != DialogResult.OK || wizard.Results.Count == 0) return; taskEntries = wizard.Results; } _visibleCallback(false); // No turning back at this point (kind of) listRefreshNeeded = true; if (_settings.MessagesRestorePoints != YesNoAsk.No) { try { SystemRestore.BeginSysRestore(taskEntries.Count, true); } catch (Exception exception) { PremadeDialogs.GenericError(exception); } } if (_settings.ExternalEnable && _settings.ExternalPreCommands.IsNotEmpty()) { LoadingDialog.ShowDialog( MessageBoxes.DefaultOwner, Localisable.LoadingDialogTitlePreUninstallCommands, controller => { RunExternalCommands(_settings.ExternalPreCommands, controller); }); } var status = UninstallManager.CreateBulkUninstallTask(taskEntries, GetConfiguration(quiet)); status.OneLoudLimit = _settings.UninstallConcurrentOneLoud; status.ConcurrentUninstallerCount = _settings.UninstallConcurrency ? _settings.UninstallConcurrentMaxCount : 1; status.Start(); UninstallProgressWindow.ShowUninstallDialog(status, entries => SearchForAndRemoveJunk(entries, allUninstallerList)); var junkRemoveTargetsQuery = from bulkUninstallEntry in status.AllUninstallersList where bulkUninstallEntry.CurrentStatus == UninstallStatus.Completed || bulkUninstallEntry.CurrentStatus == UninstallStatus.Invalid || (bulkUninstallEntry.CurrentStatus == UninstallStatus.Skipped && !bulkUninstallEntry.UninstallerEntry.RegKeyStillExists()) select bulkUninstallEntry.UninstallerEntry; if (MessageBoxes.LookForJunkQuestion()) SearchForAndRemoveJunk(junkRemoveTargetsQuery, allUninstallerList); if (_settings.ExternalEnable && _settings.ExternalPostCommands.IsNotEmpty()) { LoadingDialog.ShowDialog( MessageBoxes.DefaultOwner, Localisable.LoadingDialogTitlePostUninstallCommands, controller => { RunExternalCommands(_settings.ExternalPostCommands, controller); }); } } else { MessageBoxes.NoUninstallersSelectedInfo(); } } catch (ObjectDisposedException ex) { // ODE at CreateHandle can be caused by closing main window in the middle of the process // It gets thrown at ShowDialog, it's safe to cancel the process at these points if (ex.TargetSite?.Name != "CreateHandle") throw; } finally { SystemRestore.EndSysRestore(); ReleaseUninstallLock(); _lockApplication(false); _visibleCallback(true); if (listRefreshNeeded) _initiateListRefresh(); } } public static IEnumerable SortIntelligently(IEnumerable entries, Func entryGetter) { var query = from x in entries let item = entryGetter(x) orderby // For safety always run simple deletes last so that actual uninstallers have a chance to run item.UninstallerEntry.UninstallerKind == UninstallerType.SimpleDelete ascending, // Always run loud first so later user can have some time to watch cat pics item.IsSilentPossible ascending, // Updates usually get uninstalled by their parent uninstallers item.UninstallerEntry.IsUpdate ascending, // SysCmps and Protected usually get uninstalled by their parent, user-visible uninstallers item.UninstallerEntry.SystemComponent ascending, item.UninstallerEntry.IsProtected ascending, // Calculate number of digits (Floor of Log10 + 1) and divide it by 4 to create buckets of sizes Math.Round(Math.Floor(Math.Log10(item.UninstallerEntry.EstimatedSize.GetKbSize(true)) + 1) / 4) descending, // Prioritize Msi uninstallers because they tend to take the longest item.UninstallerEntry.UninstallerKind == UninstallerType.Msiexec descending, // Final sorting to get things deterministic item.UninstallerEntry.EstimatedSize.GetKbSize(true) descending select x; return query; } public static IEnumerable SortIntelligently(List taskEntries) { return SortIntelligently(taskEntries, entry => entry); } public void AdvancedUninstall(IEnumerable selectedUninstallers, IEnumerable allUninstallers) { if (!TryGetUninstallLock()) return; var listRefreshNeeded = false; try { _lockApplication(true); listRefreshNeeded = SearchForAndRemoveJunk(selectedUninstallers, allUninstallers); } finally { ReleaseUninstallLock(); _lockApplication(false); if (listRefreshNeeded) _initiateListRefresh(); } } /// /// Returns true if things were actually removed, false if user cancelled the operation. /// private bool SearchForAndRemoveJunk(IEnumerable selectedUninstallers, IEnumerable allUninstallers) { var junk = new List(); var error = LoadingDialog.ShowDialog(MessageBoxes.DefaultOwner, Localisable.LoadingDialogTitleLookingForJunk, dialogInterface => { var allValidUninstallers = allUninstallers.Where(y => y.RegKeyStillExists()); dialogInterface.SetSubProgressVisible(true); junk.AddRange(JunkManager.FindJunk(selectedUninstallers, allValidUninstallers.ToList(), x => { if (x.TotalCount <= 1) { // Don't update the title label to uninstaller name when there's only one uninstaller dialogInterface.SetMaximum(-1); } else { dialogInterface.SetMaximum(x.TotalCount); dialogInterface.SetProgress(x.CurrentCount, x.Message); } var inner = x.Inner; if (inner != null) { dialogInterface.SetSubMaximum(inner.TotalCount); dialogInterface.SetSubProgress(inner.CurrentCount, inner.Message); } else { dialogInterface.SetSubMaximum(-1); dialogInterface.SetSubProgress(0, string.Empty); } if (dialogInterface.Abort) throw new OperationCanceledException(); })); }); if (error != null) { PremadeDialogs.GenericError(error); return false; } return ShowJunkWindow(junk); } private bool ShowJunkWindow(List junk) { if (!junk.Any(x => _settings.MessagesShowAllBadJunk || x.Confidence.GetRawConfidence() >= 0)) { MessageBoxes.NoJunkFoundInfo(); return false; } using (var junkWindow = new JunkRemoveWindow(junk)) { if (junkWindow.ShowDialog() != DialogResult.OK) return false; var selectedJunk = junkWindow.SelectedJunk.ToList(); if (!CheckForRunningProcessesBeforeCleanup(selectedJunk)) return false; //Removing the junk LoadingDialog.ShowDialog(MessageBoxes.DefaultOwner, Localisable.LoadingDialogTitleRemovingJunk, controller => { var top = selectedJunk.Count; controller.SetMaximum(top); var itemsRemoved = 0; // current value var sortedJunk = from item in selectedJunk // Run commands before deleting any files or reg keys to avoid missing files orderby item is RunProcessJunk descending, // Need to stop and unregister service before deleting its exe item is StartupJunkNode descending select item; foreach (var junkNode in sortedJunk) { controller.SetProgress(itemsRemoved++); if (_settings.AdvancedSimulate) { Thread.Sleep(100); } else { try { junkNode.Delete(); } catch (Exception ex) { Console.WriteLine("Exception while removing junk: " + ex); } } } }); return true; } } public void SearchForAndRemoveProgramFilesJunk(IEnumerable allUninstallers) { if (!TryGetUninstallLock()) return; try { _lockApplication(true); var junk = new List(); var error = LoadingDialog.ShowDialog(null, Localisable.LoadingDialogTitleLookingForJunk, x => junk.AddRange(JunkManager.FindProgramFilesJunk(allUninstallers.Where(y => y.RegKeyStillExists()).ToList()))); if (error != null) PremadeDialogs.GenericError(error); else ShowJunkWindow(junk); } catch (ObjectDisposedException) { } finally { ReleaseUninstallLock(); _lockApplication(false); } } public void UninstallUsingMsi(MsiUninstallModes mode, IEnumerable selectedUninstallers) { if (!TryGetUninstallLock()) return; var listRefreshNeeded = false; try { _lockApplication(true); var results = selectedUninstallers.Take(2).ToList(); if (results.Count != 1) { MessageBoxes.CanSelectOnlyOneItemInfo(); return; } var selected = results.First(); if (!_settings.AdvancedDisableProtection && selected.IsProtected) { MessageBoxes.ProtectedItemError(selected.DisplayName); return; } if (selected.BundleProviderKey.IsEmpty()) { MessageBoxes.UninstallMsiGuidMissing(); return; } if (!CheckForRunningProcessesBeforeUninstall(new[] { selected }, true)) return; try { selected.UninstallUsingMsi(mode, _settings.AdvancedSimulate); listRefreshNeeded = true; } catch (Exception ex) { PremadeDialogs.GenericError(ex); } } finally { ReleaseUninstallLock(); _lockApplication(false); if (listRefreshNeeded) _initiateListRefresh(); } } public void UninstallFromDirectory(IEnumerable allUninstallers) { if (!TryGetUninstallLock()) return; var listRefreshNeeded = false; var applicationUninstallerEntries = allUninstallers as IList ?? allUninstallers.ToList(); try { var result = MessageBoxes.SelectFolder(Localisable.UninstallFromDirectory_FolderBrowse); if (result == null) return; var items = new List(); LoadingDialog.ShowDialog(MessageBoxes.DefaultOwner, Localisable.UninstallFromDirectory_ScanningTitle, _ => items.AddRange(DirectoryFactory.TryCreateFromDirectory(new DirectoryInfo(result), Array.Empty()))); if (items.Count == 0) items.AddRange(applicationUninstallerEntries.Where(x => PathTools.PathsEqual(result, x.InstallLocation))); if (items.Count == 0) MessageBoxes.UninstallFromDirectoryNothingFound(); else { foreach (var item in items.ToList()) { if (item.UninstallPossible && item.UninstallerKind != UninstallerType.SimpleDelete && MessageBoxes.UninstallFromDirectoryUninstallerFound(item.DisplayName, item.UninstallString)) { try { item.RunUninstaller(false, Settings.Default.AdvancedSimulate).WaitForExit(60000); } catch (Exception ex) { PremadeDialogs.GenericError(ex); } items.Remove(item); listRefreshNeeded = true; } else { var found = applicationUninstallerEntries.Where( x => PathTools.PathsEqual(item.InstallLocation, x.InstallLocation)).ToList(); if (!found.Any()) continue; items.Remove(item); foreach (var entry in found) { if (entry.UninstallPossible && entry.UninstallerKind != UninstallerType.SimpleDelete && MessageBoxes.UninstallFromDirectoryUninstallerFound(entry.DisplayName, entry.UninstallString)) { try { item.RunUninstaller(false, Settings.Default.AdvancedSimulate).WaitForExit(60000); } catch (Exception ex) { PremadeDialogs.GenericError(ex); } listRefreshNeeded = true; } else items.Add(entry); } } } AdvancedUninstall(items, applicationUninstallerEntries.Where( x => !items.Any(y => PathTools.PathsEqual(y.InstallLocation, x.InstallLocation)))); } } finally { ReleaseUninstallLock(); _lockApplication(false); if (listRefreshNeeded) _initiateListRefresh(); } } /// /// Ask to self uninstall and do so if user agrees, else return and do nothing. /// internal void AskToSelfUninstall() { if (MessageBoxes.SelfUninstallQuestion()) { if (!TryGetUninstallLock()) return; try { var fullPath = MessageBoxes.GetBundledFilePath("unins000.exe"); if (fullPath != null) { Process.Start(fullPath); Environment.Exit(0); } } catch (Exception ex) { PremadeDialogs.GenericError(ex); } finally { ReleaseUninstallLock(); } } } private BulkUninstallConfiguration GetConfiguration(bool quiet) { return new BulkUninstallConfiguration(_settings.AdvancedDisableProtection, quiet, _settings.AdvancedSimulate, _settings.QuietAutoKillStuck, _settings.QuietRetryFailedOnce); } private void ReleaseUninstallLock() { Monitor.Exit(PublicUninstallLock); Monitor.Exit(_uninstallLock); } private static void RunExternalCommands(string commands, LoadingDialogInterface controller) { var lines = commands.SplitNewlines(StringSplitOptions.RemoveEmptyEntries); controller.SetMaximum(lines.Length); for (var i = 0; i < lines.Length; i++) { controller.SetProgress(i); var line = lines[i]; try { var filename = ProcessTools.SeparateArgsFromCommand(line); filename.FileName = Path.GetFullPath(filename.FileName); if (!File.Exists(filename.FileName)) throw new IOException(Localisable.Error_FileNotFound); filename.ToProcessStartInfo().StartAndWait(); } catch (Exception ex) { MessageBox.Show(string.Format(Localisable.MessageBoxes_ExternalCommandFailed_Message, line) + Localisable.MessageBoxes_Error_details + ex.Message, Localisable.MessageBoxes_ExternalCommandFailed_Title, MessageBoxButtons.OK, MessageBoxIcon.Error); } } } /// /// Attempt to get the lock and display error popup if the process fails. /// /// True if lock was succesfully acquired, otherwise false. private bool TryGetUninstallLock() { if (Monitor.TryEnter(_uninstallLock)) { Monitor.Enter(PublicUninstallLock); return true; } MessageBoxes.UninstallAlreadyRunning(); return false; } public static ICollection GetApplicationsFromDirectories( IEnumerable allUninstallers, ICollection results) { var output = new List(); var processed = new List(); foreach (var dir in results.Distinct(PathTools.PathsEqual).OrderBy(x => x.FullName)) { if (processed.Any(x => x.FullName.Contains(dir.FullName, StringComparison.InvariantCultureIgnoreCase))) continue; processed.Add(dir); } var exceptions = allUninstallers.Where(x => x.InstallLocation != null).ToList(); var infoAdder = new InfoAdderManager(); foreach (var dir in processed) { var items = exceptions.Where( x => x.InstallLocation.Contains(dir.FullName, StringComparison.InvariantCultureIgnoreCase)) .ToList(); if (items.Count > 0) { output.AddRange(items); continue; } var res = DirectoryFactory.TryCreateFromDirectory(dir, exceptions).ToList(); if (res.Count == 0) { MessageBox.Show( string.Format(Localisable.Uninstaller_GetApplicationsFromDirectories_NothingFound_Message, dir.FullName), Localisable.Uninstaller_GetApplicationsFromDirectories_NothingFound_Title, MessageBoxButtons.OK, MessageBoxIcon.Warning); continue; } foreach (var result in res) { infoAdder.AddMissingInformation(result); output.Add(result); } } return output; } public void Modify(IEnumerable selectedUninstallers) { if (!TryGetUninstallLock()) return; var listRefreshNeeded = false; try { _lockApplication(true); var results = selectedUninstallers.Take(2).ToList(); if (results.Count != 1) { MessageBoxes.CanSelectOnlyOneItemInfo(); return; } var selected = results.First(); if (!_settings.AdvancedDisableProtection && selected.IsProtected) { MessageBoxes.ProtectedItemError(selected.DisplayName); return; } if (string.IsNullOrEmpty(selected.ModifyPath)) { MessageBoxes.ModifyCommandMissing(); return; } if (!CheckForRunningProcessesBeforeUninstall(new[] { selected }, true)) return; try { selected.Modify(_settings.AdvancedSimulate); listRefreshNeeded = true; } catch (Exception ex) { PremadeDialogs.GenericError(ex); } } finally { ReleaseUninstallLock(); _lockApplication(false); if (listRefreshNeeded) _initiateListRefresh(); } } } } ================================================ FILE: source/BulkCrapUninstaller/Functions/ApplicationList/ApplicationListColors.cs ================================================ /* Copyright (c) 2018 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System.Drawing; namespace BulkCrapUninstaller.Functions.ApplicationList { internal class ApplicationListColors { public static ApplicationListColors Normal = new( Color.FromArgb(unchecked((int)0xffccffcc)), Color.FromArgb(unchecked((int)0xffbbddff)), Color.FromArgb(unchecked((int)0xffE0E0E0)), Color.FromArgb(unchecked((int) 0xffffdbcd)), Color.FromArgb(unchecked((int) 0xffe7cfff)), Color.FromArgb(unchecked((int)0xffa3ffff))); public static ApplicationListColors ColorBlind = new( Color.FromArgb(unchecked((int) 0xfff6382d)), Color.FromArgb(unchecked((int)0xfffc8d59)), Color.FromArgb(unchecked((int) 0xff5189d3)), Color.FromArgb(unchecked((int)0xff91bfdb)), Color.FromArgb(unchecked((int)0xfffee090)), Color.FromArgb(unchecked((int) 0xffc9dade))); public ApplicationListColors(Color verifiedColor, Color unverifiedColor, Color invalidColor, Color unregisteredColor, Color windowsFeatureColor, Color windowsStoreAppColor) { VerifiedColor = verifiedColor; UnverifiedColor = unverifiedColor; InvalidColor = invalidColor; UnregisteredColor = unregisteredColor; WindowsFeatureColor = windowsFeatureColor; WindowsStoreAppColor = windowsStoreAppColor; } public Color VerifiedColor { get; } public Color UnverifiedColor { get; } public Color InvalidColor { get; } public Color UnregisteredColor { get; } public Color WindowsFeatureColor { get; } public Color WindowsStoreAppColor { get; } } } ================================================ FILE: source/BulkCrapUninstaller/Functions/ApplicationList/ApplicationListConstants.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System.Drawing; using BulkCrapUninstaller.Properties; using UninstallTools; namespace BulkCrapUninstaller.Functions.ApplicationList { internal static class ApplicationListConstants { public static ApplicationListColors Colors => Settings.Default.MiscColorblind ? ApplicationListColors.ColorBlind : ApplicationListColors.Normal; public static Color GetApplicationBackColor(ApplicationUninstallerEntry entry) { if (Settings.Default.AdvancedHighlightSpecial) { if (entry.UninstallerKind == UninstallerType.WindowsFeature) return Colors.WindowsFeatureColor; if (entry.UninstallerKind == UninstallerType.StoreApp) return Colors.WindowsStoreAppColor; if (entry.IsOrphaned) return Colors.UnregisteredColor; } if (!entry.IsValid && Settings.Default.AdvancedTestInvalid) return Colors.InvalidColor; if (Settings.Default.AdvancedTestCertificates) { var result = entry.IsCertificateValid(true); if (result.HasValue) return result.Value ? Colors.VerifiedColor : Colors.UnverifiedColor; } return Color.Empty; } public static Color GetApplicationTreemapColor(ApplicationUninstallerEntry entry) { if (entry.UninstallerKind == UninstallerType.WindowsFeature) return Colors.WindowsFeatureColor; if (entry.UninstallerKind == UninstallerType.StoreApp) return Colors.WindowsStoreAppColor; if (entry.IsOrphaned) return Colors.UnregisteredColor; if (!entry.IsValid) return Colors.InvalidColor; if (Settings.Default.AdvancedTestCertificates) { var result = entry.IsCertificateValid(true); if (result.HasValue) return result.Value ? Colors.VerifiedColor : Colors.UnverifiedColor; } return Color.White; } } } ================================================ FILE: source/BulkCrapUninstaller/Functions/ApplicationList/CertificateCache.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Security.Cryptography.X509Certificates; using System.Xml.Serialization; using Klocman.Tools; namespace BulkCrapUninstaller.Functions.ApplicationList { public sealed class CertCacheEntry { public bool Valid { get; set; } [XmlIgnore] public X509Certificate2 Cert { get; set; } public byte[] CertData // ReadOnlySpan crashes XML serializer in new versions of .NET { get => Cert?.RawData; set => Cert = value == null ? null : new X509Certificate2(value); } } internal class CertificateCache { public string CacheFilename { get; } private IDictionary _dictionaryCache; private readonly object _cacheLock = new object(); public CertificateCache(string cacheFilename) { CacheFilename = cacheFilename ?? throw new ArgumentNullException(nameof(cacheFilename)); } public void LoadCertificateCache() { lock (_cacheLock) { _dictionaryCache = null; try { if (File.Exists(CacheFilename)) { _dictionaryCache = SerializationTools.DeserializeDictionary(CacheFilename); // Remove invalid entries in case the xml is corrupted _dictionaryCache?.Where(x => x.Value == null).ToList().ForEach(pair => _dictionaryCache.Remove(pair.Key)); } } catch (SystemException e) { Console.WriteLine(e); ClearChache(); } } } public void SaveCertificateCache() { lock (_cacheLock) { if (_dictionaryCache == null || _dictionaryCache.Count == 0) { ClearChache(); return; } try { SerializationTools.SerializeDictionary(_dictionaryCache, CacheFilename); } catch (SystemException e) { Console.WriteLine(e); ClearChache(); } } } public void ClearChache() { lock (_cacheLock) { _dictionaryCache = null; try { File.Delete(CacheFilename); } catch { System.Threading.Thread.Sleep(50); File.Delete(CacheFilename); } } } public void SetItem(string id, X509Certificate2 cert, bool verified) { lock (_cacheLock) { if (!string.IsNullOrEmpty(id)) { if (_dictionaryCache == null) _dictionaryCache = new Dictionary(); _dictionaryCache[id] = new CertCacheEntry { Cert = cert, Valid = verified }; } } } public bool TryGetCachedItem(string id, out CertCacheEntry entry) { lock (_cacheLock) { if (_dictionaryCache == null || string.IsNullOrEmpty(id)) { entry = null; return false; } return _dictionaryCache.TryGetValue(id, out entry); } } } } ================================================ FILE: source/BulkCrapUninstaller/Functions/ApplicationList/ListViewDelegates.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.IO; using System.Linq; using BulkCrapUninstaller.Properties; using Klocman.Extensions; using Klocman.IO; using Klocman.Resources; using Klocman.Tools; using UninstallTools; namespace BulkCrapUninstaller.Functions.ApplicationList { internal static class ListViewDelegates { internal static string AspectToStringConverter(object x) { return x is long l ? new FileSize(l).ToString() : string.Empty; } internal static string BoolToYesNoAspectConverter(object rowObject) { var result = rowObject as bool?; return result.ToYesNo(); } internal static object ColumnGuidAspectGetter(object rowObj) { if (rowObj is ApplicationUninstallerEntry entry) { var result = entry.BundleProviderKey; if (!result.IsEmpty()) return $"{result:B}".ToUpperInvariant(); } return string.Empty; } internal static object ColumnGuidGroupKeyGetter(object rowObj) { if (rowObj is ApplicationUninstallerEntry entry) { var result = entry.BundleProviderKey; if (result.Equals(Guid.Empty)) return Localisable.GuidFound; } return Localisable.GuidMissing; } internal static object ColumnInstallLocationGroupKeyGetter(object rowObj) { var entry = rowObj as ApplicationUninstallerEntry; return GetFuzzyDirectory(entry?.InstallLocation); } internal static object ColumnInstallSourceGroupKeyGetter(object rowObj) { var entry = rowObj as ApplicationUninstallerEntry; return GetFuzzyDirectory(entry?.InstallSource); } internal static object ColumnPublisherGroupKeyGetter(object rowObj) { var entry = rowObj as ApplicationUninstallerEntry; return string.IsNullOrEmpty(entry?.PublisherTrimmed) ? CommonStrings.Unknown : entry.PublisherTrimmed; } internal static object ColumnQuietUninstallStringGroupKeyGetter(object rowObj) { var entry = rowObj as ApplicationUninstallerEntry; return GetFuzzyDirectory(entry?.QuietUninstallString); } internal static object ColumnSizeAspectGetter(object x) { if (x is ApplicationUninstallerEntry applicationUninstallerEntry) return applicationUninstallerEntry.EstimatedSize.GetKbSize(); return (long)0; } internal static object ColumnUninstallStringGroupKeyGetter(object rowObj) { var entry = rowObj as ApplicationUninstallerEntry; return GetFuzzyDirectory(entry?.UninstallString); } /// The source sequence is empty. internal static object GetFirstCharGroupKeyGetter(object rowobject) { var entry = rowobject as ApplicationUninstallerEntry; if (entry?.DisplayName == null) return Localisable.Empty; var character = entry.DisplayName.StripAccents().FirstOrDefault(x => !char.IsWhiteSpace(x)); return character.IsDefault() ? Localisable.Empty : char.ToUpperInvariant(character).ToString(); } internal static object DisplayVersionGroupKeyGetter(object rowObject) { var entry = rowObject as ApplicationUninstallerEntry; if (string.IsNullOrEmpty(entry?.DisplayVersion)) return CommonStrings.Unknown; var dotIndex = entry.DisplayVersion.IndexOf('.'); return dotIndex > 0 ? entry.DisplayVersion.Substring(0, dotIndex) + ".x" : entry.DisplayVersion; } internal static object ColumnSizeGroupKeyGetter(object rowObject) { return rowObject is not ApplicationUninstallerEntry entry ? 0L : entry.EstimatedSize.GetRoundedKbSize(); } /// /// Convert path to a directory string usable for grouping /// private static string GetFuzzyDirectory(string fullCommand) { if (string.IsNullOrEmpty(fullCommand)) return Localisable.Empty; if (fullCommand.StartsWith("msiexec", StringComparison.OrdinalIgnoreCase) || fullCommand.Contains("msiexec.exe", StringComparison.OrdinalIgnoreCase)) return "MsiExec"; try { if (fullCommand.Contains('\\')) { string strOut; try { strOut = ProcessTools.SeparateArgsFromCommand(fullCommand).FileName; } catch { strOut = fullCommand; } strOut = Path.GetDirectoryName(strOut); strOut = PathTools.GetPathUpToLevel(strOut, 1, false); if (strOut.IsNotEmpty()) { return PathTools.PathToNormalCase(strOut); //Path.GetFullPath(strOut); } } } catch { // Assume path is invalid } return Localisable.Empty; } private static readonly string UninstallStringTrimString = '"' + Program.AssemblyLocation.FullName + '\\'; private static object CleanupUninstallString(string uninstallString) { if (uninstallString == null) return string.Empty; if (uninstallString.StartsWith(UninstallStringTrimString, StringComparison.OrdinalIgnoreCase)) { var trimmed = uninstallString.Substring(UninstallStringTrimString.Length); var closingQuote = trimmed.IndexOf('"'); if (closingQuote >= 0) { trimmed = trimmed.Remove(closingQuote, 1); return trimmed; } } return uninstallString; } public static object ColumnUninstallStringGetter(object rowobject) { if (rowobject is ApplicationUninstallerEntry entry) return CleanupUninstallString(entry.UninstallString); return string.Empty; } public static object ColumnQuietUninstallStringGetter(object rowobject) { if (rowobject is ApplicationUninstallerEntry entry) return CleanupUninstallString(entry.QuietUninstallString); return string.Empty; } } } ================================================ FILE: source/BulkCrapUninstaller/Functions/ApplicationList/UninstallerListConfigurator.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Windows.Forms; using BrightIdeasSoftware; using BulkCrapUninstaller.Forms; using BulkCrapUninstaller.Functions.Ratings; using BulkCrapUninstaller.Properties; using Klocman.Binding.Settings; using Klocman.Extensions; using Klocman.IO; using Klocman.Localising; using Klocman.Resources; using UninstallTools; using UninstallTools.Factory; using UninstallTools.Lists; namespace BulkCrapUninstaller.Functions.ApplicationList { internal class UninstallerListConfigurator : IDisposable { private readonly FilterCondition _filteringFilterCondition = new() { FilterText = string.Empty }; private readonly TypedObjectListView _listView; private readonly MainWindow _reference; private readonly Timer _updateThrottleTimer; private readonly SettingBinder _settings = Settings.Default.SettingBinder; public UninstallerListConfigurator(MainWindow reference) { _reference = reference; _listView = new TypedObjectListView(reference.uninstallerObjectListView); _reference.filterEditor1.TargetFilterCondition = _filteringFilterCondition; _updateThrottleTimer = new Timer { Interval = 500 }; _updateThrottleTimer.Tick += (sender, args) => { _updateThrottleTimer.Stop(); _listView.ListView.UpdateColumnFiltering(); }; SetupListView(); RatingManagerWrapper = new RatingManagerWrapper(); RatingManagerWrapper.InitializeRatingColumn(_reference.olvColumnRating, _reference.uninstallerObjectListView); _reference.FormClosed += (x, y) => { RatingManagerWrapper.ProcessGatheredRatings(); }; _settings.Subscribe((sender, args) => RatingManagerWrapper.InitializeRatings(), x => x.MiscUserRatings, this); } public ITestEntry FilteringOverride { get; set; } public RatingManagerWrapper RatingManagerWrapper { get; } public void Dispose() { _updateThrottleTimer.Dispose(); } [System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1713:Events should not have 'Before' or 'After' prefix", Justification = "")] public event EventHandler AfterFiltering; /// /// Return a filter equivalent to current basic filtering settings /// /// public IEnumerable GenerateEquivalentFilter() { var results = new List(); if (string.IsNullOrEmpty(_filteringFilterCondition.FilterText)) results.Add(new Filter("Include all", false, new FilterCondition("!", ComparisonMethod.Equals, nameof(ApplicationUninstallerEntry.IsOrphaned)) { InvertResults = true })); else results.Add(new Filter(_filteringFilterCondition.FilterText, false, (FilterCondition)_filteringFilterCondition.Clone())); if (_settings.Settings.FilterHideMicrosoft) results.Add(new Filter("Published by Microsoft", true, new FilterCondition("Microsoft", ComparisonMethod.Contains, nameof(ApplicationUninstallerEntry.Publisher)))); if (!_settings.Settings.FilterShowStoreApps) results.Add(new Filter("Store Apps", true, new FilterCondition(nameof(UninstallerType.StoreApp), ComparisonMethod.Equals, nameof(ApplicationUninstallerEntry.UninstallerKind)))); if (!_settings.Settings.FilterShowWinFeatures) results.Add(new Filter("Windows Features", true, new FilterCondition(nameof(UninstallerType.WindowsFeature), ComparisonMethod.Equals, nameof(ApplicationUninstallerEntry.UninstallerKind)))); if (!_settings.Settings.AdvancedDisplayOrphans) results.Add(new Filter("Orphaned apps", true, new FilterCondition(true.ToString(), ComparisonMethod.Equals, nameof(ApplicationUninstallerEntry.IsOrphaned)))); if (!_settings.Settings.FilterShowProtected) results.Add(new Filter("Protected apps", true, new FilterCondition(true.ToString(), ComparisonMethod.Equals, nameof(ApplicationUninstallerEntry.IsProtected)))); if (!_settings.Settings.FilterShowSystemComponents) results.Add(new Filter("System Components", true, new FilterCondition(true.ToString(), ComparisonMethod.Equals, nameof(ApplicationUninstallerEntry.SystemComponent)))); if (!_settings.Settings.FilterShowUpdates) results.Add(new Filter("Updates", true, new FilterCondition(true.ToString(), ComparisonMethod.Equals, nameof(ApplicationUninstallerEntry.IsUpdate)))); // TODO Better detection, can lead to bugs down the line if (!_settings.Settings.FilterShowTweaks) results.Add(new Filter("Tweaks", true, new FilterCondition(@"\Resources\Scripts\Tweak", ComparisonMethod.Contains, nameof(ApplicationUninstallerEntry.UninstallString)))); return results; } private bool ListViewFilter(object obj) { if (obj is not ApplicationUninstallerEntry entry) return false; if (FilteringOverride != null) return FilteringOverride.TestEntry(entry) == true; if (_settings.Settings.FilterHideMicrosoft && !string.IsNullOrEmpty(entry.Publisher) && entry.Publisher.Contains("Microsoft")) return false; if (!_settings.Settings.FilterShowStoreApps && entry.UninstallerKind == UninstallerType.StoreApp) return false; if (!_settings.Settings.FilterShowWinFeatures && entry.UninstallerKind == UninstallerType.WindowsFeature) return false; if (!_settings.Settings.AdvancedDisplayOrphans && entry.IsOrphaned) return false; if (!_settings.Settings.FilterShowProtected && entry.IsProtected) return false; if (!_settings.Settings.FilterShowSystemComponents && entry.SystemComponent) return false; if (!_settings.Settings.FilterShowUpdates && entry.IsUpdate) return false; if (entry.RatingId != null) { if (!_settings.Settings.FilterShowTweaks && entry.RatingId.StartsWith("tweak", StringComparison.Ordinal)) return false; } if (string.IsNullOrEmpty(_filteringFilterCondition.FilterText)) return true; return _filteringFilterCondition.TestEntry(entry) == true; } public void SetupListView() { _reference.uninstallerObjectListView.VirtualMode = false; _reference.olvColumnDisplayName.AspectName = RegistryFactory.RegistryNameDisplayName; _reference.olvColumnDisplayName.GroupKeyGetter = ListViewDelegates.GetFirstCharGroupKeyGetter; _reference.olvColumnStartup.AspectGetter = x => { var obj = x as ApplicationUninstallerEntry; return (obj?.HasStartups).ToYesNo(); }; _reference.olvColumnPublisher.AspectName = RegistryFactory.RegistryNamePublisher; _reference.olvColumnPublisher.GroupKeyGetter = ListViewDelegates.ColumnPublisherGroupKeyGetter; _reference.olvColumnDisplayVersion.AspectName = RegistryFactory.RegistryNameDisplayVersion; _reference.olvColumnDisplayVersion.GroupKeyGetter = ListViewDelegates.DisplayVersionGroupKeyGetter; _reference.olvColumnUninstallString.AspectGetter = ListViewDelegates.ColumnUninstallStringGetter; _reference.olvColumnUninstallString.GroupKeyGetter = ListViewDelegates.ColumnUninstallStringGroupKeyGetter; _reference.olvColumnQuietUninstallString.AspectGetter = ListViewDelegates.ColumnQuietUninstallStringGetter; _reference.olvColumnQuietUninstallString.GroupKeyGetter = ListViewDelegates.ColumnQuietUninstallStringGroupKeyGetter; _reference.olvColumnInstallDate.AspectGetter = x => { var obj = x as ApplicationUninstallerEntry; return obj?.InstallDate.Date ?? DateTime.MinValue; }; //_reference.olvColumnInstallDate.AspectName = ApplicationUninstallerEntry.RegistryNameInstallDate; _reference.olvColumnInstallDate.AspectToStringConverter = x => { if (x is not DateTime time) return Localisable.Empty; try { return time.IsDefault() ? Localisable.Empty : time.ToShortDateString(); } catch (SystemException) { return Localisable.NotAvailable; } }; _reference.olvColumnGuid.AspectGetter = ListViewDelegates.ColumnGuidAspectGetter; _reference.olvColumnGuid.GroupKeyGetter = ListViewDelegates.ColumnGuidGroupKeyGetter; _reference.olvColumnSystemComponent.AspectName = RegistryFactory.RegistryNameSystemComponent; _reference.olvColumnSystemComponent.AspectToStringConverter = ListViewDelegates.BoolToYesNoAspectConverter; _reference.olvColumnSystemComponent.GroupKeyToTitleConverter = ListViewDelegates.BoolToYesNoAspectConverter; _reference.olvColumnIs64.AspectGetter = y => (y as ApplicationUninstallerEntry)?.Is64Bit.GetLocalisedName(); _reference.olvColumnProtected.AspectToStringConverter = ListViewDelegates.BoolToYesNoAspectConverter; _reference.olvColumnProtected.GroupKeyToTitleConverter = ListViewDelegates.BoolToYesNoAspectConverter; _reference.olvColumnInstallLocation.AspectName = RegistryFactory.RegistryNameInstallLocation; _reference.olvColumnInstallLocation.GroupKeyGetter = ListViewDelegates.ColumnInstallLocationGroupKeyGetter; _reference.olvColumnInstallSource.AspectName = RegistryFactory.RegistryNameInstallSource; _reference.olvColumnInstallSource.GroupKeyGetter = ListViewDelegates.ColumnInstallSourceGroupKeyGetter; _reference.olvColumnRegistryKeyName.AspectName = "RegistryKeyName"; _reference.olvColumnUninstallerKind.AspectGetter = y => (y as ApplicationUninstallerEntry)?.UninstallerKind.GetLocalisedName(); _reference.olvColumnAbout.AspectName = "AboutUrl"; _reference.olvColumnAbout.GroupKeyGetter = x => { var entry = x as ApplicationUninstallerEntry; var aboutUri = entry?.GetAboutUri(); return aboutUri?.Host ?? Localisable.Empty; }; _reference.olvColumnSize.TextAlign = HorizontalAlignment.Right; _reference.olvColumnSize.AspectGetter = ListViewDelegates.ColumnSizeAspectGetter; _reference.olvColumnSize.AspectToStringConverter = ListViewDelegates.AspectToStringConverter; _reference.olvColumnSize.GroupKeyGetter = ListViewDelegates.ColumnSizeGroupKeyGetter; _reference.olvColumnSize.GroupKeyToTitleConverter = x => x is long num and > 0 ? FileSize.GetUnitName(num) : CommonStrings.Unknown; _reference.uninstallerObjectListView.PrimarySortColumn = _reference.olvColumnDisplayName; _reference.uninstallerObjectListView.SecondarySortColumn = _reference.olvColumnPublisher; _reference.uninstallerObjectListView.Sorting = SortOrder.Ascending; _reference.uninstallerObjectListView.AdditionalFilter = new ModelFilter(ListViewFilter); _reference.uninstallerObjectListView.UseFiltering = true; _reference.uninstallerObjectListView.FormatRow += UninstallerObjectListView_FormatRow; _listView.ListView.AfterSorting += (x, y) => { AfterFiltering?.Invoke(x, y); }; } private void UninstallerObjectListView_FormatRow(object sender, FormatRowEventArgs e) { if (e.Model is not ApplicationUninstallerEntry entry) return; var color = ApplicationListConstants.GetApplicationBackColor(entry); if (!color.IsEmpty) e.Item.BackColor = color; } public void UpdateColumnFiltering(bool anyUninstallers) { _listView.ListView.EmptyListMsg = anyUninstallers ? Localisable.SearchNothingFoundMessage : null; _updateThrottleTimer.Stop(); _updateThrottleTimer.Start(); } } } ================================================ FILE: source/BulkCrapUninstaller/Functions/ApplicationList/UninstallerListPostProcesser.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Security.Cryptography.X509Certificates; using System.Threading; using BulkCrapUninstaller.Properties; using Klocman.Binding.Settings; using Klocman.Events; using UninstallTools; namespace BulkCrapUninstaller.Functions.ApplicationList { internal class UninstallerListPostProcesser : IDisposable { private readonly SettingBinder _settings = Settings.Default.SettingBinder; private bool _abortPostprocessingThread; private Thread _finalizerThread; private readonly Queue _itemsToProcess = new(); private readonly List _objectsToUpdate = new(); private readonly Action _updateItemsCallback; /// /// External lock to the uninstall system. /// internal object UninstallerFileLock { get; set; } = new(); private readonly CertificateCache _certificateCache; public event EventHandler UninstallerPostprocessingProgressUpdate; public UninstallerListPostProcesser(Action updateItemsCallback, CertificateCache certificateCache) { _updateItemsCallback = updateItemsCallback ?? throw new ArgumentNullException(nameof(updateItemsCallback)); _certificateCache = certificateCache; } public void AbortPostprocessingThread() { _abortPostprocessingThread = true; lock (_itemsToProcess) _itemsToProcess.Clear(); } public void StartProcessingThread(IEnumerable itemsToProcess) { lock (_itemsToProcess) { foreach (var entry in itemsToProcess.Except(_itemsToProcess)) _itemsToProcess.Enqueue(entry); } if (_finalizerThread == null || !_finalizerThread.IsAlive) { _finalizerThread = new Thread(UninstallerPostprocessingThread) { Name = "UninstallerPostprocessingThread", IsBackground = true, Priority = ThreadPriority.Lowest }; _abortPostprocessingThread = false; _finalizerThread.Start(); } } public void StopProcessingThread() { lock (_itemsToProcess) _itemsToProcess.Clear(); } private void UninstallerPostprocessingThread() { while (true) { int count; ApplicationUninstallerEntry target = null; lock (_itemsToProcess) { count = _itemsToProcess.Count; if (count > 0) target = _itemsToProcess.Dequeue(); } if (count == 0 || _abortPostprocessingThread) { _finalizerThread = null; OnUninstallerPostprocessingProgressUpdate(new CountingUpdateEventArgs(0, 0, 0)); return; } var sendTag = true; if (_settings.Settings.AdvancedTestCertificates) { lock (UninstallerFileLock) { var cert = GetCert(target); sendTag = cert != null; } } var countingUpdateEventArgs = new CountingUpdateEventArgs(0, count, 0); if (sendTag) countingUpdateEventArgs.Tag = target; OnUninstallerPostprocessingProgressUpdate(countingUpdateEventArgs); } } private X509Certificate2 GetCert(ApplicationUninstallerEntry uninstaller) { var id = uninstaller.GetCacheId(); if (_certificateCache.TryGetCachedItem(id, out var cachedCert)) { uninstaller.SetCertificate(cachedCert.Cert, cachedCert.Valid); return cachedCert.Cert; } else { var cert = uninstaller.GetCertificate(); _certificateCache.SetItem(id, cert, uninstaller.IsCertificateValid(true) == true); return cert; } } public void Dispose() { StopProcessingThread(); } protected virtual void OnUninstallerPostprocessingProgressUpdate(CountingUpdateEventArgs y) { lock (_objectsToUpdate) { if (y.Tag != null) _objectsToUpdate.Add(y.Tag); if (y.Value == y.Maximum || _objectsToUpdate.Count % 35 == 0) { try { _updateItemsCallback(_objectsToUpdate.ToList()); } catch (SystemException ex) { // The list view got disposed before we could update it. AbortPostprocessingThread(); Debug.Fail(ex.Message, ex.StackTrace); } _objectsToUpdate.Clear(); } } UninstallerPostprocessingProgressUpdate?.Invoke(this, y); } } } ================================================ FILE: source/BulkCrapUninstaller/Functions/ApplicationList/UninstallerListViewUpdater.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Windows.Forms; using BrightIdeasSoftware; using BulkCrapUninstaller.Forms; using BulkCrapUninstaller.Properties; using Klocman.Binding.Settings; using Klocman.Extensions; using Klocman.Forms; using Klocman.Forms.Tools; using Klocman.IO; using Klocman.Tools; using UninstallTools; using UninstallTools.Controls; using UninstallTools.Factory; using UninstallTools.Startup; namespace BulkCrapUninstaller.Functions.ApplicationList { internal class UninstallerListViewUpdater : IDisposable { private readonly UninstallerIconGetter _iconGetter; private readonly TypedObjectListView _listView; private readonly MainWindow _reference; readonly SettingBinder _settings = Settings.Default.SettingBinder; private IEnumerable _allUninstallers; private bool _firstRefresh = true; private bool _listRefreshIsRunning; internal UninstallerListViewUpdater(MainWindow reference) { _reference = reference; _listView = new TypedObjectListView(reference.uninstallerObjectListView); _iconGetter = new UninstallerIconGetter(); _reference.olvColumnDisplayName.ImageGetter = _iconGetter.ColumnImageGetter; // Refresh items marked as invalid after corresponding setting change _settings.Subscribe((x, y) => { if (CheckIsAppDisposed()) return; if (!_firstRefresh) _listView.ListView.RefreshObjects(AllUninstallers.Where(u => !u.IsValid).ToList()); }, x => x.AdvancedTestInvalid, this); // Refresh items marked as orphans after corresponding setting change _settings.Subscribe((x, y) => { if (CheckIsAppDisposed()) return; if (!_firstRefresh) _listView.ListView.UpdateColumnFiltering(); }, x => x.AdvancedDisplayOrphans, this); } public IEnumerable AllUninstallers { get { return _allUninstallers ?? Enumerable.Empty(); } private set { _allUninstallers = value; } } public IEnumerable FilteredUninstallers => CheckIsAppDisposed() ? AllUninstallers : _listView.ListView.FilteredObjects.Cast(); public bool FirstRefreshCompleted => !_firstRefresh; public bool ListRefreshIsRunning { get { return _listRefreshIsRunning; } private set { if (value != _listRefreshIsRunning) { _listRefreshIsRunning = value; ListRefreshIsRunningChanged?.Invoke(this, new ListRefreshEventArgs(value, !FirstRefreshCompleted)); } } } /// /// Faster than SelectedUninstallers.Count() /// public int SelectedUninstallerCount => _listView.ListView.CheckBoxes ? _listView.CheckedObjects.Count : _listView.SelectedObjects.Count; public IEnumerable SelectedUninstallers => _listView.ListView.CheckBoxes ? _listView.ListView.GetAllObjectsWithMappedCheckState(CheckState.Checked).Cast().Where(e => e != null && AllUninstallers.Contains(e)) : _listView.SelectedObjects.Where(e => e != null); public void Dispose() { _iconGetter?.Dispose(); } public event EventHandler ListRefreshIsRunningChanged; private void ChangeSelection(IEnumerable newSelection) { _listView.ListView.BeginUpdate(); var items = newSelection.ToList(); if (_listView.ListView.CheckBoxes) _listView.ListView.CheckedObjects = items; _listView.ListView.SelectedObjects = items; _listView.ListView.EndUpdate(); _listView.ListView.Refresh(); _listView.ListView.Focus(); } public bool CheckIsAppDisposed() { return _listView.ListView.IsDisposed || _listView.ListView.Disposing || _reference.IsDisposed || _reference.Disposing; } public void DeselectAllItems(object sender, EventArgs e) { var selected = _listView.ListView.CheckBoxes ? _listView.CheckedObjects : _listView.SelectedObjects; var subtracted = selected.Except(FilteredUninstallers); ChangeSelection(subtracted); } /// /// Get total size of all visible uninstallers. /// public FileSize GetFilteredSize() { return FilteredUninstallers.Select(x => x.EstimatedSize).DefaultIfEmpty(FileSize.Empty) .Aggregate((size1, size2) => size1 + size2); } /// /// Get total size of selected uninstallers /// /// public FileSize GetSelectedSize() { return SelectedUninstallers.Select(x => x.EstimatedSize).DefaultIfEmpty(FileSize.Empty) .Aggregate((size1, size2) => size1 + size2); } public void InitiateListRefresh() { if (ListRefreshIsRunning || CheckIsAppDisposed()) return; ListRefreshIsRunning = true; _reference.LockApplication(true); if (CheckIsAppDisposed()) return; _listView.ListView.SuspendLayout(); _listView.ListView.BeginUpdate(); var dialog = LoadingDialog.Show(_reference, Localisable.LoadingDialogTitlePopulatingList, ListRefreshThread, new Point(-35, -35), ContentAlignment.BottomRight); dialog.FormClosed += OnRefreshFinished; void OnRefreshFinished(object sender, FormClosedEventArgs args) { dialog.FormClosed -= OnRefreshFinished; if (dialog.Error != null) { if (dialog.Error is OperationCanceledException) return; throw new InvalidOperationException("Uncaught exception in ListRefreshThread", dialog.Error); } if (CheckIsAppDisposed() || args.CloseReason == CloseReason.WindowsShutDown || args.CloseReason == CloseReason.ApplicationExitCall || args.CloseReason == CloseReason.FormOwnerClosing || args.CloseReason == CloseReason.TaskManagerClosing) return; var oldList = _listView.ListView.SmallImageList; _listView.ListView.SmallImageList = _iconGetter.IconList; oldList?.Dispose(); _listView.ListView.SetObjects(AllUninstallers); try { _listView.ListView.EndUpdate(); _listView.ListView.ResumeLayout(); _listView.ListView.Focus(); } catch (ObjectDisposedException) { } _reference.LockApplication(false); // Run events ListRefreshIsRunning = false; // Set after running events _firstRefresh = false; } dialog.StartWork(); } public void InvertSelectedItems(object sender, EventArgs e) { var selected = _listView.ListView.CheckBoxes ? _listView.CheckedObjects : _listView.SelectedObjects; var inverted = FilteredUninstallers.Except(selected); ChangeSelection(inverted); } private void ListRefreshThread(LoadingDialogInterface dialogInterface) { dialogInterface.SetSubProgressVisible(true); var progressMax = 0; var uninstallerEntries = ApplicationUninstallerFactory.GetUninstallerEntries(x => { progressMax = x.TotalCount + 1; dialogInterface.SetMaximum(progressMax); dialogInterface.SetProgress(x.CurrentCount, x.Message); var inner = x.Inner; if (inner != null) { dialogInterface.SetSubMaximum(inner.TotalCount); dialogInterface.SetSubProgress(inner.CurrentCount, inner.Message); } else { dialogInterface.SetSubMaximum(-1); dialogInterface.SetSubProgress(0, string.Empty); } if (dialogInterface.Abort) throw new OperationCanceledException(); }); dialogInterface.SetProgress(progressMax, Localisable.Progress_Finishing, true); dialogInterface.SetSubMaximum(2); dialogInterface.SetSubProgress(0, string.Empty); if (!string.IsNullOrEmpty(Program.InstalledRegistryKeyName)) uninstallerEntries.RemoveAll( x => PathTools.PathsEqual(x.RegistryKeyName, Program.InstalledRegistryKeyName)); AllUninstallers = uninstallerEntries; dialogInterface.SetSubProgress(1, Localisable.Progress_Finishing_Icons); try { _iconGetter.UpdateIconList(AllUninstallers); } catch (Exception ex) { PremadeDialogs.GenericError(ex); } dialogInterface.SetSubProgressVisible(false); // Fixes loading gettings stuck on finalizing if main window is minimized _reference.SafeInvoke(() => { if (_reference.WindowState == FormWindowState.Minimized) _reference.WindowState = FormWindowState.Normal; }); } internal void ReassignStartupEntries(bool refreshListView, IEnumerable items) { ApplicationUninstallerFactory.AttachStartupEntries(AllUninstallers, items); if (refreshListView) RefreshList(); } public void RefreshList() { if (CheckIsAppDisposed()) return; _listView.ListView.UpdateColumnFiltering(); //_listView.ListView.BuildList(true); No need, UpdateColumnFiltering already does this } public void SelectAllItems(object sender, EventArgs e) { var selected = _listView.ListView.CheckBoxes ? _listView.CheckedObjects : _listView.SelectedObjects; var added = selected.Union(FilteredUninstallers); ChangeSelection(added); } /// /// Select first item starting with the keycode. /// If keycode leads to a valid selection true is returned. Otherwise, if there is nothing relevant to select false is /// returned. /// public bool SelectItemFromKeystroke(Keys keyCode) { var keyName = keyCode.ToLetterOrNumberString(); if (keyName != null) { var selectedObj = FilteredUninstallers.FirstOrDefault( x => x.DisplayName.StartsWith(keyName, StringComparison.InvariantCultureIgnoreCase)); _listView.ListView.DeselectAll(); if (selectedObj != null) { _listView.ListView.SelectObject(selectedObj, true); _listView.ListView.EnsureModelVisible(selectedObj); return true; } } return false; } public sealed class ListRefreshEventArgs : EventArgs { public ListRefreshEventArgs(bool refreshIsRunning, bool firstRefresh) { RefreshIsRunning = refreshIsRunning; FirstRefresh = firstRefresh; } public bool FirstRefresh { get; } public bool RefreshIsRunning { get; } } } } ================================================ FILE: source/BulkCrapUninstaller/Functions/MessageBoxes.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Drawing; using System.Globalization; using System.IO; using System.Linq; using System.Windows.Forms; using BulkCrapUninstaller.Properties; using Klocman; using Klocman.Forms; using Klocman.Forms.Tools; using Klocman.Localising; using Klocman.Tools; using UninstallTools; namespace BulkCrapUninstaller.Functions { internal static class MessageBoxes { public enum PressedButton { Cancel, Yes, No } public static Form DefaultOwner { get; set; } public static void RatingsDisabled() { MessageBox.Show(DefaultOwner, Localisable.MessageBoxes_RatingsDisabled_Message, Localisable.MessageBoxes_RatingErrorTitle, MessageBoxButtons.OK, MessageBoxIcon.Warning); } public static void RatingUnavailable() { MessageBox.Show(DefaultOwner, Localisable.MessageBoxes_RatingUnavailable_Message, Localisable.MessageBoxes_RatingErrorTitle, MessageBoxButtons.OK, MessageBoxIcon.Warning); } internal static CustomMessageBox.PressedButton AskToSubmitFeedback() { return CustomMessageBox.ShowDialog(DefaultOwner, new CmbBasicSettings(Localisable.MessageBoxes_Title_Submit_feedback, Localisable.MessageBoxes_AskToSubmitFeedback_Message, Localisable.MessageBoxes_AskToSubmitFeedback_Details, SystemIcons.Question, Buttons.ButtonRate, Buttons.ButtonSubmit, Buttons.ButtonClose)); } internal static PressedButton BackupFailedQuestion(string exMessage, Form owner) { switch ( CustomMessageBox.ShowDialog(owner ?? DefaultOwner, new CmbBasicSettings(Localisable.MessageBoxes_Title_Leftover_removal, Localisable.MessageBoxes_BackupFailedQuestion_Message, Localisable.MessageBoxes_BackupFailedQuestion_Details + exMessage, SystemIcons.Warning, Buttons.ButtonContinue, Buttons.ButtonCancel))) { case CustomMessageBox.PressedButton.Middle: return PressedButton.Yes; default: return PressedButton.Cancel; } } internal static PressedButton BackupRegistryQuestion(Form owner) { var check = new CmbCheckboxSettings(Localisable.MessageBoxes_RememberChoiceCheckbox) { DisableRightButton = true }; switch ( CustomMessageBox.ShowDialog(owner ?? DefaultOwner, new CmbBasicSettings(Localisable.MessageBoxes_Title_Leftover_removal, Localisable.MessageBoxes_BackupRegistryQuestion_Message, Localisable.MessageBoxes_BackupRegistryQuestion_Details, SystemIcons.Question, Buttons.ButtonCreate, Buttons.ButtonDontCreate, Buttons.ButtonCancel), check)) { case CustomMessageBox.PressedButton.Left: if (check.Result == true) Settings.Default.BackupLeftovers = YesNoAsk.Yes; return PressedButton.Yes; case CustomMessageBox.PressedButton.Middle: if (check.Result == true) Settings.Default.BackupLeftovers = YesNoAsk.No; return PressedButton.No; default: return PressedButton.Cancel; } } internal static void CanSelectOnlyOneItemInfo() { CustomMessageBox.ShowDialog(DefaultOwner, new CmbBasicSettings(Localisable.MessageBoxes_CanSelectOnlyOneItemInfo_Title, Localisable.MessageBoxes_CanSelectOnlyOneItemInfo_Message, Localisable.MessageBoxes_CanSelectOnlyOneItemInfo_Details, SystemIcons.Warning, Buttons.ButtonOk)); } /// /// Used when sorted uninstall task hits the first quiet uninstaller. /// internal static CustomMessageBox CanWalkAwayInfo(Form owner) { return CustomMessageBox.Show(owner, new CmbBasicSettings(Localisable.MessageBoxes_CanWalkAwayInfo_Title, Localisable.MessageBoxes_CanWalkAwayInfo_Message, Localisable.MessageBoxes_CanWalkAwayInfo_Details, SystemIcons.Information, Buttons.ButtonOk) { StartPosition = FormStartPosition.CenterParent, AlwaysOnTop = true }); } internal static bool ConfirmLowConfidenceQuestion(Form owner) { return CustomMessageBox.ShowDialog(owner ?? DefaultOwner, new CmbBasicSettings(Localisable.MessageBoxes_Title_Junk_Leftover_removal, Localisable.MessageBoxes_ConfirmLowConfidenceQuestion_Message, Localisable.MessageBoxes_ConfirmLowConfidenceQuestion_Details, SystemIcons.Warning, Buttons.ButtonYes, Buttons.ButtonCancel)) == CustomMessageBox.PressedButton.Middle; } internal static bool DeleteRegKeysConfirmation(string[] affectedKeyNames) { return CustomMessageBox.ShowDialog(DefaultOwner, new CmbBasicSettings(Localisable.MessageBoxes_DeleteRegKeysConfirmation_Title, Localisable.MessageBoxes_DeleteRegKeysConfirmation_Message, string.Format(CultureInfo.InvariantCulture, Localisable.MessageBoxes_DeleteRegKeysConfirmation_Details, string.Join("\n", affectedKeyNames)), SystemIcons.Question, Buttons.ButtonRemove, Buttons.ButtonCancel)) == CustomMessageBox.PressedButton.Middle; } internal static void ExportFailed(string exMessage, Form owner) { CustomMessageBox.ShowDialog(owner ?? DefaultOwner, new CmbBasicSettings(Localisable.MessageBoxes_ExportFailed_Title, Localisable.MessageBoxes_ExportFailed_Message, Localisable.MessageBoxes_ExportFailed_Details + Localisable.MessageBoxes_Error_details + exMessage, SystemIcons.Error, Buttons.ButtonOk)); } internal static string GetSystemRestoreDescription(int count) { return string.Format(CultureInfo.InvariantCulture, Localisable.MessageBoxes_GetSystemRestoreDescription, count); } internal static void InvalidNewEntryName() { CustomMessageBox.ShowDialog(DefaultOwner, new CmbBasicSettings(Localisable.MessageBoxes_Title_Rename_uninstaller, Localisable.MessageBoxes_InvalidNewEntryName_Message, string.Format(CultureInfo.InvariantCulture, Localisable.MessageBoxes_InvalidNewEntryName_Details, string.Join(" ", StringTools.InvalidPathChars.Select(x => x.ToString()).ToArray())), SystemIcons.Warning, Buttons.ButtonOk)); } /// /// True if user wants to look for junk /// /// internal static bool LookForJunkQuestion() { switch (Settings.Default.MessagesRemoveJunk) { case YesNoAsk.Yes: return true; case YesNoAsk.No: return false; } var check = new CmbCheckboxSettings(Localisable.MessageBoxes_RememberChoiceCheckbox); var result = CustomMessageBox.ShowDialog(DefaultOwner, new CmbBasicSettings(Localisable.MessageBoxes_Title_Junk_Leftover_removal, Localisable.MessageBoxes_LookForJunkQuestion_Message, Localisable.MessageBoxes_LookForJunkQuestion_Details, SystemIcons.Question, Buttons.ButtonYes, Buttons.ButtonNo), check); if (check.Result.HasValue && check.Result.Value) Settings.Default.MessagesRemoveJunk = result == CustomMessageBox.PressedButton.Middle ? YesNoAsk.Yes : YesNoAsk.No; return result == CustomMessageBox.PressedButton.Middle; } internal static void NoJunkFoundInfo() { // If automatically searching for junk do not show this message if (Settings.Default.MessagesRemoveJunk == YesNoAsk.Yes) return; CustomMessageBox.ShowDialog(DefaultOwner, new CmbBasicSettings(Localisable.MessageBoxes_Title_Leftover_removal, Localisable.MessageBoxes_NoJunkFoundInfo_Message, Localisable.MessageBoxes_NoJunkFoundInfo_Details, SystemIcons.Information, Buttons.ButtonOk)); } internal static void NoNetworkConnected() { CustomMessageBox.ShowDialog(DefaultOwner, new CmbBasicSettings(Localisable.MessageBoxes_NoNetworkConnected_Open_online_content, Localisable.MessageBoxes_NoNetworkConnected_Message, Localisable.MessageBoxes_NoNetworkConnected_Details, SystemIcons.Error, Buttons.ButtonOk)); } internal static void NothingToCopy() { MessageBox.Show( Localisable.MessageBoxes_NothingToCopy_Message, Localisable.MessageBoxes_Title_Copy_to_clipboard, MessageBoxButtons.OK, MessageBoxIcon.Warning); } internal static void NoUninstallersSelectedInfo() { CustomMessageBox.ShowDialog(DefaultOwner, new CmbBasicSettings(Localisable.MessageBoxes_NoUninstallersSelectedInfo_Title, Localisable.MessageBoxes_NoUninstallersSelectedInfo_Message, Localisable.MessageBoxes_NoUninstallersSelectedInfo_Details, SystemIcons.Warning, Buttons.ButtonOk)); } internal static bool OpenDirectoriesMessageBox(int sourceDirCount) { if (sourceDirCount <= 0) { MessageBox.Show(Localisable.MessageBoxes_OpenDirectories_NoDirsToOpen, Localisable.MessageBoxes_Title_Open_directories, MessageBoxButtons.OK, MessageBoxIcon.Information); return false; } return (sourceDirCount == 1) || (MessageBox.Show( string.Format(CultureInfo.CurrentCulture, Localisable.MessageBoxes_OpenDirectoriesMessageBox_OpenMultiple, sourceDirCount), Localisable.MessageBoxes_Title_Open_directories, MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) != DialogResult.Cancel); } internal static void OpenDirectoryError(Exception e) { CustomMessageBox.ShowDialog(DefaultOwner, new CmbBasicSettings(Localisable.MessageBoxes_Title_Open_directories, Localisable.MessageBoxes_OpenDirectoryError_Message, Localisable.MessageBoxes_Error_details + e.Message, SystemIcons.Error, Buttons.ButtonOk)); } internal static void OpenUninstallListError(string exMessage) { CustomMessageBox.ShowDialog(DefaultOwner, new CmbBasicSettings(Localisable.MessageBoxes_Title_Open_Uninstall_List, Localisable.MessageBoxes_OpenUninstallListError_Message, exMessage, SystemIcons.Error, Buttons.ButtonClose)); } internal static PressedButton OpenUninstallListQuestion() { switch ( CustomMessageBox.ShowDialog(DefaultOwner, new CmbBasicSettings(Localisable.MessageBoxes_Title_Open_Uninstall_List, Localisable.MessageBoxes_OpenUninstallListQuestion_Message, Localisable.MessageBoxes_OpenUninstallListQuestion_Details, SystemIcons.Question, Buttons.ButtonKeep, Buttons.ButtonClear, Buttons.ButtonCancel))) { case CustomMessageBox.PressedButton.Left: return PressedButton.Yes; case CustomMessageBox.PressedButton.Middle: return PressedButton.No; default: return PressedButton.Cancel; } } internal static void OpenUrlError(Exception e) { CustomMessageBox.ShowDialog(DefaultOwner, new CmbBasicSettings(Localisable.MessageBoxes_Title_Open_urls, Localisable.MessageBoxes_OpenUrlError_Message, Localisable.MessageBoxes_Error_details + e.Message, SystemIcons.Error, Buttons.ButtonOk)); } internal static bool OpenUrlsMessageBox(int sourceDirCount) { if (sourceDirCount <= 0) { MessageBox.Show(Localisable.MessageBoxes_OpenUrlsMessageBox_No_URLs_to_open_Title, Localisable.MessageBoxes_Title_Open_urls, MessageBoxButtons.OK, MessageBoxIcon.Information); return false; } return (sourceDirCount == 1) || (MessageBox.Show( string.Format(CultureInfo.CurrentCulture, Localisable.MessageBoxes_OpenUrlsMessageBox_OpenMultiple_Message, sourceDirCount), Localisable.MessageBoxes_Title_Open_urls, MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) != DialogResult.Cancel); } /// /// Returns false if user wants to cancel /// internal static void ProtectedItemError(string affectedKeyName) { CustomMessageBox.ShowDialog(DefaultOwner, new CmbBasicSettings(Localisable.MessageBoxes_Title_Modify_protected_items, Localisable.MessageBoxes_ProtectedItemError_Message, string.Format(CultureInfo.InvariantCulture, Localisable.MessageBoxes_ProtectedItemError_Details, affectedKeyName), SystemIcons.Error, Buttons.ButtonOk)); } /// /// Returns false if user wants to cancel /// internal static PressedButton ProtectedItemsWarningQuestion(string[] affectedKeyNames) { if (!affectedKeyNames.Any()) return PressedButton.Yes; switch ( CustomMessageBox.ShowDialog(DefaultOwner, new CmbBasicSettings(Localisable.MessageBoxes_Title_Modify_protected_items, Localisable.MessageBoxes_ProtectedItemsWarningQuestion_Message, string.Format(CultureInfo.InvariantCulture, Localisable.MessageBoxes_ProtectedItemsWarningQuestion_Details, string.Join("\n", affectedKeyNames)), SystemIcons.Warning, Buttons.ButtonRemove, Buttons.ButtonCancel))) { case CustomMessageBox.PressedButton.Middle: return PressedButton.Yes; default: return PressedButton.Cancel; } } internal static PressedButton QuietUninstallersNotAvailableQuestion(string[] nonQuiet) { if (!Settings.Default.MessagesAskRemoveLoudItems) return PressedButton.Yes; var check = new CmbCheckboxSettings(Localisable.MessageBoxes_RememberChoiceCheckbox) { DisableRightButton = true, DisableMiddleButton = true }; var result = CustomMessageBox.ShowDialog(DefaultOwner, new CmbBasicSettings(Localisable.MessageBoxes_Title_Quiet_uninstall, Localisable.MessageBoxes_QuietUninstallersNotAvailableQuestion_Message, string.Format(CultureInfo.InvariantCulture, Localisable.MessageBoxes_QuietUninstallersNotAvailableQuestion_Details, string.Join("\n", nonQuiet)), SystemIcons.Question, Buttons.ButtonUseLoud, Buttons.ButtonRemove, Buttons.ButtonCancel), check); switch (result) { case CustomMessageBox.PressedButton.Left: if (check.Result.HasValue && check.Result.Value) Settings.Default.MessagesAskRemoveLoudItems = false; return PressedButton.Yes; case CustomMessageBox.PressedButton.Middle: return PressedButton.No; default: return PressedButton.Cancel; } } internal static PressedButton ResetSettingsConfirmation() { switch ( CustomMessageBox.ShowDialog(DefaultOwner, new CmbBasicSettings(Localisable.MessageBoxes_Title_Restore_default_settings, Localisable.MessageBoxes_ResetSettingsConfirmation_Message, Localisable.MessageBoxes_ResetSettingsConfirmation_Details, SystemIcons.Warning, Buttons.ButtonReset, Buttons.ButtonCancel))) { case CustomMessageBox.PressedButton.Middle: return PressedButton.Yes; default: return PressedButton.Cancel; } } internal static bool RestartNeededForSettingChangeQuestion() { var result = CustomMessageBox.ShowDialog(DefaultOwner, new CmbBasicSettings( Localisable.MessageBoxes_RestartNeededForSettingChangeQuestion_Title, Localisable.MessageBoxes_RestartNeededForSettingChangeQuestion_Message, Localisable.MessageBoxes_RestartNeededForSettingChangeQuestion_Details, SystemIcons.Question, Buttons.ButtonYes, Buttons.ButtonNo)); return result == CustomMessageBox.PressedButton.Middle; } internal static void SaveUninstallListError(string exMessage) { CustomMessageBox.ShowDialog(DefaultOwner, new CmbBasicSettings(Localisable.MessageBoxes_Title_Save_Uninstall_List, Localisable.MessageBoxes_SaveUninstallListError_Message, exMessage, SystemIcons.Error, Buttons.ButtonClose)); } internal static void SearchOnlineError(Exception e) { CustomMessageBox.ShowDialog(DefaultOwner, new CmbBasicSettings(Localisable.MessageBoxes_Title_Search_online, Localisable.MessageBoxes_SearchOnlineError_Message, Localisable.MessageBoxes_Error_details + e.Message, SystemIcons.Error, Buttons.ButtonOk)); } internal static PressedButton SearchOnlineMessageBox(int sourceDirCount) { if (sourceDirCount <= 0) { MessageBox.Show(Localisable.MessageBoxes_SearchOnlineMessageBox_NothingToSearchFor_Message, Localisable.MessageBoxes_Title_Search_online, MessageBoxButtons.OK, MessageBoxIcon.Information); return PressedButton.Cancel; } if (sourceDirCount == 1) return PressedButton.Yes; switch (MessageBox.Show( string.Format(CultureInfo.CurrentCulture, Localisable.MessageBoxes_OpenDirectoriesMessageBox_OpenMultiple, sourceDirCount), Localisable.MessageBoxes_Title_Open_directories, MessageBoxButtons.OKCancel, MessageBoxIcon.Warning)) { case DialogResult.OK: return PressedButton.Yes; default: return PressedButton.Cancel; } } internal static bool SelfUninstallQuestion() { return CustomMessageBox.ShowDialog(DefaultOwner, new CmbBasicSettings(Localisable.MessageBoxes_SelfUninstallQuestion_Title, Localisable.MessageBoxes_SelfUninstallQuestion_Message, Localisable.MessageBoxes_SelfUninstallQuestion_Details, SystemIcons.Question, Buttons.ButtonUninstall, Buttons.ButtonCancel)) == CustomMessageBox.PressedButton.Middle; } internal static PressedButton SysRestoreBeginQuestion() { switch (Settings.Default.MessagesRestorePoints) { case YesNoAsk.Yes: return PressedButton.Yes; case YesNoAsk.No: return PressedButton.No; } var check = new CmbCheckboxSettings(Localisable.MessageBoxes_RememberChoiceCheckbox) { DisableRightButton = true }; switch ( CustomMessageBox.ShowDialog(DefaultOwner, new CmbBasicSettings(Localisable.MessageBoxes_Title_Create_restore_point, Localisable.MessageBoxes_SysRestoreBeginQuestion_Message, Localisable.MessageBoxes_SysRestoreBeginQuestion_Details, SystemIcons.Question, Buttons.ButtonCreate, Buttons.ButtonDontCreate, Buttons.ButtonCancel), check)) { case CustomMessageBox.PressedButton.Left: if (check.Result.HasValue && check.Result.Value) Settings.Default.MessagesRestorePoints = YesNoAsk.Yes; return PressedButton.Yes; case CustomMessageBox.PressedButton.Middle: if (check.Result.HasValue && check.Result.Value) Settings.Default.MessagesRestorePoints = YesNoAsk.No; return PressedButton.No; default: return PressedButton.Cancel; } } /// /// Returns true if user wants to continue even though system restore failed /// internal static PressedButton SysRestoreContinueAfterError(string exMessage) { switch ( CustomMessageBox.ShowDialog(DefaultOwner, new CmbBasicSettings(Localisable.MessageBoxes_Title_Create_restore_point, Localisable.MessageBoxes_SysRestoreContinueAfterError_Message, Localisable.MessageBoxes_SysRestoreContinueAfterError_Details + Localisable.MessageBoxes_Error_details + exMessage, SystemIcons.Warning, Buttons.ButtonContinue, Buttons.ButtonCancel))) { case CustomMessageBox.PressedButton.Middle: return PressedButton.Yes; default: return PressedButton.Cancel; } } /// /// Yes if the task should be killed, /// No if the process should continue without killing the task and /// Cancel if the skip should be aborted. /// internal static CustomMessageBox TaskSkipCurrentKillTaskQuestion(Form parent) { return CustomMessageBox.Show(parent, new CmbBasicSettings(Localisable.MessageBoxes_TaskSkip_Title, Localisable.MessageBoxes_TaskSkip_Message, Localisable.MessageBoxes_TaskSkip_Details, SystemIcons.Question, Buttons.ButtonTerminate, Buttons.ButtonSkip, Buttons.ButtonCancel)); } internal static PressedButton TaskStopConfirmation(Form ownerForm) { switch ( CustomMessageBox.ShowDialog(ownerForm, new CmbBasicSettings(Localisable.MessageBoxes_TaskStopConfirmation_Title, Localisable.MessageBoxes_TaskStopConfirmation_Message, Localisable.MessageBoxes_TaskStopConfirmation_Details, SystemIcons.Question, Buttons.ButtonStop, Buttons.ButtonCancel))) { case CustomMessageBox.PressedButton.Middle: return PressedButton.Yes; default: return PressedButton.Cancel; } } internal static void UninstallAlreadyRunning() { PremadeDialogs.GenericError(Localisable.MessageBoxes_UninstallAlreadyRunning_Message); } internal static void UninstallMsiGuidMissing() { CustomMessageBox.ShowDialog(DefaultOwner, new CmbBasicSettings(Localisable.MessageBoxes_UninstallMsiGuidMissing_Title, Localisable.MessageBoxes_UninstallMsiGuidMissing_Message, Localisable.MessageBoxes_UninstallMsiGuidMissing_Details, SystemIcons.Warning, Buttons.ButtonOk)); } internal static void ModifyCommandMissing() { CustomMessageBox.ShowDialog(DefaultOwner, new CmbBasicSettings(Localisable.MessageBoxes_ModifyCommandMissing_Title, Localisable.MessageBoxes_ModifyCommandMissing_Message, Localisable.MessageBoxes_ModifyCommandMissing_Details, SystemIcons.Warning, Buttons.ButtonOk)); } internal static bool UpdateAskToDownload(Version latestVersion) { if (latestVersion == null) throw new ArgumentNullException(nameof(latestVersion)); return CustomMessageBox.ShowDialog(DefaultOwner, new CmbBasicSettings(Localisable.MessageBoxes_Title_Search_for_updates, string.Format(CultureInfo.CurrentCulture, Localisable.MessageBoxes_UpdateAskToDownload_Message, latestVersion), // string.Format(CultureInfo.CurrentCulture, Localisable.MessageBoxes_UpdateAskToDownload_Details, string.Join("\n- ", changes)), string.Format(CultureInfo.CurrentCulture, "Do you want to open the download page to get the latest version of BCUninstaller?"), //todo localize SystemIcons.Information, Buttons.ButtonYes, Buttons.ButtonNo)) == CustomMessageBox.PressedButton.Middle; } internal static void UpdateFailed(string errorMessage) { CustomMessageBox.ShowDialog(DefaultOwner, new CmbBasicSettings(Localisable.MessageBoxes_Title_Search_for_updates, Localisable.MessageBoxes_UpdateFailed_Message, Localisable.MessageBoxes_UpdateFailed_Details + Localisable.MessageBoxes_Error_details + errorMessage, SystemIcons.Error, Buttons.ButtonClose)); } internal static void UpdateUptodate() { CustomMessageBox.ShowDialog(DefaultOwner, new CmbBasicSettings(Localisable.MessageBoxes_Title_Search_for_updates, Localisable.MessageBoxes_UpdateUptodate_Message, Localisable.MessageBoxes_UpdateUptodate_Details, SystemIcons.Information, Buttons.ButtonClose)); } internal static void ForceRunUninstallFailedError(Form owner, IEnumerable failed) { CustomMessageBox.ShowDialog(owner, new CmbBasicSettings(Localisable.MessageBoxes_ForceRunUninstallFailedError_Title, Localisable.MessageBoxes_ForceRunUninstallFailedError_Header, string.Format(CultureInfo.InvariantCulture, Localisable.MessageBoxes_ForceRunUninstallFailedError_Message, string.Join("\n", failed.ToArray())), SystemIcons.Error, Buttons.ButtonClose)); } //public static void Net4MissingInfo() //{ // CustomMessageBox.ShowDialog(DefaultOwner, // new CmbBasicSettings(Localisable.MessageBoxes_Net4Missing_Title, // Localisable.MessageBoxes_Net4Missing_Message, // Localisable.MessageBoxes_Net4Missing_Details, SystemIcons.Warning, Buttons.ButtonOk)); //} public static void DisplayHelp() { var path = GetBundledFilePath(Resources.HelpFilename); if (path != null) PremadeDialogs.StartProcessSafely(path); } public static void DisplayLicense() { var path = GetBundledFilePath(Resources.LicenceFilename); if (path != null) PremadeDialogs.StartProcessSafely(path); } public static void DisplayPrivacyPolicy() { var path = GetBundledFilePath(Resources.PrivacyPolicyFilename); if (path != null) PremadeDialogs.StartProcessSafely(path); } public static string GetBundledFilePath(string filename) { var path = Path.Combine(Program.AssemblyLocation.FullName, filename); if (!File.Exists(path)) { path = Path.Combine(Program.AssemblyLocation.FullName, "..", filename); if (!File.Exists(path)) { MessageBox.Show("Could not find file " + filename); path = null; } } return path; } public static bool AskToRetryFailedQuietAsLoud(Form owner, IEnumerable failedNames) { return CustomMessageBox.ShowDialog(owner, new CmbBasicSettings(Localisable.MessageBoxes_AskToRetryFailedQuietAsLoud_Title, Localisable.MessageBoxes_AskToRetryFailedQuietAsLoud_Header, string.Format(CultureInfo.InvariantCulture, "{0}\n\n{1}", Localisable.MessageBoxes_AskToRetryFailedQuietAsLoud_Details, string.Join("\n", failedNames.OrderBy(x => x).ToArray())), SystemIcons.Question, Buttons.ButtonYes, Buttons.ButtonNo)) == CustomMessageBox.PressedButton.Middle; } public static void UninstallFromDirectoryNothingFound() { CustomMessageBox.ShowDialog(DefaultOwner, new CmbBasicSettings(Localisable.MessageBoxes_UninstallFromDirectory_Title, Localisable.MessageBoxes_UninstallFromDirectoryNothingFound_Message, Localisable.MessageBoxes_UninstallFromDirectoryNothingFound_Details, SystemIcons.Information, Buttons.ButtonOk)); } public static bool UninstallFromDirectoryUninstallerFound(string displayName, string uninstallString) { return CustomMessageBox.ShowDialog(DefaultOwner, new CmbBasicSettings(Localisable.MessageBoxes_UninstallFromDirectory_Title, string.Format(Localisable.MessageBoxes_UninstallFromDirectoryUninstallerFound_Message, displayName), Localisable.MessageBoxes_UninstallFromDirectoryUninstallerFound_Details + "\n\n" + uninstallString, SystemIcons.Information, Buttons.ButtonUninstall, Buttons.ButtonSkip)) == CustomMessageBox.PressedButton.Middle; } public static PressedButton AskToSaveUninstallList() { switch (CustomMessageBox.ShowDialog(DefaultOwner, new CmbBasicSettings(Localisable.MessageBoxes_AskToSaveUninstallList_Title, Localisable.MessageBoxes_AskToSaveUninstallList_Message, Localisable.MessageBoxes_AskToSaveUninstallList_Details, SystemIcons.Question, Buttons.ButtonYes, Buttons.ButtonNo, Buttons.ButtonCancel))) { case CustomMessageBox.PressedButton.Right: return PressedButton.Yes; case CustomMessageBox.PressedButton.Middle: return PressedButton.No; default: return PressedButton.Cancel; } } public static string SelectFolder(string title) { try { var dialog = new FolderBrowserDialog { AutoUpgradeEnabled = true, Description = title, UseDescriptionForTitle = true, }; return dialog.ShowDialog() == DialogResult.OK ? dialog.SelectedPath : null; } catch (Exception e) { Console.WriteLine(e); var dialog = new FolderBrowserDialog { RootFolder = Environment.SpecialFolder.Desktop, Description = title, ShowNewFolderButton = false }; return dialog.ShowDialog() == DialogResult.OK ? dialog.SelectedPath : null; } } public static void CantRenameUninstallerKind(string displayName, UninstallerType uninstallerKind) { CustomMessageBox.ShowDialog(DefaultOwner, new CmbBasicSettings(Localisable.MessageBoxes_Title_Rename_uninstaller, string.Format(Localisable.MessageBoxes_CantRenameUninstallerKind_Title, displayName), string.Format(Localisable.MessageBoxes_CantRenameUninstallerKind_Details, uninstallerKind.GetLocalisedName()), SystemIcons.Error, Buttons.ButtonOk)); } } } ================================================ FILE: source/BulkCrapUninstaller/Functions/Ratings/RatingEntry.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using BulkCrapUninstaller.Properties; namespace BulkCrapUninstaller.Functions.Ratings { public struct RatingEntry : IEquatable { public override int GetHashCode() { unchecked { return (AverageRating.GetHashCode() * 397) ^ MyRating.GetHashCode(); } } public string ApplicationName { get; set; } public int? AverageRating { get; set; } public int? MyRating { get; set; } public bool IsEmpty => ApplicationName == null && !HasValue; public bool HasValue => AverageRating.HasValue || MyRating.HasValue; public static RatingEntry Empty { get; } = default(RatingEntry); public static RatingEntry NotAvailable { get; } = new() { AverageRating = null, MyRating = null, ApplicationName = Localisable.NotAvailable }; public bool Equals(RatingEntry other) { return AverageRating == other.AverageRating && MyRating == other.MyRating && ApplicationName == other.ApplicationName; } public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) return false; return obj is RatingEntry entry && Equals(entry); } public static bool operator ==(RatingEntry left, RatingEntry right) { return left.Equals(right); } public static bool operator !=(RatingEntry left, RatingEntry right) { return !left.Equals(right); } public static UninstallerRating ToRating(int value) { if (value <= ((int)UninstallerRating.Bad + (int)UninstallerRating.Neutral) / 2) return UninstallerRating.Bad; if (value >= ((int)UninstallerRating.Good + (int)UninstallerRating.Neutral) / 2) return UninstallerRating.Good; return UninstallerRating.Neutral; } public override string ToString() { return string.Format(Localisable.RatingEntry_ToString, AverageRating.HasValue ? ToRating(AverageRating.Value) : UninstallerRating.Unknown, MyRating.HasValue ? ToRating(MyRating.Value) : UninstallerRating.Unknown); } } } ================================================ FILE: source/BulkCrapUninstaller/Functions/Ratings/RatingManagerWrapper.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Drawing; using System.Globalization; using System.Linq; using System.Threading; using System.Windows.Forms; using BrightIdeasSoftware; using BulkCrapUninstaller.Forms; using BulkCrapUninstaller.Properties; using Klocman.Binding.Settings; using Klocman.Forms.Tools; using Klocman.Resources; using Klocman.Tools; using UninstallTools; namespace BulkCrapUninstaller.Functions.Ratings { internal class RatingManagerWrapper { private readonly UninstallerRatingManager _ratingManager = new(Settings.Default.MiscUserId); private readonly SettingBinder _settings = Settings.Default.SettingBinder; /// /// Upload or discard user ratings based on current settings. /// public void ProcessGatheredRatings() { if (_settings.Settings.MiscUserRatings) { new Thread(() => { try { _ratingManager.UploadRatings(); } catch { //TODO: Handle this better? } try { _ratingManager.SerializeCache(Program.AssemblyLocation); } catch { FlushRatings(); } }) { IsBackground = false, Name = "ProcessRatingDispose_Thread" }.Start(); } else { FlushRatings(); } } public void InitializeRatingColumn(OLVColumn olvColumnRating, ObjectListView uninstallerObjectListView) { olvColumnRating.AspectGetter = x => { var entry = x as ApplicationUninstallerEntry; return string.IsNullOrEmpty(entry?.RatingId) ? RatingEntry.NotAvailable : _ratingManager.GetRating(entry.RatingId); }; olvColumnRating.Renderer = new RatingRenderer(); olvColumnRating.GroupKeyGetter = x => { var model = x as ApplicationUninstallerEntry; if (!_settings.Settings.MiscUserRatings || string.IsNullOrEmpty(model?.RatingId) || _ratingManager.RemoteRatingCount <= 0) return Localisable.NotAvailable; var rating = _ratingManager.GetRating(model.RatingId); if (rating.MyRating.HasValue) return string.Format("Your rating: {0}", RatingEntry.ToRating(rating.MyRating.Value)); else if (rating.AverageRating.HasValue) return string.Format("Average rating: {0}", RatingEntry.ToRating(rating.AverageRating.Value)); else return CommonStrings.Unknown; }; uninstallerObjectListView.CellClick += (x, y) => { if (y.Column == null || (y.ModifierKeys != Keys.None) || !y.Column.Equals(olvColumnRating)) return; if (y.Model is not ApplicationUninstallerEntry model) return; RateEntries(new[] { model }, uninstallerObjectListView.PointToScreen(y.Location)); }; } public void RateEntries(ApplicationUninstallerEntry[] entries, Point location) { if (!_settings.Settings.MiscUserRatings) { MessageBoxes.RatingsDisabled(); } else if (!entries.Any() || entries.All(x => string.IsNullOrEmpty(x.RatingId))) { MessageBoxes.RatingUnavailable(); } else { var title = entries.Length == 1 ? entries[0].DisplayName : string.Format(CultureInfo.CurrentCulture, Localisable.RateTitle_Counted, entries.Length); var result = RatingPopup.ShowRateDialog(MessageBoxes.DefaultOwner, title, location); if (result == UninstallerRating.Unknown) return; foreach (var entry in entries.Where(x => !string.IsNullOrEmpty(x.RatingId))) { _ratingManager.SetMyRating(entry.RatingId, result); } } } public void InitializeRatings() { if (_settings.Settings.MiscUserRatings) { new Thread(() => { try { _ratingManager.DeserializeCache(Program.AssemblyLocation); } catch (Exception ex) { FlushRatings(); PremadeDialogs.GenericError(ex); } // If _ratingManager has no ratings it means that deserialization failed so we need to fetch from db // Otherwise fetch at most every few hours, unless user manually clears the cache if (_ratingManager.RemoteRatingCount > 0 && (DateTime.Now - _settings.Settings.MiscRatingCacheDate).Duration() < _settings.Settings._CacheUpdateRate) return; if (!WindowsTools.IsNetworkAvailable()) return; try { _ratingManager.FetchRatings(); _settings.Settings.MiscRatingCacheDate = DateTime.Now; } catch (Exception ex) { Console.WriteLine(ex); } }) { IsBackground = false, Name = "ProcessRatingInit_Thread" }.Start(); } else { FlushRatings(); } } private void FlushRatings() { try { _ratingManager.ClearRatings(); UninstallerRatingManager.DeleteCache(Program.AssemblyLocation); } catch { //Ignore errors, the cashe won't be accessed anyways } _settings.Settings.MiscRatingCacheDate = DateTime.MinValue; } } } ================================================ FILE: source/BulkCrapUninstaller/Functions/Ratings/RatingRenderer.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System.Drawing; using System.Windows.Forms; using BrightIdeasSoftware; using BulkCrapUninstaller.Properties; using Klocman.Resources; namespace BulkCrapUninstaller.Functions.Ratings { public class RatingRenderer : BaseRenderer { private readonly Image[] _coloredImages = { Resources.rating1, Resources.rating3, Resources.rating4, Resources.rating5 }; private readonly Image _baseImage = Resources.star; private readonly int _maximumValue = 8; private readonly int _maxNumberImages = 4; private readonly int _minimumValue = -8; public override void Render(Graphics g, Rectangle r) { DrawBackground(g, r); r = ApplyCellPadding(r); // Convert our aspect to a numeric value var aspect = (RatingEntry)Aspect; if (aspect.Equals(RatingEntry.NotAvailable)) { DrawText(g, r, Localisable.NotAvailable); } else if (aspect.AverageRating.HasValue || aspect.MyRating.HasValue) { var aspectValue = (float)(aspect.MyRating ?? aspect.AverageRating); // Calculate how many images we need to draw to represent our aspect value int numberOfImages; if (aspectValue <= _minimumValue) numberOfImages = 1; // ReSharper disable once PossibleLossOfFraction else if (aspectValue <= (_maximumValue + _minimumValue) / 2) numberOfImages = 2; else if (aspectValue < _maximumValue) numberOfImages = 3; else numberOfImages = _maxNumberImages; // If we need to shrink the image, what will its on-screen dimensions be? var imageScaledWidth = _baseImage.Width; var imageScaledHeight = _baseImage.Height; if (r.Height < _baseImage.Height) { imageScaledWidth = (int)(_baseImage.Width * (float)r.Height / _baseImage.Height); imageScaledHeight = r.Height; } // Calculate where the images should be drawn var imageBounds = r; imageBounds.Width = _maxNumberImages * (imageScaledWidth + Spacing) - Spacing; imageBounds.Height = imageScaledHeight; imageBounds = AlignRectangle(r, imageBounds); // Finally, draw the images var singleImageRect = new Rectangle(imageBounds.X, imageBounds.Y, imageScaledWidth, imageScaledHeight); var backgroundColor = GetBackgroundColor(); for (var i = 0; i < numberOfImages; i++) { if (ListItem.Enabled) { var displayedImage = aspect.MyRating.HasValue || Settings.Default.MiscColorblind ? _baseImage : _coloredImages[numberOfImages - 1]; g.DrawImage(displayedImage, singleImageRect); //DrawImage(g, singleImageRect, image); } else ControlPaint.DrawImageDisabled(g, _baseImage, singleImageRect.X, singleImageRect.Y, backgroundColor); singleImageRect.X += (imageScaledWidth + Spacing); } } else { DrawText(g, r, CommonStrings.Unknown); } } } } ================================================ FILE: source/BulkCrapUninstaller/Functions/Ratings/UninstallerRating.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ namespace BulkCrapUninstaller.Functions.Ratings { public enum UninstallerRating { Unknown = 127, Neutral = 0, Bad = -10, Good = 10 } } ================================================ FILE: source/BulkCrapUninstaller/Functions/Ratings/UninstallerRatingManager.Utils.cs ================================================ using System; using System.Collections.Concurrent; using System.IO; using System.IO.Compression; using System.Text; using System.Text.Json; namespace BulkCrapUninstaller.Functions.Ratings { public partial class UninstallerRatingManager { internal static class Utils { public static T DecompressAndDeserialize(byte[] bytes, JsonSerializerOptions jsonSerializerOptions = null) { using (var msInput = new MemoryStream(bytes)) using (var bs = new BrotliStream(msInput, CompressionMode.Decompress)) using (var msOutput = new MemoryStream()) { bs.CopyTo(msOutput); msOutput.Seek(0, SeekOrigin.Begin); var output = msOutput.ToArray(); return JsonSerializer.Deserialize(output, jsonSerializerOptions); } } public static byte[] SerializeAndCompress(object objToJsonserialize) { var inputStr = JsonSerializer.Serialize(objToJsonserialize); var bytes = Encoding.UTF8.GetBytes(inputStr); using (var outputStream = new MemoryStream()) { using (var gZipStream = new BrotliStream(outputStream, CompressionLevel.Optimal)) gZipStream.Write(bytes, 0, bytes.Length); var result = outputStream.ToArray(); //Debug.WriteLine($"Compression result: {bytes.Length} -> {result.Length} ({(result.Length / (double)bytes.Length) * 100:F1}%)"); return result; } } [ThreadStatic] private static System.Security.Cryptography.MD5 _md5; private static readonly ConcurrentDictionary _hashCache = new(); public static ulong StableHash(string str) { if (str == null) return 0; if (_hashCache.TryGetValue(str, out var hash)) { return hash; } else { if (_md5 == null) _md5 = System.Security.Cryptography.MD5.Create(); byte[] inputBytes = Encoding.UTF8.GetBytes(str); var hashBytes = _md5.ComputeHash(inputBytes); var stableHash = BitConverter.ToUInt64(hashBytes, 0) ^ BitConverter.ToUInt64(hashBytes, 8); _hashCache.TryAdd(str, stableHash); return stableHash; } } // Needed for deserializing incoming data from the server public class AverageRatingEntry { public int AverageRating { get; set; } public ulong AppId { get; set; } } // Needed for deserializing incoming data from the server public class UserRatingEntry { public ulong UserId { get; set; } public int Rating { get; set; } public ulong AppId { get; set; } } } } } ================================================ FILE: source/BulkCrapUninstaller/Functions/Ratings/UninstallerRatingManager.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.IO; using System.Text.Json; namespace BulkCrapUninstaller.Functions.Ratings { public partial class UninstallerRatingManager { private readonly Dictionary _ratingsToSend = new(); private readonly Dictionary _avgRatings = new(); private readonly Dictionary _myRatings = new(); public UninstallerRatingManager(ulong userId) { if (userId == 0) throw new ArgumentOutOfRangeException(nameof(userId)); UserId = userId; } private ulong UserId { get; } public int RemoteRatingCount => _avgRatings.Count; public int UserRatingCount => _myRatings.Count; public void FetchRatings() { using var cl = Program.HomeServerClient; var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }; var txt = cl.GetStringAsync(new Uri(@"GetAverageRatingsComp", UriKind.Relative)).Result.Trim('"'); var bytes = Convert.FromBase64String(txt); var remoteAvgRatings = Utils.DecompressAndDeserialize>(bytes, options); var txt2 = cl.GetStringAsync(new Uri(@"GetUserRatings?userId=" + UserId, UriKind.Relative)).Result; var remoteMyRatings = JsonSerializer.Deserialize>(txt2, options); _avgRatings.Clear(); foreach (Utils.AverageRatingEntry entry in remoteAvgRatings) _avgRatings.Add(entry.AppId, entry.AverageRating); if (remoteMyRatings != null) { _myRatings.Clear(); foreach (Utils.UserRatingEntry entry in remoteMyRatings) _myRatings.Add(entry.AppId, entry.Rating); } } public void UploadRatings() { lock (_ratingsToSend) if (_ratingsToSend.Count < 1) return; using var cl = Program.HomeServerClient; lock (_ratingsToSend) { foreach (var uninstallerRating in _ratingsToSend) { var msg = cl.PutAsync(new Uri($@"SetUserRating?userId={UserId}&appId={uninstallerRating.Key}&rating={uninstallerRating.Value}", UriKind.Relative), null!).Result; msg.EnsureSuccessStatusCode(); } _ratingsToSend.Clear(); } } public void SetMyRating(string appKey, UninstallerRating rating) { if (string.IsNullOrEmpty(appKey)) throw new ArgumentNullException(nameof(appKey)); if (rating == UninstallerRating.Unknown) throw new ArgumentException("Can't set unknown rating", nameof(rating)); lock (_ratingsToSend) { var appId = Utils.StableHash(appKey); _ratingsToSend[appId] = (int)rating; _myRatings[appId] = (int)rating; } } public RatingEntry GetRating(string appName) { var appId = Utils.StableHash(appName); int? avg = null; int? my = null; if (_avgRatings.TryGetValue(appId, out var a)) avg = a; if (_myRatings.TryGetValue(appId, out var m)) my = m; return new RatingEntry { ApplicationName = appName, AverageRating = avg, MyRating = my }; } public void SerializeCache(DirectoryInfo directory) { if (directory == null) throw new ArgumentNullException(nameof(directory)); lock (_ratingsToSend) { var dir = directory.FullName; var avgPath = Path.Combine(dir, "RatingCashe_Avg.json"); var myPath = Path.Combine(dir, "RatingCashe_User.json"); var pendingPath = Path.Combine(dir, "RatingCashe_Pending.json"); File.WriteAllText(avgPath, JsonSerializer.Serialize(_avgRatings)); File.WriteAllText(myPath, JsonSerializer.Serialize(_myRatings)); File.WriteAllText(pendingPath, JsonSerializer.Serialize(_ratingsToSend)); } } public static void DeleteCache(DirectoryInfo directory) { if (directory == null) throw new ArgumentNullException(nameof(directory)); var dir = directory.FullName; var avgPath = Path.Combine(dir, "RatingCashe_Avg.json"); var myPath = Path.Combine(dir, "RatingCashe_User.json"); var pendingPath = Path.Combine(dir, "RatingCashe_Pending.json"); File.Delete(avgPath); File.Delete(myPath); File.Delete(pendingPath); } public void DeserializeCache(DirectoryInfo directory) { if (directory == null) throw new ArgumentNullException(nameof(directory)); lock (_ratingsToSend) { var dir = directory.FullName; var avgPath = Path.Combine(dir, "RatingCashe_Avg.json"); var myPath = Path.Combine(dir, "RatingCashe_User.json"); var pendingPath = Path.Combine(dir, "RatingCashe_Pending.json"); LoadFromFile(avgPath, _avgRatings); LoadFromFile(myPath, _myRatings); LoadFromFile(pendingPath, _ratingsToSend); } } private static void LoadFromFile(string path, Dictionary target) { try { var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }; var avgRatings = JsonSerializer.Deserialize>(File.ReadAllText(path), options); if (avgRatings != null) { target.Clear(); foreach (var avgRating in avgRatings) target.Add(avgRating.Key, avgRating.Value); } } catch (Exception e) { Console.WriteLine(e); } } public void ClearRatings() { lock (_ratingsToSend) { _ratingsToSend.Clear(); _myRatings.Clear(); _avgRatings.Clear(); } } } } ================================================ FILE: source/BulkCrapUninstaller/Functions/Tools/ImportExport.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; using Klocman.Extensions; using Klocman.Forms.Tools; using UninstallTools; namespace BulkCrapUninstaller.Functions.Tools { internal static class ImportExport { public static void CopyToClipboard(IEnumerable inputLines) { var text = string.Join("\r\n", inputLines.OrderBy(t => t).ToArray()); if (text.IsNotEmpty()) { try { Clipboard.SetText(text); } catch (Exception ex) { PremadeDialogs.GenericError(ex); } } else MessageBoxes.NothingToCopy(); } public static void CopyNamesToClipboard(IEnumerable items) { CopyToClipboard(items.Select(z => z.DisplayName)); } public static void CopyRegKeysToClipboard(IEnumerable items) { CopyToClipboard(items.Select(z => z.RegistryPath)); } public static void CopyUninstallStringsToClipboard(IEnumerable items) { CopyToClipboard(items.Select(z => z.UninstallString)); } public static void CopyGuidsToClipboard(IEnumerable items) { CopyToClipboard(items.Select(z => z.BundleProviderKey.ToString("B").ToUpperInvariant())); } public static void CopyFullInformationToClipboard(IEnumerable items) { CopyToClipboard(items.Select(z => z.ToLongString())); } } } ================================================ FILE: source/BulkCrapUninstaller/Functions/Tools/LocalizedX509Certificate.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Linq; using System.Security.Cryptography.X509Certificates; using BulkCrapUninstaller.Properties; using Klocman.Extensions; using Klocman.Localising; namespace BulkCrapUninstaller.Functions.Tools { internal class LocalizedX509Certificate2 { public LocalizedX509Certificate2(X509Certificate2 baseCert) { BaseCert = baseCert; } private X509Certificate2 BaseCert { get; } [LocalisedName(typeof(Localisable), nameof(Localisable.LocalizedX509Certificate2_Archived))] public bool Archived => BaseCert.Archived; [LocalisedName(typeof(Localisable), nameof(Localisable.LocalizedX509Certificate2_Extensions))] public string Extensions => string.Join(", ", BaseCert.Extensions.Cast().Where(x => x.Oid != null).Select(x => x.Oid.FriendlyName).ToArray()); [LocalisedName(typeof(Localisable), nameof(Localisable.LocalizedX509Certificate2_FriendlyName))] public string FriendlyName => BaseCert.FriendlyName; [LocalisedName(typeof(Localisable), nameof(Localisable.LocalizedX509Certificate2_HasPrivateKey))] public bool HasPrivateKey => BaseCert.HasPrivateKey; [LocalisedName(typeof(Localisable), nameof(Localisable.LocalizedX509Certificate2_Issuer))] public string Issuer => BaseCert.Issuer; [LocalisedName(typeof(Localisable), nameof(Localisable.LocalizedX509Certificate2_IssuerName))] public string IssuerName => BaseCert.IssuerName.Format(false); [LocalisedName(typeof(Localisable), nameof(Localisable.LocalizedX509Certificate2_NotAfter))] public DateTime NotAfter => BaseCert.NotAfter; [LocalisedName(typeof(Localisable), nameof(Localisable.LocalizedX509Certificate2_NotBefore))] public DateTime NotBefore => BaseCert.NotBefore; #pragma warning disable SYSLIB0027 #pragma warning disable SYSLIB0028 [LocalisedName(typeof(Localisable), nameof(Localisable.LocalizedX509Certificate2_PrivateKey))] public string PrivateKey => BaseCert.PrivateKey?.ToString(); [LocalisedName(typeof(Localisable), nameof(Localisable.LocalizedX509Certificate2_PublicKey))] public string PublicKey => BaseCert.PublicKey.Key.SignatureAlgorithm; #pragma warning restore SYSLIB0028 #pragma warning restore SYSLIB0027 [LocalisedName(typeof(Localisable), nameof(Localisable.LocalizedX509Certificate2_RawData))] public string RawData => BaseCert.RawData.ToHexString(); [LocalisedName(typeof(Localisable), nameof(Localisable.LocalizedX509Certificate2_SerialNumber))] public string SerialNumber => BaseCert.SerialNumber; [LocalisedName(typeof(Localisable), nameof(Localisable.LocalizedX509Certificate2_SignatureAlgorithm))] public string SignatureAlgorithm => BaseCert.SignatureAlgorithm.FriendlyName; [LocalisedName(typeof(Localisable), nameof(Localisable.LocalizedX509Certificate2_Subject))] public string Subject => BaseCert.Subject; [LocalisedName(typeof(Localisable), nameof(Localisable.LocalizedX509Certificate2_SubjectName))] public string SubjectName => BaseCert.SubjectName.Format(false); [LocalisedName(typeof(Localisable), nameof(Localisable.LocalizedX509Certificate2_Thumbprint))] public string Thumbprint => BaseCert.Thumbprint; [LocalisedName(typeof(Localisable), nameof(Localisable.LocalizedX509Certificate2_Version))] public int Version => BaseCert.Version; } } ================================================ FILE: source/BulkCrapUninstaller/Functions/Tools/OnlineSearchTools.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Web; using Klocman.Tools; using UninstallTools; namespace BulkCrapUninstaller.Functions.Tools { public static class OnlineSearchTools { public static void SearchGoogle(IEnumerable selectedUninstallers) { SearchOnline(selectedUninstallers, @"https://www.google.com/search?q=", GetFullName, SearchSeparatorType.Plus); } public static void SearchFilehippo(IEnumerable selectedUninstallers) { SearchOnline(selectedUninstallers, @"http://filehippo.com/search?q=", GetTrimmedName, SearchSeparatorType.Plus); } public static void SearchSourceforge(IEnumerable selectedUninstallers) { SearchOnline(selectedUninstallers, @"https://sourceforge.net/directory/?q=", GetTrimmedName, SearchSeparatorType.Escaped); } public static void SearchFosshub(IEnumerable selectedUninstallers) { SearchOnline(selectedUninstallers, @"https://www.fosshub.com/search/", GetTrimmedName, SearchSeparatorType.Escaped); } public static void SearchAlternativeTo(IEnumerable selectedUninstallers) { SearchOnline(selectedUninstallers, @"https://alternativeto.net/browse/search/?q=", GetTrimmedName, SearchSeparatorType.Plus); } public static void SearchGithub(IEnumerable selectedUninstallers) { SearchOnline(selectedUninstallers, @"https://github.com/search?q=", GetTrimmedName, SearchSeparatorType.Plus); } public static void SearchSlantCo(IEnumerable selectedUninstallers) { SearchOnline(selectedUninstallers, @"https://www.slant.co/search?query=", GetTrimmedName, SearchSeparatorType.Escaped); } private static string GetTrimmedName(ApplicationUninstallerEntry entry) { var displayNameTrimmed = entry.DisplayNameTrimmed; return displayNameTrimmed.Length > 3 ? displayNameTrimmed : entry.DisplayName; } private static string GetFullName(ApplicationUninstallerEntry entry) { return entry.DisplayName; } public static void SearchOnline(IEnumerable selectedUninstallers, string searchString, Func searchStringGetter, SearchSeparatorType spaceReplacement) { if (WindowsTools.IsNetworkAvailable()) { var items = selectedUninstallers .Select(searchStringGetter) .Where(x => !string.IsNullOrEmpty(x)) .Select(str => { switch (spaceReplacement) { case SearchSeparatorType.Plus: return HttpUtility.UrlEncode(str); //return str.Replace(' ', '+'); case SearchSeparatorType.Escaped: return HttpUtility.UrlEncode(str).Replace("+", "%20"); default: throw new ArgumentOutOfRangeException(nameof(spaceReplacement), spaceReplacement, null); } }).Select(y => string.Concat(searchString, y)).ToList(); if (MessageBoxes.SearchOnlineMessageBox(items.Count) == MessageBoxes.PressedButton.Yes) { try { items.ForEach(x => Process.Start(new ProcessStartInfo(x) { UseShellExecute = true })); } catch (Exception ex) { MessageBoxes.SearchOnlineError(ex); } } } else MessageBoxes.NoNetworkConnected(); } public enum SearchSeparatorType { Plus, Escaped } } } ================================================ FILE: source/BulkCrapUninstaller/Functions/Tools/SettingTools.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Drawing; using System.IO; using System.Linq; using System.Windows.Forms; using BulkCrapUninstaller.Forms; using BulkCrapUninstaller.Properties; using Klocman.Binding.Settings; using Klocman.Forms.Tools; namespace BulkCrapUninstaller.Functions.Tools { internal sealed class SettingTools { private readonly MainWindow _mainWindow; private bool _resetSettings; public SettingTools(SettingBinder settingSet, MainWindow mainWindow) { Selected = settingSet; _mainWindow = mainWindow; } public SettingBinder Selected { get; } public void LoadSettings() { #if DEBUG Selected.Settings.Debug = true; #endif if (Selected.Settings.MiscFirstRun) return; if (Selected.Settings.WindowSize.Width >= _mainWindow.MinimumSize.Width && Selected.Settings.WindowSize.Height >= _mainWindow.MinimumSize.Height && !Selected.Settings.WindowPosition.IsEmpty) { var targetRect = new Rectangle(Selected.Settings.WindowPosition, Selected.Settings.WindowSize); if (Screen.AllScreens.Any(s => s.WorkingArea.IntersectsWith(targetRect))) { _mainWindow.Size = Selected.Settings.WindowSize; _mainWindow.Location = Selected.Settings.WindowPosition; _mainWindow.StartPosition = FormStartPosition.Manual; if (Selected.Settings.WindowState != FormWindowState.Minimized) _mainWindow.WindowState = Selected.Settings.WindowState; } } if (!string.IsNullOrEmpty(Selected.Settings.UninstallerListViewState)) { try { _mainWindow.uninstallerObjectListView.RestoreState( Convert.FromBase64String(Selected.Settings.UninstallerListViewState)); } catch (Exception) { // Failed to load listview state, likely old version that used binaryformatter } } } public void LoadSorting() { try { _mainWindow.uninstallerObjectListView.Sorting = Selected.Settings.UninstallerListSortOrder; _mainWindow.uninstallerObjectListView.Sort(Selected.Settings.UninstallerListSortColumn); } catch { // OLV can throw a nullref } } /// /// Ask user to reset settings. If user selects yes the settings are reset and application is restarted. /// public void ResetSettingsDialog() { if (MessageBoxes.ResetSettingsConfirmation() == MessageBoxes.PressedButton.Yes) { _resetSettings = true; EntryPoint.Restart(); } } public void SaveSettings() { if (_resetSettings) { try { File.Delete(Program.ConfigFileFullname); } catch (Exception ex) { /*Failed to save settings, probably read only drive*/ PremadeDialogs.GenericError(new IOException(Localisable.Error_SaveSettingsFailed, ex)); } } else { Selected.Settings.WindowState = _mainWindow.WindowState; if (_mainWindow.WindowState == FormWindowState.Normal) { Selected.Settings.WindowSize = _mainWindow.Size; Selected.Settings.WindowPosition = _mainWindow.Location; } Selected.Settings.UninstallerListViewState = Convert.ToBase64String(_mainWindow.uninstallerObjectListView.SaveState()); Selected.Settings.UninstallerListSortOrder = _mainWindow.uninstallerObjectListView.PrimarySortOrder; Selected.Settings.UninstallerListSortColumn = _mainWindow.uninstallerObjectListView.Columns.IndexOf( _mainWindow.uninstallerObjectListView.PrimarySortColumn); Selected.Settings.MiscVersion = Program.AssemblyVersion.ToString(); try { Selected.Settings.Save(); } catch (Exception ex) { /*Failed to save settings, probably read only drive*/ PremadeDialogs.GenericError(new IOException(Localisable.Error_SaveSettingsFailed, ex)); } } } } } ================================================ FILE: source/BulkCrapUninstaller/Functions/Tools/SystemRestore.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.IO; using System.Windows.Forms; using BulkCrapUninstaller.Properties; using Klocman.Forms; using Klocman.IO; using Microsoft.UI.Xaml; namespace BulkCrapUninstaller.Functions.Tools { internal static class SystemRestore { /// /// Currently running system restore number /// private static long _currentRestoreId = long.MinValue; /// /// Ask the user to begin system restore and do so if he accepts. Returns false if user decides to cancel the /// operation. /// /// How many items are being uninstalled /// If user should be asked to create the restore point. If false, always create /// Window to show on top of public static bool BeginSysRestore(int count, bool displayMessage = true, Form owner = null) { if (!SysRestore.SysRestoreAvailable()) return false; // If a restore is already running, do not start another one if (_currentRestoreId != long.MinValue) return true; switch (displayMessage ? MessageBoxes.SysRestoreBeginQuestion() : MessageBoxes.PressedButton.Yes) { case MessageBoxes.PressedButton.Yes: var error = LoadingDialog.ShowDialog(owner, Localisable.LoadingDialogTitleCreatingRestorePoint, x => { EndSysRestore(); var result = SysRestore.StartRestore(MessageBoxes.GetSystemRestoreDescription(count), out _currentRestoreId, 3); if (result < 0) throw new IOException(Localisable.SysRestoreGenericError); }); return error == null || MessageBoxes.SysRestoreContinueAfterError(error.Message) == MessageBoxes.PressedButton.Yes; default: case MessageBoxes.PressedButton.No: case MessageBoxes.PressedButton.Cancel: return false; } } /// /// Cancel running restore if any /// public static void CancelSysRestore() { try { if (_currentRestoreId != long.MinValue) SysRestore.CancelRestore(_currentRestoreId); } catch (Exception ex) { Console.WriteLine(ex); } finally { _currentRestoreId = long.MinValue; } } public static void EndSysRestore() { try { if (_currentRestoreId != long.MinValue) SysRestore.EndRestore(_currentRestoreId); } catch (Exception ex) { Console.WriteLine(ex); } finally { _currentRestoreId = long.MinValue; } } } } ================================================ FILE: source/BulkCrapUninstaller/Functions/Tools/UpdateGrabber.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Diagnostics; using System.Net; using System.Net.Http; using System.Reflection; using System.Threading; using BulkCrapUninstaller.Properties; using Klocman.Forms; using Klocman.Tools; namespace BulkCrapUninstaller.Functions.Tools { internal static class UpdateGrabber { /// /// Look for updates while displaying a progress bar. At the end display a message box with the result. /// public static void LookForUpdates() { bool? result = null; Version latestVersion = null; var error = LoadingDialog.ShowDialog(null, Localisable.LoadingDialogTitleSearchingForUpdates, _ => { result = IsUpdateAvailable(Assembly.GetExecutingAssembly().GetName().Version, out latestVersion); }); if (error == null) { switch (result) { case null: MessageBoxes.UpdateFailed("Unknown error"); break; case true: AskAndBeginUpdate(latestVersion); break; case false: MessageBoxes.UpdateUptodate(); break; } } else { MessageBoxes.UpdateFailed(error.Message); } } public static void AskAndBeginUpdate(Version latestVersion) { if (MessageBoxes.UpdateAskToDownload(latestVersion)) { try { // Prevent log cleaner from running in portable builds //EntryPoint.IsRestarting = true; Process.Start(new ProcessStartInfo(LatestReleaseUrl) { UseShellExecute = true }); } catch (Exception ex) { EntryPoint.IsRestarting = false; Console.WriteLine(ex); MessageBoxes.UpdateFailed(ex.Message); } } } /// /// Setup update system and automatically search for them if auto update is enabled. /// Doesn't block, use delegates to interface. /// public static void Setup() { //UpdateSystem.UpdateFeedUri = Program.EnableDebug ? DebugUpdateFeedUri : UpdateFeedUri; //UpdateSystem.CurrentVersion = Assembly.GetExecutingAssembly().GetName().Version; } /// /// Automatically search for updates if auto update is enabled. /// Doesn't block, use delegates to interface. /// /// updateFoundCallback will be called after this returns true /// Launched only if a new update was found. It's launched from a background thread. public static void AutoUpdate(Func canDisplayMessage, Action updateFoundCallback) { if (Settings.Default.MiscCheckForUpdates && WindowsTools.IsNetworkAvailable()) { new Thread(() => { if (IsUpdateAvailable(Assembly.GetExecutingAssembly().GetName().Version, out var updateVersion) == true) { while (!canDisplayMessage()) Thread.Sleep(100); try { updateFoundCallback(updateVersion); } catch { // Ignore background error, not necessary } } }) { Name = "UpdateCheck_Thread", IsBackground = true }.Start(); } } public static string LatestReleaseUrl = "https://github.com/Klocman/Bulk-Crap-Uninstaller/releases/latest"; public static Version CheckLatestVersion() { // Should result in something like "https://github.com/Klocman/Bulk-Crap-Uninstaller/releases/tag/v4.1" var url = GetFinalRedirect(LatestReleaseUrl); if (url != null) { var i = url.LastIndexOf('/'); var tag = url.Substring(i).TrimStart('/', 'v'); return new Version(tag); } return null; } /// /// Returns null if failed to look for updates, else returns if there is a newer version available /// public static bool? IsUpdateAvailable(Version currentVersion, out Version updateVersion) { updateVersion = null; try { var latestVersion = CheckLatestVersion(); if (latestVersion == null) { throw new WebException("Failed to get version from URL"); } else if (latestVersion > currentVersion) { updateVersion = latestVersion; Console.WriteLine("A new version is available: " + latestVersion); return true; } else { Console.WriteLine("The current version is the latest"); return false; } } catch (Exception e) { Console.WriteLine("Failed to check for new versions: " + e.Message); return null; } } private static string GetFinalRedirect(string url) { if (string.IsNullOrWhiteSpace(url)) return null; try { // https://stackoverflow.com/a/79339216 using (var client = new HttpClient(new HttpClientHandler { AllowAutoRedirect = true })) { client.Timeout = new TimeSpan(0, 0, 10); using (var response = client.SendAsync(new HttpRequestMessage(HttpMethod.Head, url))) { var result = response.Result.RequestMessage?.RequestUri; return result?.ToString(); } } } catch (Exception ex) { Console.WriteLine($"GetFinalRedirect failed for url=[{url}] with exception: {ex}"); return null; } } } } ================================================ FILE: source/BulkCrapUninstaller/Functions/Tracking/DatabaseStatSender.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using Klocman.Tools; namespace BulkCrapUninstaller.Functions.Tracking { public class DatabaseStatSender { private readonly ulong userId; public DatabaseStatSender(ulong userId) { this.userId = userId; } public bool SendData(string value) { try { var compressed = CompressionTools.BrotliCompress(value); using var s = Program.HomeServerClient; var response = s.PostAsync(new Uri($"SendStats?userId={userId}&data={Convert.ToBase64String(compressed)}", UriKind.Relative), null!).Result; response.EnsureSuccessStatusCode(); } catch (Exception e) { Console.WriteLine("Failed to send stats: " + e); return false; } return true; } } } ================================================ FILE: source/BulkCrapUninstaller/Functions/Tracking/EventHook.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Reflection; namespace BulkCrapUninstaller.Functions.Tracking { internal sealed class EventHook : IDisposable { private readonly List _hooks = new(); public EventHook(object target, FieldInfo targetField, IEnumerable targetEvents) { Parent = target; Field = targetField; ParentName = Parent.GetType().Name; FieldName = Field.Name; SubscribeToEvents(targetEvents); } public FieldInfo Field { get; } public string FieldName { get; } public IEnumerable Hooks => _hooks; public object Parent { get; } public string ParentName { get; } public void Dispose() { foreach (var hook in _hooks) { hook.Dispose(); } } private void SubscribeToEvents(IEnumerable targetEvents) { foreach (var targetEvent in targetEvents) { try { _hooks.Add(new SingleEventHook(this, targetEvent)); } catch (ArgumentException) { } } } } } ================================================ FILE: source/BulkCrapUninstaller/Functions/Tracking/SingleEventHook.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Diagnostics; using System.Reflection; namespace BulkCrapUninstaller.Functions.Tracking { internal sealed class SingleEventHook : IDisposable { private static readonly MethodInfo SimpleHandlerInfo = typeof (SingleEventHook).GetMethod("SimpleHandler", BindingFlags.Instance | BindingFlags.NonPublic); public SingleEventHook(EventHook parent, EventInfo targetEvent) { if (parent == null) throw new ArgumentNullException(nameof(parent)); if (targetEvent == null) throw new ArgumentNullException(nameof(targetEvent)); EventName = targetEvent.Name; Parent = parent; TargetProperty = parent.Field.GetValue(parent.Parent); if (TargetProperty == null) throw new ArgumentException("EventHook has an invalid Field or Parent property."); TargetEvent = targetEvent; Handler = Delegate.CreateDelegate(targetEvent.EventHandlerType ?? throw new ArgumentException("EventHandlerType is null"), this, SimpleHandlerInfo); TargetEvent.AddEventHandler(TargetProperty, Handler); } public string EventName { get; } public Delegate Handler { get; } public int HitCount { get; private set; } public string Name => Parent.ParentName + " -> " + Parent.FieldName + " -> " + EventName; public EventHook Parent { get; } public EventInfo TargetEvent { get; } public object TargetProperty { get; } public void Dispose() { TargetEvent.RemoveEventHandler(TargetProperty, Handler); } public override string ToString() { return Name; } // Accessed via reflection by SimpleHandlerInfo private void SimpleHandler(object sender, EventArgs args) { HitCount++; Debug.WriteLine(Name + " | Times hit: " + HitCount); } } } ================================================ FILE: source/BulkCrapUninstaller/Functions/Tracking/UsageManager.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Reflection; using System.Xml; using System.Xml.Linq; using Klocman.Extensions; using Klocman.IO; using Klocman.Tools; namespace BulkCrapUninstaller.Functions.Tracking { public static class UsageManager { private static readonly string StatsFilename = Program.AssemblyLocation + @"\UsageStatistics.xml"; internal static List Trackers = new(); private static XDocument _currentData; private static readonly object OperationLock = new(); public static bool IsCollectingData { get; private set; } private static XDocument CurrentData { get { lock (OperationLock) { if (_currentData == null) { XDocument doc; try { doc = XDocument.Load(StatsFilename); if (doc.Root == null || (doc.Root.Name != "UsageStatistics" || doc.Root.IsEmpty)) throw new XmlException(); } catch { doc = CreateNewDataDocument(); } _currentData = doc; AppLaunchCount++; } return _currentData; } } } public static int AppLaunchCount { get { lock (OperationLock) { var metadata = CurrentData.Root.GetOrCreateElement("Metadata"); var counter = metadata.GetOrCreateElement("LaunchCount"); int.TryParse(counter.Value, out var launchCount); return launchCount; } } private set { lock (OperationLock) { var metadata = CurrentData.Root.GetOrCreateElement("Metadata"); var counter = metadata.GetOrCreateElement("LaunchCount"); counter.SetValue(value); } } } /// /// Object used to send the usage data. /// public static DatabaseStatSender DataSender { get; set; } /// /// Finish tracking data and save results to the hard drive /// public static void FinishCollectingData() { lock (Trackers) { IsCollectingData = false; foreach (var tracker in Trackers) { SerializeToXml(tracker.Hooks); } // Save to disk try { CurrentData.Save(StatsFilename); } catch { /*PremadeDialogs.GenericError(ex); // No need, not critical*/ } } } public static void RemoveStoredData() { try { File.Delete(StatsFilename); } catch { //Ignore permission and read errors } } /// /// Send usage data specified mail address /// public static void SendUsageData() { if (DataSender == null) throw new InvalidOperationException("DataSender must be set before sending data"); lock (OperationLock) { DataSender.SendData(CurrentData.ToString(SaveOptions.DisableFormatting)); } } internal static void UsageTrackerDestructionCallback(UsageTracker tracker) { lock (Trackers) { if (Trackers.Contains(tracker)) Trackers.Remove(tracker); if (IsCollectingData) SerializeToXml(tracker.Hooks); } } private static XDocument CreateNewDataDocument() { var tempDoc = new XDocument(new XDeclaration("1.0", "utf-8", null), new XElement("UsageStatistics")); var metadata = tempDoc.Root.GetOrCreateElement("Metadata"); metadata.Add(new XElement("ApplicationVersion", Assembly.GetEntryAssembly()?.GetName().Version?.ToString() ?? "Unknown")); metadata.Add(new XElement("SystemVersion", Environment.OSVersion.VersionString)); metadata.Add(new XElement("Is64Bit", ProcessTools.Is64BitProcess)); metadata.Add(new XElement("Locale", CultureInfo.InstalledUICulture.ToString())); //metadata.Add(new XElement("UserId", WindowsTools.GetUserSid())); var net = new XElement("Net", string.Join("; ", NetFrameworkTools.GetInstalledFrameworkVersions())); metadata.Add(net); return tempDoc; } private static void SerializeToXml(IEnumerable hooks) { lock (OperationLock) { var root = CurrentData.Root.GetOrCreateElement("InterfaceStatistics"); foreach (var mainHook in hooks) { var parentElement = root.GetOrCreateElement(mainHook.ParentName); var fieldElement = parentElement.GetOrCreateElement(mainHook.FieldName); foreach (var singleHook in mainHook.Hooks) { if (singleHook.HitCount <= 0) continue; var element = fieldElement.GetOrCreateElement(singleHook.EventName); int.TryParse(element.Value, out var result); element.SetValue(singleHook.HitCount + result); } if (fieldElement.IsEmpty) fieldElement.Remove(); } } } } } ================================================ FILE: source/BulkCrapUninstaller/Functions/Tracking/UsageTracker.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Windows.Forms; using Klocman.Forms.Tools; namespace BulkCrapUninstaller.Functions.Tracking { public sealed class UsageTracker : ReferencedComponent { private static readonly IEnumerable EventFilters = new[] {"Click", "DoubleClick"}; private static readonly List TypeBlacklist = new(); // new[] { typeof(Forms.CustomMessageBox) }); private readonly List _hooks = new(); internal IEnumerable Hooks => _hooks; public static void AddBlacklistType(Type typeToBlacklist) { TypeBlacklist.Add(typeToBlacklist); } protected override void Dispose(bool disposing) { if (disposing) { UsageManager.UsageTrackerDestructionCallback(this); } base.Dispose(disposing); } private void HookToForm() { var type = ContainerControl.GetType(); var fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (var field in fields) { var fieldType = field.FieldType; if (typeof (Form).IsAssignableFrom(fieldType) || TypeBlacklist.Contains(fieldType)) continue; var targetEvents = fieldType.GetEvents(BindingFlags.Instance | BindingFlags.Public) .Where(x => EventFilters.Contains(x.Name)).ToList(); if (targetEvents.Count > 0) _hooks.Add(new EventHook(ContainerControl, field, targetEvents)); } } protected override void OnContainerInitialized(object obj, EventArgs args) { HookToForm(); UsageManager.Trackers.Add(this); } } } ================================================ FILE: source/BulkCrapUninstaller/NBugConfigurator.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Globalization; using System.IO; using System.Windows.Forms; using Klocman.Tools; using NBug; using NBug.Core.Reporting.Info; using NBug.Core.Submission; using NBug.Core.Util.Serialization; using NBug.Enums; using Settings = NBug.Settings; namespace BulkCrapUninstaller { /// /// Can not be contained inside of a static class as it needs to be serialized /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1051:Do not declare visible instance fields", Justification = "Used during serialization")] public class BugReportExtraInfo { public bool Is64Bit = ProcessTools.Is64BitProcess; public string Locale = CultureInfo.InstalledUICulture.ToString(); public string SystemVersion = Environment.OSVersion.VersionString; internal BugReportExtraInfo() { } } public static class NBugConfigurator { public static void SetupNBug() { Settings.UIMode = UIMode.Full; Settings.UIProvider = UIProvider.WinForms; Settings.SleepBeforeSend = 3; Settings.MaxQueuedReports = 4; Settings.StopReportingAfter = 10; Settings.MiniDumpType = MiniDumpType.None; Settings.WriteLogToDisk = false; Settings.ExitApplicationImmediately = true; Settings.HandleProcessCorruptedStateExceptions = false; Settings.ReleaseMode = true; Settings.Destinations.Add(new NBugDatabaseSenderWrapper()); AppDomain.CurrentDomain.UnhandledException += Handler.UnhandledException; Application.ThreadException += Handler.ThreadException; } private class NBugDatabaseSenderWrapper : ProtocolBase { public override bool Send(string fileName, Stream file, Report report, SerializableException exception) { try { report.CustomInfo = new BugReportExtraInfo(); var data = string.Concat("", report.ToString(), exception.ToString(), ""); var compressed = CompressionTools.BrotliCompress(data); using var s = Program.HomeServerClient; var result = s.PostAsync(new Uri($"SendCrashReport?userId={Properties.Settings.Default.MiscUserId}&data={Convert.ToBase64String(compressed)}", UriKind.Relative), null!).Result; result.EnsureSuccessStatusCode(); } catch (Exception e) { Console.WriteLine("Failed to send crash report: " + e); return false; } return true; } } } } ================================================ FILE: source/BulkCrapUninstaller/Program.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Diagnostics; using System.IO; using System.Linq; using System.Net.Http; using System.Net.NetworkInformation; using System.Reflection; using System.Runtime.InteropServices; using System.Security.Principal; using System.Xml.Linq; using BulkCrapUninstaller.Forms; using BulkCrapUninstaller.Functions.Ratings; using BulkCrapUninstaller.Properties; using Klocman.Extensions; using Klocman.Forms.Tools; using Klocman.Tools; using Microsoft.Win32; using UninstallTools; using UninstallTools.Factory; namespace BulkCrapUninstaller { //TODO This is a leftover class, extract the self installed detection logic and get rid of it public static class Program { private static DirectoryInfo _assemblyLocation; private static string _installedRegistryKeyName; private static bool? _isInstalled; public static DirectoryInfo AssemblyLocation { get { if (_assemblyLocation == null) { var location = Assembly.GetAssembly(typeof(Program))?.Location; if (location == null) throw new InvalidOperationException("Failed to get entry assembly location"); if (Path.HasExtension(location)) location = PathTools.GetDirectory(location); _assemblyLocation = new DirectoryInfo(location); } return _assemblyLocation; } } public static Version AssemblyVersion => Assembly.GetExecutingAssembly().GetName().Version; /// /// Do not call before CheckForOldSettings() completes /// public static bool EnableDebug => Debugger.IsAttached || Settings.Default.Debug; /// /// Don't use settings /// public static Uri ConnectionString { get; } = Debugger.IsAttached ? new Uri(@"http://localhost:7721") : new Uri(@"http://bugsklocman.ddns.net:7721"); public static string InstalledRegistryKeyName { get { if (_installedRegistryKeyName == null) GetInstalledRegKey(); return _installedRegistryKeyName; } } public static bool IsAfterUpgrade { get; private set; } /// /// Use setter to override the value /// public static bool IsInstalled { get { if (!_isInstalled.HasValue) _isInstalled = InstalledRegistryKeyName.IsNotEmpty(); return _isInstalled.Value; } internal set { _isInstalled = value; } } internal static string ConfigFileFullname { get; private set; } /// /// Remove old or invalid setting files and make sure settings are ready to be used. /// Run before the settings are used, best at the very start of the application. /// internal static void PrepareSettings() { const string exeName = "BCUninstaller"; IsAfterUpgrade = false; try { var dir = AssemblyLocation; // Check if we are bundled with a launcher and place settings in the same folder as the launcher, so they are shared between different builds if (dir.Name.StartsWith("win-") && dir.Parent != null && File.Exists(Path.Combine(dir.Parent.FullName, exeName + ".exe"))) dir = dir.Parent; var settingsDir = dir.FullName; ConfigFileFullname = Path.Combine(settingsDir, exeName + ".settings"); PortableSettingsProvider.PortableSettingsProvider.AppSettingsPathOverride = settingsDir; PortableSettingsProvider.PortableSettingsProvider.ApplicationNameOverride = exeName; var settingsXmlDocument = XDocument.Parse(File.ReadAllText(ConfigFileFullname)); if (settingsXmlDocument.Root == null) throw new FormatException("Missing root element"); var result = settingsXmlDocument.Root.Element("MiscVersion"); if (result == null) throw new FormatException("Invalid version number"); if (result.Value.Equals("Reset")) throw new OperationCanceledException("Settings reset was requested"); if (!string.IsNullOrWhiteSpace(result.Value) && new Version(result.Value) < AssemblyVersion) IsAfterUpgrade = true; // One extra check to make sure loading and using the settings doesn't throw // Initializes the Default settings object (unless it has been accessed before, which it shouldn't have) Settings.Default.Reload(); Settings.Default.AdvancedSimulate = Settings.Default.AdvancedSimulate; } catch (Exception ex) { if (ex is FileNotFoundException) Console.WriteLine(@"Settings file not found, creating new one."); else if (ex is not OperationCanceledException) Console.WriteLine(@"Failed to load settings from the config file: " + ex); File.Delete(ConfigFileFullname); Settings.Default.Reload(); } // Ensure the user ID is valid if (Settings.Default.MiscUserId == 0) Settings.Default.MiscUserId = GetUniqueUserId(); if (IsAfterUpgrade) ClearCaches(false); } /// /// Get an ID that is unlikely to be duplicate but that should always return the same on current pc /// private static ulong GetUniqueUserId() { var windowsIdentity = WindowsIdentity.GetCurrent(); string networkIdentity; try { var networkInterfaces = NetworkInterface.GetAllNetworkInterfaces(); networkIdentity = string.Join("", networkInterfaces.Select(x => x.GetPhysicalAddress().ToString())); } catch (Exception e) { Console.WriteLine(e); networkIdentity = e.ToString(); } var idStr = windowsIdentity.User?.Value + string.Join("", windowsIdentity.Claims.Select(x => x.Value)) + networkIdentity; return UninstallerRatingManager.Utils.StableHash(idStr); } /// /// Check if this application is installed by looking for the registry key created by the installer. /// If the key is not found it means this is most likely a portable version. /// private static void GetInstalledRegKey() { // This GUID is the AppID from the installer. It can end with an optional identifier if the installer had to create a new key because of a conflict. const string appId = "f4fef76c-1aa9-441c-af7e-d27f58d898d1"; const string regUninstallersKeyDirect = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"; try { using var regKey = Registry.LocalMachine.OpenSubKey(regUninstallersKeyDirect); if (regKey == null) throw new ArgumentException("Could not open Software registry key"); var keyNames = regKey.GetSubKeyNames().Where(x => x.Contains(appId, StringComparison.InvariantCultureIgnoreCase)); foreach (var keyName in keyNames) { using var subKey = regKey.OpenSubKey(keyName, true); var installLocation = subKey?.GetStringSafe(RegistryFactory.RegistryNameInstallLocation); if (string.IsNullOrEmpty(installLocation)) continue; if (PathTools.SubPathIsInsideBasePath(installLocation, AssemblyLocation.FullName, true, true)) { // We are installed! _installedRegistryKeyName = keyName; // Update the version number in case it changed, so the user can see it in the list of installed programs subKey.SetValue("DisplayVersion", AssemblyVersion.ToString(), RegistryValueKind.String); } } } catch { _installedRegistryKeyName = String.Empty; } } public static void StartLogCleaner() { try { const string cleanerName = "CleanLogs.bat"; var cleanerPath = Path.Combine(AssemblyLocation.FullName, cleanerName); if (!File.Exists(cleanerPath)) { Console.WriteLine(@"WARNING: CleanLogs.bat doesn't exist, can't clean logs."); return; } var cleanerUri = PathToUri(cleanerPath); if (cleanerUri.IsUnc) { // 'cmd.exe /c start' doesn't work with UNC paths, script has to run in foreground. Process.Start(new ProcessStartInfo(cleanerPath) { UseShellExecute = true }); } else { // Run cleanup script in minimized cmd window var ps = new ProcessStartInfo { WorkingDirectory = AssemblyLocation.FullName, FileName = "cmd.exe", Arguments = "/c start /min " + cleanerName, UseShellExecute = true, WindowStyle = ProcessWindowStyle.Minimized }; Process.Start(ps); } } catch (Exception ex) { // Ignore errors, not critical Console.WriteLine(ex); } } private static Uri PathToUri(string filePath) { try { return new Uri(filePath); } catch (UriFormatException) { filePath = Path.GetFullPath(filePath); return new Uri(filePath); } } public static void ClearCaches(bool showErrors) { try { MainWindow.CertificateCache.ClearChache(); UninstallToolsGlobalConfig.ClearChache(); } catch (SystemException systemException) { if (showErrors) PremadeDialogs.GenericError(systemException); else Console.WriteLine(systemException); } } public static HttpClient HomeServerClient { get { var cl = new HttpClient(); cl.BaseAddress = ConnectionString; return cl; } } } } ================================================ FILE: source/BulkCrapUninstaller/Properties/Localisable.Designer.cs ================================================ //------------------------------------------------------------------------------ // // This code was generated by a tool. // Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ namespace BulkCrapUninstaller.Properties { using System; /// /// A strongly-typed resource class, for looking up localized strings, etc. /// // This class was auto-generated by the StronglyTypedResourceBuilder // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Localisable { private static global::System.Resources.ResourceManager resourceMan; private static global::System.Globalization.CultureInfo resourceCulture; [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] internal Localisable() { } /// /// Returns the cached ResourceManager instance used by this class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("BulkCrapUninstaller.Properties.Localisable", typeof(Localisable).Assembly); resourceMan = temp; } return resourceMan; } } /// /// Overrides the current thread's CurrentUICulture property for all /// resource lookups using this strongly typed resource class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Globalization.CultureInfo Culture { get { return resourceCulture; } set { resourceCulture = value; } } /// /// Looks up a localized string similar to Default. /// internal static string DefaultLanguage { get { return ResourceManager.GetString("DefaultLanguage", resourceCulture); } } /// /// Looks up a localized string similar to Empty. /// internal static string Empty { get { return ResourceManager.GetString("Empty", resourceCulture); } } /// /// Looks up a localized string similar to File not found.. /// internal static string Error_FileNotFound { get { return ResourceManager.GetString("Error_FileNotFound", resourceCulture); } } /// /// Looks up a localized string similar to Failed to save settings. /// internal static string Error_SaveSettingsFailed { get { return ResourceManager.GetString("Error_SaveSettingsFailed", resourceCulture); } } /// /// Looks up a localized string similar to Select the directory with the applications to uninstall.. /// internal static string FileTargeter_SelectDirectoryWithAppsToRemove { get { return ResourceManager.GetString("FileTargeter_SelectDirectoryWithAppsToRemove", resourceCulture); } } /// /// Looks up a localized string similar to GUID found. /// internal static string GuidFound { get { return ResourceManager.GetString("GuidFound", resourceCulture); } } /// /// Looks up a localized string similar to GUID missing. /// internal static string GuidMissing { get { return ResourceManager.GetString("GuidMissing", resourceCulture); } } /// /// Looks up a localized string similar to Rating: {0} /// ///Positives: ///{1} /// ///Negatives: ///{2}. /// internal static string JunkRemove_Details_Message { get { return ResourceManager.GetString("JunkRemove_Details_Message", resourceCulture); } } /// /// Looks up a localized string similar to Rating details. /// internal static string JunkRemove_Details_Title { get { return ResourceManager.GetString("JunkRemove_Details_Title", resourceCulture); } } /// /// Looks up a localized string similar to Select down to.... /// internal static string JunkRemove_SelectionBoxText { get { return ResourceManager.GetString("JunkRemove_SelectionBoxText", resourceCulture); } } /// /// Looks up a localized string similar to Select where to save the backup. A new directory will be created.. /// internal static string JunkRemoveWindow_SelectBackupDirectoryTitle { get { return ResourceManager.GetString("JunkRemoveWindow_SelectBackupDirectoryTitle", resourceCulture); } } /// /// Looks up a localized string similar to Creating a restore point.... /// internal static string LoadingDialogTitleCreatingRestorePoint { get { return ResourceManager.GetString("LoadingDialogTitleCreatingRestorePoint", resourceCulture); } } /// /// Looks up a localized string similar to Loading Windows Features.... /// internal static string LoadingDialogTitleLoadingWindowsFeatures { get { return ResourceManager.GetString("LoadingDialogTitleLoadingWindowsFeatures", resourceCulture); } } /// /// Looks up a localized string similar to Searching for leftovers.... /// internal static string LoadingDialogTitleLookingForJunk { get { return ResourceManager.GetString("LoadingDialogTitleLookingForJunk", resourceCulture); } } /// /// Looks up a localized string similar to Populating uninstaller list.... /// internal static string LoadingDialogTitlePopulatingList { get { return ResourceManager.GetString("LoadingDialogTitlePopulatingList", resourceCulture); } } /// /// Looks up a localized string similar to Running post-uninstall commands.... /// internal static string LoadingDialogTitlePostUninstallCommands { get { return ResourceManager.GetString("LoadingDialogTitlePostUninstallCommands", resourceCulture); } } /// /// Looks up a localized string similar to Running pre-uninstall commands.... /// internal static string LoadingDialogTitlePreUninstallCommands { get { return ResourceManager.GetString("LoadingDialogTitlePreUninstallCommands", resourceCulture); } } /// /// Looks up a localized string similar to Removing leftovers.... /// internal static string LoadingDialogTitleRemovingJunk { get { return ResourceManager.GetString("LoadingDialogTitleRemovingJunk", resourceCulture); } } /// /// Looks up a localized string similar to Searching for updates.... /// internal static string LoadingDialogTitleSearchingForUpdates { get { return ResourceManager.GetString("LoadingDialogTitleSearchingForUpdates", resourceCulture); } } /// /// Looks up a localized string similar to Archived. /// internal static string LocalizedX509Certificate2_Archived { get { return ResourceManager.GetString("LocalizedX509Certificate2_Archived", resourceCulture); } } /// /// Looks up a localized string similar to Extensions. /// internal static string LocalizedX509Certificate2_Extensions { get { return ResourceManager.GetString("LocalizedX509Certificate2_Extensions", resourceCulture); } } /// /// Looks up a localized string similar to Friendly Name. /// internal static string LocalizedX509Certificate2_FriendlyName { get { return ResourceManager.GetString("LocalizedX509Certificate2_FriendlyName", resourceCulture); } } /// /// Looks up a localized string similar to Has Private Key. /// internal static string LocalizedX509Certificate2_HasPrivateKey { get { return ResourceManager.GetString("LocalizedX509Certificate2_HasPrivateKey", resourceCulture); } } /// /// Looks up a localized string similar to Issuer. /// internal static string LocalizedX509Certificate2_Issuer { get { return ResourceManager.GetString("LocalizedX509Certificate2_Issuer", resourceCulture); } } /// /// Looks up a localized string similar to Issuer Name. /// internal static string LocalizedX509Certificate2_IssuerName { get { return ResourceManager.GetString("LocalizedX509Certificate2_IssuerName", resourceCulture); } } /// /// Looks up a localized string similar to Not After. /// internal static string LocalizedX509Certificate2_NotAfter { get { return ResourceManager.GetString("LocalizedX509Certificate2_NotAfter", resourceCulture); } } /// /// Looks up a localized string similar to Not Before. /// internal static string LocalizedX509Certificate2_NotBefore { get { return ResourceManager.GetString("LocalizedX509Certificate2_NotBefore", resourceCulture); } } /// /// Looks up a localized string similar to Private Key. /// internal static string LocalizedX509Certificate2_PrivateKey { get { return ResourceManager.GetString("LocalizedX509Certificate2_PrivateKey", resourceCulture); } } /// /// Looks up a localized string similar to Public Key. /// internal static string LocalizedX509Certificate2_PublicKey { get { return ResourceManager.GetString("LocalizedX509Certificate2_PublicKey", resourceCulture); } } /// /// Looks up a localized string similar to Raw Data. /// internal static string LocalizedX509Certificate2_RawData { get { return ResourceManager.GetString("LocalizedX509Certificate2_RawData", resourceCulture); } } /// /// Looks up a localized string similar to Serial Number. /// internal static string LocalizedX509Certificate2_SerialNumber { get { return ResourceManager.GetString("LocalizedX509Certificate2_SerialNumber", resourceCulture); } } /// /// Looks up a localized string similar to Signature Algorithm. /// internal static string LocalizedX509Certificate2_SignatureAlgorithm { get { return ResourceManager.GetString("LocalizedX509Certificate2_SignatureAlgorithm", resourceCulture); } } /// /// Looks up a localized string similar to Subject. /// internal static string LocalizedX509Certificate2_Subject { get { return ResourceManager.GetString("LocalizedX509Certificate2_Subject", resourceCulture); } } /// /// Looks up a localized string similar to Subject Name. /// internal static string LocalizedX509Certificate2_SubjectName { get { return ResourceManager.GetString("LocalizedX509Certificate2_SubjectName", resourceCulture); } } /// /// Looks up a localized string similar to Thumbprint. /// internal static string LocalizedX509Certificate2_Thumbprint { get { return ResourceManager.GetString("LocalizedX509Certificate2_Thumbprint", resourceCulture); } } /// /// Looks up a localized string similar to Version. /// internal static string LocalizedX509Certificate2_Version { get { return ResourceManager.GetString("LocalizedX509Certificate2_Version", resourceCulture); } } /// /// Looks up a localized string similar to Renaming "{0}". /// internal static string MainWindow_Rename_Description { get { return ResourceManager.GetString("MainWindow_Rename_Description", resourceCulture); } } /// /// Looks up a localized string similar to Rename selected entry. /// internal static string MainWindow_Rename_Title { get { return ResourceManager.GetString("MainWindow_Rename_Title", resourceCulture); } } /// /// Looks up a localized string similar to Processing detected applications, {0} left.... /// internal static string MainWindow_Statusbar_ProcessingUninstallers { get { return ResourceManager.GetString("MainWindow_Statusbar_ProcessingUninstallers", resourceCulture); } } /// /// Looks up a localized string similar to Refreshing startup information.... /// internal static string MainWindow_Statusbar_RefreshingStartup { get { return ResourceManager.GetString("MainWindow_Statusbar_RefreshingStartup", resourceCulture); } } /// /// Looks up a localized string similar to Ready. /// internal static string MainWindow_Statusbar_StatusReady { get { return ResourceManager.GetString("MainWindow_Statusbar_StatusReady", resourceCulture); } } /// /// Looks up a localized string similar to {0} uninstallers selected. /// internal static string MainWindow_Statusbar_StatusSelection { get { return ResourceManager.GetString("MainWindow_Statusbar_StatusSelection", resourceCulture); } } /// /// Looks up a localized string similar to {0} uninstallers in total, {1}. /// internal static string MainWindow_Statusbar_Total { get { return ResourceManager.GetString("MainWindow_Statusbar_Total", resourceCulture); } } /// /// Looks up a localized string similar to Following uninstallers will be restarted loudly:. /// internal static string MessageBoxes_AskToRetryFailedQuietAsLoud_Details { get { return ResourceManager.GetString("MessageBoxes_AskToRetryFailedQuietAsLoud_Details", resourceCulture); } } /// /// Looks up a localized string similar to Do you want to try running quiet uninstallers that failed as loud?. /// internal static string MessageBoxes_AskToRetryFailedQuietAsLoud_Header { get { return ResourceManager.GetString("MessageBoxes_AskToRetryFailedQuietAsLoud_Header", resourceCulture); } } /// /// Looks up a localized string similar to Some uninstallers failed. /// internal static string MessageBoxes_AskToRetryFailedQuietAsLoud_Title { get { return ResourceManager.GetString("MessageBoxes_AskToRetryFailedQuietAsLoud_Title", resourceCulture); } } /// /// Looks up a localized string similar to There are unsaved changes in the opened uninstall list that will be lost by closing it.. /// internal static string MessageBoxes_AskToSaveUninstallList_Details { get { return ResourceManager.GetString("MessageBoxes_AskToSaveUninstallList_Details", resourceCulture); } } /// /// Looks up a localized string similar to Save changes to the opened uninstall list?. /// internal static string MessageBoxes_AskToSaveUninstallList_Message { get { return ResourceManager.GetString("MessageBoxes_AskToSaveUninstallList_Message", resourceCulture); } } /// /// Looks up a localized string similar to Save uninstall list. /// internal static string MessageBoxes_AskToSaveUninstallList_Title { get { return ResourceManager.GetString("MessageBoxes_AskToSaveUninstallList_Title", resourceCulture); } } /// /// Looks up a localized string similar to This will take you less than a minute but help the development greatly! All feedback is appreciated, be it a bug report, feature request or a simple thanks! /// ///You can send it later from the top menu bar (Help->Submit feedback).. /// internal static string MessageBoxes_AskToSubmitFeedback_Details { get { return ResourceManager.GetString("MessageBoxes_AskToSubmitFeedback_Details", resourceCulture); } } /// /// Looks up a localized string similar to Would you like to send feedback concerning BCU?. /// internal static string MessageBoxes_AskToSubmitFeedback_Message { get { return ResourceManager.GetString("MessageBoxes_AskToSubmitFeedback_Message", resourceCulture); } } /// /// Looks up a localized string similar to Error details: . /// internal static string MessageBoxes_BackupFailedQuestion_Details { get { return ResourceManager.GetString("MessageBoxes_BackupFailedQuestion_Details", resourceCulture); } } /// /// Looks up a localized string similar to Registry backup failed, do you want to continue anyway?. /// internal static string MessageBoxes_BackupFailedQuestion_Message { get { return ResourceManager.GetString("MessageBoxes_BackupFailedQuestion_Message", resourceCulture); } } /// /// Looks up a localized string similar to You will be able to roll back all changes by double-clicking it afterwards. /// ///Files and directories will be moved to the recycle bin, you can restore them from there.. /// internal static string MessageBoxes_BackupRegistryQuestion_Details { get { return ResourceManager.GetString("MessageBoxes_BackupRegistryQuestion_Details", resourceCulture); } } /// /// Looks up a localized string similar to Do you want to create a registry backup before continuing?. /// internal static string MessageBoxes_BackupRegistryQuestion_Message { get { return ResourceManager.GetString("MessageBoxes_BackupRegistryQuestion_Message", resourceCulture); } } /// /// Looks up a localized string similar to Select exactly one uninstaller from the list. If you are using check-boxes make sure to check them.. /// internal static string MessageBoxes_CanSelectOnlyOneItemInfo_Details { get { return ResourceManager.GetString("MessageBoxes_CanSelectOnlyOneItemInfo_Details", resourceCulture); } } /// /// Looks up a localized string similar to You need to select only one entry for this action. /// internal static string MessageBoxes_CanSelectOnlyOneItemInfo_Message { get { return ResourceManager.GetString("MessageBoxes_CanSelectOnlyOneItemInfo_Message", resourceCulture); } } /// /// Looks up a localized string similar to Action failed. /// internal static string MessageBoxes_CanSelectOnlyOneItemInfo_Title { get { return ResourceManager.GetString("MessageBoxes_CanSelectOnlyOneItemInfo_Title", resourceCulture); } } /// /// Looks up a localized string similar to This uninstaller kind does not support renaming ({0}).. /// internal static string MessageBoxes_CantRenameUninstallerKind_Details { get { return ResourceManager.GetString("MessageBoxes_CantRenameUninstallerKind_Details", resourceCulture); } } /// /// Looks up a localized string similar to Cannot rename {0}. /// internal static string MessageBoxes_CantRenameUninstallerKind_Title { get { return ResourceManager.GetString("MessageBoxes_CantRenameUninstallerKind_Title", resourceCulture); } } /// /// Looks up a localized string similar to Remaining uninstallers should be able to complete without any user intervention. You should still check in from time to time in case one of the uninstallers crashes.. /// internal static string MessageBoxes_CanWalkAwayInfo_Details { get { return ResourceManager.GetString("MessageBoxes_CanWalkAwayInfo_Details", resourceCulture); } } /// /// Looks up a localized string similar to You can now leave the computer. /// internal static string MessageBoxes_CanWalkAwayInfo_Message { get { return ResourceManager.GetString("MessageBoxes_CanWalkAwayInfo_Message", resourceCulture); } } /// /// Looks up a localized string similar to Uninstall progress. /// internal static string MessageBoxes_CanWalkAwayInfo_Title { get { return ResourceManager.GetString("MessageBoxes_CanWalkAwayInfo_Title", resourceCulture); } } /// /// Looks up a localized string similar to Removing items marked with confidence lower than Good can be very dangerous! It is recommended that you verify that every single item is safe to delete.. /// internal static string MessageBoxes_ConfirmLowConfidenceQuestion_Details { get { return ResourceManager.GetString("MessageBoxes_ConfirmLowConfidenceQuestion_Details", resourceCulture); } } /// /// Looks up a localized string similar to Do you really want to modify low-confidence items?. /// internal static string MessageBoxes_ConfirmLowConfidenceQuestion_Message { get { return ResourceManager.GetString("MessageBoxes_ConfirmLowConfidenceQuestion_Message", resourceCulture); } } /// /// Looks up a localized string similar to Following items will be removed from registry and will disappear from the uninstaller list, but will not be uninstalled. /// ///{0}. /// internal static string MessageBoxes_DeleteRegKeysConfirmation_Details { get { return ResourceManager.GetString("MessageBoxes_DeleteRegKeysConfirmation_Details", resourceCulture); } } /// /// Looks up a localized string similar to Are you sure you want to remove selected uninstaller entries?. /// internal static string MessageBoxes_DeleteRegKeysConfirmation_Message { get { return ResourceManager.GetString("MessageBoxes_DeleteRegKeysConfirmation_Message", resourceCulture); } } /// /// Looks up a localized string similar to Remove keys from registry. /// internal static string MessageBoxes_DeleteRegKeysConfirmation_Title { get { return ResourceManager.GetString("MessageBoxes_DeleteRegKeysConfirmation_Title", resourceCulture); } } /// /// Looks up a localized string similar to /// ///Error details: ///. /// internal static string MessageBoxes_Error_details { get { return ResourceManager.GetString("MessageBoxes_Error_details", resourceCulture); } } /// /// Looks up a localized string similar to If the error persists try saving to a different directory, for example to the desktop.. /// internal static string MessageBoxes_ExportFailed_Details { get { return ResourceManager.GetString("MessageBoxes_ExportFailed_Details", resourceCulture); } } /// /// Looks up a localized string similar to An error has been encountered while saving exported data. /// internal static string MessageBoxes_ExportFailed_Message { get { return ResourceManager.GetString("MessageBoxes_ExportFailed_Message", resourceCulture); } } /// /// Looks up a localized string similar to Export failed. /// internal static string MessageBoxes_ExportFailed_Title { get { return ResourceManager.GetString("MessageBoxes_ExportFailed_Title", resourceCulture); } } /// /// Looks up a localized string similar to Following command failed to execute: ///{0}. /// internal static string MessageBoxes_ExternalCommandFailed_Message { get { return ResourceManager.GetString("MessageBoxes_ExternalCommandFailed_Message", resourceCulture); } } /// /// Looks up a localized string similar to External execute failed. /// internal static string MessageBoxes_ExternalCommandFailed_Title { get { return ResourceManager.GetString("MessageBoxes_ExternalCommandFailed_Title", resourceCulture); } } /// /// Looks up a localized string similar to Failed to run some of the uninstallers. /// internal static string MessageBoxes_ForceRunUninstallFailedError_Header { get { return ResourceManager.GetString("MessageBoxes_ForceRunUninstallFailedError_Header", resourceCulture); } } /// /// Looks up a localized string similar to Following uninstallers failed to execute, likely because of a collision. Please wait for other uninstallers to finish and try again. ///{0} /// ///You can try disabling collision detection in the settings, but it is not recommended.. /// internal static string MessageBoxes_ForceRunUninstallFailedError_Message { get { return ResourceManager.GetString("MessageBoxes_ForceRunUninstallFailedError_Message", resourceCulture); } } /// /// Looks up a localized string similar to Force uninstallation. /// internal static string MessageBoxes_ForceRunUninstallFailedError_Title { get { return ResourceManager.GetString("MessageBoxes_ForceRunUninstallFailedError_Title", resourceCulture); } } /// /// Looks up a localized string similar to BCUninstaller is uninstalling {0} application(s). /// internal static string MessageBoxes_GetSystemRestoreDescription { get { return ResourceManager.GetString("MessageBoxes_GetSystemRestoreDescription", resourceCulture); } } /// /// Looks up a localized string similar to Make sure you have not included any of the following characters: ///{0}. /// internal static string MessageBoxes_InvalidNewEntryName_Details { get { return ResourceManager.GetString("MessageBoxes_InvalidNewEntryName_Details", resourceCulture); } } /// /// Looks up a localized string similar to Supplied name is empty or contains invalid characters. /// internal static string MessageBoxes_InvalidNewEntryName_Message { get { return ResourceManager.GetString("MessageBoxes_InvalidNewEntryName_Message", resourceCulture); } } /// /// Looks up a localized string similar to Please note that this feature is intended only for power users that understand how it works. It is not necessary to remove these files and they will not affect system performance in any meaningful way.. /// internal static string MessageBoxes_LookForJunkQuestion_Details { get { return ResourceManager.GetString("MessageBoxes_LookForJunkQuestion_Details", resourceCulture); } } /// /// Looks up a localized string similar to Do you want to look for leftovers from performed uninstallation(s)?. /// internal static string MessageBoxes_LookForJunkQuestion_Message { get { return ResourceManager.GetString("MessageBoxes_LookForJunkQuestion_Message", resourceCulture); } } /// /// Looks up a localized string similar to The selected application has no modify command specified. It might be necessary to uninstall, and then install it again to change install settings.. /// internal static string MessageBoxes_ModifyCommandMissing_Details { get { return ResourceManager.GetString("MessageBoxes_ModifyCommandMissing_Details", resourceCulture); } } /// /// Looks up a localized string similar to Selected application can't be modified. /// internal static string MessageBoxes_ModifyCommandMissing_Message { get { return ResourceManager.GetString("MessageBoxes_ModifyCommandMissing_Message", resourceCulture); } } /// /// Looks up a localized string similar to Modify application. /// internal static string MessageBoxes_ModifyCommandMissing_Title { get { return ResourceManager.GetString("MessageBoxes_ModifyCommandMissing_Title", resourceCulture); } } /// /// Looks up a localized string similar to The v4.0 framework is optional, but recommended. The features that rely on the framework will be disabled until you install it.. /// internal static string MessageBoxes_Net4Missing_Details { get { return ResourceManager.GetString("MessageBoxes_Net4Missing_Details", resourceCulture); } } /// /// Looks up a localized string similar to .NET Framework v4.0 was not found, some features will be disabled. /// internal static string MessageBoxes_Net4Missing_Message { get { return ResourceManager.GetString("MessageBoxes_Net4Missing_Message", resourceCulture); } } /// /// Looks up a localized string similar to .NET Framework v4.0 not found. /// internal static string MessageBoxes_Net4Missing_Title { get { return ResourceManager.GetString("MessageBoxes_Net4Missing_Title", resourceCulture); } } /// /// Looks up a localized string similar to No leftovers were found. There still might be some residue left so you can run a temporary file cleaner like BleachBit.. /// internal static string MessageBoxes_NoJunkFoundInfo_Details { get { return ResourceManager.GetString("MessageBoxes_NoJunkFoundInfo_Details", resourceCulture); } } /// /// Looks up a localized string similar to No leftovers were found. /// internal static string MessageBoxes_NoJunkFoundInfo_Message { get { return ResourceManager.GetString("MessageBoxes_NoJunkFoundInfo_Message", resourceCulture); } } /// /// Looks up a localized string similar to Make sure that your network cable is plugged in. If you are using Wi-Fi ensure that you have good signal strength.. /// internal static string MessageBoxes_NoNetworkConnected_Details { get { return ResourceManager.GetString("MessageBoxes_NoNetworkConnected_Details", resourceCulture); } } /// /// Looks up a localized string similar to Can't connect to the internet, there are no networks available.. /// internal static string MessageBoxes_NoNetworkConnected_Message { get { return ResourceManager.GetString("MessageBoxes_NoNetworkConnected_Message", resourceCulture); } } /// /// Looks up a localized string similar to Open on-line content. /// internal static string MessageBoxes_NoNetworkConnected_Open_online_content { get { return ResourceManager.GetString("MessageBoxes_NoNetworkConnected_Open_online_content", resourceCulture); } } /// /// Looks up a localized string similar to There was nothing to copy to the clipboard. Either no selected uninstaller has this bit of information or you didn't select anything.. /// internal static string MessageBoxes_NothingToCopy_Message { get { return ResourceManager.GetString("MessageBoxes_NothingToCopy_Message", resourceCulture); } } /// /// Looks up a localized string similar to To uninstall applications you must first select them from the list view. If you are using check-boxes, make sure that they are checked.. /// internal static string MessageBoxes_NoUninstallersSelectedInfo_Details { get { return ResourceManager.GetString("MessageBoxes_NoUninstallersSelectedInfo_Details", resourceCulture); } } /// /// Looks up a localized string similar to No uninstallers were selected, nothing to uninstall. /// internal static string MessageBoxes_NoUninstallersSelectedInfo_Message { get { return ResourceManager.GetString("MessageBoxes_NoUninstallersSelectedInfo_Message", resourceCulture); } } /// /// Looks up a localized string similar to Run uninstallers. /// internal static string MessageBoxes_NoUninstallersSelectedInfo_Title { get { return ResourceManager.GetString("MessageBoxes_NoUninstallersSelectedInfo_Title", resourceCulture); } } /// /// Looks up a localized string similar to No directories to open. /// internal static string MessageBoxes_OpenDirectories_NoDirsToOpen { get { return ResourceManager.GetString("MessageBoxes_OpenDirectories_NoDirsToOpen", resourceCulture); } } /// /// Looks up a localized string similar to This action will open {0} directories at once, are you sure you want to continue?. /// internal static string MessageBoxes_OpenDirectoriesMessageBox_OpenMultiple { get { return ResourceManager.GetString("MessageBoxes_OpenDirectoriesMessageBox_OpenMultiple", resourceCulture); } } /// /// Looks up a localized string similar to An error has been encountered while opening the directory. /// internal static string MessageBoxes_OpenDirectoryError_Message { get { return ResourceManager.GetString("MessageBoxes_OpenDirectoryError_Message", resourceCulture); } } /// /// Looks up a localized string similar to Failed to load selected files. /// internal static string MessageBoxes_OpenUninstallListError_Message { get { return ResourceManager.GetString("MessageBoxes_OpenUninstallListError_Message", resourceCulture); } } /// /// Looks up a localized string similar to If you choose to keep current selection it will be merged with the opened list(s). /// internal static string MessageBoxes_OpenUninstallListQuestion_Details { get { return ResourceManager.GetString("MessageBoxes_OpenUninstallListQuestion_Details", resourceCulture); } } /// /// Looks up a localized string similar to Do you want to keep current selection?. /// internal static string MessageBoxes_OpenUninstallListQuestion_Message { get { return ResourceManager.GetString("MessageBoxes_OpenUninstallListQuestion_Message", resourceCulture); } } /// /// Looks up a localized string similar to An error has been encountered while opening the URL. /// internal static string MessageBoxes_OpenUrlError_Message { get { return ResourceManager.GetString("MessageBoxes_OpenUrlError_Message", resourceCulture); } } /// /// Looks up a localized string similar to No URLs to open. /// internal static string MessageBoxes_OpenUrlsMessageBox_No_URLs_to_open_Title { get { return ResourceManager.GetString("MessageBoxes_OpenUrlsMessageBox_No_URLs_to_open_Title", resourceCulture); } } /// /// Looks up a localized string similar to This action will open {0} URLs at once, are you sure you want to continue?. /// internal static string MessageBoxes_OpenUrlsMessageBox_OpenMultiple_Message { get { return ResourceManager.GetString("MessageBoxes_OpenUrlsMessageBox_OpenMultiple_Message", resourceCulture); } } /// /// Looks up a localized string similar to Protected entry: {0} /// ///To modify this entry you need to disable uninstaller protection from the settings panel.. /// internal static string MessageBoxes_ProtectedItemError_Details { get { return ResourceManager.GetString("MessageBoxes_ProtectedItemError_Details", resourceCulture); } } /// /// Looks up a localized string similar to Selected entry is protected and can not be modified. /// internal static string MessageBoxes_ProtectedItemError_Message { get { return ResourceManager.GetString("MessageBoxes_ProtectedItemError_Message", resourceCulture); } } /// /// Looks up a localized string similar to Affected entries: ///{0} /// ///To modify these entries you need to disable uninstaller protection from the settings sidebar.You can remove them from the task and continue with other items if you want.. /// internal static string MessageBoxes_ProtectedItemsWarningQuestion_Details { get { return ResourceManager.GetString("MessageBoxes_ProtectedItemsWarningQuestion_Details", resourceCulture); } } /// /// Looks up a localized string similar to Some entries are protected and can not be modified. /// internal static string MessageBoxes_ProtectedItemsWarningQuestion_Message { get { return ResourceManager.GetString("MessageBoxes_ProtectedItemsWarningQuestion_Message", resourceCulture); } } /// /// Looks up a localized string similar to Following items are missing quiet uninstallers: ///{0} /// ///Do you want to use "loud" uninstallers for those items, or should they be removed them from the task?. /// internal static string MessageBoxes_QuietUninstallersNotAvailableQuestion_Details { get { return ResourceManager.GetString("MessageBoxes_QuietUninstallersNotAvailableQuestion_Details", resourceCulture); } } /// /// Looks up a localized string similar to Some applications can't be uninstalled quietly. /// internal static string MessageBoxes_QuietUninstallersNotAvailableQuestion_Message { get { return ResourceManager.GetString("MessageBoxes_QuietUninstallersNotAvailableQuestion_Message", resourceCulture); } } /// /// Looks up a localized string similar to Ratings not available. /// internal static string MessageBoxes_RatingErrorTitle { get { return ResourceManager.GetString("MessageBoxes_RatingErrorTitle", resourceCulture); } } /// /// Looks up a localized string similar to You have to enable ratings from the settings first.. /// internal static string MessageBoxes_RatingsDisabled_Message { get { return ResourceManager.GetString("MessageBoxes_RatingsDisabled_Message", resourceCulture); } } /// /// Looks up a localized string similar to You can't rate applications that are not installed properly.. /// internal static string MessageBoxes_RatingUnavailable_Message { get { return ResourceManager.GetString("MessageBoxes_RatingUnavailable_Message", resourceCulture); } } /// /// Looks up a localized string similar to Remember choice. /// internal static string MessageBoxes_RememberChoiceCheckbox { get { return ResourceManager.GetString("MessageBoxes_RememberChoiceCheckbox", resourceCulture); } } /// /// Looks up a localized string similar to All of your settings will be lost permanently. BCUninstaller will have to restart to complete this action.. /// internal static string MessageBoxes_ResetSettingsConfirmation_Details { get { return ResourceManager.GetString("MessageBoxes_ResetSettingsConfirmation_Details", resourceCulture); } } /// /// Looks up a localized string similar to Are you sure you want to reset all application settings?. /// internal static string MessageBoxes_ResetSettingsConfirmation_Message { get { return ResourceManager.GetString("MessageBoxes_ResetSettingsConfirmation_Message", resourceCulture); } } /// /// Looks up a localized string similar to Some settings will not take effect until the application is restarted.. /// internal static string MessageBoxes_RestartNeededForSettingChangeQuestion_Details { get { return ResourceManager.GetString("MessageBoxes_RestartNeededForSettingChangeQuestion_Details", resourceCulture); } } /// /// Looks up a localized string similar to Do you want to restart BCU to apply new settings?. /// internal static string MessageBoxes_RestartNeededForSettingChangeQuestion_Message { get { return ResourceManager.GetString("MessageBoxes_RestartNeededForSettingChangeQuestion_Message", resourceCulture); } } /// /// Looks up a localized string similar to Change application settings. /// internal static string MessageBoxes_RestartNeededForSettingChangeQuestion_Title { get { return ResourceManager.GetString("MessageBoxes_RestartNeededForSettingChangeQuestion_Title", resourceCulture); } } /// /// Looks up a localized string similar to Failed to save the list to a file. /// internal static string MessageBoxes_SaveUninstallListError_Message { get { return ResourceManager.GetString("MessageBoxes_SaveUninstallListError_Message", resourceCulture); } } /// /// Looks up a localized string similar to An error has been encountered while opening the search page. /// internal static string MessageBoxes_SearchOnlineError_Message { get { return ResourceManager.GetString("MessageBoxes_SearchOnlineError_Message", resourceCulture); } } /// /// Looks up a localized string similar to Nothing to search for. /// internal static string MessageBoxes_SearchOnlineMessageBox_NothingToSearchFor_Message { get { return ResourceManager.GetString("MessageBoxes_SearchOnlineMessageBox_NothingToSearchFor_Message", resourceCulture); } } /// /// Looks up a localized string similar to I'm sorry to see you leave! If you have a minute or two please drop a word on why you uninstalled BCU on my website (http://klocmansoftware.weebly.com/). I'll do my best to fix any legitimate problems.. /// internal static string MessageBoxes_SelfUninstallQuestion_Details { get { return ResourceManager.GetString("MessageBoxes_SelfUninstallQuestion_Details", resourceCulture); } } /// /// Looks up a localized string similar to Are you sure you want to uninstall BCUninstaller?. /// internal static string MessageBoxes_SelfUninstallQuestion_Message { get { return ResourceManager.GetString("MessageBoxes_SelfUninstallQuestion_Message", resourceCulture); } } /// /// Looks up a localized string similar to Uninstall BCUninstaller. /// internal static string MessageBoxes_SelfUninstallQuestion_Title { get { return ResourceManager.GetString("MessageBoxes_SelfUninstallQuestion_Title", resourceCulture); } } /// /// Looks up a localized string similar to If you are unsure if applications you are uninstalling are important or required to system stability it is recommended to create a restore point. /// If anything breaks after the procedure you can then use System Restore to roll back the changes.. /// internal static string MessageBoxes_SysRestoreBeginQuestion_Details { get { return ResourceManager.GetString("MessageBoxes_SysRestoreBeginQuestion_Details", resourceCulture); } } /// /// Looks up a localized string similar to Do you want to create a restore point before continuing?. /// internal static string MessageBoxes_SysRestoreBeginQuestion_Message { get { return ResourceManager.GetString("MessageBoxes_SysRestoreBeginQuestion_Message", resourceCulture); } } /// /// Looks up a localized string similar to The restore point WAS NOT CREATED, you will not be able to restore changes! Do you want to continue with the uninstallation anyway?. /// internal static string MessageBoxes_SysRestoreContinueAfterError_Details { get { return ResourceManager.GetString("MessageBoxes_SysRestoreContinueAfterError_Details", resourceCulture); } } /// /// Looks up a localized string similar to Failed to create a new restore point. /// internal static string MessageBoxes_SysRestoreContinueAfterError_Message { get { return ResourceManager.GetString("MessageBoxes_SysRestoreContinueAfterError_Message", resourceCulture); } } /// /// Looks up a localized string similar to Selecting "Terminate" will immediately close the running uninstaller and might result in uninstallation not being completed. Usually it is possible to run the uninstaller again to finish the uninstallation. /// ///Alternatively you can skip waiting for this process. Skipping will let the uninstaller continue working while the task moves on to the next item. Keep in mind that some uninstallers can fail to run until the skipped process finishes.. /// internal static string MessageBoxes_TaskSkip_Details { get { return ResourceManager.GetString("MessageBoxes_TaskSkip_Details", resourceCulture); } } /// /// Looks up a localized string similar to Do you want to skip waiting for the currently running uninstaller?. /// internal static string MessageBoxes_TaskSkip_Message { get { return ResourceManager.GetString("MessageBoxes_TaskSkip_Message", resourceCulture); } } /// /// Looks up a localized string similar to Skip currently running task. /// internal static string MessageBoxes_TaskSkip_Title { get { return ResourceManager.GetString("MessageBoxes_TaskSkip_Title", resourceCulture); } } /// /// Looks up a localized string similar to Stopping the task prematurely will not revert any changes. Currently running uninstaller won't be stopped, the task will wait for it to finish.. /// internal static string MessageBoxes_TaskStopConfirmation_Details { get { return ResourceManager.GetString("MessageBoxes_TaskStopConfirmation_Details", resourceCulture); } } /// /// Looks up a localized string similar to Are you sure you want to stop currently running task?. /// internal static string MessageBoxes_TaskStopConfirmation_Message { get { return ResourceManager.GetString("MessageBoxes_TaskStopConfirmation_Message", resourceCulture); } } /// /// Looks up a localized string similar to Stop current uninstall task. /// internal static string MessageBoxes_TaskStopConfirmation_Title { get { return ResourceManager.GetString("MessageBoxes_TaskStopConfirmation_Title", resourceCulture); } } /// /// Looks up a localized string similar to Copy to clipboard. /// internal static string MessageBoxes_Title_Copy_to_clipboard { get { return ResourceManager.GetString("MessageBoxes_Title_Copy_to_clipboard", resourceCulture); } } /// /// Looks up a localized string similar to Create restore point. /// internal static string MessageBoxes_Title_Create_restore_point { get { return ResourceManager.GetString("MessageBoxes_Title_Create_restore_point", resourceCulture); } } /// /// Looks up a localized string similar to Junk/Leftover removal. /// internal static string MessageBoxes_Title_Junk_Leftover_removal { get { return ResourceManager.GetString("MessageBoxes_Title_Junk_Leftover_removal", resourceCulture); } } /// /// Looks up a localized string similar to Leftover removal. /// internal static string MessageBoxes_Title_Leftover_removal { get { return ResourceManager.GetString("MessageBoxes_Title_Leftover_removal", resourceCulture); } } /// /// Looks up a localized string similar to Modify protected item. /// internal static string MessageBoxes_Title_Modify_protected_items { get { return ResourceManager.GetString("MessageBoxes_Title_Modify_protected_items", resourceCulture); } } /// /// Looks up a localized string similar to Open directories. /// internal static string MessageBoxes_Title_Open_directories { get { return ResourceManager.GetString("MessageBoxes_Title_Open_directories", resourceCulture); } } /// /// Looks up a localized string similar to Open Uninstall List. /// internal static string MessageBoxes_Title_Open_Uninstall_List { get { return ResourceManager.GetString("MessageBoxes_Title_Open_Uninstall_List", resourceCulture); } } /// /// Looks up a localized string similar to Open URLs. /// internal static string MessageBoxes_Title_Open_urls { get { return ResourceManager.GetString("MessageBoxes_Title_Open_urls", resourceCulture); } } /// /// Looks up a localized string similar to Quiet uninstall. /// internal static string MessageBoxes_Title_Quiet_uninstall { get { return ResourceManager.GetString("MessageBoxes_Title_Quiet_uninstall", resourceCulture); } } /// /// Looks up a localized string similar to Rename uninstaller. /// internal static string MessageBoxes_Title_Rename_uninstaller { get { return ResourceManager.GetString("MessageBoxes_Title_Rename_uninstaller", resourceCulture); } } /// /// Looks up a localized string similar to Restore default settings. /// internal static string MessageBoxes_Title_Restore_default_settings { get { return ResourceManager.GetString("MessageBoxes_Title_Restore_default_settings", resourceCulture); } } /// /// Looks up a localized string similar to Save Uninstall List. /// internal static string MessageBoxes_Title_Save_Uninstall_List { get { return ResourceManager.GetString("MessageBoxes_Title_Save_Uninstall_List", resourceCulture); } } /// /// Looks up a localized string similar to Search for updates. /// internal static string MessageBoxes_Title_Search_for_updates { get { return ResourceManager.GetString("MessageBoxes_Title_Search_for_updates", resourceCulture); } } /// /// Looks up a localized string similar to Search on line. /// internal static string MessageBoxes_Title_Search_online { get { return ResourceManager.GetString("MessageBoxes_Title_Search_online", resourceCulture); } } /// /// Looks up a localized string similar to Submit feedback. /// internal static string MessageBoxes_Title_Submit_feedback { get { return ResourceManager.GetString("MessageBoxes_Title_Submit_feedback", resourceCulture); } } /// /// Looks up a localized string similar to Another uninstall task is already running. Please wait for it to finish and then try again.. /// internal static string MessageBoxes_UninstallAlreadyRunning_Message { get { return ResourceManager.GetString("MessageBoxes_UninstallAlreadyRunning_Message", resourceCulture); } } /// /// Looks up a localized string similar to Uninstall from directory. /// internal static string MessageBoxes_UninstallFromDirectory_Title { get { return ResourceManager.GetString("MessageBoxes_UninstallFromDirectory_Title", resourceCulture); } } /// /// Looks up a localized string similar to Make sure that you selected the correct directory and that the application's executables are still present.. /// internal static string MessageBoxes_UninstallFromDirectoryNothingFound_Details { get { return ResourceManager.GetString("MessageBoxes_UninstallFromDirectoryNothingFound_Details", resourceCulture); } } /// /// Looks up a localized string similar to No applications were found in the specified directory. /// internal static string MessageBoxes_UninstallFromDirectoryNothingFound_Message { get { return ResourceManager.GetString("MessageBoxes_UninstallFromDirectoryNothingFound_Message", resourceCulture); } } /// /// Looks up a localized string similar to Do you want to run this uninstaller?. /// internal static string MessageBoxes_UninstallFromDirectoryUninstallerFound_Details { get { return ResourceManager.GetString("MessageBoxes_UninstallFromDirectoryUninstallerFound_Details", resourceCulture); } } /// /// Looks up a localized string similar to Found an uninstaller for {0}. /// internal static string MessageBoxes_UninstallFromDirectoryUninstallerFound_Message { get { return ResourceManager.GetString("MessageBoxes_UninstallFromDirectoryUninstallerFound_Message", resourceCulture); } } /// /// Looks up a localized string similar to Selected uninstaller doesn't have a valid Guid for use with MsiExec.. /// internal static string MessageBoxes_UninstallMsiGuidMissing_Details { get { return ResourceManager.GetString("MessageBoxes_UninstallMsiGuidMissing_Details", resourceCulture); } } /// /// Looks up a localized string similar to The selected entry can't be uninstalled using the MsiExec installer. /// internal static string MessageBoxes_UninstallMsiGuidMissing_Message { get { return ResourceManager.GetString("MessageBoxes_UninstallMsiGuidMissing_Message", resourceCulture); } } /// /// Looks up a localized string similar to Uninstall using Msi. /// internal static string MessageBoxes_UninstallMsiGuidMissing_Title { get { return ResourceManager.GetString("MessageBoxes_UninstallMsiGuidMissing_Title", resourceCulture); } } /// /// Looks up a localized string similar to BCUninstaller will automatically download the update and apply it after a restart. Please note that you might lose your settings in the process. /// ///Changelog: ///- {0} /// ///Warning: During update the folder "Update" and the file "Update.zip" inside of the BCU directory will be removed.. /// internal static string MessageBoxes_UpdateAskToDownload_Details { get { return ResourceManager.GetString("MessageBoxes_UpdateAskToDownload_Details", resourceCulture); } } /// /// Looks up a localized string similar to New version {0} is available, do you want to upgrade now?. /// internal static string MessageBoxes_UpdateAskToDownload_Message { get { return ResourceManager.GetString("MessageBoxes_UpdateAskToDownload_Message", resourceCulture); } } /// /// Looks up a localized string similar to Make sure that BCUninstaller is not blocked in your firewall and that you have a working internet connection. /// ///. /// internal static string MessageBoxes_UpdateFailed_Details { get { return ResourceManager.GetString("MessageBoxes_UpdateFailed_Details", resourceCulture); } } /// /// Looks up a localized string similar to Encountered an error while checking for updates. /// internal static string MessageBoxes_UpdateFailed_Message { get { return ResourceManager.GetString("MessageBoxes_UpdateFailed_Message", resourceCulture); } } /// /// Looks up a localized string similar to No updates were found at this time, you have the latest version. /// ///Want some functionality added or a bug fixed? Please send me your feedback using "Help->Submit feedback" menu.. /// internal static string MessageBoxes_UpdateUptodate_Details { get { return ResourceManager.GetString("MessageBoxes_UpdateUptodate_Details", resourceCulture); } } /// /// Looks up a localized string similar to Current version is up to date. /// internal static string MessageBoxes_UpdateUptodate_Message { get { return ResourceManager.GetString("MessageBoxes_UpdateUptodate_Message", resourceCulture); } } /// /// Looks up a localized string similar to Welcome to BCU version {0}!. /// internal static string NewsPopup_FirstStartTitle { get { return ResourceManager.GetString("NewsPopup_FirstStartTitle", resourceCulture); } } /// /// Looks up a localized string similar to BCU has been updated to v{0}!. /// internal static string NewsPopup_UpdatedTitle { get { return ResourceManager.GetString("NewsPopup_UpdatedTitle", resourceCulture); } } /// /// Looks up a localized string similar to Not available. /// internal static string NotAvailable { get { return ResourceManager.GetString("NotAvailable", resourceCulture); } } /// /// Looks up a localized string similar to Finishing up.... /// internal static string Progress_Finishing { get { return ResourceManager.GetString("Progress_Finishing", resourceCulture); } } /// /// Looks up a localized string similar to Loading icons. /// internal static string Progress_Finishing_Icons { get { return ResourceManager.GetString("Progress_Finishing_Icons", resourceCulture); } } /// /// Looks up a localized string similar to Error. /// internal static string PropertiesWindow_Table_Error { get { return ResourceManager.GetString("PropertiesWindow_Table_Error", resourceCulture); } } /// /// Looks up a localized string similar to File doesn't exist.. /// internal static string PropertiesWindow_Table_ErrorDoesntExist { get { return ResourceManager.GetString("PropertiesWindow_Table_ErrorDoesntExist", resourceCulture); } } /// /// Looks up a localized string similar to This application does not have a valid registry entry. /// internal static string PropertiesWindow_Table_ErrorMissingRegistry { get { return ResourceManager.GetString("PropertiesWindow_Table_ErrorMissingRegistry", resourceCulture); } } /// /// Looks up a localized string similar to This application does not have a valid uninstaller. /// internal static string PropertiesWindow_Table_ErrorMissingUninstaller { get { return ResourceManager.GetString("PropertiesWindow_Table_ErrorMissingUninstaller", resourceCulture); } } /// /// Looks up a localized string similar to Nothing to display. This application is uninstalled using Windows Installer (MsiExec).. /// internal static string PropertiesWindow_Table_ErrorMsi { get { return ResourceManager.GetString("PropertiesWindow_Table_ErrorMsi", resourceCulture); } } /// /// Looks up a localized string similar to Certificate is missing. /// internal static string PropertiesWindow_Table_ErrorNoCertificate { get { return ResourceManager.GetString("PropertiesWindow_Table_ErrorNoCertificate", resourceCulture); } } /// /// Looks up a localized string similar to Name. /// internal static string PropertiesWindow_Table_Name { get { return ResourceManager.GetString("PropertiesWindow_Table_Name", resourceCulture); } } /// /// Looks up a localized string similar to Value. /// internal static string PropertiesWindow_Table_Value { get { return ResourceManager.GetString("PropertiesWindow_Table_Value", resourceCulture); } } /// /// Looks up a localized string similar to {0} applications. /// internal static string RateTitle_Counted { get { return ResourceManager.GetString("RateTitle_Counted", resourceCulture); } } /// /// Looks up a localized string similar to Average rating: {0}; My rating: {1}. /// internal static string RatingEntry_ToString { get { return ResourceManager.GetString("RatingEntry_ToString", resourceCulture); } } /// /// Looks up a localized string similar to There are no entries matching your search criteria.. /// internal static string SearchNothingFoundMessage { get { return ResourceManager.GetString("SearchNothingFoundMessage", resourceCulture); } } /// /// Looks up a localized string similar to x64. /// internal static string Str64Bit { get { return ResourceManager.GetString("Str64Bit", resourceCulture); } } /// /// Looks up a localized string similar to DEBUG. /// internal static string StrDebug { get { return ResourceManager.GetString("StrDebug", resourceCulture); } } /// /// Looks up a localized string similar to BCUninstaller export ///Publisher | Version | Date | Size | Registry | Uninstaller type | Uninstall string | Quiet uninstall string | Comments. /// internal static string StrExportHeader { get { return ResourceManager.GetString("StrExportHeader", resourceCulture); } } /// /// Looks up a localized string similar to Portable. /// internal static string StrIsPortable { get { return ResourceManager.GetString("StrIsPortable", resourceCulture); } } /// /// Looks up a localized string similar to Failed to call the API. /// internal static string SysRestoreGenericError { get { return ResourceManager.GetString("SysRestoreGenericError", resourceCulture); } } /// /// Looks up a localized string similar to No valid files or directories were selected. Make sure you have access to them, and they aren't marked as system files.. /// internal static string TargetWindow_NoFilesSelected_Message { get { return ResourceManager.GetString("TargetWindow_NoFilesSelected_Message", resourceCulture); } } /// /// Looks up a localized string similar to Look for application. /// internal static string TargetWindow_NoFilesSelected_Title { get { return ResourceManager.GetString("TargetWindow_NoFilesSelected_Title", resourceCulture); } } /// /// Looks up a localized string similar to Failed to find any applications inside {0}. /// internal static string Uninstaller_GetApplicationsFromDirectories_NothingFound_Message { get { return ResourceManager.GetString("Uninstaller_GetApplicationsFromDirectories_NothingFound_Message", resourceCulture); } } /// /// Looks up a localized string similar to Look for applications. /// internal static string Uninstaller_GetApplicationsFromDirectories_NothingFound_Title { get { return ResourceManager.GetString("Uninstaller_GetApplicationsFromDirectories_NothingFound_Title", resourceCulture); } } /// /// Looks up a localized string similar to Does nothing. /// internal static string UninstallerListDoubleClickAction_DoNothing { get { return ResourceManager.GetString("UninstallerListDoubleClickAction_DoNothing", resourceCulture); } } /// /// Looks up a localized string similar to Opens properties. /// internal static string UninstallerListDoubleClickAction_Properties { get { return ResourceManager.GetString("UninstallerListDoubleClickAction_Properties", resourceCulture); } } /// /// Looks up a localized string similar to Uninstalls. /// internal static string UninstallerListDoubleClickAction_Uninstall { get { return ResourceManager.GetString("UninstallerListDoubleClickAction_Uninstall", resourceCulture); } } /// /// Looks up a localized string similar to Select directory with applications that you want to remove.. /// internal static string UninstallFromDirectory_FolderBrowse { get { return ResourceManager.GetString("UninstallFromDirectory_FolderBrowse", resourceCulture); } } /// /// Looks up a localized string similar to Scanning specified directory.... /// internal static string UninstallFromDirectory_ScanningTitle { get { return ResourceManager.GetString("UninstallFromDirectory_ScanningTitle", resourceCulture); } } /// /// Looks up a localized string similar to Putting PC to sleep in {0}s. Uncheck the sleep checkbox to cancel.. /// internal static string UninstallProgressWindow_StatusPuttingToSleepInSeconds { get { return ResourceManager.GetString("UninstallProgressWindow_StatusPuttingToSleepInSeconds", resourceCulture); } } /// /// Looks up a localized string similar to Task finished. /// internal static string UninstallProgressWindow_TaskDone { get { return ResourceManager.GetString("UninstallProgressWindow_TaskDone", resourceCulture); } } /// /// Looks up a localized string similar to Uninstalling. /// internal static string UninstallProgressWindow_Uninstalling { get { return ResourceManager.GetString("UninstallProgressWindow_Uninstalling", resourceCulture); } } } } ================================================ FILE: source/BulkCrapUninstaller/Properties/Localisable.ar.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 الاسم القيمه فارغ موجود GUID مفقود GUID حدد لاسفل الى... لم يتم العثور على الملف. تشغيل الاوامر بعد الغاء التثبيت... تشغيل الاوامر السابقة لالغاء التثبيت... انشاء نقطه استعاده... بحث عن البقايا ... ملء قائمه الغاء التثبيت... ازاله البقايا... بحث عن التحديثات... محمول keep space in front API فشل استدعاء فشل النسخ الاحتياطي لمكتب السجل ، هل تريد المتابعة على ايه حال ؟ تفاصيل الخطا: ازاله البقايا فشل الاجراء تحتاج الى تحديد ادخال واحد فقط لهذا الاجراء حدد الغاء تثبيت واحد بالضبط من القائمة. اذا انت تستخدم خانات الاختيار للتاكد من التحقق منها. البحث عن التحديثات فتح المحتوي على الخط لا يمكن الاتصال بالانترنت ، لا توجد شبكات متوفرة. تاكد من توصيل كبل الشبكة. اذا كنت تستخدم واي فاي ضمان ان لديك قوه اشاره جيده. ارسال الملاحظات x64 keep space in front DEBUG keep space in front لا توجد ادخالات مطابقه لمعايير البحث. Bcuninstaller تصدير الناشر | الاصدار | التاريخ | الحجم | التسجيل | الغاء التثبيت نوع | الغاء تثبيت السلسلة | سلسله الغاء التثبيت بهدوء| هل تريد انشاء نسخه احتياطيه لمكتب السجل قبل المتابعة ؟ سوف تكون قادره على دحر جميع التغييرات عن طريق النقر المزدوج بعد ذلك. سيتم نقل الملفات والدلائل ىلى سله المحذوفات ، يمكنك استعادتها من هناك. فتح الروابط لا توجد روابط لفتحها تعديل المادة المحمية الادخالات المتاثره: {0} لتعديل هذه الادخالات تعطيل الحماية من الغاء التثبيت من الشريط الجانبي الاعدادات. يمكنك ازالتها من المهمة ومتابعه المواد الاخرى اذا اردت. 0 names of protected uninstallers لادخال المحمي: {0} لتعديل هذا الادخال ، تحتاج الى تعطيل حماية الغاء التثبيت من لوحه الاعدادات. 0 name of protected uninstaller المواد التالية مفقوده غير مثبتات بهدوء: {0} هل تريد استخدام "بصوت عال" للالغاء تثبيت هذه المواد ، او يجب ازالتها من المهمة ؟ 0 is names of non-quiet uninstallers الغاء التثبيت بهدوء استعاده الاعدادات الافتراضية سيتم فقدان كافة اعداداتك بشكل دائم. سيكون لديك المثبت لاعاده تشغيل لاكمال هذا الاجراء. فتح قائمه الغاء التثبيت لم يتم انشاء نقطه الاستعادة ، لن تكون قادرا على استعاده التغييرات! هل تريد متابعه الغاء التثبيت على ايه حال ؟ اعاده تسميه "{0}" اعاده تسميه الادخال المحدد انتهت المهمة Shown on the status bar تثبيت Shown on the status bar تذكر الاختيار خطا الملف غير موجود. (MsiExec) لا شيء للعرض. يتم الغاء تثبيت هذا التطبيق باستخدام مثبت الوندوز جاهز Shows up when nothing else is displayed on the status bar. تم تحديد {0} الغاء التثبيت {0} is a number of selected uninstallers {0} الغاء التثبيت في المجموع ، {1} {0} is a number of all uninstallers, {1} is a long file size (123 Megabytes) فشل تنفيذ الامر التالي: {0} {0} is a command line (c:\example.exe /help) فشل التنفيذ الخارجي افتراضي Used in language select box when you want to use the system language لن تصبح بعض الاعدادات نافذه المفعول حتى يتم اعاده تشغيل التطبيق. لتطبيق الاعدادات الجديدة BCU هل تريد اعاده تشغيل ؟ تغيير اعدادات التطبيق الشهادة مفقوده معالجه الغاء التثبيت {0} {1} = how many application uninstallers still need to be processed هل تريد تخطي انتظار الغاء التثبيت قيد التشغيل حاليا ؟ تخطي المهمة قيد التشغيل حاليا هناك مهمة اخرى لالغاء التثبيت قيد التشغيل بالفعل. الرجاء الانتظار حتى تنتهي ثم حاول مره اخرى. التقييم: {0} ايجابي: {1} نفي: {2} {0} - Rating as a string {1} - List of strings of positive parts of the rating {2} - List of strings of negative parts of the rating The lists are separated by a single newline. تفاصيل التصنيف لا يوجد ادخال مكتب تسجيل صالح لهذا التطبيق ليس لهذا التطبيق الغاء تثبيت صالح يتم الان تحميل ميزات الوندوز... تحديث معلومات بدء التشغيل... Shown when refreshing autostart information of the uninstallers لا توجد دلائل للفتح غير متاحه Used on application list when value is not available التصنيفات غير متوفرة يجب عليك تمكين التصنيفات من الاعدادات اولا. لا يمكنك تقييم التطبيقات التي لم يتم تثبيتها بشكل صحيح. {0} التطبيقات {0} is number of apps to rate, "Rate " will be automatically put in front of this string متوسط التقييم: {0}; تقييمي: {1} فشلت عمليه التثبيت التالية في التنفيذ ، ومن المحتمل بسبب حدوث اصطدام. الرجاء الانتظار لانهاء التثبيت الاخرى والمحاولة مره اخرى. {0} يمكنك محاولة تعطيل الكشف عن الاصطدام في الاعدادات ، ولكن لا ينصح به. اجبار الغاء التثبيت فشل تشغيل بعض المثبتات NET Framework v4.0 لم يتم العثور على سيتم تعطيل بعض الميزات NET Framework v4.0 لم يتم العثور على المصدر الموضوع المؤرشف امتدادات اسم مالوف اسم المصدر ليس بعد ليس قبل مفتاح خاص لديه مفتاح خاص مفتاح عمومي البيانات الخام الرقم التسلسلي اسم الموضوع خوارزميه التوقيع الاصدار بصمه الابهام فشل حفظ الاعدادات الانتهاء... تحميل الايقونات بحث عن التطبيق لم يتم تحديد ايه ملفات او دلائل صالحه. تاكد من ان لديك حق الوصول اليها ، ولا يتم وضع علامة عليها كملفات نظام. بحث عن التطبيقات فشل العثور على ايه تطبيقات داخل {0} تعديل التطبيق لا يمكن تعديل التطبيق المحدد التطبيق المحدد ليس له امر تعديل محدد. قد يكون من الضروري الغاء تثبيته ، ثم تثبيته مره اخرى لتغيير اعدادات التثبيت. سيؤدي تحديد "الانهاء" الى اغلاق الغاء التثبيت الذي تم تشغيله فورا وقد ينتج عنه عدم اكتمال عمليه الغاء التثبيت. وعاده ما يكون من الممكن لتشغيل الغاء التثبيت مره اخرى لانهاء الغاء التثبيت بدلا من ذلك يمكنك تتخطى انتظار هذه العملية. التخطي سيسمح الغاء التثبيت الاستمرار في العمل اثناء انتقال المهمة الى المادة التالية. تذكر ان بعض المثبتات قد تفشل في التشغيل حتى تنتهي عمليه التخطي. اختياري ، ولكن ينصح به. سيتم تعطيل الميزات التي تعتمد على الاطار حتى تقوم بتثبيته. v4.0 الاطار فشل بعض غير المثبتين هل تريد محاولة تشغيل المثبتات بهدوء التي فشلت بصوت عال ؟ سيتم اعاده تشغيل المثبتات التالية بصوت عال: يتم الان مسح الدليل المحدد... حدد الدليل مع التطبيقات التي تريد ازالتها. الغاء التثبيت من الدليل لم يتم العثور على اي تطبيقات في الدليل المحدد تاكد من تحديد الدليل الصحيح ومن ان الملفات التنفيذية للتطبيق لا تزال موجودة. تم العثور على الغاء التثبيت ل {0} هل تريد تشغيل هذا الغاء التثبيت ؟ ؟ BCU هل ترغب في ارسال الملاحظات بشان سوف ياخذك اقل من دقيقه ولكن مساعده التنمية بشكل كبير! ويقدر جميع ردود الفعل ، ان يكون تقرير الشوائب ، وطلب ميزه او بفضل بسيط! (يمكنك ارسالها لاحقا من شريط القوائم العلوي (مساعده-< ارسال ملاحظات. الاصدار الحالي محدث لم يتم العثور على ايه تحديثات في هذا الوقت ، لديك الاصدار الاحدث. تريد بعض الوظائف المضافة او الشوائب الثابتة ؟ الرجاء ارسال ملاحظاتك "باستخدام القائمة "مساعده-< ارسال ملاحظات. صادف خطا اثناء التحقق من وجود تحديثات تاكد من عدم حظر المثبت في جدار حمايتك ومن ان لديك اتصال بالانترنت يعمل. الاصدار الجديد {0} متوفر ، هل تريد الترقية الان ؟ 0 is version number سيقوم المثبت بتحميل التحديث تلقائيا وتطبيقه بعد اعاده التشغيل. يرجى ملاحظه انه قد تفقد اعداداتك في العملية. التغييرات: -{0} ستتم ازاله.BCU تحذير: اثناء تحديث المجلد "تحديث" و الملف "التحديث .ضغط" داخل الدليل 0 is a list of changes separated by "- " Msi الغاء التثبيت باستخدام msiexec لا يمكن الغاء تثبيت الادخال المحدد باستخدام المثبت MsiExec صالح للاستخدام مع Guid الغاء التثبيت المحدد ليس له ايقاف مهمة الغاء التثبيت الحالية هل تريد بالتاكيد ايقاف تشغيل المهمة حاليا ؟ لن يؤدي ايقاف المهمة قبل الاوان الى ارجاع ايه تغييرات. لن يتم ايقاف تشغيل الغاء التثبيت حاليا ، ستنتظر المهمة حتى تنتهي. انشاء نقطه استعاده فشل انشاء نقطه استعاده جديده تقدم الغاء التثبيت يمكنك الان ترك الحاسوب يجب ان يكون التثبيت المتبقي قادرا على اكمال دون اي تدخل من قبل المستخدم. يجب عليك الاختيار ما زالت في من وقت لاخر في حاله واحده من تعطل التركيب. ازاله الخردة/البقايا هل تريد حقا تعديل المواد ذات الثقة المنخفضة ؟ ازاله المواد التي تحمل الثقة اقل من جيده يمكن ان تكون خطيره جدا! من المستحسن التحقق من ان كل مادة واحدة امنة لحذف. ازاله مفاتيح من مكتب التسجيل هل تريد بالتاكيد ازاله ادخالات الغاء التثبيت المحددة ؟ سيتم ازاله المواد التالية من مكتب التسجيل وسوف تختفي من قائمه الغاء التثبيت ، ولكن لن يتم الغاء تثبيت. {0} فشل التصدير تمت مصادفه خطا اثناء حفظ البيانات المصدرة اذا استمر الخطا في محاولة الحفظ الى دليل مختلف ، على سبيل المثال الى سطح المكتب. يتم ازاله تثبيت التطبيق (التطبيقات) {0} 0 is the uninstaller count اعاده تسميه الغاء التثبيت الاسم الذي تم توفيره فارغ او يحتوي على احرف غير صالحه تاكد من انك لم تقم بتضمين اي من الاحرف التالية: {0} 0 is list of characters separated by spaces هل تريد البحث عن البقايا التي تم اجراؤها من غير المنشات ؟ يرجى ملاحظه ان هذه الميزة مخصصه فقط لمستخدمي الطاقة الذين يفهمون كيفيه عملها. ليس من الضروري ازاله هذه الملفات وانها لن تؤثر على اداء النظام باي طريقه مجديه. لم يتم العثور على البقايا BleachBit لم يتم العثور علي البقايا. لا يزال هناك قد يكون بعض البقايا متبقية حتى تتمكن من تشغيل ملف مؤقت المنظف مثل ليس هناك شيء للنسخ الى الحافظة. اما اي الغاء التثبيت المحدد لديه هذا القليل من المعلومات او انك لم تحدد اي شيء. نسخ الى الحافظة فتح الدلائل سيقوم هذا الاجراء بفتح {0} دليل في نفس الوقت ، هل تريد بالتاكيد المتابعة ؟ 0 is number of directories to open بحث عن الخط لا شيء للبحث عنة الغاء تثبيت المثبت هل تريد بالتاكيد الغاء تثبيت المثبت ؟ تفاصيل الخطا: Add space or newline afterwards and two newlines before سافعل ما بوسعي لاصلاح اي مشاكل مشروعه (http://klocmansoftware.weebly.com/).على موقعي BCU انا اسف لرؤيتك ترحل اذا كان لديك دقيقه او اثنتين يرجى اسقاط كلمه واحده لماذا قمت بالغاء تثبيت هل تريد انشاء نقطه استعاده قبل المتابعة ؟ اذا كنت غير متاكد اذا كانت التطبيقات التي تقوم بالغاء تثبيتها هامه او مطلوبه لاستقرار النظام فمن المستحسن انشاء نقطه استعاده. اذا كان اي شيء فواصل بعد الاجراء يمكنك استخدام استعاده النظام لاسترجاع التغييرات. تمت مصادفه خطا اثناء فتح صفحه البحث حفظ قائمه الغاء التثبيت فشل حفظ القائمة في ملف هل تريد بالتاكيد اعاده تعيين كافة اعدادات التطبيق ؟ لا يمكن الغاء تثبيت بعض التطبيقات بهدوء بعض الادخالات محمية ولا يمكن تعديلها الادخال المحدد محمي ولا يمكن تعديله حدث خطا اثناء فتح الرابط هل تريد الاحتفاظ بالتحديد الحالي ؟ تمت مصادفه خطا اثناء فتح الدليل فشل تحميل الملفات المحددة لم يتم تحديد اي المثبتات ، لا شيء للغاء تشغيل الغاء التثبيت لالغاء تثبيت التطبيقات يجب اولا تحديدها من عرض القائمة. اذا كنت تستخدم خانات الاختيار ، تاكد من ان يتم التحقق منها. اذا اخترت الاحتفاظ بالتحديد الحالي سيتم دمجه مع القائمة (القوائم)المفتوحة سيقوم هذا الاجراء بفتح رابط {0} في نفس الوقت ، هل تريد بالتاكيد المتابعة ؟ حفظ قائمه الغاء التثبيت حفظ التغييرات في قائمه الغاء التثبيت المفتوحة ؟ توجد تغييرات غير محفوظه في قائمه الغاء التثبيت المفتوحة سيتم فقدانها عند اغلاقها. حدد الدليل مع التطبيقات لالغاء التثبيت. حدد مكان حفظ النسخة الاحتياطية. سيتم انشاء دليل جديد. ================================================ FILE: source/BulkCrapUninstaller/Properties/Localisable.cs.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Vytvoření bodu obnovení ... Vyhledávání pozůstatků ... Vyplnění seznamu odinstalací ... Odstranění pozůstatků ... Hledání aktualizací ... Nejsou k dispozici žádné záznamy odpovídající hledanému řetězeci. BCUninstaller export Vydavatel | Verze | Datum | Velikost | Registr | Typ odinstalátoru | Odinstalovat řetězec | Tichá odinstalace řetězece | Komentáře Přenosná keep space in front Nepodařilo se volání API Zálohování registru selhalo, chcete přesto pokračovat? Podrobnosti o chybě: Odstranění pozůstatků Podrobnosti o chybě: Add space or newline afterwards and two newlines before Chcete vytvořit zálohu registru před pokračováním? Budete mít možnost se vrátit zpět všechny změny dvojitým kliknutím na něj později. Soubory a adresáře budou přesunuty do koše, můžete je obnovit tam. Akce se nezdařila Musíte vybrat pouze jednu položku pro tuto akci Vyberte přesně jednu položku ze seznamu. Používáte-li zaškrtávací políčka, ujistěte se, že jsou vybrány. Vyhledat aktualizace Otevřená on-line obsah Nelze se připojit k internetu, není k dispozici žádné připojení k síti. Ujistěte se, že síťový kabel je zapojen. Pokud používáte Wi-Fi, ujistěte, že máte dobrou sílu signálu. Odeslat zpětnou vazbu Chcete poslat zpětnou vazbu týkající se BCU? Bude vám trvat méně než minutu, ale muže nám to pomoc při vývoji programu! Všechny názory a připomínky jsou vítány! Můžete ji poslat později přes pozici v horním menu (Nápověda-> Odeslat zpětné vazby). Současná verze je aktuální Nebyly nalezeny žádné aktualizace, máte nejnovější verzi programu. Ty čekají na nové funkce nebo zlepšit chybu? Dejte mi vědět, přes menu "Nápověda-> Odeslat zpětné vazby". Došlo k chybě při kontrole aktualizací Ujistěte se, že BCUninstaller není blokován ve vašem firewallu, a že máte funkční připojení k internetu. Nová verze {0} je k dispozici, chcete upgradovat teď? 0 is version number BCUninstaller automaticky stáhne aktualizaci a aplikuje po restartu. Vezměte prosím na vědomí, že může dojít ke ztrátě nastavení v procesu. changelog: - {0} Upozornění: Během aktualizace bude odstraněna složka "Update" a soubor "Update.zip" uvnitř adresáře BCU. 0 is a list of changes separated by "- " Odinstalace pomocí Msi Vybraná položka nelze odinstalovat pomocí instalátoru msiexec Vybraný odinstalátor nemá platnou GUID pro použití s Msiexec. Zastavit aktuální úkol odinstalaci Jste si jisti, že chcete právě zastavit běžící úlohu? Zastavení úkolu předčasně nebude možné vrátit žádné změny. V současné době běží odinstalování nebude zastaveno, bude úkol čekat na dokončení. Vytvořit bod obnovení Nepodařilo se vytvořit nový bod obnovení x64 keep space in front DEBUG keep space in front Odinstalační proces Nyní můžete opustit počítač Ostatní odinstalace jsou schopen se dokončit bez vašeho zásahu. Přesto, tu a tam zkontrolujte, zda některá z odinstalací, nezaznamenala neočekávanou chybu. Nevyžádané/Zbylé odstranění Jste si jisti, že chcete změnit položky s nízkou duvěryhodností? Odebrat prvky s nízkou úrovní důvěry je velmi nebezpečné, pečlivě před odstraněním zkontrolujte každou položku. Odstranit klíče od registru Jste si jisti, že chcete odstranit vybrané položky? Následující položky budou odstraněny z registru a zmizí ze seznamu aplikací, ale není možné je odinstalovat. {0} Export selhal Došlo k chybě při ukládání exportovaných dat Pokud chyba přetrvává, zkuste uložit do jiného adresáře, například na plochu. BCUninstaller odinstaluje aplikace {0} 0 is the uninstaller count Přejmenovat odinstalátor Zadané jméno je prázdné nebo obsahuje nepovolené znaky Ujistěte se, že jste nezahrnuli některý z následujících znaků: {0} 0 is list of characters separated by spaces Chcete se podívat na zbytky z provedených odinstalaci ? Vezměte prosím na vědomí, že tato funkce je určena pouze pro pokročilé uživatele, aby pochopili, jak to funguje. Není nutné, tyto soubory odebrat a nebudou mít vliv na výkon systému významným způsobem. Nebyly nalezeny žádné zbytky Nebyl nalezen žádný zbytek. Aby se ujistil, můžete spustit další program pro čištění smetí, např. BleachBit. Nebylo co zkopírovat do schránky. Buď není vybraný odinstalátor nebo nějaké informace, nebo jste nevybrali nic. Kopírovat do schránky Otevřené adresáře Tato akce otevře {0} adresářů okamžitě, jsou si jisti, že chcete pokračovat? 0 is number of directories to open Hledání Online Nic k vyhledání Odinstalovat BCUninstaller Jste si jisti, že chcete odinstalovat BCUninstaller? Je mi líto, že odcházíte! Pokud máte minutu nebo dvě, prosím napište slovo o tom, proč jste odinstalovali BCU na mých webových stránkách (http://klocmansoftware.weebly.com/). Budu se snažit opravit legitimní problémy. Chcete vytvořit bod obnovení před instalací? Pokud si nejste jisti, zda aplikace, které chcete odinstalovat, jsou důležité nebo nutné pro stabilitou systému doporučuje se vytvořit bod obnovení.   Kdyby se něco poškodilo po zákroku pak můžete použít nástroje Obnovení systému a vrátit změny zpět. Byla nalezena chyba při otevírání vyhledávací stránku Uložit seznam odinstalací Nepodařilo se uložení seznamu do souboru Jste si jisti, že chcete obnovit všechna nastavení aplikace? Některé aplikace nelze odinstalovat tiše Některé položky jsou chráněné a nelze změnit Vybraný záznam je chráněn a nelze změnit Byla nalezena chyba při otevírání URL Chcete zachovat aktuální výběr? Byla nalezena chyba při otevírání adresáře Nepodařilo se načíst vybrané soubory Nebyli vybrány odinstalace, není co odinstalovat Spustit odinstalace K odinstalování aplikace je nutné nejprve ji vyberat ze zobrazého seznamu. Pokud používáte zaškrtávacích políček, ujistěte se, že jsou vybrány. Pokud se rozhodnete zachovat aktuální výběr, bude sloučen do otevřeného seznamu Tato akce otevře {0} URL ihned, jste si jisti, že chcete pokračovat? Otevřít URL Žádné URL k otevření Změnit chráněné položky Dotčené údaje: {0} Chcete-li změnit tyto položky, potřebujete vypnout ochranu odinstalátoru z postranního panelu nastavení. Můžete je odstranit z úkolu, a pokračovat s dalšími položkami, pokud chcete. 0 names of protected uninstallers Chráněná položka: {0} Chcete-li změnit tuto položku, potřebujete vypnout ochranu odinstalátoru z panelu nastavení. 0 name of protected uninstaller Následující položky nemají tichou odinstalaci: {0} Ponechat je v úloze a použijte "hlasité" odinstalace nebo zcela odstranit z úkolu? 0 is names of non-quiet uninstallers Tichá odinstalace Obnovit výchozí nastavení Všechna nastavení budou natrvalo ztraceny. BCUninstaller bude muset restartovat k dokončení této akce. Otevřít seznam odinstalovat Bod obnovení nebyl vytvořen, nebudete moci obnovit změny! Chcete pokračovat v odinstalaci ? Přejmenování "{0}" Přejmenovat vybrané položky Úlohá dokončena Shown on the status bar Odinstalace Shown on the status bar Pamatovat si výběr Chyba Soubor neexistuje. Nic k zobrazení. Tato aplikace je odinstalovat pomocí Windows Installer (msiexec). Název Hodnota Prázdné GUID nalezeno GUID chybí Vyberte až na ... Soubor nenalezen. Spuštění po-odinstalační příkazy ... Spuštění před-odinstalační příkazy ... Připraven Shows up when nothing else is displayed on the status bar. {0} odinstalace vybraných {0} is a number of selected uninstallers Celkem {0} odinstalováno, {1} {0} is a number of all uninstallers, {1} is a long file size (123 Megabytes) Provedení následujícího příkazu se nezdařilo: {0} {0} is a command line (c:\example.exe /help) Chyba při vykonání příkazu Výchozí Used in language select box when you want to use the system language Některá nastavení se projeví až po restartu aplikace. Chcete restartovat BCU pro použít nového nastavení? Změna nastavení aplikace Certifikát chybí Zpracování odinstalace ({0}) {1} = how many application uninstallers still need to be processed Volba "Ukončit" se okamžitě uzavře běžící odinstalace a může způsobit že odinstalace není dokončena. Obvykle je možné spustit odinstalátor znovu a dokončit odinstalování. Případně můžete přeskočit čekání na tento proces. Přeskakování umožní v odinstalaci pokračovat, zatímco úkol přesune na další položku. Mějte na paměti, že některé odinstalace mohou selhat, pokud proces přeskočí a nedokončí. Chcete přeskočit čekání na spuštění odinstalování? Přeskočit aktuálně běžící úlohy Další odinstalace probíhá. Prosím, vyčkejte na dokončení procesu a zkuste to znovu. Hodnocení: {0} Pozitivní: {1} Negativní: {2} {0} - Rating as a string {1} - List of strings of positive parts of the rating {2} - List of strings of negative parts of the rating The lists are separated by a single newline. Podrobnosti o hodnocení Tato aplikace nemá platnou položku registru Tato aplikace nemá platný odinstalalátor Windows Vlastnosti se Načítájí ... Aktualizace startup informací ... Shown when refreshing autostart information of the uninstallers Žádné adresáře pro otevření Není dostupný Used on application list when value is not available {0} aplikací {0} is number of apps to rate, "Rate " will be automatically put in front of this string Hodnocení není k dispozici. Musíte hodnocení povolit při prvním nastavení. Nelze hodnotit aplikace, které nejsou správně nainstalovány. Průměrné hodnocení: {0}; Mé hodnocení: {1} Odinstalace programů se nezdařila, pravděpodobně kvůli kolizim. Počkejte na ostatní dokončení odinstalací a akci opakujte. {0} Můžete zkusit zakázat detekci kolizí v nastavení, není doporučeno. Vynutit odinstalaci Nepodařilo se spustit některé odinstalace programů .NET framework v4.0 nebyla nalezena. .NET framework v4.0 nebylo nalezeno, budou zakázány některé funkce Framework v4.0 je nepovinný, ale doporučený. Funkce které spoléhají na framework budou zakázány, dokud nebude nainstalován. Některé odinstalace selhaly Chcete si vyzkoušet tichý chod odinstalace, pokud selhala hlasitá? Následující odinstalace bude hlasitá: Vyhledávání zadaného adresáře... Vyberte adresář s aplikacemi, které chcete odstranit. Odinstalovat z adresáře V zadaném adresáři nebyly nalezeny žádné aplikace Ujistěte se, že jste vybrali správného adresáře a že spustitelné soubory aplikace jsou stále přítomny. Našel pro odinstalaci {0} Chcete spustit odinstalační program? Vydavatel Předmět Archivováno Rozšíření Název popisu Název vystavitele Ne po Ne před Soukromý klíč Has Soukromý klíč Veřejný klíč Nezpracovaná Data Sériové číslo Název předmětu Algoritmus podpisu Verze Miniatura Nepodařilo se uložit nastavení Dokončuje se ... Načtení ikon Vyhledat aplikaci Nebyly vybrány žádné platné soubory nebo adresáře. Ujistěte se, že k nim máte přístup a nejsou označeny jako systémové soubory. Vyhledat aplikace Nepodařilo se najít žádné aplikace uvnitř {0} Změnit aplikaci Vybranou aplikaci nelze změnit. Vybraná aplikace nemá žádný příkaz pro úpravu. Bude nutné ji odinstalovat a znovu jej nainstalovat Uložit seznam odinstalace Uložit změny do seznamu otevřených odinstalací? V otevřeném odinstalačním seznamu jsou neuložené změny, které budou ztraceny zavřením. Vyberte adresář s aplikacemi, které chcete odinstalovat. Vyberte, kam chcete zálohu uložit. Bude vytvořen nový adresář. ================================================ FILE: source/BulkCrapUninstaller/Properties/Localisable.de.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Erstelle Wiederherstellungspunkt... Suche nach Programmresten... Fülle die Uninstaller Liste... Entferne Programmreste... Suche nach Updates... Es gibt keine Einträge, die Ihrem Suchbegriff entsprechen. BCUninstaller Export Herausgeber | Version | Datum | Größe | Registry | Uninstallertyp | Uninstallanweisung | Uninstallanweisung (still) | Kommentar Portabel keep space in front Fehler beim Aufruf der API Sicherung der Registry ist fehlgeschlagen. Trotzdem fortfahren? Fehlerdetails: Entfernen von Resten Fehlerdetails: Add space or newline afterwards and two newlines before Möchten Sie eine Sicherung der Registry erstellen, bevor Sie fortfahren? Sie können alle Änderungen zurücksetzen, in dem Sie später darauf doppelklicken. Dateien und Verzeichnisse werden in den Papierkorb veschoben, von wo Sie sie wiederherstellen können. Aktion fehlgeschlagen Sie müssen nur einen Eintrag für diese Aktion auswählen Einen bestimmten Uninstaller aus der Liste auswählen. Bei Verwendung von Checkboxen, vor Ausführung überprüfen! Suche nach Updates Online-Inhalte öffnen Keine Verbindung zum Internet. Es sind keine Netzwerke verfügbar. Stellen Sie sicher, dass das Netzwerkkabel angeschlossen ist. Bei Verwendung von Wi-Fi achten Sie auf eine gute Signalstärke. Feedback senden Möchten Sie mir ein Feedback zu BCU senden? Es wird Sie weniger als eine Minute kosten und der Programm-Entwicklung enorm helfen! Jede Art Feedback ist willkommen, sei es Fehlerbericht, Feature-Anfrage oder ein einfaches Danke! Sie können es auch später senden aus dem Top-Menü (Hilfe-> Feedback senden). Version ist auf aktuellem Stand Aktuell gibt es keine Updates. Sie verwenden die neueste Version. Möchten Sie Funktionen hinzugefügt oder einen Fehler behoben haben? Bitte senden Sie mir Ihr Feedback über das Menü "Hilfe-> Feedback senden". Fehler beim Suchen nach Updates Stellen Sie sicher, dass BCUninstaller in der Firewall nicht blockiert wird und Sie eine funktionierende Internetverbindung haben. Neue Version {0} ist verfügbar, möchten sie jetzt aktualisieren? 0 is version number BCUninstaller wird automatisch das Update herunterladen und es nach einem Neustart anwenden. Bitte beachten Sie, dass Sie Ihre Einstellungen in den Prozess verloren gehen können. Änderungsprotokoll: - {0} Achtung: während der Aktualisierung werden der Ordner "Update" und die Datei "Update.zip" innerhalb des BCU-Verzeichnisses entfernt. 0 is a list of changes separated by "- " Deinstallation mit Msi Ausgewählter Eintrag kann mit dem MsiExec-Installer nicht deinstalliert werden. Ausgewählter Uninstaller hat keine gültige Guid für die Verwendung mit MsiExec. Aktuellen Deinstallations-Task beenden Laufenden Task wirklich beenden? Vorzeitiges Beenden des Tasks macht Änderungen nicht rückgängig. Laufender Uninstaller wird nicht gestoppt, der Task wartet auf seinen Abschluss. Wiederherstellungspunkt erstellen Konnte keinen neuen Wiederherstellungspunkt erstellen x64 keep space in front DEBUG keep space in front Deinstallations-Fortschritt Sie können nun den Computer verlassen. Verbliebene Uninstaller sollten ohne weiteren Eingriff abgeschlossen werden können. Von Zeit zu Zeit sollten Sie kontrollieren, ob nicht einer der Uninstaller abgestürzt ist. Müll/Programmreste entfernen Wirklich Elemente mit niedrigem Vertrauensgrad ändern? Das Entfernen von Elementen mit niedrigerem Vertrauensgrad als GUT kann sehr gefährlich sein! Stellen Sie sicher, dass jedes Element sicher zu entfernen ist. Schlüssel aus der Registry entfernen Wirklich die ausgewählten Uninstaller-Einträge entfernen? Folgende Elemente werden aus der Registry entfernt und verschwinden aus der Uninstaller-Liste, werden aber nicht deinstalliert. {0} Export fehlgeschlagen Fehler beim Speichern der exportierten Daten Tritt der Fehler weiter auf, versuchen Sie, in ein anderes Verzeichnis zu sichern, z.B. den Desktop BCUninstaller deinstalliert {0} Anwendung(en) 0 is the uninstaller count Uninstaller umbenennen Angegebener Name ist leer oder enthält ungültige Zeichen Stellen Sie sicher, dass Sie keines der folgenden Zeichen verwendet haben: {0} 0 is list of characters separated by spaces Nach durchgeführter Deinstallation nach Programmresten suchen? Hinweis: dieses Feature ist nur für erfahrene Anwender, die verstehen, wie es funktioniert. Es ist nicht erforderlich, diese Dateien zu entfernen, weil sie die Systemleistung nicht bedeutend beeinträchtigen Keine Programm-Rückstände gefunden Keine Elemente gefunden. Mögliche Rückstände können Sie mit einem temporären Dateireiniger wie BleachBit entfernen. Es gab nichts in die Zwischenablage zu kopieren. Sie haben entweder nichts ausgewählt oder die Information stammt vom Uninstaller In Zwischenablage kopieren Verzeichnisse öffnen Diese Aktion öffnet {0} Verzeichnisse auf einmal. Sind Sie sicher, dass Sie fortfahren möchten? 0 is number of directories to open Online-Suche Nichts zu suchen BCUninstaller deinstallieren Möchten Sie BCUninstaller wirklich deinstallieren? Tut mir leid, Sie gehen zu sehen! Wenn Sie eine Minute Zeit haben, schreiben Sie mir kurz etwas über Ihre Gründe auf meiner Website (http://klocmansoftware.weebly.com/). Ich werde mein Bestes tun, um berechtigte Probleme zu beheben. Wiederherstellungspunkt erstellen, bevor Sie fortfahren? Wenn Sie unsicher sind, ob die Anwendungen, die Sie deinstallieren, wichtig oder für die Systemstabilität erforderlich sind, ist es empfehlenswert, einen Wiederherstellungspunkt zu erstellen. Sollte etwas schief gehen, können Sie mittels Systemwiederherstellung die Änderungen zurücknehmen. Beim Öffnen der Seite "Suche" ist ein Fehler aufgetreten Deinstallations-Liste speichern Liste konnte nicht in Datei gespeichert werden Sind Sie sicher, dass Sie alle Einstellungen zurücksetzen möchten? Für manche Anwendungen geht keine stille Deinstallation Einige Einträge sind geschützt und können nicht verändert werden Gewählter Eintrag ist geschützt und kann nicht verändert werden Beim Öffnen der URL ist ein Fehler aufgetreten Möchten Sie die aktuelle Auswahl beibehalten? Beim Öffnen des Verzeichnisses ist ein Fehler aufgetreten Konnte gewählte Dateien nicht laden Keine Uninstaller ausgewählt. Nichts zu deinstallieren Uninstaller ausführen Um Anwendungen zu deinstallieren müssen Sie sie zuerst aus der Listenansicht auswählen. Wenn Sie Checkboxen verwenden, stellen Sie sicher, dass sie aktiviert sind. Wenn Sie die aktuelle Auswahl behalten möchten, wird sie mit der geöffneten Liste zusammengeführt Diese Aktion öffnet {0} URLs gleichzeitig. Sind Sie sicher, dass Sie fortfahren möchten? URLs öffnen Keine URLs zu öffnen Geschütztes Element verändern Betroffene Einträge: {0} Um diese Einträge zu ändern, müssen Sie aus der Einstellungen Seitenleiste den Schutz der Uninstaller deaktivieren. Sie können sie aus dem Task entfernen und mit anderen fortfahren 0 names of protected uninstallers Geschützter Eintrag: {0} Um diesen Eintrage zu ändern, müssen Sie aus dem Bedienfeld Einstellungen den Schutz der Uninstaller deaktivieren. 0 name of protected uninstaller Folgene Elemente haben keine 'stillen' Uninstaller: {0} Möchten Sie für diese Elemente die Standard Uninstaller verwenden oder sollen die Einträge aus dem Task entfernt werden? 0 is names of non-quiet uninstallers Stille Deinstallation Standardeinstellungen wiederherstellen Alle Einstellungen werden dauerhaft gelöscht. BCUninstaller neu starten, um diesen Vorgang zu beenden. Deinstallations-Liste öffnen Der Wiederherstellungspunkt WURDE NICHT ERSTELLT, Sie werden Änderungen nicht wiederherstellen können! Möchten Sie trotzdem mit der Deinstallation fortfahren? Umbenennen "{0}" Gewählten Einrag umbenennen Task abgeschlossen Shown on the status bar Deinstallation Shown on the status bar Auswahl merken Fehler Datei existiert nicht Keine Anzeige. Diese Anwendung wird mittels Windows Installer (MsiExec) deinstalliert. Name Wert Leer GUID gefunden GUID fehlt Wählen Sie bis zu... Datei nicht gefunden Ausführen von NACH-Deinstallations Anweisungen... Ausführen von VOR-Deinstallations Anweisungen... Fertig Shows up when nothing else is displayed on the status bar. {0} Uninstaller gewählt {0} is a number of selected uninstallers {0} Uninstaller gesamt, {1} {0} is a number of all uninstallers, {1} is a long file size (123 Megabytes) Folgender Befehl konnte nicht ausgeführt werden: {0} {0} is a command line (c:\example.exe /help) Externe Ausführung fehlgeschlagen Voreinstellung Used in language select box when you want to use the system language Einige Einstellungen werden erst nach einem Neustart der Anwendung wirksam. Wollen Sie BCU neu starten, um die neuen Einstellungen zu übernehmen? Anwendungseinstellungen ändern Zertifikat fehlt Verarbeitung der Uninstaller ({0}) {1} = how many application uninstallers still need to be processed Die Auswahl "Beenden" schließt unmittelbar den laufenden Uninstaller und kann dazu führen, dass die Deinstallation nicht abgeschlossen wird. In der Regel können Sie den Uninstaller erneut ausführen, um die Deinstallation abzuschließen. Alternativ können Sie die Wartezeit für diesen Prozess überspringen. Dies lässt den Uninstaller weiterarbeiten, während der Task zum nächsten Element springt. Denken Sie daran, dass einige Uninstaller nicht ausgeführt werden können, bevor der übersprungene Prozess abgeschlossen ist. Warten auf den laufenden Uninstaller überspringen? Aktuell laufende Aufgabe überspringen Ein anderer Uninstall-Task läuft bereits. Warten Sie auf dessen Beendung und versuchen Sie es erneut. Bewertung: {0} Positive: {1} Negative: {2} {0} - Rating as a string {1} - List of strings of positive parts of the rating {2} - List of strings of negative parts of the rating The lists are separated by a single newline. Bewertungs-Details Diese Anwendung hat keinen gültigen Registry-Eintrag Diese Anwendung hat keinen gültigen Uninstaller Windows-Funktionen laden... Startinformationen aktualisieren... Shown when refreshing autostart information of the uninstallers Keine Verzeichnsse zu öffnen Nicht verfügbar Used on application list when value is not available {0} Anwendungen {0} is number of apps to rate, "Rate " will be automatically put in front of this string Bewertung nicht verfügbar Sie müssen zuerst Bewertungen anhand der Einstellungen aktivieren. Sie können Anwendungen nicht bewerteten wenn sie nicht vollständig installiert wurden. Durchschnittliche Bewertung: {0}; Meine Bewertung: {1} .NET Framework v4.0 nicht gefunden .NET Framework v4.0 wurde nicht gefunden, einige Funktionen sind nicht verfügbar. Öffentlicher Schlüssel Serien Nummer Version Fingerabdruck Lade Icons Willkommen zu BCU version {0}! Nachfolgende Uninstaller verhinderten die Ausführung wahrscheinlich wegen einer Kollision. Bitte warten Sie, bis andere Uninstaller fertig sind, und versuchen Sie es erneut. {0} Sie können versuchen, die Kollisionserkennung in den Einstellungen zu deaktivieren, dieses wird jedoch nicht empfohlen. Deinstallation erzwingen Einige der Deinstallationsprogramme konnten nicht ausgeführt werden Das .NET v4.0 Framework ist optional, wird aber empfohlen. Die Funktionen, die auf diesem Framework basieren, werden deaktiviert, bis Sie es installieren. Einige Deinstallationsprogramme sind fehlgeschlagen Möchten Sie versuchen, quiet Deinstallationsprogramme auszuführen, die fehlgeschlagen sind? Folgende Deinstallationsprogramme werden neu gestartet: Überprüfen des angegebenen Verzeichnisses Wählen Sie das Verzeichnis mit den Anwendungen aus, die Sie entfernen möchten Deinstallieren aus dem Verzeichnis Im angegebenen Verzeichnis wurden keine Anwendungen gefunden Stellen Sie sicher, dass Sie das richtige Verzeichnis ausgewählt haben und dass die ausführbaren Dateien der Anwendung noch vorhanden sind. Deinstallationsprogramm für {0} gefunden Möchten Sie dieses Deinstallationsprogramm ausführen? Aussteller Gegenstand Archiviert Erweiterungen Anzeigename Name des Ausstellers nicht nach nicht vor Privater Schlüssel Hat einen privaten Schlüssel Rohdaten Gegenstands Name Signaturalgorithmus Einstellungen konnten nicht gespeichert werden Beenden Suchen Sie nach Anwendung Es wurden keine gültigen Dateien oder Ordner ausgewählt. Stellen sie sicher, dass sie Zugriff auf diese haben und es keine Systemdateien sind. Suchen Sie nach Anwendung Fehler bei der Suche nach Anwendungen {0} Ändern der Anwendung Ausgewählte Anwendung kann nicht verändert werden. Für die ausgewählte Anwendung wurde kein Änderungsbefehl angegeben. Möglicherweise muss eine Deinstallation durchgeführt werden und eine Neuinstallation durchgeführt werden um Änderungen zu speichern. Speichern der Uninstall Liste Speichern der Änderungen in der geöffneten Uninstall Liste Änderungen wurden in der geöffneten Uninstall Liste noch nicht gespeichert und werden beim Schließen verloren gehen. Wählen Sie das Verzeichnis mit den zu deinstallierenden Anwendungen aus. Wählen Sie, wo die Sicherung gespeichert werden soll. Ein neues Verzeichnis wird erstellt. BCU wurde Upgedated auf v{0}! Einschlafen des PCs in {0}s. Deaktivieren Sie das Kontrollkästchen für den Ruhezustand, um abzubrechen. Macht nichts Option for "Double clicking in application list..." Öffnet Eigenschaften Option for "Double clicking in application list..." Deinstalliert Option for "Double clicking in application list..." ================================================ FILE: source/BulkCrapUninstaller/Properties/Localisable.es.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Creando un punto de restauración... Buscando actualizaciones... Portable keep space in front Detalles del error: Detalles del error: Add space or newline afterwards and two newlines before ¿Le gustaría crear una copia de seguridad del registro antes de continuar? Acción fallida Solo necesita seleccionar una entrada para ésta acción Seleccione exactamente un desinstalador de la lista. Si está utilizando las casillas de verificación, asegúrese de revisarlas. Buscar actualizaciones Desinstalar BCUninstaller ¿Está seguro que desea desinstalar BCUninstaller? ¿Le gustaría crear un punto de restauración antes de continuar? Por defecto Used in language select box when you want to use the system language Buscando restos... Poblando lista de desinstalación... Eliminando restos... No hay entradas que coincidan con sus criterios de búsqueda. Exportación BCUninstaller Editor | Versión | Fecha | Tamaño | Registro | Tipo de desinstalación | Cadena de desinstalación | Cadena de desinstalación silenciosa | Comentarios No se ha podido llamar a la API Error en la copia de seguridad del registro, ¿desea continuar de todos modos? Eliminación de restos Enviar comentario Listo Shows up when nothing else is displayed on the status bar. {0} desinstaladores seleccionados {0} is a number of selected uninstallers {0} desinstaladores en total, {1} {0} is a number of all uninstallers, {1} is a long file size (123 Megabytes) Cargando características de Windows... No disponible Used on application list when value is not available {0} aplicaciones {0} is number of apps to rate, "Rate " will be automatically put in front of this string Promedio de calificación: {0}; Mi calificación: {1} .NET Framework v4.0 no encontrado .NET Framework v4.0 no ha sido encontrado, algunas características podrían desactivarse Calificaciones no disponibles Primero tiene que activar las calificaciones desde la configuración. No puede calificar aplicaciones no instaladas adecuadamente. Calificación: {0} Positivos: {1} Negativos: {2} {0} - Rating as a string {1} - List of strings of positive parts of the rating {2} - List of strings of negative parts of the rating The lists are separated by a single newline. Esta aplicación no tiene una entrada de registro válida Esta aplicación no tiene un desinstalador válido Detalles de calificación Actualizando información de inicio... Shown when refreshing autostart information of the uninstallers No hay directorios que abrir Forzar desinstalación Saltar la tarea actualmente en ejecución Otra tarea de desinstalación está ejecutándose. Por favor espere a que finalice e inténtelo nuevamente. ¿Desea reiniciar BCU para aplicar los nuevos cambios? Procesando desinstaladores ({0}) {1} = how many application uninstallers still need to be processed Cambiar configuración de la aplicación Hace falta el certificado Nombre Valor GUID encontrado GUID ausente Archivo no encontrado. Algunos cambios no tendrán efecto hasta que se reinicie la aplicación. Error Vacio Tarea finalizada Shown on the status bar Desinstalando Shown on the status bar Recordar elección El archivo no existe. Renombrando "{0}" Renombrar entrada seleccionada. Desinstalación silenciosa Abrir lista de desinstalación Abrir URLs Restaurar configuración por defecto No hay URLs que abrir Modificar elemento protegido Abrir los contenidos en línea No se puede conectar a Internet, no hay redes disponibles. Asegúrese de que el cable de red está enchufado. Si está utilizando Wi-Fi asegúrese de que tiene buena la señal. ¿Le gustaría enviar comentarios acerca de BCU? Ejecutar desinstaladores Usted podrá revertir todos los cambios haciendo doble clic después. Los archivos y directorios se moverán a la papelera de reciclaje, puede restaurarlos desde allí. ¡Esto le llevará menos de un minuto, pero ayudará en gran medida al desarrollo! Se agradece cualquier comentario, ya sea un informe de error, solicitud de función ¡o un simple gracias! Puede enviarlo más tarde desde la barra de menú superior (Ayuda->Enviar comentario). La versión actual está actualizada No hay actualizaciones, usted cuenta con la última versión. ¿Desea un poco más de funcionalidad o corregir un error? Por favor, envíe sus comentarios usando "Ayuda->Enviar comentario" del menú. Encontrado un error al buscar actualizaciones Asegúrese de que BCUninstaller no está bloqueado por su cortafuegos y que tiene una conexión a Internet. Nueva versión {0} disponible, ¿desea actualizar ahora? 0 is version number BCUninstaller descargará automáticamente la actualización y la aplicará después de un reinicio. Tenga en cuenta que es posible que pierda su configuración en el proceso. Lista de cambios: - {0} Advertencia: Durante la actualización serán eliminados la carpeta "Update" y el archivo "Update.zip" dentro del directorio delBCU. 0 is a list of changes separated by "- " Desinstalar utilizando MSI La entrada seleccionada no se puede desinstalar utilizando el instalador MsiExec El desinstalador seleccionado no tiene un GUID válido para su uso con MsiExec. Detener la tarea actual de desinstalación ¿Seguro que desea detener la ejecución de la tarea actual? Detener la tarea prematuramente no revertirá ningún cambio. El desinstalador en ejecución actual no se detendrá, la tarea esperará a que finalice. Crear un punto de restauración Error al crear un nuevo punto de restauración x64 keep space in front DEPURAR keep space in front Progreso de la desinstalación Ahora puede dejar el ordenador No se pudo ejecutar algunos de los desinstaladores .NET Framework v4.0 es opcional, pero recomendado. Las características que se basan en el framework se desactivará hasta que se instale. Eliminación de basura/restos ¿Realmente desea modificar los elementos de baja confianza? Los desinstaladores restantes deben poder completarse sin intervención del usuario. Usted debe todavía comprobar de vez en cuando en caso de que uno de los desinstaladores se bloquee. ¡La eliminación de los elementos marcados con baja a buena confianza pueden ser muy peligrosos! Se recomienda que compruebe si cada elemento es seguro para eliminar. Eliminar las claves de registro ¿Seguro que desea eliminar las entradas de desinstalación seleccionadas? Los siguientes elementos serán eliminados del registro y desaparecerán de la lista de desinstalación, pero no se pueden desinstalar. {0} Exportación fallida Se ha encontrado un error al guardar datos exportados Si el error persiste, intente guardar en un directorio diferente, por ejemplo en el escritorio. BCUninstaller está desinstalando {0} aplicaciones 0 is the uninstaller count Renombrar desinstalador El nombre proporcionado está vacío o contiene caracteres no válidos Asegúrese de que no ha incluido alguno de los siguientes caracteres: {0} 0 is list of characters separated by spaces ¿Desea buscar restos de las desinstalaciones realizadas? Tenga en cuenta que esta función está pensada para usuarios que entienden cómo funciona. No es necesario quitar estos archivos y no afectará el rendimiento del sistema en cualquier manera significativa. No se encontraron restos No se encontraron restos. Todavía puede haber algún residuo faltante por lo que debería ejecutar un limpiador de archivos temporales como BleachBit o similar. No había nada que copiar en el portapapeles. Ningún desinstalador seleccionado tiene este bit de información o no ha seleccionado nada. Copiar al portapapeles Abrir directorios Esta acción abrirá {0} directorios a la vez, ¿está seguro de que desea continuar? 0 is number of directories to open Buscar en línea No hay que buscar ¡Siento que nos deje! Si tiene un minuto, por favor, indique en mi sitio Web (http://klocmansoftware.weebly.com/) por qué desinstaló BCU. Haré mi mejor esfuerzo para solucionar cualquier problema legítimo. Si no está seguro de que las aplicaciones que está desinstalando son importantes o necesarias para la estabilidad del sistema, se recomienda crear un punto de restauración.  Si se daña algo después del siguiente procedimiento, puede utilizar Restaurar Sistema para deshacer los cambios. Se ha encontrado un error al abrir la página de búsqueda Guardar lista de desinstalación No se ha podido guardar la lista en un archivo ¿Está seguro que desea restablecer todos los ajustes de la aplicación? Algunas aplicaciones no se pueden desinstalar silenciosamente Algunas entradas están protegidas y no pueden ser modificadas La entrada seleccionada está protegida y no puede ser modificada Se ha encontrado un error al abrir la URL ¿Desea mantener la selección actual? Se ha encontrado un error al abrir el directorio No se pudieron cargar los archivos seleccionados No se seleccionaron desinstaladores, nada que desinstalar El siguiente comando no se pudo ejecutar: {0} {0} is a command line (c:\example.exe /help) Error de ejecución externa Al seleccionar "Terminar", se cerrará inmediatamente la desinstalación en ejecución y podría no ompletarse. Normalmente, es posible ejecutar el desinstalador de nuevo para terminar la desinstalación. Puede omitir la espera de este proceso. Esto permitirá que el desinstalador continúe trabajando mientras la tarea pasa al siguiente elemento. Tenga en cuenta que algunos desinstaladores pueden fallar para ejecutarse hasta que el proceso omitido termine. ¿Desea omitir la espera del desinstalador en ejecución? Los siguientes desinstaladores no se pudieron ejecutar, probablemente a causa de una colisión. Por favor, espere a que otros desinstaladores terminen y vuelva a intentarlo. {0} Puede intentar deshabilitar la detección de colisiones en la configuración, pero no es recomendable. Seleccionar abajo hasta... Ejecutando comandos de post-desinstalación... Ejecutando comandos de pre-desinstalación... Para desinstalar aplicaciones primero debe seleccionarlas de entre la lista. Si usted está usando checkboxs, asegúrese de que estén marcados. Si decide quedarse con la selección actual se fusionará con la(s) lista(s) abierta(s) Esta acción abrirá {0} URLs a la vez, ¿está seguro de que desea continuar? Entradas afectadas: {0} Para modificar estas entradas desactive la protección de desinstalación de la barra lateral de configuración. Puede eliminarlas de la tarea y continuar con otros elementos si lo desea. 0 names of protected uninstallers Entrada protegida: {0} Para modificar esta entrada tiene que desactivar la protección de desinstalación desde el panel de configuración. 0 name of protected uninstaller Los siguientes elementos no tienen desinstaladores silenciosos: {0} ¿Desea usar desinstaladores "fuertes" para estos elementos, o deberían ser removidos de la tarea? 0 is names of non-quiet uninstallers Todos los ajustes se perderán de forma permanente. BCUninstaller tendrá que reiniciarse para completar esta acción. El punto de restauración NO FUE CREADO, ¡usted no podrá restaurar los cambios! ¿Desea continuar con la desinstalación de todos modos? Nada que mostrar. Esta aplicación se desinstala utilizando el desinstalador de Windows (MsiExec). Algunos desinstaladores han fallado ¿Desea intentar ejecutar desinstaladores silenciosos que fallaron como fuertes? Los desinstaladores siguientes se reiniciarán altamente: Analizando directorio especificado... Seleccione el directorio con las aplicaciones que desea eliminar. Desinstalar del directorio No se encontraron aplicaciones en el directorio especificado Asegúrese de que ha seleccionado el directorio correcto y que los ejecutables de la aplicación siguen estando presentes. Encontrado un desinstalador para {0} ¿Desea ejecutar este desinstalador? Editor Asunto Archivado Extensiones Nombre Amigable Nombre del Editor Clave Privada Tiene Clave Privada Clave Pública Versión No Después No Antes Datos en Bruto Número de Serie Nombre del Asunto Algoritmo de Firma Huella Digital Error al guardar la configuración Terminando... Cargando iconos Buscar aplicación No se seleccionaron archivos o directorios válidos. Asegúrese de tener acceso a ellos y no están marcados como archivos de sistema. Buscar aplicaciones No se pudo encontrar ninguna aplicación dentro de {0} Modificar aplicación La aplicación seleccionada no se puede modificar La aplicación seleccionada no tiene comando de modificación especificado. Puede ser necesario desinstalar e instalar de nuevo para cambiar la configuración de instalación. Guardar lista de desinstalación ¿Desea guardar cambios en la lista de desinstalación abierta? Hay cambios no guardados en la lista de desinstalación abierta que se perderán al cerrarla. Seleccione el directorio con las aplicaciones a desinstalar. Seleccione dónde guardar la copia de seguridad. Se creará un nuevo directorio. ¡BCU se ha actualizado a v{0}! ¡Bienvenido a BCU, versión {0}! Poniendo la PC en reposo en {0}s. Desmarque la casilla de reposo para cancelar. No hace nada Option for "Double clicking in application list..." Abre las propiedades Option for "Double clicking in application list..." Desinstala Option for "Double clicking in application list..." ================================================ FILE: source/BulkCrapUninstaller/Properties/Localisable.fr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Création d'un point de restauration... Recherche de vestiges... Remplissage de la liste de désinstalleurs... Suppression des vestiges... Recherche de mises à jour... Il n'y a pas d'entrée correspondant à votre critère de recherche. Export BCUninstaller Éditeur | Version | Date | Taille | Registre | Type de désinstalleur | Chaîne de désinstallation | Chaîne de désinstallation silencieuse | Commentaires Portable keep space in front Échec en appelant l'API Échec en sauvegarde du registre, voulez-vous continuer tout de même ? Détails d'erreur : Suppression des vestiges Détails de l'erreur : Add space or newline afterwards and two newlines before Voulez-vous créer une sauvegarde du registre avant de continuer ? Vous pourrez revenir sur tous les changements en double-cliquant dessus par la suite. Fichiers et dossiers seront déplacés dans la corbeille, vous pouvez les restaurer à partir d'ici. Action échouée Vous devez ne sélectionner qu'une entrée pour cette action Sélectionnez exactement un désinstalleur dans la liste. Si vous utilisez les cases à cocher, assurez-vous de les cocher. Rechercher des mises à jour Ouvrir du contenu en ligne Connexion à internet impossible, il n'y a pas de réseau disponible. Vérifiez que le câble réseau est branché. Si vous utilisez le Wi-Fi vérifiez que vous avez une bonne force de signal. Soumettre un retour Voudriez-vous envoyer un retour concernant BCU ? Cela prendra moins d'une minute mais aidera grandement le développement ! Tout retour est apprécié, que ce soit un rapport de bogue, une demande de fonction ou un simple merci ! Vous pouvez l'envoyer plus tard à partir de la barre de menu du haut (Aide->Soumettre un retour). La version courante est à jour Aucune mise à jour n'a été trouvée pour l'heure, vous avez la dernière version. Vous voulez ajouter une fonctionnalité ou corriger une bogue ? Merci de m'envoyer votre retour en utilisant le menu "Aide->Soumettre un retour". Erreur rencontrée en vérifiant les mises à jour Vérifiez que BCUninstaller n'est pas bloqué dans votre pare-feu et que vous avez une connection internet fonctionnelle. Nouvelle version {0} disponible, voulez-vous mettre à jour maintenant ? 0 is version number BCUninstaller téléchargera automatiquement la mise à jour et l'appliquera après un redémarrage. Merci de noter que vous pouvez perdre vos réglages dans l'opération. Journal de changement : - {0} Attention : pendant la mise à jour le dossier "Update" et le fichier "Update.zip" dans le dossier de BCU seront supprimés. 0 is a list of changes separated by "- " Désinstaller en utilisant Msi L'entrée sélectionnée ne peut être désinstallée en utilisant l'installeur MsiExec Le désinstalleur sélectionné n'a pas pas de Guid valide à utiliser avec MsiExec. Arrêter la tâche courante de désinstallation Etes-vous sûr de vouloir arrêter la tâche courante ? Arrêter prématurément la tâche n'annulera pas tout changement. Le désinstalleur en cours d'exécution ne sera pas stoppé, la tâche attendra qu'il ait terminé. Créer un point de restauration Échec en créant un nouveau point de restauration x64 keep space in front DEBUG keep space in front Progression de la désinstallation Vous pouvez maintenant laisser l'ordinateur Les désinstalleurs restants devraient pouvoir terminer sans aucune intervention de l'utilisateur. Vous devriez quand même vérifier de temps en temps au cas où un des désinstalleurs plante. Suppression des déchets/vestiges Voulez-vous réellement modifier les éléments de faible-confiance ? La suppression des éléments marqués d'une confiance inférieure à Bon peut être très dangereuse ! Il vous est recommandé de vérifier qu'il est sûr de supprimer chaque élément individuel. Supprimer les clés du registre Êtes-vous sûr de vouloir supprimer les entrées du désinstalleur sélectionné ? Les élements suivants seront supprimés du registre et disparaîtront de la liste du désinstalleur, mais ne seront pas désinstallés. {0} Échec en exportant Erreur rencontrée pendant l'enregistrement des données exportées Si l'erreur persiste essayez de sauvegarder dans un dossier différent, par exemple sur le bureau. BCUninstaller désinstalle {0} application(s) 0 is the uninstaller count Renommer le désinstalleur Le nom fourni est vide ou contient des caractères invalides Vérifiez que vous n'avez inclus aucun des caractères suivants : {0} 0 is list of characters separated by spaces Voulez-vous voir les vestiges des désinstallations réalisées ? Merci de noter que cette fonction est conçue uniquement pour les utilisateurs avancés qui comprennent comment cela marche. Il n'est pas nécessaire de supprimer ces fichiers et ils n'affecteront les performances du système en aucune façon significative. Aucun vestige trouvé Aucun élément n'a été trouvé. Il pourrait encore rester des résidus, de sorte que vous pouvez lancer un nettoyeur de fichiers temporaires comme BleachBit. Il n'y a rien à copier dans le presse-papiers. Soit aucun désinstalleur sélectionné n'a ce bout d'information, soit vous n'avez rien sélectionné. Copier dans le presse-papiers Ouvrir les dossiers Cette action ouvrira {0} dossiers d'un coup, êtes-vous sûr de vouloir continuer ? 0 is number of directories to open Rechercher en ligne Rien à rechercher Désinstaller BCUninstaller Êtes-vous sur de vouloir désinstaller BCUninstaller ? Je suis désolé de vous voir partir ! Si vous avez une minute ou deux merci de laisser un mot sur mon site web (http://klocmansoftware.weebly.com/) pour dire pourquoi vous désinstallez BCU. Je ferai de mon mieux pour réparer tout problème légitime. Voulez-vous créer un point de restauration avant de continuer ? Si vous n'êtes pas sûr que les applications que vous désinstallez sont importantes ou nécessaires à la stabilité du système, il est recommandé de créer un point de restauration. Si quelque chose est rompu après la procédure vous pouvez alors utiliser la Restauration du système pour revenir sur les changements. Erreur rencontrée en ouvrant la page de recherche Sauvegarder la liste de désinstallation Échec en sauvegardant la liste dans un fichier Êtes-vous sûr de vouloir réinitialiser tous les réglages de l'application ? Quelques applications ne peuvent être désinstallées silencieusement Quelques entrées sont protégées et ne peuvent être modifiées L'entrée sélectionnée est protégée et ne peut être modifiée Une erreur a été rencontrée en ouvrant l'URL Voulez-vous garder la sélection courante ? Une erreur a été rencontrée en ouvrant le dossier Échec en chargeant les fichiers sélectionnés Aucun désinstalleur sélectionné, rien à désinstaller Lancer les désinstalleurs Pour désinstaller les applications vous devez d'abord les sélectionner depuis la vue liste. Si vous utilisez des cases à cochers, vérifiez qu'elles sont cochées. Si vous choisissez de garder la sélection courante, elle sera fusionnée avec la ou les listes ouvertes Cette action ouvrira {0} URLs d'un coup, êtes-vous sûr de vouloir continuer ? Ouvrir les URLs Pas d'URL à ouvrir Modifier l'élément protégé Entrées affectées : {0} Pour modifier ces entrées vous devez désactiver la protection du désinstalleur dans la barre latérale des réglages. Vous pouvez les supprimer de la tâche et continuer avec les autres éléments si vous voulez. 0 names of protected uninstallers Entrée protégée : {0} Pour modifier cette entrée vous devez désactiver la protection du désinstalleur dans le panneau de réglages. 0 name of protected uninstaller Les éléments suivants ne comportent pas de désinstalleur silencieux : {0} Voulez-vous utiliser les désinstalleurs "causants" pour ces éléments, ou doivent-ils être supprimés de la tâche ? 0 is names of non-quiet uninstallers Désinstallation silencieuse Restaurer les réglages par défaut Tous vos réglages seront perdus définitivement. BCUninstaller devra redémarrer pour terminer cette action. Ouvrir la liste de désinstallation Le point de restauration N'A PAS ETE CRÉÉ, vous ne pourrez pas restaurer les changements ! Voulez-vous continuer quand même la désinstallation ? Renommage de "{0}" Renommer l'entrée sélectionnée Tâche terminée Shown on the status bar Désinstallation Shown on the status bar Se rappeler le choix Erreur Fichier inexistant. Rien à afficher. Cette application est désinstallée en utilisant Windows Installer (MsiExec). Nom Valeur Vide GUID trouvé GUID manquant Sélectionner jusqu'à... Prêt Shows up when nothing else is displayed on the status bar. {0} désinstalleur(s) sélectionné(s) {0} is a number of selected uninstallers {0} désinstalleur(s) au total, {1} {0} is a number of all uninstallers, {1} is a long file size (123 Megabytes) La commande suivante a échoué à l'exécution: {0} {0} is a command line (c:\example.exe /help) Par défaut Used in language select box when you want to use the system language Fichier non trouvé. Lancement de commandes post-désinstallation... Lancement de commandes pré-désinstallation... Échec d'exécution externe Certains paramètres ne prendront pas effet jusqu'à ce que l'application soit relancée. Voulez-vous redémarrer BCU à appliquer les nouveaux réglages ? Modifier les réglages de l'application Certificat manquant Traitement des applications détectées, ({0}) restantes... {1} = how many application uninstallers still need to be processed Sélectionner "Terminer" fermera immédiatement le désinstalleur en cours et pourrait aboutir à une désinstallation incomplète. D'ordinaire, il est possible de relancer le désinstalleur pour finir la désinstallation. Alternativement, vous pouvez passer l'attente de ce processus. Passer laissera le désinstalleur continuer à travailler pendant que la tâche passera à l'élément suivant. Gardez à l'esprit que quelques désinstalleurs peuvent échouer à se lancer jusqu'à ce que le processus passé se termine. Voulez-vous passer l'attente pour le désinstalleur en cours ? Passer la tâche en cours Une autre tâche de désinstallation est déjà en cours. Merci d'attendre qu'elle ait fini puis réessayer. Notes : {0} Positives : {1} Négatives : {2} {0} - Rating as a string {1} - List of strings of positive parts of the rating {2} - List of strings of negative parts of the rating The lists are separated by a single newline. Détails de la note Cette application n'a pas une entrée de registre valide Cette application n'a pas un désinstalleur valide Chargement des Fonctionnalités Windows... Rafraîchissement des informations de démarrage... Shown when refreshing autostart information of the uninstallers Aucun dossier à ouvrir Indisponible Used on application list when value is not available Notes non disponibles Vous devez d'abord activer les notes dans les réglages. Vous ne pouvez pas noter les applications qui ne sont pas installées correctement. {0} applications {0} is number of apps to rate, "Rate " will be automatically put in front of this string Note moyenne: {0}; Ma note: {1} Les désinstalleurs suivants ont échoué à l'exécution, sûrement en raison d'une collision. Veuillez attendre que les autres désinstalleurs aient fini et réessayer. {0} Vous pouver tenter de désactiver la prévention de collision dans les réglages, mais ce n'est pas recommandé. Forcer la désinstallation Échec au lancement de certains des désinstalleurs Framework .NET 4.0 introuvable Framework .NET 4.0 introuvable, certaines fonctions seront désactivées Le Framework .NET 4.0 est optionnel, mais recommandé. Les fonctions reposant sur le framework seront désactivées jusqu'à son installation. Quelques désinstalleurs ont échoué Voulez-vous tenter de lancer des désinstalleurs silencieux qui ont échoué en normal ? Les désinstalleurs suivants seront redemarrés normalement : Balayage du dossier spécifié... Sélectionner le dossier avec les applications que vous voulez enlever. Désinstaller depuis le dossier Aucune application trouvée dans le dossier spécifié Assurez-vous d'avoir sélectionné le dossier correct et que les exécutables de l'application sont encore présents. Désinstalleur trouvé pour {0} Voulez-vous lancer ce désinstalleur? Émetteur Sujet Archivé Extensions Nom Familier Nom de l'Emetteur Pas Après Pas Avant Clé Privée A une Clé Privée Clé Publique Données Brutes Numéro de Série Nom de sujet Algorithme Signature Version Empreinte Échec à l'enregistrement des paramètres En train de finir... Icônes de chargement Chercher une application Aucun fichier ou dossier valide n'a été sélectionné. Assurez-vous que vous y avez accès, et qu'ils ne sont pas marqués comme fichiers système. Chercher des applications Impossible de trouver une application dans {0} Modifier l'application L'application sélectionnée ne peut être modifiée L'application sélectionnée n'a pas la commande modifier spécifiée. Il peut être nécessaire de la désinstaller, puis de l'installer à nouveau pour changer les réglages d'installation. Sauver la liste de désinstallation Sauver les changements de la liste de désinstallation ouverte ? Il y a des changements non sauvés dans la liste de désinstallation ouverte qui seront perdus en la fermant. Sélectionner le dossier avec les applications à désinstaller. Sélectionner où enregistrer la sauvegarde. Un nouveau dossier sera créé. BCU a été mis à jour en v{0} ! Bienvenue à BCU version {0} ! Mise en veille du PC dans {0}s. Décocher la case veille pour annuler. Ne fait rien Option for "Double clicking in application list..." Ouvre les propriétés Option for "Double clicking in application list..." Désinstalle Option for "Double clicking in application list..." Ne peut renommer {0} Ce type de désinstalleur ne supporte pas de renommer ({0}). ================================================ FILE: source/BulkCrapUninstaller/Properties/Localisable.hu.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Visszaállítási pont létrehozása... Maradványok keresése... Eltávolító lista feltöltése... Maradványok eltávolítása... Frissítések keresése... Nincs a keresési feltételnek megfelelő bejegyzés. BCUninstaller exportálás Kiadó | Verzió | Dátum | Méret | Beállításjegyzék | Eltávolító típusa | Eltávolítási karaktersorozat | Csendes eltávolító karaktersorozat | Megjegyzések Hordozható keep space in front Az API meghívása nem sikerült A beállításjegyzék mentése nem sikerült, mégis folytatni szeretné? Hiba részletei: Maradványeltávolítás Hiba részletei: Add space or newline afterwards and two newlines before Szeretné elkészíteni a beállításjegyzék mentését a folytatás előtt? Minden módosítást visszaállíthat a dupla kattintást követően. A fájlok és mappák a Lomtárba kerülnek, ahonnan visszaállíthatja azokat. A művelet nem sikerült Ehhez a művelethez csak egy bejegyzést kell kiválasztania A szükséges eltávolítót válassza ki a listából. Ha a jelölőnégyzeteket használja ellenőrizze a kijelölését. Frissítések keresése Online tartalom megnyitása Nem lehet csatlakozni az Internethez, nincsenek elérhető hálózatok. Kérem ellenőrizze, hogy a hálózati kábel be van-e dugva. Ha Wi-Fi-t használ vizsgálja meg a jelerősséget. Visszajelzés küldése Szeretne visszajelzést küldeni a BCU-val kapcsolatban? Ez kevesebb mint egy percet vesz csak igénybe, de nagyban segítheti a fejlesztéseinket! Minden visszajelzést nagyra értékelünk, legyen az hibajelzés, új igény, vagy egyszerűen csak köszönetnyilvánítás! Ezeket később is elküldheti a menüsávból (Súgó->Visszajelzés küldése). A jelenlegi verzió naprakész Jelenleg nem érhetők el frissítések, ön a legújabb verziót használja. Szeretné a funkciók bővítését, vagy hibával találkozott? Kérjük, hogy küldje el a visszajelzését a "Súgó->Visszajelzés küldése" menü használatával. Hiba történt a frissítések ellenőrzése közben Kérem ellenőrizze, hogy a BCUninstaller-t nem blokkolja-e a tűzfala, és működik-e az Internetkapcsolata. Új verzió {0} érhető el. Szeretne erre frissíteni most? 0 is version number A BCUininstaller automatikusan letölti a frissítéseket, és telepíti azokat a program újraindítását követően. A folyamat során a saját beállításai elveszhetnek. Módosítások: - {0} Figyelem: A frissítés közben a BCU könyvtárában levő "Update" mappa, és az "Update.zip" fájl törlésre kerül. 0 is a list of changes separated by "- " Eltávolítás az Msi használatával A kiválasztott bejegyzés nem távolítható el az MsiExec telepítővel A kiválasztott eltávolító nem rendelkezik érvényes GUID-al, az MsiExec használatához. Eltávolítási feladat leállítása Biztos benne, hogy leállítja az aktuálisan futó feladatot? A feladat idő előtti leállításával nem vonhatja vissza a módosításokat. A jelenleg futó eltávolítót nem lehet leállítani, a feladat várakozni fog a befejeződéséig. Visszaállítási pont létrehozása Az új visszaállítási pont létrehozása nem sikerült x64 keep space in front DEBUG keep space in front Eltávolítási folyamat Most itt hagyhatja a számítógépet A hátrahagyott eltávolítóknak képesnek kell lenniük, a felhasználói beavatkozás nélküli eltávolításra. Ennek ellenére időről-időre ellenőrizze azokat, ha az egyik eltávolító összeomlana. Feleslegesek/visszamaradtak törlése Valójában módosítani szeretné az alacsony biztonságú elemeket? Az eltávolításra kijelölt elemek biztonságos eltávolíthatósága a Jó szintnél alacsonyabb, ezért ez veszélyes lehet! Nagyon ajánlott az egyes elemek biztonságos törlésének az ellenőrzése. Kulcsok eltávolítása a Beállításjegyzékből Biztos benne, hogy törli a kijelölt eltávolítási bejegyzéseket? A következő elemek törlésre kerültek a Beállításjegyzékből, és eltűntek az eltávolítási listából, de nem lettek eltávolítva. {0} Az exportálás nem sikerült Egy hiba történt az exportált adatok elmentése közben Ha a hiba továbbra is fennáll, próbálja meg egy másik könyvtárba, például az Asztalra elmenteni. A BCUninstaller eltávolított {0} alkalmazást 0 is the uninstaller count Eltávolító átnevezése A megadott név üres, vagy érvénytelen karaktereket tartalmaz Győződjön meg róla, hogy ne legyenek benne a következő karakterek: {0} 0 is list of characters separated by spaces Szeretné felkutatni az eltávolítás után visszamaradt elemeket? Felhívjuk a figyelmét, hogy ez a lehetőség csak hozzáértő felhasználóknak ajánlott, akik tudják mit csinálnak. Ezeknek a fájloknak az eltávolítása nem szükséges, és nem lesznek hatással a rendszere teljesítményére. Nem találhatók maradványok Nem találhatók maradványok. Ennek ellenére bizonyos szemét hátramaradhatott, ezért futtasson le egy olyan jellegű takarítót, mint például a BleachBit. Semmi sem lett kimásolva a Vágólapra. Vagy nem jelölt ki semmit se, vagy az eltávolító nagyon kevés információval rendelkezik. Másolás a Vágólapra Könyvtárak megnyitása Ezzel a művelettel, egyszerre {0} könyvtár fog megnyílni. Biztos benne, hogy folytatja? 0 is number of directories to open Keresés az Interneten Nincs megadva semmi keresendő BCUninstaller eltávolítása Biztos benne, hogy szeretné eltávolítani a BCUninstaller-t? Sajnáljuk, hogy nem tetszett önnek a program! Ha van egy-két perce írjon pár szót a webhelyünkön (http://klocmansoftware.weebly.com/), hogy miért távolította el a BCU-t. Mindent megteszünk, hogy kijavítsuk a valós problémákat. Szeretne létrehozni egy visszaállítási pontot a folytatás előtt? Ha nem biztos abban, hogy az eltávolítandó alkalmazás fontos, vagy szükséges-e a rendszere működéséhez, javasolt egy visszaállítási pont létrehozása. Amennyiben a műveletet követően hibákat észlelne, a módosításokat visszavonhatja a Rendszer-visszaállítás segítségével. Hiba történt a keresőlap megnyitása közben Eltávolítási lista mentése Nem sikerült a lista mentése egy fájlba Biztos benne, hogy visszaállítja az alkalmazás összes beállítását? Néhány alkalmazást nem lehet csendesen eltávolítani Néhány bejegyzés védett, és ezért nem módosítható A kiválasztott bejegyzés védett és nem módosítható Egy hiba történt az URL megnyitása közben Szeretné megtartani a jelenlegi kijelöléseit? Egy hiba történt a könyvtár megnyitása közben Nem sikerült a kijelölt fájlok betöltése Nincsenek eltávolítók kiválasztva, semmi sem lesz eltávolítva Eltávolítók futtatása Az alkalmazások eltávolításához, először ki kell választania azokat a listanézetben. Ha a jelölőnégyzeteket használja, ellenőrizze a kijelölését. Ha úgy dönt, hogy szeretné megtartani a jelenlegi kijelöléseit, azok egyesítésre kerülnek a megnyitott listával Ezzel a művelettel, egyszerre {0} URL fog megnyílni. Biztos benne, hogy folytatja? URL-ek megnyitása Nincsenek megnyitható URL-ek Védett elem módosítása Érintett bejegyzések: {0} Ezeknek a bejegyzéseknek módosításához ki kell kapcsolnia a beállításoknál, az eltávolító védelmet. Vagy el is távolíthatja azokat a feladatból, és más elemekkel folytathatja, ha akarja. 0 names of protected uninstallers Védett bejegyzés: {0} A bejegyzés módosításához ki kell kapcsolnia a beállításoknál, az eltávolító védelmet. 0 name of protected uninstaller A következő elemeknek nincs csendes eltávolítójuk: {0} Szeretne normál eltávolítást ezekhez az elemekhez, vagy inkább eltávolítja azokat a feladatból? 0 is names of non-quiet uninstallers Csendes eltávolítás Alapbeállítások visszaállítása Az összes saját beállítása elfog veszni. A BCUninstaller-t újra kell indítani a művelet befejezéséhez. Eltávolítási lista megnyitása A visszaállítási pont NEM KERÜLT LÉTREHOZÁSRA, így a módosítások nem vonhatók vissza! Ennek ellenére továbbra is folytatni szeretné az eltávolítást? "{0}" átnevezése Kijelölt bejegyzés átnevezése A feladat befejeződött Shown on the status bar Eltávolítás Shown on the status bar Választás megjegyzése Hiba A fájl nem létezik. Nincs mit megjeleníteni. Ez az alkalmazás a Windows Installer (MsiExec) használatával távolítható el. Név Érték Üres GUID van A GUID hiányzik Kijelölés lefelé... A fájl nem található. Eltávolítás utáni parancsok futtatása... Eltávolítás előttii parancsok futtatása... Kész Shows up when nothing else is displayed on the status bar. {0} eltávolító kijelölve {0} is a number of selected uninstallers {0} eltávolító, összesen {1} {0} is a number of all uninstallers, {1} is a long file size (123 Megabytes) A következő parancs végrehajtása nem sikerült: {0} {0} is a command line (c:\example.exe /help) A külső futtatás nem sikerült Alapérték Used in language select box when you want to use the system language Néhány beállítása nem lép életbe, amíg nem indítja újra a programot. Szeretné újraindítani a BCU-t, az új beállítások érvényesítéséhez? Programbeállítások módosítása A tanúsítvány hiányzik Eltávolítók feldolgozása ({0}) {1} = how many application uninstallers still need to be processed A "Leállítás" választásával azonnal bezárásra kerül az épp futó eltávolító, és ez azt eredményezheti, hogy az eltávolítás nem lesz teljes. Általában az eltávolító újra futtatható, az eltávolítás befejezése érdekében. Másik lehetőség, hogy kihagyja ezt a várakozó folyamatot. A kihagyással az eltávolító folytatja a működését, a következő elemre történő lépéssel. Vegye figyelembe, hogy néhány eltávolító nem fog futni, amíg a kihagyott folyamat nem fejeződik be. Szeretné kihagyni a jelenleg várakozó eltávolítót? Jelenlegi feladat kihagyása Egy másik feladat már folyamatban van. Kérem, hogy várja meg amíg az befejeződik, majd próbálja meg újra. Értékelés: {0} Pozitív: {1} Negatív: {2} {0} - Rating as a string {1} - List of strings of positive parts of the rating {2} - List of strings of negative parts of the rating The lists are separated by a single newline. Értékelés részletei Ez az alkalmazás nem rendelkezik érvényes registry bejegyzéssel Ez az alkalmazás nem rendelkezik szabályos eltávolítóval Windows-szolgáltatások betöltése... Indítópult információk frissítése... Shown when refreshing autostart information of the uninstallers Nincsenek megnyitandó könyvtárak Nem érhető el Used on application list when value is not available Az értékelés nem érhető el Az értékeléshez először azt engedélyeznie kell a beállításoknál. Azok az alkalmazások nem értékelhetők, amelyek nincsenek megfelelően telepítve. {0} program {0} is number of apps to rate, "Rate " will be automatically put in front of this string Átlagos értékelés: {0}; Saját értékelés: {1} A következő eltávolítók futtatása, feltehetően összeütközés miatt nem sikerült. Kérem várjon, amíg az egyéb eltávolítók végeznek, majd próbálja meg újra. {0} A beállításoknál megpróbálhatja letiltani az összeütközések észlelését, de ez nem ajánlott. Kényszerített eltávolítás Néhány eltávolító futtatása nem sikerült A .NET Framework v4.0 nem található A .NET Framework v4.0 nem található, ezért néhány lehetőség letiltásra kerül A v4.0 keretrendszer megléte nem kötelező, de ajánlott. A keretrendszerhez kapcsolódó funkciók letiltásra kerülnek, amíg nem telepíti azt. Néhány eltávolító nem működött A sikertelenek esetében megpróbálja a háttérben az eltávolítást? A következő eltávolítók normál módú újraindítása: Megadott könyvtár ellenőrzése... Válassza ki azt a könyvtárat, ahonnan szeretné a programokat eltávolítani. Eltávolítás a könyvtárból Nem találhatóak alkalmazások a megadott könyvtárban Gondoskodjék a megfelelő könyvtár kiválasztásáról és arról, hogy a futtatható alkalmazás ebben a könyvtárban legyen. Eltávolítót találtam ehhez {0} Szeretné futtatni ezt az eltávolítóprogramot? Kiállító Tulajdonos Archiválva Kiterjesztések Rövid név Kiállító neve Ezután nem Ez előtt nem Titkos kulcs Van titkos kulcs Nyilvános kulcs Nyers adatok Sorozatszám Tulajdonos neve Aláírási algoritmus Verzió Ujjlenyomat Nem sikerült a beállítások mentése Befejezés... Ikonok betöltése A BCU a(z) {0} verzióra frissült! Üdvözli a BCU {0} verziója! Alvó módba lépés {0} mp múlva. Kattintson az alvó mód beállítás jelölőnégyzetébe a visszavonáshoz. Alkalmazás keresése Nincs érvényes fájl vagy könyvtár kiválasztva. Győződjön meg arról, hogy hozzáférhet ezekhez, és hogy nincsenek rendszerfájlként megjelölve. Alkalmazás keresése Nem található alkalmazás a ezen helyen: {0} Alkalmazás módosítása Kijelölt alkalmazás nem módosítható Eltávolítólista mentése A megnyitott eltávolítólistán végzett módosítatások mentése? A megnyitott eltávolítólistában vannak nem mentett módosítások, amelyek bezárásakor elvesznek. Válassza ki az eltávolítani kívánt alkalmazások könyvtárát. Válassza ki, hová szeretné menteni a biztonsági másolatot. Egy új könyvtár jön létre. ================================================ FILE: source/BulkCrapUninstaller/Properties/Localisable.it.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Creazione punto di ripristino... Ricerca oggetti residui... Creazione elenco disinstallazione... Rimozione oggetti residui... Ricerca aggiornamenti... Non ci sono voci che corrispondano ai criteri di ricerca. Esportazione BCUninstaller Editore | Versione | Data | Dimensione | Registro | Tipo di disinstallatore | Stringa disinstallazione | Stringa disinstallazione silenziosa | Commenti Portatile keep space in front Chiamata dell'API non riuscita Backup del registro non riuscito. Vuoi continuare ugualmente? Dettaglio errori: Rimozione oggetti residui Dettaglio errori: Add space or newline afterwards and two newlines before Vuoi creare un backup del registro prima di continuare ? Sarà possibile annullare tutti i cambiamenti facendo clic due volte successivamente. File e cartelle saranno spostati nel Cestino. Potrai recuperarli da lì. Azione fallita Per questa azione devi selezionare una sola voce Seleziona esattamente un installatore dall'elenco. Se usi le caselle di controllo assicurati di selezionarli. Ricerca aggiornamenti Apri contenuti online Non è possibile collegarsi ad internet, poixchè non ci sono reti disponibili. Assicurati che il cavo di rete sia collegato. Se usi il WiFi assicurati che la qualità del segnale sia buona. Invia feedback Vuoi inviare feedback su BCU? Ti occuperà per meno di un minuto ma aiuterà molto lo sviluppo! Tutti i feedback sono apprezzati, che siano una segnalazione di errori, una richiesta di funzionalità aggiuntive o un semplice grazie! Puoi inviarlo in seguito dalla barra del menù superiore (Aiuto -> Invia feedback). Questa versione è aggiornata Non sono disponibili aggiornamenti. La versione in uso è aggiornata. Vuoi che siano aggiunte nuove funzionalità o correggere un errore? Puoi inviarci un feedback dal menù "Aiuto -> Invia feedback". Errore riscontrato durante la verifica di aggiornamenti Assicurati che BCUninstaller non sia bloccato dal firewall e che la connessione internet sia funzionante. È disponibile una nuova versione {0}. Vuoi aggiornare ora? 0 is version number BCUninstaller scaricherà automaticamente l'aggiornamento e lo installerà al riavvio. Nel corso del processo potresti perdere le configurazioni . Novità programma (changelog): - {0} Attenzione: nel corso dell'aggiornamento la cartella "Update" e il file "Update.zip" nella cartella di BCU saranno rimossi. 0 is a list of changes separated by "- " Disinstalla utilizzando Msi La voce selezionata non può essere disinstallata con l'installatore MsiExec Il disinstallatore selezionato non ha una GUID valida per essere utilizzato con MsiExec. Ferma l'operazione di disinstallazione in corso Sei sicuro di voler interrompere l'operazione? Fermando l'attività prima della sua fine non verranno annullate tutte le modifiche effettuate. I disinstallatori in esecuzione non saranno fermati, continueranno fino al termine. Crea un punto di ripristino Creazione del nuovo punto di ripristino fallita x64 keep space in front DEBUG keep space in front Avanzamento disinstallazione Ora puoi lasciare il computer I disinstallatori rimasti dovrebbero poter completare le operazioni senza intervento dell'utente. Controlla ogni tanto l'avanzamento nel caso il disinstallatore si blocchi. Rimozione oggetti residui Vuoi davvero modificare gli elementi con bassa affidabilità? La rimozione di elementi con affidabilità minore di "Buona" può essere molto pericolosa! Ti raccomandiamo di verificare che ogni singolo elemento sia sicuro da rimuovere. Rimozione chiavi di registro Sei sicuro di voler rimuovere le voci di disinstallazione selezionate? I seguenti elementi saranno rimossi dal registro e dall'elenco del disinstallatore, ma non saranno disinstallati. {0} Esportazione fallita Errore riscontrato durante il salvataggio dei dati esportati Se l'errore persiste prova a salvare in una cartella diversa, ad esempio sul desktop. BCUninstaller sta disinstallando {0} applicazione/i 0 is the uninstaller count Rinomina disinstallatore Il nome indicato è vuoto o contiene caratteri invalidi Assicurati di non aver incluso nessuno dei seguenti caratteri: {0} 0 is list of characters separated by spaces Vuoi controllare le presenza nelle disinstallazioni effettuate di elementi rimanenti? Considera che questa funzionalità è rivolta ad utenti esperti che sanno come funziona. Non è necessario rimuovere questi file e non comprometteranno le prestazioni del sistema in maniera significativa. Non è stato triovato nessun elemento rimanente Nessun elemento rimanente trovato. Ci potrebbero essere alcuni residui e file temporanei che puoi rimuovere con programmi tipo BleachBit. Non c'è nulla da copiare negli Appunti. Nessun disinstallatore selezionato ha questo bit di informazione oppure non hai selezionato nulla. Copia negli Appunti Apri cartella Questa azione aprirà {0} cartelle alla volta. Sei sicuro di voler continuare? 0 is number of directories to open Ricerca in internet Nulla da cercare Disinstalla BCUninstaller Sei sicuro di voler disinstallare BCUninstaller? Mi dispiace che ci vuoi lasciare! Se hai un minuto ti chiedo di scrivere sul sito web (http://klocmansoftware.weebly.com/) per quale motivo disinstalli BCU. Farò il massimo per porre rimedio ad ogni problema. Prima di continuare vuoi creare un punto di ripristino? Se hai dubbi che l'applicazione che stai disinstallando sia importante o necessaria per la stabilità del sistema è raccomandata la creazione di un punto di ripristino. Se qualunque cosa non dovesse funzionare dopo la procedura potrai ripristinare il sistema per annullare i cambiamenti. Errore nell'apertura della pagina di ricerca Salva elenco disinstallazione Errore nel salvataggio dell'elenco disinstallazione in un file Sei sicuro di voler ripristinare tutti i paramenti dell'applicazione? Alcune applicazioni non possono essere disinstallate silenziosamente Alcune voci sono protette e non possono essere modificate La voce selezionata è protetta e non può essere modificata Errore nell'apertura dell'URL Vuoi mantenere la selezione attuale? Errore nell'apertura della cartella Impossibile caricare i file selezionati Nessun disinstallatore è stato selezionato, niente da disinstallare Esegui disinstallazioni Per disinstallare la applicazioni devi prima selezionarle nell'elenco. Se usi i riquadri di controllo assicurati che siano segnate. Se decidi di mantenere l'attuale selezione questa sarà unita agli elenchi aperti Questa operazione aprirà {0} URL alla volta. Sei sicuro di voler continuare? Apri URL Nessuna URL da aprire Modifica elemento protetto Voci interessate: {0} Per modificare queste voci devi disabilitare la protezione della disinstallazione dalla barra laterale di configurazione. Se preferisci puoi rimuoverle dall'attività e continuare con gli altri elementi. 0 names of protected uninstallers Voci protette: {0} Per modificare queste voci devi disabilitare la protezione della disinstallazione dal pannello di configurazione. 0 name of protected uninstaller I seguenti elementi non hanno un disinstallatore silenzioso: {0} Vuoi utilizzare i disinstallatori guidati per questi elementi? O preferisci siano rimossi dall'attività? 0 is names of non-quiet uninstallers Disinstallazione silenziosa Ripristina impostazioni predefinite Tutte le tue impostazioni saranno perse definitivamente. Per completare questa azione BCUninstaller deve essere riavviato. Apri elenco disinstallazione Il punto di ripristino NON E' STATO CREATO. Non sarà possibile annullare le modifiche. Vuoi continuare comunque con la disinstallazione? Rinomina di "{0}" Rinomina la voce selezionata Attività completata Shown on the status bar Disinstallazione Shown on the status bar Ricorda la scelta Errore Il file non esiste. Nulla da visualizzare. Questa applicazione si disinstalla con Windows Installer (MsiExec). Nome Valore Vuoto GUID trovato GUID mancante Seleziona in basso fino a... FIle non trovato. Esecuzione comandi post-disinstallazione... Esecuzione comandi pre-disinstallazione... Pronto Shows up when nothing else is displayed on the status bar. {0} disinstallatori selezionati {0} is a number of selected uninstallers {0} disinstallatori in totale, {1} {0} is a number of all uninstallers, {1} is a long file size (123 Megabytes) Fallita esecuzione del seguente comando: {0} {0} is a command line (c:\example.exe /help) Esecuzione esterna fallita Predefinita Used in language select box when you want to use the system language Alcuni parametri non saranno attivi fino a quando l'applicazione non sarà riavviata. Vuoi riavviare BCU per rendere operative le nuove impostazioni? Modifica impostazioni programma Certificato mancante Elaborazione applicazioni rilevate. {0} mancanti... {1} = how many application uninstallers still need to be processed Selezionando "Termina" sarà immediatamente fermato il disinstallatore in esecuzione e la disinstallazione potrebbe non essere completata. Normalmente per completare l'attività è possibile eseguire nuovamente il disinstallatore. In alternativa puoi saltare l'attesa per questo processo. In questo modo farai in modo che il disinstallatore continuerà a lavorare mentre l'attività passerà all'elemento successivo. Ricorda che alcuni disinstallatori potrebbero non avviarsi fino a quando il processo saltato non verrà completato. Vuoi smettere di attendere il processo di disinstallazione in corso? Salta operazione in esecuzione Un altro processo di disinstallazione è già in corso. Attendi il completamento e quindi riprova. Valutazioni: {0} Positive: {1} Negative: {2} {0} - Rating as a string {1} - List of strings of positive parts of the rating {2} - List of strings of negative parts of the rating The lists are separated by a single newline. Dettagli valutazione Questa applicazione non ha voci di registro valide Questa applicazione non ha un disinstallatore valido Caricamento funzionalità di Windows... Aggiornamento informazioni avvio automatico... Shown when refreshing autostart information of the uninstallers Nessuna cartella da aprire Non disponibile Used on application list when value is not available Valutazioni non disponibili Devi prima abilitare le valutazioni nelle impostazioni. Non puoi valutare le applicazioni che non sono installate correttamente. {0} applicazioni {0} is number of apps to rate, "Rate " will be automatically put in front of this string Valutazione media: {0}; la mia valutazione: {1} I seguenti disinstallatori hanno fallito l'esecuzione, forse per una collisione. Attendi che gli altri disinstallatori finiscano e riprova. {0} Puoi provare a disabilitare la rilevazione delle collisioni nelle impostazioni, ma non è raccomandato. Forza disinstallazione Esecuzione fallita di alcuni disinstallatori .NET Framework v4.0 non trovato .NET Framework v4.0 non trovato. Alcune funzioni saranno disabilitate Il framework v4.0 è opzionale, ma raccomandato. Le funzionalità che si basano su framework saranno disabilitate fino quando non sarà installato. Alcuni disinstallatori hanno fallito Vuoi provare ad eseguire i disinstallatori silenziosi che hanno fallito in modalità guidata? I seguenti disinstallatori saranno riavviati in modalità guidata: Scansione cartelle specificate... Seleziona le cartelle con applicazioni che vuoi rimuovere. Disinstalla dalla cartella Nessuna applicazione trovata nelle cartelle specificate Assicurati di aver selezionato le cartelle corrette e che gli eseguibili delle applicazioni siano ancora presenti. Trovato un disinstallatore per {0} Vuoi eseguire questo disinstallatore? Produttore Argomento Archiviato Estensioni Nome intuitivo Nome emittente Non dopo Non prima Chiave privata Ha una chiave privata Chiave pubblica Dati grezzi Numero seriale Nome argomento Algoritmo di firma Versione Impronta digitale Salvataggio impostazioni fallito Completamento operazioni... Caricamento icone Ricerca applicazione Non sono stati selezionati file o cartelle validi. Assicurati di avere i corretti diritti di accesso e che non abbiano attributi di sistema Ricerca applicazioni Impossibile rilevare applicazioni all'interno di {0} Modifica applicazione L'applicazione selezionata non uò essere modificata L'applicazione selezionata non ha i comandi di modifica specificati. Per modificare i parametri di installazione potrebbe essere necessario disinstallarla e quindi reinstallarla.. Salva elenco disinstallazione Vuoi salvare le modifiche dell'elenco disinstallazione aperto? Nell'elenco disinstallazione aperto sono presenti alcune modifiche non salvate che saranno perse alla chiusura. Seleziona la cartella con le applicazioni da disinstallare. Seleziona dove salvare la copia di sicurezza. Sarà creata una nuova cartella. BCU è stato aggiornato alla versione v{0}! Benvenuto/a nella versione {0} di BCU! Il PC verrà messo nello stato di sleep tra {0} secondi. Per annullare deseleziona la casella di controllo 'sleep'. Non fare nulla Option for "Double clicking in application list..." Apri proprietà Option for "Double clicking in application list..." Disinstalla Option for "Double clicking in application list..." Impossibile rinominare {0} Questo tipo di programma di disinstallazione non supporta la ridenominazione ({0}). ================================================ FILE: source/BulkCrapUninstaller/Properties/Localisable.ja.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 適切にインストールされていないアプリケーションを評価することはできません。 静かにアンインストール デフォルト設定を復元 すべての設定は永久に失われます。BCUninstallerはこのアクションを完了するために再起動する必要があります。 アンインストールリストを開く リストアポイントが作成されませんでした。変更を元に戻すことはできません!それでもアンインストールを続行しますか? "{0}"の名前を変更 選択したエントリの名前を変更 タスク完了 Shown on the status bar アンインストール中 Shown on the status bar 選択を記憶 エラー ファイルが存在しません。 表示するものはありません。このアプリケーションはWindows Installer(MsiExec)を使用してアンインストールされています。 名前 GUIDが見つかりました GUIDがありません ...まで選択 ファイルが見つかりません。 アンインストール後のコマンドを実行中... アンインストール前のコマンドを実行中... 準備完了 Shows up when nothing else is displayed on the status bar. {0}のアンインストーラーが選択されました {0} is a number of selected uninstallers 合計{0}のアンインストーラー、{1} {0} is a number of all uninstallers, {1} is a long file size (123 Megabytes) 次のコマンドの実行に失敗しました: {0} {0} is a command line (c:\example.exe /help) 外部実行に失敗しました デフォルト Used in language select box when you want to use the system language 一部の設定はアプリケーションが再起動されるまで適用されません。 新しい設定を適用するためにBCUを再起動しますか? アプリケーション設定を変更 証明書がありません 検出されたアプリケーションを処理中、残り{0}... {1} = how many application uninstallers still need to be processed 選択した「終了」は、実行中のアンインストーラーを即座に閉じ、アンインストールが完了しない可能性があります。通常、アンインストーラーを再実行してアンインストールを完了することができます。 また、このプロセスを待つのをスキップすることもできます。スキップすることで、アンインストーラーは作業を続け、タスクは次の項目に移動します。ただし、スキップしたプロセスが完了するまで、一部のアンインストーラーが実行されない可能性があることに注意してください。 評価の詳細 このアプリケーションには有効なレジストリエントリがありません。 このアプリケーションには有効なアンインストーラーがありません。 Windowsの機能を読み込んでいます... 起動情報を更新しています... Shown when refreshing autostart information of the uninstallers 開くディレクトリはありません。 利用できません。 Used on application list when value is not available 評価は利用できません。 設定から評価を有効にする必要があります。 {0} アプリケーション {0} is number of apps to rate, "Rate " will be automatically put in front of this string 平均評価: {0}; 私の評価: {1} 次のアンインストーラーの実行に失敗しました。おそらく衝突が原因です。他のアンインストーラーが完了するのを待ってから再試行してください。 {0} 設定で衝突検出を無効にすることもできますが、お勧めしません。 強制アンインストール いくつかのアンインストーラーを実行できませんでした。 .NET Framework v4.0が見つかりませんでした。 .NET Framework v4.0が見つかりませんでした。一部の機能が無効になります。 v4.0フレームワークはオプションですが、推奨されます。このフレームワークに依存する機能は、インストールするまで無効のままとなります。 いくつかのアンインストーラーが失敗しました。 失敗した静かなアンインストーラーを騒音アンインストーラーで再実行しますか? 次のアンインストーラーは、騒音アンインストーラーで再実行されます: 指定されたディレクトリをスキャンしています... 削除したいアプリケーションがあるディレクトリを選択してください。 ディレクトリからアンインストール 指定されたディレクトリ内にアプリケーションが見つかりませんでした。 正しいディレクトリを選択し、アプリケーションの実行ファイルがまだ存在することを確認してください。 {0} のアンインストーラーが見つかりました。 このアンインストーラーを実行しますか? 発行者 件名 アーカイブされた 拡張子 表示名 発行者名 有効期限 発行日 秘密鍵 秘密鍵があります 公開鍵 生データ シリアル番号 件名 署名アルゴリズム バージョン サムプリント 設定の保存に失敗しました。 最終処理中... アイコンを読み込んでいます アプリケーションを探しています 有効なファイルまたはディレクトリが選択されていません。 アプリケーションを探す {0} 内にアプリケーションが見つかりませんでした。 アプリケーションを変更 選択したアプリケーションは変更できません。 選択したアプリケーションには変更コマンドが指定されていません。 インストール設定を変更するには、アンインストールして再インストールする必要がある場合があります。 アンインストールリストを保存 開いているアンインストールリストに変更を保存しますか? 開いているアンインストールリストに未保存の変更があります。これを閉じると失われます。 アンインストールするアプリケーションのあるディレクトリを選択してください。 バックアップを保存する場所を選択します。新しいディレクトリが作成されます。 BCUはv{0}に更新されました! BCUバージョン{0}へようこそ! {0}秒後にPCをスリープ状態にします。スリープのチェックボックスを外すとキャンセルされます。 何もしない Option for "Double clicking in application list..." プロパティを開く Option for "Double clicking in application list..." アンインストールする Option for "Double clicking in application list..." 復元ポイントを作成する... 残留物の検索... アンインストーラリストを作成する 残存物を削除しています... アップデートを検索する... 検索条件に一致するエントリはありません。 BCUninstaller のエクスポート 発行者|バージョン|日付|サイズ|レジストリ|アンインストーラの種類|アンインストール文字列|静かなアンインストール文字列|コメント ポータブル keep space in front APIの呼び出しに失敗しました レジストリのバックアップに失敗しましたが、続行しますか? エラー詳細: 残存物の削除 エラーの詳細です: Add space or newline afterwards and two newlines before 続行する前にレジストリのバックアップを作成しますか? 後でダブルクリックすることで、すべての変更を元に戻すことができます。 ファイルとディレクトリはゴミ箱に移動され、そこから復元できます。 アクションの失敗 このアクションには1つのエントリのみを選択する必要があります。 リストから正確に1つのアンインストーラーを選択してください。チェックボックスを使用している場合は、必ずチェックしてください。 アップデートを検索する オンラインコンテンツを開く インターネットに接続できない、利用可能なネットワークがない。 インターネットに接続できません。利用可能なネットワークがありません。 ネットワークケーブルが接続されていることを確認してください。Wi-Fiを使用している場合は、信号強度が良好であることを確認してください。 フィードバックの送信 BCUに関するフィードバックを送信しますか? これには1分もかかりませんが、開発に大いに役立ちます!バグ報告、機能リクエスト、単なる感謝の言葉など、どんなフィードバックでも歓迎です! 後で上部メニューバーから送信できます(ヘルプ->フィードバックを送信) 現在のバージョンは最新です。 現在のところ更新は見つかりませんでした。最新バージョンを使用しています。 機能の追加やバグの修正を希望しますか?「ヘルプ->フィードバックを送信」メニューを使用してフィードバックを送信してください。 更新を確認中にエラーが発生しました BCUninstallerがファイアウォールでブロックされておらず、インターネット接続が正常であることを確認してください。 新しいバージョン{0}が利用可能です。今すぐアップグレードしますか? 0 is version number BCUninstallerは自動的に更新をダウンロードし、再起動後に適用します。この過程で設定が失われる可能性があることに注意してください。 変更履歴: - {0} 警告:更新中にBCUディレクトリ内の「Update」フォルダと「Update.zip」ファイルが削除されます。 0 is a list of changes separated by "- " 影響を受けるエントリ: {0} これらのエントリを変更するには、設定サイドバーからアンインストーラー保護を無効にする必要があります。タスクから削除し、他のアイテムを続行することもできます。 0 names of protected uninstallers 保護されたエントリ: {0} このエントリを変更するには、設定パネルからアンインストーラー保護を無効にする必要があります。 0 name of protected uninstaller 次のアイテムにはサイレントアンインストーラーがありません: {0} これらのアイテムに「騒音」アンインストーラーを使用しますか、それともタスクから削除しますか? 0 is names of non-quiet uninstallers Msiを使用してアンインストールする 選択したエントリはMsiExecインストーラーを使用してアンインストールできません 選択したアンインストーラーには、MsiExecで使用するための有効なGuidがありません。 現在のアンインストールタスクを停止 現在実行中のタスクを停止してもよろしいですか? タスクを早期に停止すると、変更は元に戻りません。現在実行中のアンインストーラーは停止せず、タスクは完了するまで待機します。 リストアポイントを作成 新しいリストアポイントの作成に失敗しました x64 keep space in front デバッグ keep space in front アンインストールの進行状況 コンピューターを離れることができます 残りのアンインストーラーは、ユーザーの介入なしに完了できるはずです。アンインストーラーの1つがクラッシュした場合に備えて、時々確認してください。 ジャンク/残存物の削除 本当に信頼度の低いアイテムを変更しますか? 良い以下の信頼度でマークされたアイテムを削除することは非常に危険です!すべてのアイテムが削除しても安全であることを確認することをお勧めします。 レジストリからキーを削除 選択したアンインストーラーエントリを削除してもよろしいですか? 次のアイテムはレジストリから削除され、アンインストーラーリストから消えますが、アンインストールはされません。 {0} エクスポートに失敗しました エクスポートされたデータを保存中にエラーが発生しました エラーが続く場合は、別のディレクトリに保存してみてください。たとえば、デスクトップに保存します。 BCUninstallerは{0}アプリケーションをアンインストールしています 0 is the uninstaller count アンインストーラーの名前を変更 提供された名前が空であるか、無効な文字 次の文字が含まれていないことを確認してください: {0} 0 is list of characters separated by spaces 実行されたアンインストールの残留物を探しますか? この機能は、その動作を理解しているパワーユーザー向けのものです。このファイルを削除する必要はなく、システムのパフォーマンスに有意な影響を与えることはありません。 残留物は見つかりませんでした 残留物は見つかりませんでした。まだいくらかの残留物が残っている可能性があるため、BleachBitのような一時ファイルクリーナーを実行できます。 クリップボードにコピーするものはありませんでした。選択したアンインストーラーにはこの情報が含まれていないか、何も選択されていません。 クリップボードにコピー ディレクトリを開く この操作は{0}のディレクトリを一度に開きます。続行してもよろしいですか? 0 is number of directories to open オンライン検索 検索するものはありません BCUninstallerをアンインストール BCUninstallerをアンインストールしてもよろしいですか? お別れは残念です! お時間があれば、なぜBCUをアンインストールしたのかを私のウェブサイト(http://klocmansoftware.weebly.com/)で教えていただけると幸いです。 正当な問題を修正できるよう最善を尽くします。 続行する前にリストアポイントを作成しますか? アンインストールするアプリケーションが重要であるか、システムの安定性に必要かどうか不明な場合は、リストアポイントを作成することをお勧めします。 手順後に何か問題が発生した場合は、システムの復元を使用して変更を元に戻すことができます。 検索ページを開いているときにエラーが発生しました アンインストールリストを保存 リストをファイルに保存できませんでした すべてのアプリケーション設定をリセットしてもよろしいですか? 一部のアプリケーションは静かにアンインストールできません 一部のエントリは保護されており、変更できません 選択したエントリは保護されており、変更できません URLを開いているときにエラーが発生しました 現在の選択を保持しますか? ディレクトリを開いているときにエラーが発生しました 選択したファイルを読み込めませんでした アンインストーラーが選択されていません。アンインストールするものはありません アンインストーラーを実行 アプリケーションをアンインストールするには、最初にリストビューから選択する必要があります。チェックボックスを使用している場合は、必ずチェックしてください。 現在の選択を保持する場合、それは開いているリストと統合されます このアクションは{0}のURLを一度に開きますが、続行してもよろしいですか? URLを開く 開くURLはありません 保護された項目を変更 現在実行中のアンインストーラーを待つのをスキップしますか? 現在実行中のタスクをスキップ 別のアンインストールタスクがすでに実行中です。完了するまでお待ちください。その後、再試行してください。 評価: {0} ポジティブ: {1} ネガティブ: {2} {0} - Rating as a string {1} - List of strings of positive parts of the rating {2} - List of strings of negative parts of the rating The lists are separated by a single newline. ================================================ FILE: source/BulkCrapUninstaller/Properties/Localisable.nl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Maak een herstelpunt... Zoeken naar programma restanten De de-installatie lijst vullen... Programma restanten verwijderen... Zoeken naar updates... Er zijn geen registraties, die met uw zoekbegrip overeenkomen. BCUninstaller Export Uitgever | Versie | Datum | Grootte | Registry | De-installatie type | De-installatie string | De-installatie string (stil) | Commentaar Portabel keep space in front Oproep van API mislukt Back-up van register is mislukt. Wilt u toch doorgaan? Fout details: Restanten verwijderen Fout details: Add space or newline afterwards and two newlines before Wilt u een back-up van het register maken, voordat u verder gaat? U kunt alle wijzigingen terugzetten, als u daar later op dubbel klikt. Bestanden en mappen worden verplaatst naar de prullenbak, van waaruit u deze kunt herstellen. De bewerking is mislukt U moet één registratie voor deze bewerking selecteren Selecteer exact één de-installer uit de lijst. Maakt u gebruikt van checkboxen, controleer deze dan voor de uitvoering! Zoeken naar updates Online inhoud openen Geen verbinding met het Internet. Er is geen netwerk beschibaar. Weet u zeker dat u lopende taken wilt beëindigen? Een herstelpunt maken? Export is mislukt BCUninstaller de-installeert {0} programma('s) 0 is the uninstaller count De-installer hernoemen De opgegeven naam is leeg of bevat ongeldige tekens Let op: dit onderdeel is alleen bedoeld voor ervaren gebruikers, die begrijpen hoe het e.e.a. werkt. Het is niet nodig om deze bestanden te verwijderen, als deze de systeem prestaties niet wezenlijk beïnvloeden. Geen programma restanten gevonden Geen restanten gevonden. Mogelijke restanten kunt u met een tijdelijke bestandenreiniger zoals BleachBit verwijderen. Online zoeken Niets om naar te zoeken BCUninstaller de-installeren Wilt u BCUninstaller daadwerkelijk de-installeren? Wilt u een herstelpunt maken voordat u verder gaat? Naam Waarde Leeg GUID gevonden GUID ontbreekt Selecteer tot aan... Bestand niet gevonden Uitvoeren van NA de-installatie opdrachten... Uitvoeren van VOOR de-installatie opdrachten... Voltooid Shows up when nothing else is displayed on the status bar. {0} De-installer(s) geselecteerd {0} is a number of selected uninstallers {0} de-installer(s) in totaal, {1} {0} is a number of all uninstallers, {1} is a long file size (123 Megabytes) De volgende opdracht kon niet worden uitgevoerd: {0} {0} is a command line (c:\example.exe /help) Externe uitvoering is mislukt Voorinstelling Used in language select box when you want to use the system language Sommige instellingen worden pas na een herstart van het programma effectief. Wilt u BCU opnieuw starten, om de nieuwe instellingen over te nemen? Programma instellingen wijzigen Certificaat ontbreekt Verwerking van de de-installers ({0}) {1} = how many application uninstallers still need to be processed Wilt u het wachten op de nu lopende de-installatie overslaan? Actueel uitgevoerde taken overslaan Er wordt al een andere de-installatie taak uitgevoerd. Even geduld tot deze is voltooid en probeer het daarna opnieuw. Waardering: {0} Positief: {1} Negatief: {2} {0} - Rating as a string {1} - List of strings of positive parts of the rating {2} - List of strings of negative parts of the rating The lists are separated by a single newline. Dit programma heeft geen geldige register ingang Dit programma heeft geen geldige de-installer Verversen opstart informatie... Shown when refreshing autostart information of the uninstallers Geen mappen om te openen Niet beschikbaar Used on application list when value is not available Waarderingen niet beschikbaar U moet eerst 'Waarderen' inschakelen in de instellingen. U kunt onjuist geïnstalleerde programma's niet waarderen. {0} programma's {0} is number of apps to rate, "Rate " will be automatically put in front of this string Forceer de-installatie Het uitvoeren van enkele de-installers is mislukt .NET Framework v4.0 niet gevonden .NET Framework v4.0 werd niet gevonden, enkele functies zullen worden uitgeschakeld Het v4.0 Framework is optioneel, maar wordt aanbevolen. De functies die zijn gebaseerd op dit framework, zullen worden uitgeschakeld totdat u dit installeert. Enkele de-installers mislukten Wilt u proberen om lopende stille de-installers die mislukten zichtbaar te maken? De volgende de-installers worden zichtbaar herstart: De opgegeven map scannen... Selecteer de map met programma's die u wilt verwijderen. De-installeer uit map Er werden geen programma's gevonden in de opgegeven map Controleer dat u de juiste map selecteerde en dat de uitvoerbare programma's (.exe) nog aanwezig zijn. Een de-installer gevonden voor {0} Wilt u deze de-installer uitvoeren? Verlener Onderwerp Gearchiveerd Extensies Vriendelijke naam Naam verlener Niet na Niet voor Privé sleutel Heeft een prive sleutel Publieke sleutel Raw data Serienummer Onderwerp naam Signatuur algoritme Versie Vingerafdruk Opslaan instellingen is mislukt Voltooid op... Pictogrammen laden... Gemiddelde waardering: {0}; Mijn waardering: {1} Controleer dat de netwerkkabel is aangesloten. Indien u gebruik maakt van Wi-Fi, controleer dan de signaalsterkte. Feedback sturen Wilt u mij feedback over BCU sturen? Dit kost u minder dan een minuut en helpt de ontwikkelinmg van het programma enorm! Elke vorm van feedback is welkom, zoals een foutbericht, verzoeken voor nieuwe functionaliteit(en) of een bedankje! U kunt dit ook later sturen via de hoofd menubalk (Help -> Feedback sturen). De huidige versie is actueel! Er werden geen updates gevonden, u heeft de laatste versie. Mist u functionaliteiten of wilt u een oplossing voor een fout? Stuur mij dan uw feedback via het menu (Help -> Feedback sturen). Er werd een fout ontdekt bij het zoeken naar updates! Controleer dat BCUninstaller niet wordt geblokkeerd door uw 'firewall' en dat u een werkende internetverbinding hebt. Een nieuwe versie {0} is beschikbaar, wilt u nu upgraden? 0 is version number De geselecteerde registratie kan niet met de MsiEx-Installer worden gede-installeerd. De geselecteerde de-installer heeft geen geldige Guid voor het gebruik met MsiExec. De actuele de-installatie taak beëindigen? De keuze 'Beëindigen" sluit onmiddellijk de lopende de-installer en kan er in resulteren dat de de-installatie niet wordt afgesloten. In de regel kunt u de de-installer opnieuw uitvoeren om de de-installatie af te sluiten. Als alternatief kunt u de wachttijd voor dit proces overslaan. Hierdoor werkt de de-installer door, terwijl de taak naar het volgende onderdeel springt. Denk er aan, dat enkele de-installers niet kunnen worden uitgevoerd, voor dat het overgeslagen proces is afgesloten. Waardering details Windows onderdelen laden... De volgende de-installers werden uitgevoerd, mogelijk vanwege een conflict. Wacht tot de andere de-installers zijn voltooid en probeer het opnieuw. {0} U kunt proberen de detectie van conflicten in de instellingen uit te schakelen, maar dit wordt niet aanbevolen. BCUninstaller zal automatisch de update downloaden en zal dit na een herstart gebruiken. Houd er rekening mee dat uw instellingen tijdens dit proces verloren kunnen gaan. Wijzigingen log: - {0} Waarschuwing: tijdens de update worden de map "Update" en het bestand "Update.zip" in de BCU mappen verwijderd. 0 is a list of changes separated by "- " Kon geen nieuw herstelpunt maken x64 keep space in front DEBUG keep space in front De-installatie voortgang U kunt de computer nu uitzetten. Resterende de-installers zouden zonder gebruikersinterventie moeten voltooien. Van tijd tot tijd zou u moeten controleren of een van de de-installers niet is gecrashed. Afval/Programma restanten verwijderen Wilt u onderdelen met een lage graad van vertrouwen wijzigen? Het verwijderen van onderdelen met een lage graad van vertrouwen als GOED, kan zeer gevaarlijk zijn! Het wordt aanbevolen dat u elk individueel onderdeel alvorens te verwijderen verifieërd! Sleutels uit het register verwijderen Weet u zeker dat u de geselecteerde de-installer registraties wilt verwijderen? De volgende onderdelen werden uit het register verwijderd en verdwijnen uit de de-installer lijst, maar worden niet gede-installeerd. {0} Er is een fout opgetreden bij het opslaan van de geëxporteerde gegevens Als de fout blijft voortbestaan, probeer dan in een andere map op te slaan, bijv. het bureaublad. Controleer of u niet een van de volgende tekens heeft gebruikt: {0} 0 is list of characters separated by spaces Wilt na uitvoering van de-installatie(s) zoeken naar restanten? Er was niets om te kopieëren naar het klembord. Of u heeft niets geselecteerd of de informatie is afkomstig van de de-installer. Kopiëren naar het klembord Mappen openen Deze bewerking opent {0} mappen tegelijk. Weet u zeker dat u verder wilt gaan? 0 is number of directories to open Stille de-installatie Standaard instellingen herstellen Alle instellingen gaan blijvend verloren. BCUninstaller moet worden herstart om deze bewerking te voltooien. De-installatie lijst openen Het herstelpunt WERD NIET GEMAAKT, u kunt wijzigingen niet herstellen! Wilt u toch doorgaan met de de-installatie? Hernoemen "{0}" Geselecteerde registratie hernoemen Taak voltooid Shown on the status bar De-installatie Shown on the status bar Keuze onthouden Fout Het bestand bestaat niet Niets om weer te geven. Dit programmma wordt m.b.v. de Windows Installer (MsiExec) gede-installeerd. Jammer dat u ons gaat verlaten! Als u enkele minuten heeft, laat mij dan met een kort bericht op mijn website (http://klocmansoftware.weebly.com/) weten waarom u BCU de-installeerde. Ik zal mijn best doen om gemelde problemen op te lossen. Bij het openen van de pagina "Zoeken" trad een fout op De-installatiie lijst opslaan De lijst kon niet in een bestand worden opgeslagen Weet u zeker dat u alle programma-instellingen wilt terugzetten? Sommige programma's kunnen niet stil worden gede-installeerd Sommige onderdelen zijn beveiligd en kunnen niet worden gewijzigd Het geselecteerde onderdeel is beveiligd en kan niet worden gewijzigd Bij het openen van de URL trad een fout op Wilt u de huidge selectie behouden? Bij het openen van de map trad een fout op De geselecteerde bestanden konden niet worden geladen Geen uninstaller geselecteerd, er is niets om te de-installeren De-installer uitvoeren URL's openen Geen URL's om te openen Beveiligd onderdeel wijzigen De-installatie met MSI Het voortijdig beëindigen van de taak, maakt dat terugzetten niet mogelijk is. De lopende de-installer wordt niet gestopt, deze taak wacht op zijn voltooiing. Bent u onzeker of de programma's die u wilt de-installeren, belangrijk of voor de systeemstabiliteit vereist zijn? Dan wordt aanbevolen om een herstelpunt te maken. Mocht er onverhoopt iets misgaan, dan kunt u met systeemherstel de wijziging(en) ongedaan maken. Om programma's te de-installeren moet u deze eerst in de getoonde lijst selecteren. Als u gebruik maakt van checkboxen, controleer dan dat deze aangevinkt zijn. Als u de huidige selectie wilt opslaan, wordt deze met de geopende lijst(en) samengevoegd. Deze bewerking opent {0} URL's. Weet u zeker dat u wilt doorgaan? Getroffen registraties: {0} Om deze registraties te wijzigen, moet u uit de instellingen in de zijbalk lijst de beveiliging van de de-installer uitschakelen. U kunt deze uit de taak verwijderen en met de andere onderdelen doorgaan. 0 names of protected uninstallers Beveilgde registratie: {0} Om deze registratie te wijzigen, moet u de beveiliging van de de-installer in het instellingen venster uitschakelen. 0 name of protected uninstaller De volgende onderdelen hebben geen onzichtbare de-installer(s): {0} Wilt u voor deze onderdelen de standaard de-installer gebruiken of moeten de registraties uit de taak worden verwijderd? 0 is names of non-quiet uninstallers Zoeken naar programma Er werden geen geldige mappen of bestanden. Controleer of u daar toegang toe hebt en dat deze niet zijn aangeduid als systeembestanden. Zoeken naar programma's Zoeken naar programma's in {0} is mislukt Wijzig programma Het geselecteerde programma kan niet worden gewijzigd Voor het geselecteerde programma is geen wijzig opdracht gespecificeerd. Het kan noodzakelijk zijn om te de-installeren en het dan opnieuw te installeren om de installatie instellingen te wijzigen. Opslaan de-installeer lijst Wijzigingen opslaan in de de-installatie lijst? Er zijn niet opgeslagen wijzigingen in de geopende de-installatie lijst, die verloren gaan door deze te sluiten. Selecteer de map met de programma's om te de-installeren. Selecteer waar de back-up opgeslagen moet worden. Er zal een nieuwe map gemaakt worden. BCU is bijgewerkt naar v{0}! Welkom bij BCU versie {0}! Niets Option for "Double clicking in application list..." Eigenschappen openen Option for "Double clicking in application list..." De-installeert Option for "Double clicking in application list..." PC in slaapstand zetten in {0}s. Verwijder het vinkje uit het slaapvakje om te annuleren. ================================================ FILE: source/BulkCrapUninstaller/Properties/Localisable.pl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Tworzenie punktu przywracania... Szukanie pozostałości... Odświeżanie listy dezinstalatorów... Usuwanie pozostałości... Szukanie aktualizacji... Żaden element nie spełnia kryteriów wyszukiwania Eksport programu BCUninstaller | Wersja | Data | Rozmiar | Rejestr| Typ dezinstalatora | Komenda dezinstalacji | Komenda cichej dezinstalacji | Komentarze Portable keep space in front Błąd dostępu do API Tworzenia kopii zapasowej rejestru nie powiodło się, czy chcesz kontynuować mimo to? Szczegóły błędu: Usuwanie pozostałości Szczegóły błędu: Add space or newline afterwards and two newlines before Czy chcesz utworzyć kopię zapasową rejestru przed kontynuowaniem? Będzie można cofnąć wszystkie zmiany w rejestrze klikając ją dwukrotnie. Pliki i katalogi będą przenoszone do kosza, można przywrócić je stamtąd. Akcja nie powiodła się Musisz wybrać tylko jedną pozycję dla tego działania Wybierz dokładnie jedną pozycję z listy. Jeśli używasz pól wyboru upewnij się że są zaznaczone. Szukaj aktualizacji Otwórz treści sieciowe Nie można połączyć się z internetem, brak dostępnych sieci. Upewnij się, że kabel sieciowy jest podłączony. Jeśli korzystasz z Wi-Fi sprawdź, czy masz dobrą siłę sygnału. Wyślij feedback Chciałbyś wysłać opinię dotyczącą BCU? To zajmie Ci mniej niż minutę, ale znacznie pomoże w rozwoju programu! Wszystkie opinie i komentarze są mile widziane! Możesz wysłać ją później poprzez pozycję w górnym menu (Pomoc-> Wyślij feedback). Obecna wersja jest aktualna Nie znaleziono aktualizacji, masz najnowszą wersję programu. Czekasz na nowe funkcje lub poprawę błędów? Daj mi znać poprzez menu "Pomoc->Wyślij feedback". Podczas wyszukiwania aktualizacji wystąpił błąd. Upewnij się że BCUninstaller nie jest blokowany przez twojego firewalla i że masz sprawne połączenie z internetem. Nowa wersja {0} jest dostępna, zaktualizować teraz? 0 is version number BCUninstaller automatycznie ściągnie aktualizację i zainstaluje ją po restarcie programu. Lista zmian: - {0} Uwaga: Podczas aktualizacji folder "Update" i plik "Update.zip" w folderze BCU zostaną usunięte. 0 is a list of changes separated by "- " Odinstaluj używając MsiExec Wybrana pozycja nie może zostać odinstalowana poprzez MsiExec Pozycja nie posiada prawidłowego kodu produktu (GUID) potrzebnego do tej akcji. Zatrzymaj dezinstalację Czy na pewno chcesz zatrzymać dezinstalację? Przedwczesne zatrzymanie nie przywróci wprowadzonych zmian. Obecnie działający dezinstalator nie zostanie zamknięty, musi zostać zatrzymany ręcznie. Utwórz punkt przywracania Tworzenie punktu przywracania nie powiodło się x64 keep space in front DEBUG keep space in front Postęp dezinstalacji Możesz opuścić komputer, pozostałe aplikacje odinstalują się automatycznie Pozostałe dezinstalatory powinny być w stanie skończyć pracę bez twojej interwencji. Mimo to sprawdzaj co jakiś czas czy któryś z dezinstalatorów nie napotkał nieoczekiwanego błędu. Usuwanie pozostałości Czy na pewno chcesz zmodyfikować pozycje z niską pewnością? Usuwanie elementów o niskim poziomie pewności jest bardzo niebezpieczne, dokładnie sprawdź każdą pozycję przed usunięciem. Usuń klucze z rejestru Czy na pewno chcesz usunąć wybrane pozycje? Następujące elementy zostaną usunięte z rejestru i znikną z listy aplikacji, ale nie zostaną odinstalowane. {0} Eksport nie powiódł się Napotkano błąd podczas zapisywania eksportowanych danych Jeśli błąd będzie się powtarzał spróbować zapisać do innego katalogu, na przykład na pulpicie. BCUninstaller odinstalowuje {0} aplikacji 0 is the uninstaller count Zmień nazwę dezinstalatora Dostarczane nazwa jest pusta lub zawiera niedozwolone znaki Upewnij się że nie zostały użyte następujące znaki: {0} 0 is list of characters separated by spaces Czy wyszukać pozostałości po odinstalowanych aplikacjach? Pamiętaj że ta funkcja jest przeznaczona dla zaawansowanych użytkowników którzy rozumieją jej działanie. Usunięcie pozostałości nie jest wymagane - nie spowolnią one systemu, jedynie zajmą niewielką ilość miejsca na dysku. Nie znaleziono pozostałości Nie znaleziono żadnych pozostałości. Dla pewności można uruchomić inny program czyszczący śmieci, np. BleachBit. Nie znaleziono nic do skopiowania. Wybrane dezinstalatory nie posiadały tych informacji lub nie wybrałeś żadnego dezinstalatora. Kopiuj do schowka Otwórz foldery Ta akcja otworzy {0} folderów na raz, czy kontynuować? 0 is number of directories to open Szukaj online Nie ma nic do wyszukania Odinstaluj BCUninstaller Czy na pewno chcesz odinstalować BCUninstaller? Jeżeli masz chwilę wstąp na stronę programu (http://klocmansoftware.weebly.com/) i napisz co skłoniło cię do odinstalowania BCU. Czy utworzyć punkt przywracania przed dezinstalacją? If you are unsure if applications you are uninstalling are important or required to system stability it is recommended to create a restore point. If anything breaks after the procedure you can then use System Restore to roll back the changes. Wystąpił błąd podczas otwierania wyszukiwarki. Zapisz listę dezinstalatorów Zapisanie listy do pliku nie powiodło się. Czy na pewno zresetować wszystkie ustawienia? Niektóre aplikacje nie mogą zostać cicho odinstalowane Niektóre pozycje są zabezpieczone i nie mogą być zmienione Wybrana pozycja jest zabezpieczona i nie może zostać zmieniona Napotkano błąd podczas otwierania adresu. Czy chcesz zachować aktualne zaznaczenie? Napotkano błąd podczas otwierania folderu. Otwarcie plików nie powiodło się Nie wybrano żadnych dezinstalatorów, nic do odinstalowania Dezinstaluj pozycje Aby odinstalować aplikacje należy najpierw wybrać je z listy. Jeśli używasz pól wyboru, upewnij się, że są one zaznaczone. Jeżeli zachowasz zaznaczenie zostanie ono połączone z otworzoną listą/listami Ta akcja otworzy {0} adresów na raz, czy kontynuować? Otwórz adresy URL Brak adresów do otwarcia Modyfikuj zabezpieczone pozycje Zabezpieczone pozycje: {0} Aby zmienić te ustawienia musisz wyłączyć zabezpieczenia w pasku ustawień.Możesz usunąć te pozycje z zadania i kontynuować lub anulować zadanie. 0 names of protected uninstallers Zabezpieczona pozycja: {0} Aby zmienić tą pozycję musisz wyłączyć zabezpieczenia w pasku ustawień 0 name of protected uninstaller Następujące pozycje nie posiadają cichych dezinstalatorów: {0} Pozostawić je w zadaniu i użyć 'głośnych' dezinstalatorów czy całkowicie usunąć je z zadania? 0 is names of non-quiet uninstallers Cicha dezinstalacja Przywróć ustawienia domyślne Wszystkie ustawienia zostaną utracone na stałe. BCUninstaller będzie musiał ponownie uruchomić się do przeprowadzenia tej akcji. Otwórz listę dezinstalatorów Punkt przywracania nie został utworzony, nie będzie możliwości cofnięcia zmian! Czy chcesz kontynuować dezinstalację mimo to? Zmiana nazwy "{0}" Zmień nazwę dezinstalatora Zadanie zakończone Shown on the status bar Odinstalowywanie Shown on the status bar Zapamiętaj wybór Błąd Plik nie istnieje na dysku. Aplikacja jest odinstalowywana Instalator systemu Windows (MsiExec). Nazwa Wartość Brak Znaleziono GUID Brak GUID Zaznacz do... Nie znaleziono pliku. Wykonywanie komend po dezinstalacji... Wykonywanie komend przed dezinstalacją... Gotowy Shows up when nothing else is displayed on the status bar. Wybrano {0} dezinstalatorów {0} is a number of selected uninstallers Razem {0} dezinstalatorów, {1} {0} is a number of all uninstallers, {1} is a long file size (123 Megabytes) Wykonanie następującej komendy nie powiodło się: {0} {0} is a command line (c:\example.exe /help) Błąd wykonania komendy Domyślny Used in language select box when you want to use the system language Niektóre ustawienia nie zostaną wprowadzone do momentu ponownego uruchomienia aplikacji. Czy chcesz ponownie uruchomić BCU aby zastosować nowe ustawienia? Zmień ustawienia aplikacji Brak certyfikatu Przetwarzanie wykrytych aplikacji, pozostało {0}... {1} = how many application uninstallers still need to be processed Wybranie opcji "Zakończ" natychmiast zamknie uruchomiony dezinstalator i może spowodować nie dokończenie dezinstalacji. Zazwyczaj należy uruchomić dezinstalator jeszcze raz, aby dokończyć dezinstalację. Alternatywnie można pominąć czekanie na ten proces. Pomijanie pozwoli kontynuować pracę podczas dezinstalacji, zadanie przechodzi do następnej pozycji. Należy pamiętać, że niektóre dezinstalatory mogą nie działać, aż zakończy się proces pomijania. Czy chcesz pominąć czekanie na uruchomiony dezinstalator? Pomiń aktualnie uruchomione zadanie Inna dezinstalacja w toku. Proszę czekać na zakończenie procesu i spróbować ponownie. Ocena: {0} Pozytywy: {1} Negatywy: {2} {0} - Rating as a string {1} - List of strings of positive parts of the rating {2} - List of strings of negative parts of the rating The lists are separated by a single newline. Szczegóły oceny Ta aplikacja nie posiada prawidłowego wpisu w rejestrze Ta aplikacja nie posiada prawidłowego dezinstalatora Ładowanie funkcji systemu Windows... Odświeżanie informacji o autostarcie... Shown when refreshing autostart information of the uninstallers Brak katalogów do otwarcia Niedostępne Used on application list when value is not available Oceny nie dostępne Najpierw musisz włączyć oceny z ustawień. Nie można ocenić aplikacji, które nie są prawidłowo zainstalowane. {0} aplikacji {0} is number of apps to rate, "Rate " will be automatically put in front of this string Średnia ocena: {0}; Moja ocena: {1} Następujących dezinstalatorów nie udało się uruchomić, prawdopodobnie z powodu kolizji. Poczekaj aż inne dezinstalatory skonczą pracę i spróbuj ponownie. {0} Można spróbować wyłączyć wykrywanie kolizji w ustawieniach, ale nie jest to zalecane. Wymuś dezinstalację Nie powiodło się uruchomiene niektórych dezinstalatorów Nie znaleziono .NET Framework v4.0 Nie znaleziono .NET Framework v4.0, niektóre funkcje będą niedostępne Obecność .NET Framework v4.0 jest opcjonalna, ale zalecana. Funkcje które na niej polegają będą wyłączone do czasu zainstalowania .NET Framework v4.0. Niepowodzenie niektórych dezinstalatorów Czy uruchomić ciche dezinstalatory które się nie powiodły jako głośne? Następujące dezinstalatory zostaną uruchomione ponownie jako głośne: Skanowanie podanego folderu... Podaj folder z aplikacjami które chcesz usunąć. Dezinstaluj z folderu Nie znaleziono żadnych aplikacji w podanym folderze Upewnij się że wybrałeś właściwy folder i że zawiera on pliki wykonywalne aplikacji Znaleziono dezinstalator dla {0} Czy uruchomić znaleziony dezinstalator? Emitent Podmiot Zarchiwizowany Rozszerzenia Przyjazna nazwa Nazwa emitenta Nie po Nie przed Prywatny klucz Ma prywatny klucz Publiczny klucz Surowe dane Numer seryjny Nazwa podmiotu Algorytm podpisu Wersja Odcisk kciuka Nie udało się zapisać ustawień Kończenie... Ładowanie ikon Szukaj aplikację Nie wybrano żadnych poprawnych plików i/lub folderów. Upewnij się że masz do nich dostęp, i że nie są oznaczone jako pliki systemowe. Szukaj aplikacji Nie znaleziono żadnych aplikacji w {0} Zmodyfikuj aplikację Wybranej aplikacji nie można zmodyfikować Wybrana aplikacja nie ma określonego polecenia modyfikacji. Może być konieczne odinstalowanie, a następnie ponownie zainstalowanie aplikacji w celu zmiany ustawień jej instalacji. Zapisz listę odinstalowywania Czy zapisać zmiany na otwartej liście odinstalowywania? Istnieją niezapisane zmiany na otwartej liście odinstalowań, które zostaną utracone przez zamknięcie. Wybierz katalog z aplikacjami do odinstalowania. Wybierz lokalizację, w której chcesz zapisać kopię zapasową. Zostanie utworzony nowy katalog. BCU został zaktualizowany do wersji v{0}! Witamy w wersji BCU v{0}! Uśpienie komputera za {0} sekund. Jeśli chcesz przerwać tę operację, odznacz pole wyboru. Nic nie robi. Option for "Double clicking in application list..." Otwiera ustawienia. Option for "Double clicking in application list..." Odinstalowuje. Option for "Double clicking in application list..." ================================================ FILE: source/BulkCrapUninstaller/Properties/Localisable.pt-BR.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Criando um ponto de restauração Procurando por sobras... Preenchendo a lista de desinstalação... Removendo sobras... Procurando atualizações... Não há entradas que correspondam aos seus critérios de pesquisa. Exportação BCUninstaller Editora | Versão | Data | Tamanho | Registro | Tipo de desinstalador | Cadeia de desinstalação | Cadeia de desinstalação silenciosa | Comentários Portátil keep space in front Falha ao chamar a API O backup do registro falhou, você quer continuar de qualquer maneira? Detalhes do erro: Remoção das sobras Detalhes do erro: Add space or newline afterwards and two newlines before Você deseja criar um backup do registro antes de continuar? Você poderá reverter todas as alterações clicando duas vezes sobre ele mais tarde. Arquivos e diretórios serão movidos para a lixeira, você pode restaurá-los a partir de lá. A ação falhou Você precisa selecionar apenas uma entrada para esta ação Selecione exatamente um desinstalador da lista. Se você estiver usando caixas de seleção certifique-se de que as selecionou. Procurar atualizações Abrir conteúdo on-line Não é possível conectar-se à internet, não há redes disponíveis. Certifique-se de que seu cabo de rede esteja conectado. Se você estiver usando o Wi-Fi, assegure-se de ter uma boa intensidade de sinal. Enviar comentário Gostaria de enviar comentários sobre o BCU? Isso vai levar menos de um minuto mas irá ajudar o desenvolvimento imensamente! Todo feedback é apreciado, seja um bug report, solicitação de recursos ou apenas um obrigado! Você pode mandar depois pelo menu superior (Ajuda > Enviar comentário...). A versão atual está atualizada Nenhuma atualização encontrada, você possui a última versão. Quer algum recurso ou bug arrumado? Envie por favor seu feedback usando o menu "Ajuda -> Enviar comentários...". Aconteceu um erro ao buscar por atualizações Verifique se o BCUninstaller não está bloqueado pelo seu firewall e que sua conexão com a internet está funcionando. Nova versão {0} disponível, deseja atualizar agora? 0 is version number BCUninstaller irá baixar automaticamente a atualização e instalar após um reinício. Você irá perder dados não salvos. Changelog: - {0} Atenção: Durante a atualização a pasta "Update" e o arquivo "Update.zip" dentro da pasta do BCU serão removidos. 0 is a list of changes separated by "- " Desinstalar usando o MSI A entrada selecionada não pode ser desinstalada usando o instalador MsiExec Desinstalador selecionado não possui um GUID válido para uso com o MsiExec Para tarefa de desinstalação atual Você tem certeza que deseja parar a tarefa de desinstalação em uso? Interromper a tarefa prematuramente não reverterá nenhuma alteração. O desinstalador em execução não será interrompido e a tarefa aguardará até que ele finalize. Criar um ponto de restauração Falha ao criar ponto de restauração x64 keep space in front DEBUG keep space in front Progresso de desinstalação Você pode ir tomar um café Os desinstaladores restantes devem ser capazes de concluir sem intervenção do usuário. Ainda assim, você deve verificar de vez em quando, caso um dos desinstaladores trave. Remoção de lixo/sobras Você realmente deseja modificar itens de baixa confiabilidade? Remover itens marcados com confiança menor que Boa pode ser muito perigoso! É recomendado que você verifique se cada item é seguro para excluir. Remover chaves do registro Tem certeza que deseja remover as entradas de desinstalador selecionadas? Os seguintes itens serão removidos do registro e desaparecerão da lista de desinstaladores, mas não serão desinstalados. {0} A exportação falhou Um erro foi encontrado ao salvar dados exportados Se o erro persiste tente salvar em um local diferente, por exemplo a Área de trabalho. BCUninstaller está desinstalando {0} aplicação(ões) 0 is the uninstaller count Renomear desinstalador O nome fornecido está vazio ou contém caracteres inválidos. Certifique-se de não ter incluído nenhum dos seguintes caracteres: {0} 0 is list of characters separated by spaces Você quer procurar resíduos das desinstalações realizadas? Entenda que este recurso é destinado apenas a usuários avançados que entendem como funciona. Não é necessário remover esses arquivos, e eles não afetarão o desempenho do sistema de forma significativa. Nenhum resíduo foi encontrado Sem resíduos encontrados. Podem existir alguns resíduos ainda, você pode usar um limpador de arquivos temporários como o BleachBit. Não foi encontrado nada para copiar para a área de transferência. Nenhum desinstalador selecionado possui essa informação ou você não selecionou algo. Copiar para a Área de Transferência Abrir diretórios Esta ação irá abrir {0} diretórios de uma vez. Tem certeza que deseja continuar? 0 is number of directories to open Procurar online Nada para procurar Desinstalar o BCUninstaller Tem certeza que deseja desinstalar o BCUninstaller? Lamento em vê-lo partir! Se tiver um minuto ou dois, por favor, deixe um comentário sobre o motivo de ter desinstalado o BCU no meu site (http://klocmansoftware.weebly.com/). Farei o meu melhor para corrigir qualquer problema legítimo. Você quer criar um ponto de restauração antes de continuar? Se você não tem certeza que os aplicativos que está desinstalando são importantes ou necessários para a estabilidade do sistema, é recomendável criar um ponto de restauração. Se algo der errado após o procedimento, você pode usar a Restauração do Sistema para reverter as alterações. Um erro ocorreu ao abrir a página de pesquisa. Salvar lista de Desinstalação Falhar ao salvar a lista em um arquivo Tem certeza que deseja resetar todas as configurações do aplicativo? Algumas aplicaçoes não podem ser desinstaladas silenciosamente Algumas entradas sao protegiddas e não podem ser modificadas Entrada selecioanda é protegida e não pode ser modificada Ocorreu um erro ao abrir a URL Quer manter a seleçao atual? Ocorreu um erro ao abrir a pasta Falha ao carregar os arquivos selecionados Nenhum desinstalador foi selecionado, nada para desinstalar Executar desinstaladores Para desinstalar aplicativos, você deve primeiro selecioná-los na visualização da lista. Se estiver usando caixas de seleção, certifique-se de que elas estejam marcadas. Se você manter a seleção atual, ela será mesclada com a(s) lista(s) aberta(s). Esta ação abrirá {0} URLs de uma vez, você tem certeza de que deseja continuar? Abrir URLs Não há URLs para abrir Modificar item protegido Entradas afetadas: {0} Para modificar essas entradas, você precisa desabilitar a proteção do desinstalador na barra lateral de configurações. Se quiser, pode removê-las e continuar com os outros itens. 0 names of protected uninstallers Entrada protegida: {0} Para modificar esta entrada, você precisa desabilitar a proteção do desinstalador no painel de configurações. 0 name of protected uninstaller Os seguintes itens estão sem desinstaladores silenciosos: {0} Você quer usar desinstaladores "em primeiro plano" para esses itens, ou prefere removê-los da tarefa? 0 is names of non-quiet uninstallers Desinstalação silenciosa Restaurar configurações de fábrica Todas as suas configurações serão perdidas permanentemente. O BCUninstaller precisará reiniciar para concluir esta ação. Abrir lista de desinstalaçao 1 Renomeando "{0} Renomear entrada selecionada Tarefa encerrada Shown on the status bar Desinstalando Shown on the status bar Lembrar-se Erro Arquivo não existe. Nada para exibir. Este aplicativo é desinstalado usando o Windows Installer (MsiExec). Nome Valor Vazio GUID encontrado GUID em falta Selecioanr até... Arquivo não encontrado Executando comandos pós-desinstalação... Executando comandos pre-desinstalação... Pronto Shows up when nothing else is displayed on the status bar. {0} desinstaladores selecionados {0} is a number of selected uninstallers {0} desinstaladores no total, {1} {0} is a number of all uninstallers, {1} is a long file size (123 Megabytes) O seguinte comanddo falhou ao executar: {0} {0} is a command line (c:\example.exe /help) Falha de execução externa Padrão Used in language select box when you want to use the system language Algumas configurações só surtirão efeito após a reiniciação da aplicação. Deseja reiniciar o BCU para aplicar as novas configurações? Alterar configurações do aplicativo Certificado em falta Processando aplicativos detectados, {0} restantes... {1} = how many application uninstallers still need to be processed Selecionar "Terminar" fechará imediatamente o desinstalador em execução e pode resultar em uma desinstalação incompleta. Normalmente, é possível executar o desinstalador novamente para concluir a desinstalação. Como alternativa, você pode pular a espera por esse processo. Pular permitirá que o desinstalador continue funcionando enquanto a tarefa avança para o próximo item. Lembre-se de que alguns desinstaladores podem falhar em ser executados até que o processo pulado seja concluído. Deseja pular a espera pelo desinstalador em execução no momento? Pular a tarefa em execução no momento Outra tarefa de desinstalação já está em execução. Por favor, aguarde ela terminar e tente novamente. Avaliação: {0} Positivos: {1} Negativos: {2} {0} - Rating as a string {1} - List of strings of positive parts of the rating {2} - List of strings of negative parts of the rating The lists are separated by a single newline. Info. Avaliações Essa aplicação nao tem uma entrada de registro válida Essa aplicação não tem um desinstalador válido Carregando funcionalidades do Windows... Atualizando informações de inicialização... Shown when refreshing autostart information of the uninstallers Sem diretórios para abrir Indisponível Used on application list when value is not available Avaliações indisponíveis Você precisa habilitar as avaliações nas configurações antes. Você não pode avaliar aplicações que não estao instaladas corretamente. {0} aplicações {0} is number of apps to rate, "Rate " will be automatically put in front of this string Média da avaliação: {0}; Minha avaliação: {1} Os seguintes desinstaladores falharam ao ser executados, provavelmente devido a um conflito. Por favor, aguarde os outros desinstaladores terminarem e tente novamente. {0} Você pode tentar desabilitar a detecção de conflitos nas configurações, mas isso não é recomendado. Forçar desinstalação Falha para executar alguns dos desinstaladores .NET Framework v4.0 não encontrado .NET Framework v4.0 não foi encontrado, alguns recursos serão desabilitados O framework v4.0 é opcional, mas recomendado. As funcionalidades que dependem do framework serão desativadas até que você o instale. Alguns dos desinstaladores falharam Deseja tentar executar os desinstaladores silenciosos que falharam em primeiro plano? Os seguintes desinstaladores serão executados em primeiro plano: Escaneando o diretório especificado... Selecione diretórios com aplicações que você deseja remover. Desinstalar do diretório Não foram encontrado aplicações no diretório especificado Certifique-se de que selecionou o diretório correto e que os executáveis do aplicativo ainda estão presentes. Encontrado um desinstaladdor para {0} Quer executar esse desinstalador? Editor Assunto Arquivado Extensões Nome comum Nome do Editor Não depois de Não antes de Chave privada Tem chave privada Chave pública Dados não processados Número de Série Nome do Assunto Algoritmo de assinatura Versão Impressão digital Erro ao guardar as configurações Finalizando... Carregando os ícones Buscar aplicação Nenhum arquivo ou diretório válido foi selecionado. Certifique-se de que você tenha acesso a eles e que não estejam marcados como arquivos do sistema. Buscar por aplicativos Falha ao encontrar quaisquer aplicativos dentro de {0} Modificar aplicação Aplicação selecionada não pode ser modificada O aplicativo selecionado não possui um comando de modificação especificado. Pode ser necessário desinstalá-lo e, em seguida, reinstalá-lo para alterar as configurações de instalação. Salvar lista de desinstalação Salvar as alterações na lista de desinstalação aberta? Existem alterações não salvas na lista de desinstalação aberta que serão perdidas ao fechá-la. Selecione o diretório com os aplicativos a serem desinstalados. Selecione onde salvar o backup. Um novo diretório será criado. O BCU foi atualizado para v{0}! Bem-vindo ao BCU versão {0}! Colocando o PC em modo de descanso em {0} segundos. Desmarque a caixa de seleção de descanso para cancelar. Fazer nada Option for "Double clicking in application list..." Abrir propriedade Option for "Double clicking in application list..." Desinstala Option for "Double clicking in application list..." ================================================ FILE: source/BulkCrapUninstaller/Properties/Localisable.pt.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Criando um ponto de restauro... Procurando vestígios residuais... Preenchendo a lista do desinstalador... Removendo vestígios resíduais... Procurando actualizações... Não há entradas correspondentes aos seus critérios de busca. Exportação do editor do BCUninstaller | Versão | Data | Tamanho | Registo | Tipo de desinstalador | Correnten de desinstalação | Corrente de desinstalação em segundo plano | Comentários Portátil keep space in front Falha na chamada do API A cópia do registo falhou, quer continuar mesmo assim? Pormenores do erro: Remoção dos vestígios residuais Pormenores do erro: Add space or newline afterwards and two newlines before Deseja criar umam cópia de segurança antes de continuar? Pode repor todas as alterações posteriormente fazendo um duplo clique sobre ele. Os arquivos e os diretórios serão movidos para o cesto do lixo. Poderá restaurá-los a partir daí. A acção falhou Tem de seleccionar só uma entrada para esta acção. Seleccione exactamente um desinstalador da lista. Se estiver a usar caixas de verificação, certifique-se de que as seleccionou. Procurar actualizações Abrir o conteúdo on line Não é possível ligar-se à internet, não há redes disponíveis. Certifique-se de que o cabo de rede está conectado. Se estiver a usar a Wi-Fi assegure-se de que tem um sinal de boa intensidade. Enviar comentário Deseja enviar um comentário acerca do BCU? Isto tomar-lhe-á apenas um minuto do seu tempo, mas ajudar-nos-á imenso a aperfeiçoar o programa! Todo o comentário é bem-vindo, seja ele um relatório de erro, um pedido de resolução ou um simples agradecimento! Poderá enviá-lo mais tarde usando a barra superior do menu (Ajuda -> Enviar comentário). A versão presente está actualizada Não foram encontradas novas actualizações, a instalada é a mais recente. Quer ter funcionalidades adicionais ou corrigir um erro? Por favor envie-me os seus comentários usando o menu "Ajuda -> Envie comentário". Encontrado um erro na verificação de existência de atualizações. Assegure-se de que o BCU não está a ser bloqueado pela sua Firewall e que a sua ligação à Internet está activa. Está disponível uma nova versão {0}, quer actualizar agora? 0 is version number O BCUninstaller irá automaticamente baixar a actualização e aplicá-la após fazer um reinício. Por favor note que pode perder as suas configurações no processo. changelog: - {0} Aviso: Durante a actualização, a pasta "Actualizar" e o arquivo "Update.zip" incluídos no directório BCU serão removidos. 0 is a list of changes separated by "- " Desinstalar usando o Msi A entrada seleccionada não pode ser desinstalada usando o desinstalador MsiExec. O desinstalador seleccionado não tem um Guid válido para ser usado com o MsiExec. Parar a tarefa de desinstalação em curso Tem a certeza de que quer interromper a tarefa actual de desinstalação? Interromper prematuramente a tarefa não reflectirá quaisquer alterações. A desinstalação em curso não será interrompida, a tarefa aguardará o seu final. Criar um ponto de restauro Failed to create a new restore point [x64] keep space in front DEPURAÇÃO keep space in front Progresso da desinstalação Agora pode deixar o computador fazer a tarefa por si Os restantes desinstaladores devem estar aptos a completar a tarefa sem qualquer intervenção do utilizador. Deverá ainda fazer uma verificação de vez em quando para o caso de um dos desinstaladores falhar. Remoção de Lixo/Vestígios residuais Deseja realmente modificar os itens de baixa confiança? Remover itens marcados com confiança inferior a Bom pode ser muito perigoso! Recomenda-se que verifique se é seguro excluir cada um dos itens. Eliminar as chaves do registo Tem a certexa de que quer eliminar as entradas do desinstalador seleccionado?? Os itens seguintes serão removidos do registo e desaparecerão da lista do desinstalador, mas não serão desinstalados. {0} A exportação falhou Foi detectado um erro durante a salvaguarda dos dados exportados Se o erro persistir, guarde os dados num directório diferente, por exemplo no ambiente de trabalho. O BCUninstaller está a desinstalar {0} aplicação(ões) 0 is the uninstaller count Renomear o desinstalador O nome fornecido está ausente ou contém caracteres inválidos. Assegure-se de que não incluiu nenhum dos seguintes caracteres: {0} 0 is list of characters separated by spaces Deseja procurar vestígios residuais deixados pelas desinstalações realizadas? Por favor note que este recurso se destina apenas a utilizadores experientes que entendam o seu funcionamento. Não é necessário remover estes arquivos e eles não afectarão de maneira significativa o desempenho do sistema. Não foram encontrados vestígios residuais Não foram detectctados vestígios residuais. Ainda assim poderão ter ficado alguns, de maneira que poderá correr um utilitário de limpeza como o BleachBit. Não havia nada para copiar para a área de transferência. Ou, então, o desinstalador selecionado não tem a mínima informação ou você não seleccionou nada. Copiar para a Área de Transferência Abrir directórios Esta acção abrirá {0} directórios de uma só vez. Tem a certeza de que quer continuar? 0 is number of directories to open Procurar on line Nada a procurar Desinstalar o BCUninstaller Tem a certeza de que quer desinstalar o BCUninstaller? Lamento vê-lo partir! Se tiver um ou dois minutos que me dispense, por favor envie-me uma palavra no meu site (http://klocmansoftware.weebly.com/) sobre a razão pela qual desinstalou o BCU. Farei o meu melhor para corrigir quaisquer problemas legítimos. Quer criar um ponto de restauro antes de continuar? Se não tem certeza se os aplicativos que está a desinstalar são importantes ou necessários para a estabilidade do sistema, recomenda-se que crie um ponto de restauro. Se alguma coisa correr mal após o procedimento poderá recorrer ao restauro do sistema para anular as alterações. Foi detectado um erro enquanto se abria a página de pesquisa Salvar a Lista de Desinstalação Falhou a salvaguarda da lista num ficheiro Tem a certeza de que deseja redefinir todas as configurações da aplicação? Algumas das aplicações não podem ser desinstaladas em segundo plano Algumas entradas estão protegidas e não podem ser modificadas A entrada seleccionada está protegida e não pode ser modificada Foi detectado um erro quando se abriu o URL Quer manter a presente selecção? Foi detectado um erro quando se abriu o directório O carregamento dos ficheiros seleccionados falhou Não há desinstaladores seleccionados, não há nada para desinstalar Correr os desinstaladores Correr desisnataladores Para desinstalar aplicações terá primeiro de de as seleccionar na lista respectiva. Se estiver a usar as caixas seleccionadoras, assegure-se de que estas estão assinaladas. Se preferir manter a selecção actual ela será interligada com a(s) lista(s) aberta(s). Esta acção abrirá {0} URLs de uma só vez. Tem a certeza de que quer continuar? Abrir URLs Não há URLs para abrir Modify protected item Entradas afectadas: {0} Para editar estas entradas terá de desactivar a proteção do desinstalador nas configurações da barra lateral. Se quiser, pode removê-las e continuar com os outros itens. 0 names of protected uninstallers Entradas protegidas: {0} Para editar esta entrada terá de desactivar a proteção do desinstalador no painel das configurações. 0 name of protected uninstaller Os seguintes itens estão em falta nos desinstaladores de segundo plano: {0} Quer usar desinstaladores "de primeiro plano" para esses itens ou quer que sejam removidos da tarefa? 0 is names of non-quiet uninstallers Desinstalação em segundo plano Restaurar a configuração original. Todas as suas configurações serão apagadas permanentemente. O BCUninstaller irá reiniciar para concluir esta acção. Abrir a lista de desinstalação NÃO FOI CRIADO nenhum ponto de restauro, não poderá depois recuperar das mudanças efectuadas! Quer continuar com a desinstalação mesmo assim? A renomear "{0}" Renomear a entrada seleccionada Tarefa terminada Shown on the status bar Desinstalando Shown on the status bar Lembre-se da escolha feita Erro O ficheiro não existe. Nada a apresentar. Este aplicativo é desinstalado usando-se o Windows Installer (MsiExec). Nome Valor Vazio GUID encontrado GUID em falta Seleccionar até... Ficheiro não encontrado. Correndo os comandos de pós-desinstalação... Correndo os comandos de pré-desinstalação... Pronto Shows up when nothing else is displayed on the status bar. {0} desinstaladores seleccionados {0} is a number of selected uninstallers {0} desinstaladores no total, {1} {0} is a number of all uninstallers, {1} is a long file size (123 Megabytes) O comando seguinte falhou a sua execução: {0} {0} is a command line (c:\example.exe /help) Falha de execução externa Padrão Used in language select box when you want to use the system language Alguns parâmetros só surtirão efeito após a reiniciação da aplicação. Deseja reiniciar o BCU para tornar efectivas as novas configurações? Mudar as configurações da aplicação Certificado em falta Desinstaladores em curso ({0}) {1} = how many application uninstallers still need to be processed Seleccionar "Terminar" irá imediatamente fechar o desinstalador em curso e poderá resultar numa incompleta desinstalação. Normalmente, é possível retomar a desinstalação para a terminar. Em alternativa, poderá pular esta espera pelo correr do processo. Pulá-la permitirá ao desinstalador continuar a trabalhar enquanto a tarefa segue para o próximo item. Tenha presente que alguns desinstaladores podem deixar de correr até que a tarefa termine. Deseja pular a espera pelo processo em curso do desinstalador? Pular a tarefa em curso Já está a decorrer outra tarefa de desinstalação. Por favor, espere pela sua conclusão e depois tente de novo. Avaliação: {0} Positivo: {1} Negativo: {2} {0} - Rating as a string {1} - List of strings of positive parts of the rating {2} - List of strings of negative parts of the rating The lists are separated by a single newline. Pormenores da avaliação Esta aplicação não tem uma entrada de registo válida Esta aplicação não tem um desinstalador válido Carregando funcionalidades do Windows... Actualizando informações de inicialização... Shown when refreshing autostart information of the uninstallers Não há directorias para abrir Indisponível Used on application list when value is not available Avaliações indisponíveis Deverá activar primeiro as avaliações das configurações Não pode avaliar aplicações que não estejam corretamente instaladas. {0} aplicações {0} is number of apps to rate, "Rate " will be automatically put in front of this string Média da avaliação: {0}; A minha avaliação: {1} Os seguintes desinstaladores falharam a execução, ao que parece por causa de conflito. Por favor espere que outros desinstaladores terminem a sua tarefa e tente de novo. {0} Pode sentir-se tentado a desactivar o detector de conflitos nas configurações. mas isso não é recomendável. Forçar a desinstalação Falha ao correr alguns dos desinstaladores O Framework .NET v4.0 não foi encontrado O Framework .NET v4.0 não foi encontrado, algumas das funções serão desactivadas. O Framework v4.0 é opcional, masrecomendado. Os recursos que dependem do framework serão desativados até que sejam instalados por si. Alguns dos desinstaladores falharam Quer tentar executar os desinstaladores de segundo plano em caso de tentativa falhada em modo normal? Os seguintes desinstaladores são reiniciados no modo de assistente: Digitalizando o directório especificado... Seleccione o directório com os aplicativos que deseja excluir. Desinstalar do directório Não foram encontradas aplicações no directório especificado Certifique-se de que seleccionou o directório correcto e que os executáveis do aplicativo ainda estão presentes. Encontrado um dsinstalador para {0} Quer executar este desinstalador? Editor Assunto Arquivado Extensões Nome familiar Nome do Editor Não depois de Não antes de Chave privada Tem chave privada Chave pública Dados não processados Número de Série Nome do Assunto Algoritmo de assinatura Versão Impressão digital Erro ao guardar as configurações A terminar... A carregar os ícones ================================================ FILE: source/BulkCrapUninstaller/Properties/Localisable.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Creating a restore point... Searching for leftovers... Populating uninstaller list... Removing leftovers... Searching for updates... There are no entries matching your search criteria. BCUninstaller export Publisher | Version | Date | Size | Registry | Uninstaller type | Uninstall string | Quiet uninstall string | Comments Portable keep space in front Failed to call the API Registry backup failed, do you want to continue anyway? Error details: Leftover removal Error details: Add space or newline afterwards and two newlines before Do you want to create a registry backup before continuing? You will be able to roll back all changes by double-clicking it afterwards. Files and directories will be moved to the recycle bin, you can restore them from there. Action failed You need to select only one entry for this action Select exactly one uninstaller from the list. If you are using check-boxes make sure to check them. Search for updates Open on-line content Can't connect to the internet, there are no networks available. Make sure that your network cable is plugged in. If you are using Wi-Fi ensure that you have good signal strength. Submit feedback Would you like to send feedback concerning BCU? This will take you less than a minute but help the development greatly! All feedback is appreciated, be it a bug report, feature request or a simple thanks! You can send it later from the top menu bar (Help->Submit feedback). Current version is up to date No updates were found at this time, you have the latest version. Want some functionality added or a bug fixed? Please send me your feedback using "Help->Submit feedback" menu. Encountered an error while checking for updates Make sure that BCUninstaller is not blocked in your firewall and that you have a working internet connection. New version {0} is available, do you want to upgrade now? 0 is version number BCUninstaller will automatically download the update and apply it after a restart. Please note that you might lose your settings in the process. Changelog: - {0} Warning: During update the folder "Update" and the file "Update.zip" inside of the BCU directory will be removed. 0 is a list of changes separated by "- " Uninstall using Msi The selected entry can't be uninstalled using the MsiExec installer Selected uninstaller doesn't have a valid Guid for use with MsiExec. Stop current uninstall task Are you sure you want to stop currently running task? Stopping the task prematurely will not revert any changes. Currently running uninstaller won't be stopped, the task will wait for it to finish. Create restore point Failed to create a new restore point x64 keep space in front DEBUG keep space in front Uninstall progress You can now leave the computer Remaining uninstallers should be able to complete without any user intervention. You should still check in from time to time in case one of the uninstallers crashes. Junk/Leftover removal Do you really want to modify low-confidence items? Removing items marked with confidence lower than Good can be very dangerous! It is recommended that you verify that every single item is safe to delete. Remove keys from registry Are you sure you want to remove selected uninstaller entries? Following items will be removed from registry and will disappear from the uninstaller list, but will not be uninstalled. {0} Export failed An error has been encountered while saving exported data If the error persists try saving to a different directory, for example to the desktop. BCUninstaller is uninstalling {0} application(s) 0 is the uninstaller count Rename uninstaller Supplied name is empty or contains invalid characters Make sure you have not included any of the following characters: {0} 0 is list of characters separated by spaces Do you want to look for leftovers from performed uninstallation(s)? Please note that this feature is intended only for power users that understand how it works. It is not necessary to remove these files and they will not affect system performance in any meaningful way. No leftovers were found No leftovers were found. There still might be some residue left so you can run a temporary file cleaner like BleachBit. There was nothing to copy to the clipboard. Either no selected uninstaller has this bit of information or you didn't select anything. Copy to clipboard Open directories This action will open {0} directories at once, are you sure you want to continue? 0 is number of directories to open Search on line Nothing to search for Uninstall BCUninstaller Are you sure you want to uninstall BCUninstaller? I'm sorry to see you leave! If you have a minute or two please drop a word on why you uninstalled BCU on my website (http://klocmansoftware.weebly.com/). I'll do my best to fix any legitimate problems. Do you want to create a restore point before continuing? If you are unsure if applications you are uninstalling are important or required to system stability it is recommended to create a restore point. If anything breaks after the procedure you can then use System Restore to roll back the changes. An error has been encountered while opening the search page Save Uninstall List Failed to save the list to a file Are you sure you want to reset all application settings? Some applications can't be uninstalled quietly Some entries are protected and can not be modified Selected entry is protected and can not be modified An error has been encountered while opening the URL Do you want to keep current selection? An error has been encountered while opening the directory Failed to load selected files No uninstallers were selected, nothing to uninstall Run uninstallers To uninstall applications you must first select them from the list view. If you are using check-boxes, make sure that they are checked. If you choose to keep current selection it will be merged with the opened list(s) This action will open {0} URLs at once, are you sure you want to continue? Open URLs No URLs to open Modify protected item Affected entries: {0} To modify these entries you need to disable uninstaller protection from the settings sidebar.You can remove them from the task and continue with other items if you want. 0 names of protected uninstallers Protected entry: {0} To modify this entry you need to disable uninstaller protection from the settings panel. 0 name of protected uninstaller Following items are missing quiet uninstallers: {0} Do you want to use "loud" uninstallers for those items, or should they be removed them from the task? 0 is names of non-quiet uninstallers Quiet uninstall Restore default settings All of your settings will be lost permanently. BCUninstaller will have to restart to complete this action. Open Uninstall List The restore point WAS NOT CREATED, you will not be able to restore changes! Do you want to continue with the uninstallation anyway? Renaming "{0}" Rename selected entry Task finished Shown on the status bar Uninstalling Shown on the status bar Remember choice Error File doesn't exist. Nothing to display. This application is uninstalled using Windows Installer (MsiExec). Name Value Empty GUID found GUID missing Select down to... File not found. Running post-uninstall commands... Running pre-uninstall commands... Ready Shows up when nothing else is displayed on the status bar. {0} uninstallers selected {0} is a number of selected uninstallers {0} uninstallers in total, {1} {0} is a number of all uninstallers, {1} is a long file size (123 Megabytes) Following command failed to execute: {0} {0} is a command line (c:\example.exe /help) External execute failed Default Used in language select box when you want to use the system language Some settings will not take effect until the application is restarted. Do you want to restart BCU to apply new settings? Change application settings Certificate is missing Processing detected applications, {0} left... {1} = how many application uninstallers still need to be processed Selecting "Terminate" will immediately close the running uninstaller and might result in uninstallation not being completed. Usually it is possible to run the uninstaller again to finish the uninstallation. Alternatively you can skip waiting for this process. Skipping will let the uninstaller continue working while the task moves on to the next item. Keep in mind that some uninstallers can fail to run until the skipped process finishes. Do you want to skip waiting for the currently running uninstaller? Skip currently running task Another uninstall task is already running. Please wait for it to finish and then try again. Rating: {0} Positives: {1} Negatives: {2} {0} - Rating as a string {1} - List of strings of positive parts of the rating {2} - List of strings of negative parts of the rating The lists are separated by a single newline. Rating details This application does not have a valid registry entry This application does not have a valid uninstaller Loading Windows Features... Refreshing startup information... Shown when refreshing autostart information of the uninstallers No directories to open Not available Used on application list when value is not available Ratings not available You have to enable ratings from the settings first. You can't rate applications that are not installed properly. {0} applications {0} is number of apps to rate, "Rate " will be automatically put in front of this string Average rating: {0}; My rating: {1} Following uninstallers failed to execute, likely because of a collision. Please wait for other uninstallers to finish and try again. {0} You can try disabling collision detection in the settings, but it is not recommended. Force uninstallation Failed to run some of the uninstallers .NET Framework v4.0 not found .NET Framework v4.0 was not found, some features will be disabled The v4.0 framework is optional, but recommended. The features that rely on the framework will be disabled until you install it. Some uninstallers failed Do you want to try running quiet uninstallers that failed as loud? Following uninstallers will be restarted loudly: Scanning specified directory... Select directory with applications that you want to remove. Uninstall from directory No applications were found in the specified directory Make sure that you selected the correct directory and that the application's executables are still present. Found an uninstaller for {0} Do you want to run this uninstaller? Issuer Subject Archived Extensions Friendly Name Issuer Name Not After Not Before Private Key Has Private Key Public Key Raw Data Serial Number Subject Name Signature Algorithm Version Thumbprint Failed to save settings Finishing up... Loading icons Look for application No valid files or directories were selected. Make sure you have access to them, and they aren't marked as system files. Look for applications Failed to find any applications inside {0} Modify application Selected application can't be modified The selected application has no modify command specified. It might be necessary to uninstall, and then install it again to change install settings. Save uninstall list Save changes to the opened uninstall list? There are unsaved changes in the opened uninstall list that will be lost by closing it. Select the directory with the applications to uninstall. Select where to save the backup. A new directory will be created. BCU has been updated to v{0}! Welcome to BCU version {0}! Putting PC to sleep in {0}s. Uncheck the sleep checkbox to cancel. Does nothing Option for "Double clicking in application list..." Opens properties Option for "Double clicking in application list..." Uninstalls Option for "Double clicking in application list..." Cannot rename {0} This uninstaller kind does not support renaming ({0}). ================================================ FILE: source/BulkCrapUninstaller/Properties/Localisable.ru.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Создание точки восстановления... Поиск остатков... Обновление списка... Удаление остатков... Поиск обновлений... Нет элементов, соответствующих критериям поиска. BCUninstaller экспорт Издатель | Версия | Дата | Размер | Реестр | Тип деинсталлятора | Команда удаления | Команда тихого удаления | Комментарии Портативная keep space in front Не удалось вызвать API Бэкап реестра не удался, всё равно продолжить? Детали ошибки: Удаление остатков Детали ошибки: Add space or newline afterwards and two newlines before Вы хотите создать бэкап реестра перед продолжением? У Вас будет возможность откатить все изменения, дважды щёлкнув по ним впоследствии. Файлы и каталоги будут перемещены в корзину, Вы можете восстановить их оттуда. Действие не удалось Нужно выбрать только одну запись для этого действия Выберите один деинсталлятор из списка. Если Вы используете чекбоксы, не забудьте проверить их. Поиск обновлений Открыть он-лайн контент Не могу подключиться к интернету, нет доступных сетей. Убедитесь, что сетевой кабель подключён. Если Вы используете Wi-Fi, убедитесь, что сигнал достаточен. Отправить отзыв Хотите отправить отзыв о BCU? Это займёт меньше минуты, но сильно поможет развитию! Все отзывы высоко ценятся, будь то сообщение об ошибке, запрос новой фичи, или простое "спасибо"! Вы можете отправить его позже через меню (Справка-> Обратная связь). Текущая версия актуальна Обновления не найдены, у вас последняя версия. Хотите, чтобы добавились новые возможности или была исправлена ошибка? Пожалуйста, присылайте мне Ваши отзывы с помощью меню "Справка-> Обратная связь". Ошибка при проверке наличия обновлений Убедитесь, что BCUninstaller не заблокирован в вашем файрволе и что Вы подключены к интернету. Новая версия {0} доступна, желаете обновить сейчас? 0 is version number BCUninstaller загрузит обновление и применит его после перезагрузки программы. Имейте в виду, Вы можете потерять свои настройки в процессе обновления. Изменения: - {0} Внимание: Во время обновления папка "Update" и файл "Update.zip" внутри BCU каталога будут удалены. 0 is a list of changes separated by "- " Удалить с помощью Msi Выбранный элемент не может быть удалён с помощью MsiExec Выбранный деинсталлятор не имеет допустимый идентификатор Guid для использования с MsiExec. Остановить текущую деинсталляцию Вы уверены, остановить запущенные задачи? Остановка задачи не вернёт уже сделанные изменения. Работающий в данный момент деинсталлятор не остановить, это задание будет дожидаться его завершения. Создать точку восстановления Не удалось создать точку восстановления x64 keep space in front Отладка keep space in front Прогресс деинсталляции Вы можете оставить компьютер, процесс автоматический Остальные деинсталляторы должны закончить работу без вмешательства пользователя. Проверяйте процесс время от времени на случай сбоя какого-либо из деинсталляторов. Мусор/Остатки удаления Вы действительно хотите изменить неуверенно распознанные элементы? Удаление элементов, помеченных с уверенностью ниже, чем хорошая, может быть очень опасно! Рекомендуется убедиться, что каждый отдельный элемент можно безопасно удалять. Удалить ключи из реестра Вы уверены, что хотите удалить выбранные записи? Следующие элементы будут удалены из реестра и исчезнут из списка удаления, но не будут удалены. {0} Ошибка экспорта Произошла ошибка при сохранении экспортируемых данных Если ошибка повторяется, попробуйте сохранить в другой каталог, например — на рабочем столе. BCUninstaller удаляет {0} программ(ы). 0 is the uninstaller count Переименовать деинсталлятор Пустое имя или содержатся недопустимые символы Убедитесь, что Вы не включили следующие символы: {0} 0 is list of characters separated by spaces Вы хотите найти остатки удалённых программ? Обратите внимание, что эта функция предназначена для опытных пользователей, которые понимают, как это работает. Необязательно удалять эти файлы, они не будут влиять на производительность системы каким-либо значимым образом. Остатки не найдены Остатки не найдены. Тем не менее, могли остаться временные файлы, Вы можете запустить чистку временных файлов, например, в BleachBit. Нечего копировать в буфер обмена. Выбранное не имеет этот блок информации, либо ничего не выбрано. Копировать в буфер Открыть папку Это действие откроет {0} каталогов сразу, Вы уверены, что хотите продолжить? 0 is number of directories to open Поиск в интернете Нечего искать Удалить BCUninstaller Вы уверены, что хотите удалить BCUninstaller? Мне жаль видеть, что вы уходите! Если у Вас есть минута или две, пожалуйста, напишите на моём сайте несколько слов о том, почему был удалён BCU (http://klocmansoftware.weebly.com/). Я сделаю всё возможное, чтобы исправить любые существенные проблемы. Вы хотите создать точку восстановления прежде, чем продолжить? Если при удалении приложения Вы не уверены, является ли оно важными или обязательным для стабильности системы, рекомендуется создать точку восстановления. Если возникнут проблемы после удаления, Вы сможете воспользоваться восстановлением системы для отката изменений. Произошла ошибка при открытии страницы поиска Сохранить список деинсталляции Не удалось сохранить список в файл Вы уверены, действительно хотите сбросить все параметры приложения? Некоторые приложения не могут быть удалены тихо Некоторые записи защищены и не могут быть изменены Выбраннная запись защищена и не может быть изменена Произошла ошибка при открытии URL-адреса Сохранить текущий выбор элементов? Произошла ошибка при открытии каталога Не удалось загрузить выбранные файлы Вы не выбрали элементы, нечего удалять Запуск деинсталляторов Для удаления программ надо сначала выбрать их из списка. Если Вы используете флажки, убедитесь, что они отмечены. Если Вы сохраните выбор, он будет объединён с открытым списком/списками Это действие откроет {0} URL-адресов одновременно, хотите продолжить? Открыть URL-адрес(а) Нет URL для открытия Изменить защищённый элемент Затронутые записи: {0} Чтобы изменить эти записи, нужно отключить защиту в боковой панели настроек. Также Вы можете убрать их из задания и продолжать с другими элементами по желанию. 0 names of protected uninstallers Защищённые записи: {0} Чтобы изменить эту запись, необходимо отключить защиту в панели настроек. 0 name of protected uninstaller Следующие пункты не имеют тихие деинсталляторы: {0} Вы хотите использовать "громкие" деинсталляторы для этих элементов или они должны быть удалены из задания? 0 is names of non-quiet uninstallers Тихая деинсталляция Восстановление настроек по умолчанию Все ваши настройки будут потеряны навсегда. BCUninstaller придётся перезапустить, чтобы выполнить это действие. Открыть список деинсталляции Точка восстановления не была создана, Вы не сможете восстановить изменения! Вы хотите всё равно продолжить удаление? Переименование "{0}" Переименовать выбранный элемент Задача завершена Shown on the status bar Процесс деинсталляции Shown on the status bar Запомнить выбор Ошибка Файл не существует. Нечего показывать. Это приложение удаляется с помощью Windows Installer (MSIexec). Имя Значение Пустой GUID найден GUID отсутствует Выбрать вплоть до... Файл не найден. Запуск после команды удаления... Запуск перед командой удаления... Готов Shows up when nothing else is displayed on the status bar. {0} деинсталлятора(ов) отмечено {0} is a number of selected uninstallers {0} деинсталляторов всего, {1} {0} is a number of all uninstallers, {1} is a long file size (123 Megabytes) Следующую команду выполнить не удалось: {0} {0} is a command line (c:\example.exe /help) Внешняя команда не выполнена По умолчанию Used in language select box when you want to use the system language Некоторые настройки не вступят в силу, пока приложение не будет перезапущено. Вы хотите перезапустить BCU, чтобы применить новые настройки? Изменение настроек приложения Сертификат отсутствует Процесс деинсталляции ({0}) {1} = how many application uninstallers still need to be processed При выборе "Прервать" процесс удаления немедленно прекратится, это может привести к неполному удалению. Обычно можно запустить деинсталлятор снова, чтобы завершить удаление программы. В качестве альтернативы Вы можете пропустить ожидание для этого процесса. Пропуск позволит деинсталлятору продолжать работать, а заданию — перейти к следующему пункту. Имейте в виду, что некоторые деинсталляторы могут не заработать, пока не завершится предыдущий процесс. Пропустить ожидание завершения текущей деинсталляции? Пропустить текущее ожидание Уже выполняется другая задача удаления. Дождитесь её окончания и повторите попытку. Рейтинг: {0} Положительные: {1} Отрицательные: {2} {0} - Rating as a string {1} - List of strings of positive parts of the rating {2} - List of strings of negative parts of the rating The lists are separated by a single newline. Детали рейтинга Это приложение не имеет действительную запись в реестре Это приложение не имеет валидного деинсталлятора Загрузка компонентов Windows... Обновление информации автозапуска... Shown when refreshing autostart information of the uninstallers Нет каталогов для открытия Недоступно Used on application list when value is not available Рейтинги недоступны Вы должны включить рейтинги в настройках. Нельзя оценить приложения, которые не установлены должным образом. {0} приложений {0} is number of apps to rate, "Rate " will be automatically put in front of this string Средний рейтинг: {0}; Мой рейтинг: {1} Следующие деинсталляторы не удалось выполнить, скорее всего, из-за конфликтов. Дождитесь окончания текущих деинсталляций и попробуйте снова. {0} Вы можете отключить обнаружение конфликтов в настройках, но это не рекомендуется. Удалить принудительно Не все деинсталляторы удалось запустить .NET Framework v4.0 не найден .NET Framework v4.0 не найден, некоторые функции будут отключены .NET Framework v4.0 является необязательным, но рекомендуется. Функции, которые зависят от .NET, будут отключены, пока Вы не установите его. Некоторые деинсталляторы дали сбой Хотите запустить "тихо" те, которые не отработали "громко"? Сканирование указанной папки... Выбрать папку с приложениями, которые Вы хотите удалить. Удалить из каталога В указанном каталоге не найдено приложений Убедитесь, что Вы выбрали правильный каталог и исполняемые файлы программ присутствуют. Найден деинсталлятор для {0} Следующие деинсталляторы будут перезапущены "громко": Запустить этот деинсталлятор? Отправитель Субъект Архивировано Расширения Короткое имя Имя отправителя Не позднее Не ранее Приватный ключ Имеет Приватный ключ Публичный ключ Необработанные данные Серийный номер Имя субъекта Алгоритм подписи Версия Отпечаток Не удалось сохранить настройки Завершение... Загрузка иконок Показать приложение Не выбраны действительные файлы или каталоги. Убедитесь, что у Вас есть доступ к ним и они не помечены как системные. Показать приложения Приложения в {0} не найдены Изменить приложение Выбранное приложение нельзя изменить Выбранное приложение не имеет команды изменения. Возможно, потребуется удалить, а затем снова установить его, чтобы изменить настройки установки. Сохранить список удаления Сохранить изменения в списке удаления? В списке удаления есть несохранённые изменения, которые будут потеряны при закрытии. Выберите каталог с приложениями для удаления. Выберите, где сохранить резервную копию. Будет создан новый каталог. BCU обновлён до v{0}! Добро пожаловать в BCU версии {0}! Перевод компьютера в спящий режим через {0}s. Уберите флажок спящего режима для отмены. ================================================ FILE: source/BulkCrapUninstaller/Properties/Localisable.sl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Ustvarjanje obnovitvene točke... Iskanje ostankov... Naseljevanje seznama odstranjevanja... Odstranjevanje ostankov... Iskanje posodobitev... Tukaj ni ujemajočih vnosov z vašim iskalnim kriterijem. BCUninstaller izvoz Založnik | Različica | Datum | Velikost | Register | Vrsta odstranjevalca | Odstranjevalni niz | Tiho odstrani | Komentarji Prenosni keep space in front Ni uspel klic API funcije Varnostna kopija registra ni uspela. Ali želite, kljub temu nadaljevati? Podrobnosti napake: Odstranitev ostankov namestitve Podrobnosti o napaki: Add space or newline afterwards and two newlines before Ali želite pred nadaljevanjem, narediti varnostno kopijo registra? Povrnili boste vse spremembe z dvoklikom nanje. Datoteke in imeniki bodo premaknjeni v Koš. Od tam jih lahko obnovite. Postopek ni uspel. Za ta postopek morate izbrati le eden vnos S seznama izberite natančno enega odstranjevalca. Če uporabljate potrditveno polje, prepričajte se, da ste ga označili. Poišči posodobitve Odpri spletno vsebino Ne morem se povezati z internetom. Omrežje ni na voljo. Prepričajte se, da je vaš omrežni kabel priključen v računalnik. Če uporabljate brezžično omrežje, zagotovite dovolj močan signal. Pošlji povratne informacije Ali želite poslati povratne informacije v zvezi z BCU? To bo trajalo manj kot minuto vendar bo izjemno pomagalo razvijalcem! Vse povratne informacije so zelo zaželene in cenjene bodisi, da gre za poročilo o hrošču, zahtevo nove funkcije ali za preprosto zahvalo! Kasneje jih lahko pošljete iz glavne menijske vrstice (Pomoč->Pošlji povratne informacije). Trenutna različica je posodobljena V tem trenutku niso bile najdene posodobitve. Imate nameščeno zadnjo različico. Želite nove funkcije ali popravljen hrošč? Prosimo, pošljite nam vaše povratne informacije z uporabo menija "Pomoč->Pošlji povratne informacije". Pri preverjanju obstoja posodobitev je prišlo je do napake Zagotovite, da BCUninstaller ni blokiran z vašim požarnim zidom in, da ste povezani z internetom. Na voljo je nova različica {0}. Ali jo želita zdaj nadgraditi? 0 is version number BCUninstaller bo samodejno prenesel posodobitve in jih uporabil po ponovnem zagonu. Upoštevajte, da boste med postopkom morda izgubili vaše nastavitve. Dnevnik sprememb: - {0} Opozorilo: Med posodabljanjem bo odstranjena mapa "Update" in datoteka "Update.zip", v imeniku BCU. 0 is a list of changes separated by "- " Odstrani z Msi Izbran vnos ni možno odstraniti z uporabo MsiExec installerja Izbran odstranjevalec nima veljaven Guid za uporabo z MsiExec. Ustavi trenutno odstranjevanje Ali res želite ustaviti trenutno delujoče opravilo? Predčasno ustavljanje opravila ne bo povrnilo nobene spremembe. Trenutno delujoč odstranjevalec ne bo ustavljen. Opravilo bo počakalo na njegov zaključek. Ustvari obnovitveno točko Ni uspelo ustvarjanje nove obnovitvene točke x64 keep space in front DEBUG keep space in front Napredek odstranjevanja Zdaj lahko pustite računalnik Preostali odstranjevalci bi morali dokončati delo brez kakršnega koli uporabnikovega posredovanja. Od časa do časa boste jih še vedno morali preveriti, v primeru, če se eden izmed njih sesuje. Odstranitev neuporabnih/ostankov Ali res želite spremeniti vnose nizke stopnje zaupanja? Odstranjevanje vnosov, označenih z nižjim zaupanjem 'Dobro', je lahko zelo nevarno! Priporočljivo je, da preverite, ali je vsak posamičen vnos varno izbrisati. Odstrani ključe iz registra Ali ste prepričani v to, da želite odstraniti izbrane vnose odstranjevalca? Naslednji vnosi bodo odstranjeni iz registra in bodo izginili s seznama odstranjevanja, vendar ne bodo odstranjeni. {0} Izvoz ni uspel Prišlo je do napake med shranjevanjem izvoženih podatkov Če obstaja napaka, poskusite shraniti v drugo mapo! Npr. na Namizje. BCUninstaller odstranjuje {0} aplikacij 0 is the uninstaller count Preimenuj odstranjevalca Zagotovljeno ime je prazno ali vsebuje neveljavne znake Prepričajte se, da niso vključeni kateri koli naslednji znaki: {0} 0 is list of characters separated by spaces Ali želite pogledati ostanke opravljenih odstranitev? Upoštevajte, da je ta funkcija namenjena samo za napredne uporabnike, ki razumejo kako le-ta deluje. Teh datotek ni potrebno odstraniti, in te ne bodo na noben način vplivale na delovanje sistema. Niso bili najdeni ostanki namestitve Niso bili najdeni ostanki namestitve. So pa še vedno prisotni nekateri drugi neuporabni ostanki. Zato lahko zaženete čistilec začasnih datotek kot je npr. BleachBit. Ničesar ni za kopiranje v odložišče. Ali ni izbran odstranjevalec s tako malo informacijami ali pa niste nič izbrali. Kopiraj v odložišče Odpri imenike To opravilo bo naenkrat odprlo {0} imenikov. Ali res želite nadaljevati? 0 is number of directories to open Poišči na spletu Ničr ni za iskanje Odstrani BCUninstaller Ali res želite odstraniti BCUninstaller? Glejte. Žal mi je, da greste! Če imate vsaj minuto časa, na moji spletni strani (http://klocmansoftware.weebly.com/) napišite kakšno besedo o tem zakaj ste odstranili BCU. Po svojih najboljših močeh se bom potrudil popraviti vse legitimne težave. Ali želite pred nadaljevanjem, ustvariti obnovitveno točko? Če niste prepričani, ali so aplikacije, ki ste jih odstranili, pomembne ali zahtevane za stabilnost sistema, je priporočljivo, da ustvarite obnovitveno točko. Če se karkoli zalomi po pravljenem postopki, lahko uporabite Obnovitev sistema, da povrnete nazaj vse opravljene spremembe. Prišlo je do napake med odpiranjem iskane strani Shrani seznam odstranjevanja Spodletelo je shranjevanje seznama v datoteko Ali ste prepričani, da želite ponastaviti vse nastavitve aplikacije? Nekaterih aplikacij ni mogoče tiho odstraniti Nekateri vnosi so zaščiteni in jih ni mogoče spreminjati Izbran vnos je zaščiten in ga ni možno spremeniti Prišlo je do napake med odpiranje URL naslova Ali želite obdržati trenutni izbor? Prišlo je do napake med odpiranje imenika. Ni uspelo nalaganje izbranih datotek Ni izbranih odstranjevalcev. Nič ni za odstranjevanje. Zaženi odstranjevalce Za odstranjevanje aplikacij, jih morate najprej izbrati s seznama za ogled. Če uporabljate potrditvena polja se prepričajte, da so označeni. Če se odločite obdržati trenutni izbor, ta mora biti spojen z odprtimi seznami. Ta postopek bo naenkrat odprl {0} URL naslovov. Ali res želite nadaljevati? Odpri URL naslove Ni URL naslovov za odpiranje Spremeni zaščiten vnos Prizadetih vnosov: {0} Za spreminjanje teh vnosov morate onemogočiti zaščito odstranjevalca iz stranske vrstice z nastavitvami. Lahko jih odstranite iz opravila in nadaljujete z drugimi vnosi, če to želite. 0 names of protected uninstallers Zaščiten vnos: {0} Za spreminjanje vnosa morate onemogočiti zaščito odstranjevalca iz plošče z nastavitvami. 0 name of protected uninstaller Naslednji vnosi manjkajo v tihih odstranjevalcih: {0} Ali želite za te vnose uporabiti "glasne" odstranjevalce, ali morajo ti biti odstranjeni iz opravila. 0 is names of non-quiet uninstallers Tiho odstrani Obnovi privzete nastavitve Vse vaše nastavitve bodo trajno izgubljene. BCUninstaller boste morali ponovno zagnati, da dokončate ta postopek. Odpri seznam odstranjevanja Obnovitvena točka NI BILA USTVARJENA. Ne boste mogli obnoviti spremembe! Ali želite na vsak način nadaljevati? Preimenovanje "{0}" Preimenuj izbran vnos Opravilo je končano Shown on the status bar Odstranjevanje Shown on the status bar Zapomni izbiro Napaka Datoteka ne obstaja. Ni ničesar za prikaz. Ta aplikacija je odstranjena z Windows Installerjem (MsiExec). Ime Vrednost Prazno GUID je najden Manjkajoč GUID Izberi navzdol... Datoteka ni najdena. Izvajanje poodstranitvenih ukazov... Izvajanje predodstranitvenih ukazov... Pripravljen Shows up when nothing else is displayed on the status bar. {0} izbranih odstranjevalcev {0} is a number of selected uninstallers {0} odstranjevalcev skupaj {1} {0} is a number of all uninstallers, {1} is a long file size (123 Megabytes) Naslednji ukaz ni bil izveden: {0} {0} is a command line (c:\example.exe /help) Zunanje izvajanje je spodletelo Privzeto Used in language select box when you want to use the system language Nekatere nastavitve ne bodo uveljavljene, dokler aplikacija ne bo ponovno zagnana. Ali želite ponovno zagnati BCU, za uporabo novih nastavitev? Spremeni nastavitve aplikacije Manjka digitalno potrdilo Obdelava odstranjevalcev ({0}) {1} = how many application uninstallers still need to be processed Izbira "Prekini", bo takoj zaprla zagnanega odstranjevalca in lahko povzroči nedokončano odstranjevanje. Za dokončanje odstranitve ponavadi zadostuje ponovni zagon odstranjevalca. Neobvezno, lahko preskočite čakanja na ta proces. Preskok bo dovolil odstranjevalcu nadaljevati z delom, medtem, ko se bo opravilo premaknilo na naslednji vnos. Imejte v mislih, da nekaterim odstranjevalcem lahko spodleti zagon, ko se konča preskočen proces. Ali želite preskočiti čakanje trenutno zagnanega odstranjevalca? Preskoči trenutno zagnano storitev Izvaja se že drugo odstranjevanje. Počakajte na njen konec, nato poskusite znova. Ocena: {0} Pozitivnih: {1} Negativnih: {2} {0} - Rating as a string {1} - List of strings of positive parts of the rating {2} - List of strings of negative parts of the rating The lists are separated by a single newline. Podrobne ocene Ta aplikacija nima veljavnega vnosa v registru Ta aplikacija nima veljavnega odstranjevalca Nalaganje Windows funkcij... Osveževanje zagonskih informacij... Shown when refreshing autostart information of the uninstallers Ni map za odpiranje {0} aplikacij {0} is number of apps to rate, "Rate " will be automatically put in front of this string Ocene niso na voljo V nastavitvah najprej morate omogočiti ocenjevanje. Ne morete ocenjevati nepravilno nameščenih aplikacij. Povprečna ocena: {0}; Moja ocena: {1} Naslednji odstranjevalci se niso uspešno zagnali, verjetno zaradi spora. Prosimo, da najprej počakate, da drugi odstranjevalci končajo delo in nato poskusite znova. {0} Lahko poskusite onemogočiti zaznavanje sporov v Nastavitvah, toda to ni priporočeno. Vsili odstranitev Spodletel zagon nekaterih odstranjevalcev .NET Framework v4.0 nni najden .NET Framework v4.0 ni bil najden, nekatere funkcije bodo onemogočene. Različica Framework 4.0 je neobvezna, toda priporočena. Funkcije, ki zahtevajo Framework bodo onemogočene dokler ga ne namestite. Ni na voljo Used on application list when value is not available Nekateri odstranjevalci niso bili uspešni Ali želite poskusiti uporabiti tihe odstranjevalce, ko glasen ni bil uspešen? Naslednji odstranjevalci bodo znova glasno zagnani: Pregled določene mape.... Izberite mapo z aplikacijami, ki jih želite odstraniti. Odstrani iz mape V določeni mapi niso bile najdene nobene aplikacije. Prepričajte se, da ste izbrali pravilno mapo in, da so izvedljive datoteke aplikacij še vedno prisotne. Najden je odstranjevalec za {0} Ali želite zagnati tega odstranjevalca? Izdajatelj Predmet Arhiviran Razširitve Prijazno ime Ime izdajatelja Ne po Ne pred Zaseben ključ Ima zaseben ključ Javni ključ Surovi podatki Serijska številka Ime predmeta Algoritem podpisa Različica Prstni odtis Ni uspelo shranjevanje nastavitev Dokončanje... Nalaganje ikon Poglej za aplikacijo Ni izbranih veljavnih datotek ali map. Prepričajte se, da imate dostop do njih in, da te niso označene kot sistemske datoteke. Poglej za aplikacije Ni bilo mogoče najti nobenih aplikacij znotraj {0} Spremeni aplikacijo Izbrane aplikacije ni mogoče spremeniti Izbrana aplikacija nima določenega ukaza za spreminjanje. Morda jo bo potrebno odstraniti, nato pa jo znova namestiti, da spremenite nastavitve namestitve. Shrani seznam odstranjevanja Shranim spremembe na odprtem seznamu za odstranitev? Na odprtem seznamu za odstranjevanje so shranjene neshranjene spremembe, ki bodo izgubljene z njegovim zapiranjem. Izberite imenik z aplikacijami za odstranitev. Izberite, kje želite shraniti varnostno kopijo. Ustvarjen bo nov imenik. BCU je bil posodobljen v različico {0}! Dobrodošli pri delu z BCU različice {0}! ================================================ FILE: source/BulkCrapUninstaller/Properties/Localisable.sv.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Skapar en återställningspunkt Sök efter rester... Fyller listan med avinstallationsprogram... Tar bort rester... Söker efter uppdateringar... Inga poster matchar dina sökkriterier. BCUninstaller export Utgivare | Version | Datum | Storlek | Register | Avinstallations typ | Avinstallationssträng | Tyst avinstallationssträng | Kommentarer Portable keep space in front Misslyckades att anropa API:en Säkerhetskopiering av registret misslyckades, vill du fortsätta ändå? Feluppgifter: Restborttagning Feldetaljer: Add space or newline afterwards and two newlines before Vill du skapa en säkerhetskopia av registret innan du fortsätter? Du kommer att kunna ångra alla ändringar genom att dubbelklicka på den efteråt. Filer och kataloger kommer att flyttas till papperskorgen, du kan återställa dem därifrån. Åtgärd misslyckades Du kan bara välja en post för denna åtgärd Välj exakt en enstaka avinstallation från listan. Om du använder kryssrutor, se till att kontrollera dem. Sök efter uppdateringar Öppna online-innehåll Kan inte ansluta till internet, det finns inga tillgängliga nätverk. Se till att din nätverkskabel är ansluten. Om du använder Wi-Fi, se till att du har bra signalstyrka. Skicka feedback Vill du skicka feedback angående BCU? Detta tar mindre än en minut och hjälper utvecklingen enormt! All feedback uppskattas, vare sig det är en buggrapport, en funktionsförfrågan eller ett enkelt tack! Du kan skicka det senare från toppmenyn (Hjälp->Skicka feedback). Du har den senaste versionen Inga uppdateringar hittades för tillfället, du har den senaste versionen. Vill du ha någon funktionalitet tillagd eller en bugg fixad? Skicka gärna din feedback via menyn "Hjälp->Skicka feedback". Ett fel uppstod vid kontroll av uppdateringar Se till att BCUninstaller inte är blockerad i din brandvägg och att du har en fungerande internetanslutning. Ny version {0} är tillgänglig, vill du uppgradera nu? 0 is version number BCUninstaller kommer automatiskt att hämta uppdateringen och tillämpa den efter en omstart. Observera att du kanske förlorar dina inställningar i processen. Ändringslogg: - {0} Varning: Under uppdateringen kommer mappen "Update" och filen "Update.zip" inuti BCU-mappen att tas bort. 0 is a list of changes separated by "- " Avinstallera med Msi Den valda posten kan inte avinstalleras med MsiExec-installeraren Den valda avinstallationen har inte en giltig GUID för användning med MsiExec. Stoppa pågående avinstallationsjobb Är du säker på att du vill stoppa den pågående uppgiften? Att stoppa processen i förtid kommer inte att ångra några ändringar. Den körande avinstallationen kommer inte att stoppas, uppgiften kommer att vänta på att den ska slutföras. Skapa återställningspunkt Det gick inte att skapa en ny återställningspunkt x64 keep space in front DEBUG keep space in front Avinstallationsförlopp Nu kan du låta datorn jobba Återstående avinstallationer borde kunna slutföras av sig själv. Du bör ändå kontrollera med jämna mellanrum ifall någon avinstallation kraschar. Borttagning av skräp/efterlämnade filer Vill du verkligen ändra lågtillförlitliga objekt? Att ta bort objekt markerade med en tillförlitlighetsgrad lägre än Bra kan vara mycket farligt! Det rekommenderas att du verifierar att varje enskilt objekt är säkert att ta bort. Ta bort nycklar från registret Är du säker på att du vill ta bort valda avinstallationsposter? Följande poster kommer att tas bort från registret och försvinna från avinstallationslistan, men kommer inte att avinstalleras. {0} Export misslyckades Ett fel inträffade när datan skulle exporteras Om felet kvarstår, försök spara till en annan plats, till exempel till skrivbordet. BCUninstaller avinstallerar {0} app(ar) 0 is the uninstaller count Döp om avinstallationsprogram Namnet är tomt eller innehåller ogiltiga tecken Kontrollera att du inte har inkluderat något av följande tecken: {0} 0 is list of characters separated by spaces Vill du leta efter kvarlämnade filer från utförda avinstallation(er)? Den här funktionen är avsedd endast för avancerade användare som förstår hur den fungerar. Det är inte nödvändigt att ta bort dessa filer och de kommer inte att påverka systemets prestanda på något meningsfullt sätt. Inga rester hittades Inga rester hittades. Det kan dock fortfarande finnas några rester kvar så du kan köra en filrensare som BleachBit. Det fanns inget att kopiera till urklipp. Antingen har ingen vald avinstallationsprogram denna information eller så valde du ingenting. Kopiera till Urklipp Öppna mappar Denna åtgärd kommer att öppna {0} kataloger samtidigt, är du säker på att du vill fortsätta? 0 is number of directories to open Sök online Inget att söka efter Avinstallera BCUninstaller Är du säker på att du vill avinstallera BCUninstaller? Tråkigt att du lämnar! Om du har en minut eller två, vänligen lämna några ord om varför du avinstallerade BCU på min webbplats (http://klocmansoftware.weebly.com/). Jag kommer att göra mitt bästa för att åtgärda eventuella legitima problem. Vill du skapa en återställningspunkt innan du fortsätter? Om du är osäker på om de appar du avinstallerar är viktiga eller nödvändiga för systemets stabilitet, rekommenderas det att skapa en återställningspunkt. Om något går fel efter proceduren, kan du sedan använda Systemåterställning för att ångra ändringarna. Ett fel uppstod när söksidan skulle öppnas. Spara avinstallations-lista Misslyckades att spara listan till filen Är du säker på att du vill återställa alla appinställningar? Vissa appar kan inte installeras tyst Vissa poster är skyddade och kan inte ändras. Den valda posten är skyddad och kan inte ändras. Ett fel uppstod vid öppnandet av webbadressen. Vill du behålla nuvarande urval? Ett fel inträffade när katalogen öppnades Misslyckades att ladda valda filer Inga avinstallerare valdes, det finns inget att avinstallera Kör avinstallationer För att avinstallera appar måste du först välja dem från listvyn. Om du använder kryssrutor, se till att de är förbockade. Om du väljer att behålla nuvarande urval, kommer det att sammanfogas med de öppnade listorna. Detta öppnar {0} webbadresser samtidigt. Vill du vill fortsätta? Öppna webbadresser Inga webbadresser att öppna Modifiera skyddat objekt Påverkade poster: {0} För att ändra dessa poster behöver du inaktivera avinstalleringsskyddet från inställningssidofältet. Du kan ta bort dem från uppgiften och fortsätta med andra objekt om du vill. 0 names of protected uninstallers Skyddad post: {0} För att ändra denna post behöver du inaktivera avinstalleringsskyddet från inställningspanelen. 0 name of protected uninstaller Följande objekt saknar tysta avinstallationsprogram: {0} Vill du använda synliga avinstallationsprogram för dessa objekt, eller ska de tas bort från uppgiften? 0 is names of non-quiet uninstallers Tyst avinstallation Återställ standardinställningar Alla dina inställningar kommer att gå förlorade permanent. BCUninstaller måste startas om för att slutföra denna åtgärd. Öppna avinstallationslistan Återställningspunkten SKAPADES INTE, du kommer inte att kunna återställa ändringarna! Vill du fortsätta med avinstallationen ändå?” Döper om "{0}" Döp om vald post Uppgiften avslutad Shown on the status bar Avinstallerar Shown on the status bar Kom ihåg val Fel Filen finns inte. Inget att visa. Denna appen avinstalleras med Windows Installer (MsiExec). Namn Värde Tomt GUID hittad GUID saknas Välj ner till… Fil ej funnen. Kör efter-avinstallationskommandon… Kör före-avinstallationskommandon… Klar Shows up when nothing else is displayed on the status bar. {0} avinstallerare valda {0} is a number of selected uninstallers {0} avinstallerare totalt, {1} {0} is a number of all uninstallers, {1} is a long file size (123 Megabytes) Följande kommando misslyckades med att utföras: {0} {0} is a command line (c:\example.exe /help) Extern åtgärd misslyckades Standard Used in language select box when you want to use the system language Vissa inställningar kommer inte att träda i kraft förrän appen har startats om. Vill du starta om BCU för att tillämpa nya inställningar? Ändra appinställningar Certifikat saknas Bearbetar upptäckta appar, {0} kvar... {1} = how many application uninstallers still need to be processed Att välja "Avsluta" kommer omedelbart att stänga den pågående avinstallationen och kan resultera i att avinstallationen inte slutförs. Vanligtvis är det möjligt att köra avinstallationsprogrammet igen för att slutföra avinstallationen. Alternativt kan du hoppa över att vänta på denna process. Att hoppa över kommer att låta avinstallationen fortsätta arbeta medan uppgiften går vidare till nästa objekt. Tänk på att vissa avinstallationer kan misslyckas med att köras tills den hoppade över processen är färdig. Vill du hoppa över att vänta på det nuvarande körande avinstallationsprogrammet? Hoppa över pågående uppgift En annan avinstallation är redan igång. Vänligen vänta tills den är klar och försök sedan igen. Betyg: {0} Positiva: {1} Negativa: {2} {0} - Rating as a string {1} - List of strings of positive parts of the rating {2} - List of strings of negative parts of the rating The lists are separated by a single newline. Betygdetaljer Denna app har inte ett giltigt registerinlägg. Denna app har inte ett giltigt avinstallationsprogram. Laddar Windows Funktioner... Uppdaterar startinformation… Shown when refreshing autostart information of the uninstallers Inga kataloger att öppna Inte tillgängligt Used on application list when value is not available Betyg är inte tillgängligt Du måste aktivera betyg i inställningarna först. Du kan inte betygsätta appar som inte installerats korrekt. {0} appar {0} is number of apps to rate, "Rate " will be automatically put in front of this string Medelbetyg: {0}; Mitt betyg: {1} Följande avinstallationer misslyckades att köras, troligen på grund av en kollision. Vänligen vänta tills andra avinstallationsprogram har slutförts och försök igen. {0} Du kan försöka inaktivera kollisionsdetektering i inställningarna, men det rekommenderas inte. Tvinga avinstallation Misslyckades med att köra några av avinstallationsprogrammen. .NET Framework 4.0 hittades inte. .NET Framework 4.0 hittades inte, vissa funktioner kommer att inaktiveras. .NET Framework 4.0 är valfritt, men rekommenderas. De funktioner som är beroende av ramverket kommer att vara inaktiverade tills du installerar det. Några av avinstallationsprogrammen misslyckades. Vill du försöka köra de tysta avinstallationsprogrammen som misslyckades som synliga? Följande avinstallationsprogram kommer att startas om högljutt: Skannar angiven katalog... Välj katalog med appar som du vill ta bort. Avinstallera från katalog. Inga appar hittades i den angivna katalogen. Se till att du har valt rätt katalog och att programmets körbara filer fortfarande finns kvar. Hittade ett avinstallationsprogram för {0} Vill du köra detta avinstallationsprogram? Utfärdare Ämne Arkiverad Tillägg Vänligt namn Utfärdarnamn Inte efter Inte före Privat nyckel Har privat nyckel Offentlig nyckel Rådata Serienummer Ämnesnamn Signatur algoritm Version Avtryck Misslyckades med att spara inställningar Avslutar... Laddar ikoner Letar efter app Inga giltiga filer eller kataloger valdes. Kontrollera att du har åtkomst till dem och att de inte är markerade som systemfiler. Leta efter appar Misslyckades med att hitta några appar inuti {0} Modifiera app Vald app kan inte modifieras Den valda applikationen har inget ändringskommando angivet. Det kan vara nödvändigt att avinstallera och sedan installera om den för att ändra installationsinställningarna. Spara avinstallationslista Spara ändringar i den öppnade avinstallationslistan? Det finns osparade ändringar i den öppnade avinstallationslistan som kommer att gå förlorade vid stängning. Välj katalogen med apparna som ska avinstalleras. Välj var säkerhetskopian ska sparas. En ny mapp kommer att skapas. BCU har uppdaterats till v{0}! Välkommen till BCU version {0}! Ställer datorn i viloläge om {0}s. Avmarkera kryssrutan för viloläge för att avbryta. Gör ingenting Option for "Double clicking in application list..." Öppnar egenskaper Option for "Double clicking in application list..." Avinstallationer Option for "Double clicking in application list..." ================================================ FILE: source/BulkCrapUninstaller/Properties/Localisable.tr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Bir geri yükleme noktası oluşturuluyor ... Arta kalanlar aranıyor ... Kaldırma listesini kaldırılıyor ... Kalıntıları çıkarma ... Güncellemeler aranıyor ... Arama kriterinizle eşleşen giriş yok. BCUninstaller dışa aktarma. Yayıncı | Sürüm | Tarih | Boyut | Kayıt defteri | Kaldırıcı türü | Dizgiyi kaldır | Sessiz kaldırma dizesi | Yorumlar Taşınabilir keep space in front API çağrısı başarısız oldu Kayıt defteri yedeği başarısız oldu, yine de devam etmek istiyor musunuz? Hata detayları: Arta kalan kaldırma Hata detayları: Add space or newline afterwards and two newlines before Devam etmeden önce bir kayıt defteri yedeği oluşturmak ister misiniz? Tüm değişiklikleri daha sonra çift tıklatarak geri alabilirsiniz. Dosyalar ve dizinler geri dönüşüm kutusuna taşınır, onları buradan geri yükleyebilirsiniz. Eylem başarısız Bu işlem için yalnızca bir giriş seçmeniz gerekiyor Listeden tam olarak bir kaldırıcı seçin. Onay kutularını kullanıyorsanız, bunları kontrol ettiğinizden emin olun. Güncellemeleri arayın Çevrimiçi içeriği aç İnternete bağlanılamıyor, ağ yok. Ağ kablonuzun takılı olduğundan emin olun. Wi-Fi kullanıyorsanız, sinyal gücünüzün iyi olduğundan emin olun. Geri bildirim gönder BCU ile ilgili geri bildirim göndermek ister misiniz? Bu sizi bir dakikadan daha az sürecek ama gelişime büyük ölçüde yardımcı olacak! Tüm geri bildirimler takdir edilir, bir hata raporu, özellik talebi veya basit bir teşekkür! Daha sonra üst menü çubuğundan gönderebilirsiniz (Yardım-> Geri bildirim gönder). Güncel versiyon güncel Şu anda hiçbir güncelleme bulunamadı, en son sürüme sahipsiniz. Bazı işlevler eklendi mi yoksa bir hata mı düzeltildi? Lütfen "Yardım-> Geri Bildirim Gönder" menüsünü kullanarak geri bildiriminizi gönderin. Encountered an error while checking for updates Güvenlik duvarınızda BCUninstaller'ın engellenmediğinden ve çalışan bir internet bağlantınızın olduğundan emin olun. Yeni sürüm {0} kullanılabilir, şimdi yeni sürüme geçmek istiyor musunuz? 0 is version number BCUninstaller güncellemeyi otomatik olarak indirecek ve yeniden başlattıktan sonra uygulayacaktır. Lütfen ayarlarınızı bu süreçte kaybedebileceğinizi unutmayın. Değişiklikler: - {0} Uyarı: Güncelleme sırasında "Update" klasörü ve BCU dizininin içindeki "Update.zip" dosyası kaldırılacaktır. 0 is a list of changes separated by "- " Msi kullanarak kaldır Seçilen giriş MsiExec yükleyici kullanılarak kaldırılamaz Seçilen kaldırıcı, MsiExec ile kullanım için geçerli bir Kılavuza sahip değil. Mevcut kaldırma görevini durdur Şu anda çalışan görevi durdurmak istediğinizden emin misiniz? Görevi zamanından önce durdurmak herhangi bir değişikliği geri almayacaktır. Şu anda çalışan kaldırıcı durdurulmayacak, görev bitirmek için bekleyecektir. Geri yükleme noktası oluştur Yeni bir geri yükleme noktası oluşturulamadı x64 keep space in front DEBUG keep space in front Kaldırma ilerlemesi Şimdi bilgisayarı bırakabilirsin Kalan kaldırıcılar herhangi bir kullanıcı müdahalesi olmadan tamamlayabilmelidir. Kaldırma araçlarından birinin çökmesi durumunda zaman zaman kontrol etmelisiniz. Önemsiz / arta kalan Kaldırma Düşük güvenli ürünleri gerçekten değiştirmek istiyor musunuz? İyi'den daha düşük bir güven ile işaretlenmiş öğeleri çıkarmak çok tehlikeli olabilir! Her bir öğenin silinmesi güvenli olduğunu doğrulamanız önerilir. Anahtarları kayıt defterinden kaldır Seçilen kaldırıcı girişlerini kaldırmak istediğinizden emin misiniz? Aşağıdaki öğeler kayıt defterinden kaldırılacak ve kaldırıcı listesinden silinecek, ancak kaldırılmayacaktır. {0} Dışa aktarma başarısız oldu Dışa aktarılan verileri kaydederken bir hatayla karşılaşıldı Hata devam ederse, örneğin masaüstüne farklı bir dizine kaydetmeyi deneyin. BCUninstaller, {0} uygulamasını kaldırıyor 0 is the uninstaller count Kaldırıcıyı yeniden adlandır Sağlanan ad boş veya geçersiz karakterler içeriyor Aşağıdaki karakterlerden hiçbirini içermediğinden emin olun: {0} 0 is list of characters separated by spaces Arta kalan kaldırma işlemlerinden kalanları aramak ister misiniz? Lütfen bu özelliğin yalnızca nasıl çalıştığını anlayan deneyimli kullanıcıları için olduğunu unutmayın. Bu dosyaları kaldırmak gerekli değildir ve sistem performansını anlamlı bir şekilde etkilemeyecektir. Arta kalan kalıntı bulunamadı Arta kalan kalıntı bulunamadı. BleachBit gibi geçici bir dosya temizleyici çalıştırabilmeniz için hala bir miktar kalıntı kalmış olabilir. Panoya kopyalamak için hiçbir şey yoktu. Ya seçilen kaldırıcıyı bu bilgi biti yok ya da hiçbir şey seçmediniz. Panoya kopyala Açık dizinler Bu işlem bir kerede {0} dizini açacak, devam etmek istediğinizden emin misiniz? 0 is number of directories to open Çevrimiçi ara Aranacak bir şey yok BCUninstaller öğesini kaldır BCUninstaller'ı kaldırmak istediğinizden emin misiniz? Ayrıldığın için üzgünüm! Bir iki dakikanız varsa, lütfen web sitemde BCU'yu kaldırdığınıza dair bir söz bırakın (http://klocmansoftware.weebly.com/). Herhangi bir meşru sorunu çözmek için elimden geleni yapacağım. Devam etmeden önce bir geri yükleme noktası oluşturmak ister misiniz? Kaldırmakta olduğunuz uygulamaların önemli veya sistem kararlılığı için gerekli olup olmadığından emin değilseniz bir geri yükleme noktası oluşturmanız önerilir. İşlemden sonra herhangi bir şey olursa, değişiklikleri geri almak için Sistem Geri Yükleme'yi kullanabilirsiniz. Arama sayfası açılırken bir hatayla karşılaşıldı Kaldırma Listesini Kaydet Liste bir dosyaya kaydedilemedi Tüm uygulama ayarlarını sıfırlamak istediğinizden emin misiniz? Bazı uygulamalar sessizce kaldırılamaz Bazı girişler korunur ve değiştirilemez Seçilen giriş korunur ve değiştirilemez URL açılırken bir hatayla karşılaşıldı Mevcut seçimi korumak istiyor musunuz? Dizini açarken bir hatayla karşılaşıldı Seçilen dosyalar yüklenemedi Kaldırıcı seçilmedi, kaldırılacak hiçbir şey yok Kaldırıcıları çalıştır Uygulamaları kaldırmak için önce onları liste görünümünden seçmelisiniz. Onay kutularını kullanıyorsanız, kontrol edildiğinden emin olun. Mevcut seçimi korumayı seçerseniz, açılan liste (ler) ile birleştirilir. Bu işlem bir kerede {0} URL'yi açacak, devam etmek istediğinizden emin misiniz? Açık URL'ler Açılacak URL yok Korunan öğeyi değiştir Etkilenen girişler: {0} Bu girişleri değiştirmek için ayarların kenar çubuğundan kaldırıcı korumasını devre dışı bırakmanız gerekir. Bunları görevden kaldırabilir ve isterseniz diğer öğelere devam edebilirsiniz. 0 names of protected uninstallers Korumalı giriş: {0} Bu girişi değiştirmek için, kurulum panelinden kaldırıcı korumasını devre dışı bırakmanız gerekir. 0 name of protected uninstaller Aşağıdaki öğeler sessiz kaldırıcılar eksik: {0} Bu öğeler için "yüksek" kaldırıcıları mı kullanmak istiyorsunuz yoksa görevden çıkarılmaları mı gerekiyor? 0 is names of non-quiet uninstallers Sessiz kaldırma Ayarları varsayılan duruma getir Tüm ayarlarınız kalıcı olarak kaybolacak. Bu eylemi tamamlamak için BCUninstaller'ın yeniden başlatılması gerekecektir. Yükleme Kaldırma Listesi Geri yükleme noktası OLUŞTURMAZ, değişiklikleri geri yükleyemezsiniz! Kaldırma işlemine devam etmek istiyor musunuz? "{0}" yeniden adlandırılıyor Seçilen girişi yeniden adlandır Görev bitti Shown on the status bar Kaldırma Shown on the status bar Seçimi hatırla Hata Dosya mevcut değil. Gösterilecek bir şey yok. Bu uygulama Windows Installer (MsiExec) kullanılarak kaldırılmıştır. Adı Değer Boş GUID bulundu GUID eksik Aşağıya doğru seçin ... Dosya bulunamadı. Yükleme sonrası komutları çalıştırılıyor ... Ön yükleme komutlarını çalıştırılıyor ... Hazır Shows up when nothing else is displayed on the status bar. {0} kaldırıcı seçildi {0} is a number of selected uninstallers Toplam {0} kaldırıcı, {1} {0} is a number of all uninstallers, {1} is a long file size (123 Megabytes) Aşağıdaki komut çalıştırılamıyor: {0} {0} is a command line (c:\example.exe /help) Harici yürütme başarısız oldu Varsayılan Used in language select box when you want to use the system language Bazı ayarlar uygulama yeniden başlatılıncaya kadar geçerli olmaz. Yeni ayarları uygulamak için BCU'yu yeniden başlatmak istiyor musunuz? Uygulama ayarlarını değiştir Sertifika eksik Kaldırma işlemlerini gerçekleştirme ({0}) {1} = how many application uninstallers still need to be processed "Sonlandır" seçeneğinin seçilmesi, çalışan kaldırıcıyı hemen kapatır ve kaldırma işleminin tamamlanamamasına neden olabilir. Genellikle kaldırmayı bitirmek için kaldırıcıyı tekrar çalıştırmak mümkündür. Alternatif olarak, bu işlemi beklemeyi atlayabilirsiniz. Atlama, işleyici sonraki öğeye geçerken kaldırıcıyı çalışmaya devam etmesine izin verecektir. Bazı kaldırıcıların atlanan işlem bitene kadar çalışmaya devam edemeyeceğini unutmayın. Şu anda çalışan kaldırıcıyı beklemeyi mi atlamak istiyorsunuz? Şu anda çalışan görevi atla Başka bir kaldırma görevi zaten çalışıyor. Lütfen bitirmesini bekleyin ve tekrar deneyin. Değerlendirme: {0} Pozitif: {1} Negatif: {2} {0} - Rating as a string {1} - List of strings of positive parts of the rating {2} - List of strings of negative parts of the rating The lists are separated by a single newline. Derecelendirme detayları Bu uygulamanın geçerli bir kayıt defteri girişi yok Bu uygulama geçerli bir kaldırıcıya sahip değil Windows Özellikleri yükleniyor ... Yenileme başlangıç bilgileri ... Shown when refreshing autostart information of the uninstallers Açılacak dizin yok Müsait değil Used on application list when value is not available Puanlar mevcut değil İlk önce ayarlardan puanları etkinleştirmeniz gerekir. Düzgün yüklenmemiş uygulamaları değerlendiremezsiniz. {0} uygulamalar {0} is number of apps to rate, "Rate " will be automatically put in front of this string Ortalama kullanıcı oyu: {0}; Derecelendirmem: {1} Yüklemelerin kaldırılması, muhtemelen bir çarpışma nedeniyle yürütülemedi. Lütfen diğer kaldırıcıların bitmesini bekleyin ve tekrar deneyin. {0} Ayarlarda çarpışma algılamayı devre dışı bırakmayı deneyebilirsiniz, ancak önerilmez. Kaldırma işlemini zorla Bazı kaldırıcılar çalıştırılamadı .NET Framework v4.0 bulunamadı .NET Framework v4.0 bulunamadı, bazı özellikler devre dışı bırakılacak V4.0 çerçevesi isteğe bağlıdır, ancak önerilir. Çerçeveye dayanan özellikler, siz yükleyene kadar devre dışı bırakılacaktır. Bazı kaldırıcılar başarısız oldu Başarısız sessiz kaldırıcıları zorla çalıştırmayı denemek ister misiniz? Kaldırma işlemlerinin ardından yeniden başlatılacak: Belirtilen dizini tara ... Kaldırmak istediğiniz uygulamaların bulunduğu dizini seçin. Dizinden kaldır Belirtilen dizinde uygulama bulunamadı Doğru dizini seçtiğinizden ve uygulamanın yürütülebilir dosyalarının bulunduğundan emin olun. {0} için bir kaldırıcı bulundu Bu kaldırıcıyı çalıştırmak ister misin? İhraççı Konu Arşivlenmiş Eklentiler Kısa adı İhracatçı adı Sonra değil Önce değil Özel anahtar Özel Anahtarı Var Genel anahtar İşlenmemiş veri Seri Numarası Konu Adı İmza Algoritması Versiyon Parmakizi Ayarlar kaydedilemedi Tamamlama İkonlar yükleniyor Uygulamaya bak Geçerli dosya veya dizin seçilmedi. Onlara erişebildiğinizden ve sistem dosyaları olarak işaretlenmediğinden emin olun. Uygulamalar için bak {0} içinde herhangi bir uygulama bulunamadı Uygulamayı düzenle Seçilen uygulama düzenlenemez Seçilen uygulamada belirtilen değişiklik komutu yok. Yükleme ayarlarını değiştirmek için kaldırmak ve yeniden yüklemek gerekebilir. Kaldırma listesini kaydet Açılan kaldırma listesine değişiklikleri kaydedin? Açılan kaldırma listesinde, kapatılarak kaybedilecek kaydedilmemiş değişiklikler var. Kaldırılacak uygulamalar ile dizini seçin. Yedeklemeyi nereye kaydedeceğinizi seçin. Yeni bir dizin oluşturulacak. BCU, v {0} olarak güncellendi! BCU {0} sürümüne hoş geldiniz! Bilgisayarı {0} saniye içinde uyku moduna geçirir. İptal etmek için uyku onay kutusunun işaretini kaldırın. Bir şey yapmaz Option for "Double clicking in application list..." Özellikleri açar Option for "Double clicking in application list..." Yüklemeleri kaldırır Option for "Double clicking in application list..." ================================================ FILE: source/BulkCrapUninstaller/Properties/Localisable.vi.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Đang tạo một điểm khôi phục mới... Đang kiểm tra các phần còn sót lại... Đang cập nhật danh sách các trình gỡ cài đặt... Đang loại bỏ các phần còn sót lại... Đang kiểm tra các bản cập nhật... Không có mục nào phù hợp với tiêu chí tìm kiếm của bạn. Xuất BCUninstaller Nhà phát hành | Phiên bản | Ngày | Kích thước | Regsitry | Loại trình gỡ cài đặt | Câu lệnh gỡ cài đặt | Câu lệnh gỡ cài đặt âm thầm | Chú thích Portable keep space in front Gọi API không thành công Sao lưu registry không thành công, bạn có muốn tiếp tục chứ? Chi tiết lỗi: Loại bỏ phần còn sót lại Chi tiết lỗi: Add space or newline afterwards and two newlines before Bạn có muốn sao lưu registry trước khi tiếp tục không? Bạn có thể hoàn tác mọi thay đổi bằng cách nhấp đúp vào nó sau này. Các tệp và thư mục sẽ được chuyển vào thùng rác, bạn có thể khôi phục chúng từ đó. Thao tác thất bại Thao tác này chỉ yêu cầu một mục được chọn. Chọn chính xác một trình gỡ cài đặt từ danh sách. Nếu có các hộp kiểm, hãy nhớ tích vào chúng. Kiểm tra các bản cập nhật Mở nội dung trực tuyến Không thể kết nối Internet hoặc không có mạng. Đảm bảo rằng cáp mạng của bạn đã được cắm. Và nếu bạn đang sử dụng Wi-Fi, hãy đảm bảo rằng bạn có cường độ tín hiệu tốt. Gửi phản hồi Bạn có muốn gửi phản hồi liên quan về BCU không? Sẽ chỉ mất của bạn chưa đến một phút nhưng lại giúp ích rất nhiều cho việc phát triển! Mọi phản hồi đều được ghi nhận, cho dù đó là báo lỗi, yêu cầu tính năng mới hay chỉ đơn giản là lời cảm ơn! Bạn có thể gửi nó sau từ thanh menu trên cùng (Trợ giúp -> Gửi phản hồi). Phiên bản hiện tại là phiên bản mới nhất Hiện tại không tìm thấy bản cập nhật nào, bạn đang dùng phiên bản mới nhất. Bạn có muốn đề xuất thêm tính năng hoặc báo cáo lỗi không? Vui lòng gửi cho tôi phản hồi của bạn bằng cách sử dụng menu "Trợ giúp->Gửi phản hồi". Đã xảy ra lỗi khi kiểm tra các bản cập nhật Hãy đảm bảo rằng BCUninstaller không bị chặn bởi tường lửa và bạn đã kết nối Internet. Đã có phiên bản mới {0}, bạn có muốn nâng cấp ngay không? 0 is version number BCUninstaller sẽ tự động tải xuống bản các cập nhật và áp dụng chúng sau khi khởi động lại. Xin lưu ý rằng bạn có thể mất cài đặt trong quá trình này. Nhật ký thay đổi: - {0} Cảnh báo: Trong quá trình cập nhật, thư mục "Update" và tệp "Update.zip" trong thư mục BCU sẽ bị xóa. 0 is a list of changes separated by "- " Gỡ cài đặt bằng Msi Không thể gỡ cài đặt mục đã chọn bằng trình cài đặt MsiExec. Trình gỡ cài đặt đã chọn không có GUID hợp lệ để sử dụng với MsiExec. Dừng tác vụ gỡ cài đặt hiện tại Bạn có chắc là muốn dừng tác vụ hiện đang thực thi chứ? Dừng tác vụ trước khi hoàn thành sẽ không hoàn tác bất kỳ thay đổi nào đã thực hiện. Trình gỡ cài đặt đang thực thi sẽ không bị dừng lại, tác vụ sẽ đợi nó hoàn tất. Tạo điểm khôi phục Tạo điểm khôi phục không thành công x64 keep space in front GỠ LỖI keep space in front Tiến trình gỡ cài đặt Bạn có thể rời khỏi máy tính của mình ngay bây giờ Các trình gỡ cài đặt còn lại có thể hoàn thành mà không cần sự can thiệp của người dùng. Tuy nhiên, bạn vẫn nên kiểm tra định kỳ đề phòng trường hợp một trong số các trình gỡ cài đặt bị lỗi. Loại bỏ rác/phần còn sót lại Bạn có thực sự muốn thay đổi các mục có độ tin cậy thấp chứ? Việc xóa các mục được đánh dấu có độ tin cậy thấp có thể rất nguy hiểm! Bạn nên xác minh rằng mọi mục đều an toàn để xóa. Xoá các khoá khỏi registry Bạn có chắc là muốn xóa mục trình gỡ cài đặt đã chọn chứ? Các mục sau sẽ bị xóa khỏi registry và sẽ biến mất khỏi danh sách của trình gỡ cài đặt nhưng sẽ không được nó gỡ cài đặt. {0} Xuất không thành công Đã xảy ra lỗi khi lưu dữ liệu đã xuất. Nếu lỗi vẫn còn, hãy thử lưu vào một thư mục khác, chẳng hạn như "Desktop". BCUninstaller đang gỡ cài đặt {0} ứng dụng 0 is the uninstaller count Đổi tên trình gỡ cài đặt Tên đã nhập trống hoặc chứa ký tự không hợp lệ. Hãy đảm bảo rằng nó không chứa bất kỳ ký tự nào sau đây: {0} 0 is list of characters separated by spaces Bạn muốn kiểm tra các phần còn sót lại của (các) lần gỡ cài đặt mà bạn đã thực hiện chứ? Cần lưu ý rằng tính năng này chỉ dành cho người dùng chuyên sâu, hiểu rõ cách hoạt động của nó. Không cần thiết phải xóa các tệp này và chúng không ảnh hưởng đáng kể đến hiệu suất hệ thống. Không tìm thấy bất kỳ phần còn sót lại nào Không tìm thấy bất kỳ phần còn sót lại nào. Có thể vẫn còn một ít, vì vậy bạn có thể chạy trình dọn dẹp tệp tạm thời như BleachBit. Không có gì để sao chép vào bảng nhớ tạm. Trình gỡ cài đặt bạn đã chọn không có thông tin này hoặc bạn không chọn bất kỳ thông tin nào. Sao chép vào bảng nhớ tạm Mở thư mục Thao tác này sẽ mở {0} thư mục cùng một lúc, bạn có chắc là muốn tiếp tục chứ? 0 is number of directories to open Tìm kiếm trực tuyến Không có gì để tìm kiếm Gỡ cài đặt BCUninstaller Bạn có chắc là muốn gỡ cài đặt BCUninstaller chứ? Tôi rất tiếc vì bạn đã gỡ bỏ BCU! Nếu bạn có một vài phút, hãy cho tôi biết lý do tại sao bạn gỡ cài đặt BCU trên trang web của tôi (http://klocmansoftware.weebly.com/). Tôi sẽ cố gắng hết sức để khắc phục bất kỳ sự cố chính đáng nào. Bạn có muốn tạo điểm khôi phục trước khi tiếp tục chứ? Nếu bạn không chắc chắn rằng các ứng dụng bạn đang gỡ cài đặt có quan trọng hoặc cần thiết cho sự ổn định của hệ thống hay không, thì việc tạo điểm khôi phục hệ thống là điều được khuyến khích. Nếu bất kỳ vấn đề gì xảy ra sau quá trình gỡ cài đặt, bạn có thể sử dụng tính năng Khôi phục Hệ thống để hoàn tác các thay đổi. Đã xảy ra lỗi khi mở trang tìm kiếm. Lưu danh sách bộ lọc gỡ cài đặt Lưu danh sách vào tệp không thành công Bạn có chắc là muốn khôi phục lại tất cả cài đặt ứng dụng chứ? Một số ứng dụng không thể được gỡ cài đặt âm thầm. Một số mục được bảo vệ và không thể sửa đổi Mục đã chọn được bảo vệ và không thể sửa đổi Đã xảy ra lỗi khi mở URL Bạn có muốn giữ lại lựa chọn hiện tại chứ? Đã xảy ra lỗi khi mở thư mục Xử lý các tập tin đã chọn không thành công Không có gì để gỡ cài đặt vì không có trình gỡ cài đặt nào được chọn. Khởi chạy trình gỡ cài đặt Để gỡ cài đặt ứng dụng, trước tiên bạn phải chọn ứng dụng đó từ chế độ xem danh sách. Nếu có các hộp kiểm, hãy nhớ tích vào chúng. Nếu bạn chọn giữ lựa chọn hiện tại, nó sẽ được hợp nhất vào (các) danh sách đã mở. Thao tác này sẽ mở {0} URL cùng một lúc, bạn có chắc là muốn tiếp tục không? Mở URL Không có URL nào để mở Sửa đổi các mục được bảo vệ Các mục bị ảnh hưởng: {0} Để thay đổi các mục này, bạn phải tắt bảo vệ trình gỡ cài đặt từ cài đặt ở thanh bên. Bạn có thể xóa những mục này khỏi tác vụ và tiếp tục với các mục khác nếu muốn. 0 names of protected uninstallers Mục được bảo vệ: {0} Để thay đổi mục này, bạn phải tắt tính năng bảo vệ trình gỡ cài đặt khỏi bảng cài đặt. 0 name of protected uninstaller Trình gỡ cài đặt âm thầm bị thiếu các mục sau: {0} Bạn có muốn sử dụng trình gỡ cài đặt gốc cho những mục này, hay bạn muốn loại bỏ chúng khỏi tác vụ? 0 is names of non-quiet uninstallers Gỡ cài đặt âm thầm Khôi phục các cài đặt gốc Tất cả các cài đặt của bạn sẽ bị mất vĩnh viễn. BCUninstaller cần phải khởi động lại để hoàn thành hành động này. Mở danh sách gỡ cài đặt KHÔNG CÓ ĐIỂM KHÔI PHỤC NÀO ĐƯỢC TẠO, nên không thể hoàn tác các thay đổi! Bạn vẫn muốn tiếp tục gỡ cài đặt chứ? Đang đổi tên "{0}" Đổi tên mục đã chọn Tác vụ đã hoàn thành Shown on the status bar Đang gỡ cài đặt Shown on the status bar Ghi nhớ lựa chọn Lỗi Tệp tin không tồn tại. Không có gì được hiển thị. Ứng dụng này được gỡ cài đặt bằng Trình gỡ cài đặt Windows (MsiExec). Tên Giá trị Trống Đã tìm thấy GUID Thiếu GUID Lựa chọn... Không tìm thấy tệp tin. Đang các thực thi các câu lệnh sau khi gỡ cài đặt (post-uninstall)... Đang thực thi các câu lệnh trước khi gỡ cài đặt (pre-uninstall)... Sẵn sàng Shows up when nothing else is displayed on the status bar. {0} trình gỡ cài đặt được chọn {0} is a number of selected uninstallers Tổng số {0} trình gỡ cài đặt, {1} {0} is a number of all uninstallers, {1} is a long file size (123 Megabytes) Không thực hiện được câu lệnh sau: {0} {0} is a command line (c:\example.exe /help) Thực thi bên ngoài không thành công Mặc định Used in language select box when you want to use the system language Một số cài đặt không có hiệu lực cho đến khi bạn khởi động lại ứng dụng. Bạn có muốn khởi động lại BCU để áp dụng các cài đặt mới chứ? Thay đổi cài đặt ứng dụng Không có chứng chỉ Đang xử lý các ứng dụng được phát hiện, còn lại {0} ứng dụng... {1} = how many application uninstallers still need to be processed Việc chọn "Chấm dứt" sẽ ngay lập tức đóng trình gỡ cài đặt đang chạy và có thể khiến quá trình gỡ cài đặt không được hoàn tất. Thông thường, bạn có thể chạy lại trình gỡ cài đặt để hoàn tất quá trình gỡ cài đặt. Ngoài ra, bạn có thể bỏ qua việc chờ quá trình này. Việc bỏ qua sẽ cho phép trình gỡ cài đặt tiếp tục hoạt động trong khi tác vụ chuyển sang mục tiếp theo. Hãy nhớ rằng một số trình gỡ cài đặt có thể không chạy cho đến khi quá trình bị bỏ qua kết thúc. Bạn muốn bỏ qua trạng thái chờ của trình gỡ cài đặt hiện đang thực thi chứ? Bỏ qua tác vụ hiện đang thực thi Một tác vụ gỡ cài đặt khác đang thực thi. Vui lòng đợi cho đến khi nó hoàn tất và thử lại. Đánh giá: {0} Tích cực: {1} Tiêu cực: {2} {0} - Rating as a string {1} - List of strings of positive parts of the rating {2} - List of strings of negative parts of the rating The lists are separated by a single newline. Chi tiết đánh giá Ứng dụng này không có bất kỳ mục registry hợp lệ nào. Ứng dụng này không có trình gỡ cài đặt hợp lệ nào. Đang nạp Windows Features... Đang làm mới thông tin khởi động cùng hệ thống... Shown when refreshing autostart information of the uninstallers Không có thư mục nào để mở Không khả dụng Used on application list when value is not available Đánh giá không có sẵn Trước tiên, bạn cần bật tính năng đánh giá từ cài đặt. Bạn không thể đánh giá các ứng dụng không được cài đặt đúngc cách. {0} ứng dụng {0} is number of apps to rate, "Rate " will be automatically put in front of this string Đánh giá trung bình: {0}; Đánh giá của tôi: {1} Việc thực thi trình gỡ cài đặt sau không thành công. Chắc là do xung đột. Đợi các trình gỡ cài đặt khác hoàn tất và thử lại. {0} Bạn có thể thử tắt tính năng phát hiện xung đột trong cài đặt nhưng điều này không được khuyến khích. Buộc gỡ cài đặt Một số trình gỡ cài đặt không thực thi được. Không tìm thấy .NET Framework v4.0 Một số tính năng sẽ bị tắt do không tìm thấy .NET Framework v4.0. .NET framework v4.0 là tùy chọn nhưng được khuyến nghị. Các tính năng phụ thuộc vào framework sẽ bị tắt cho đến khi bạn cài đặt chúng. Một số trình gỡ cài đặt không thành công Trình gỡ cài đặt không thành công, tại sao bạn không thử chạy trình gỡ cài đặt âm thầm? Trình gỡ cài đặt bên dưới sẽ khởi động lại trình gỡ cài đặt gốc: Đang quét thư mục được chỉ định... Chọn thư mục chứa ứng dụng mà bạn muốn gỡ bỏ. Gỡ cài đặt từ thư mục Không tìm thấy ứng dụng nào trong thư mục được chỉ định Hãy chắc rằng thư mục đã chọn có chính xác và tệp thực thi của ứng dụng vẫn còn. Đã tìm thấy trình gỡ cài đặt cho {0} Bạn có muốn chạy trình gỡ cài đặt này chứ? Lưu cài đặt không thành công Sắp hoàn thành... Đang nạp biểu tượng Tìm kiếm ứng dụng Không có tệp tin hoặc thư mục hợp lệ nào được chọn. Đảm bảo rằng bạn có quyền truy cập và nó không bị đánh dấu là tệp hệ thống. Tìm kiếm ứng dụng Không thể tìm thấy ứng dụng trong {0} Thay đổi ứng dụng Không thể thay đổi ứng dụng đã chọn Không có câu lệnh sửa đổi nào được chỉ định cho ứng dụng đã chọn. Bạn có thể cần phải gỡ cài đặt và cài đặt lại để thay đổi cài đặt cài đặt. Lưu danh sách gỡ cài đặt Bạn có muốn lưu các thay đổi vào danh sách gỡ cài đặt đang mở chứ? Có những thay đổi chưa được lưu trong danh sách gỡ cài đặt đang mở và sẽ bị mất khi đóng. Chọn thư mục chứa ứng dụng mà bạn muốn gỡ cài đặt. Chọn nơi để lưu bản sao lưu. Một thư mục mới sẽ được tạo. BCU đã được cập nhật lên v{0}! Chào mừng bạn đến với phiên bản {0} của BCU! Thiếp lập PC ở chế độ ngủ trong {0} giây. Tích vào hộp kiểm để hủy. Không làm gì cả Option for "Double clicking in application list..." Mở thuộc tính Option for "Double clicking in application list..." Gỡ cài đặt Option for "Double clicking in application list..." Đã lưu trữ Thực thể chứng thực Chủ thể Phần mở rộng Tên dễ hiểu Tên của thực thể chứng thực Không sau ngày Không trước ngày Khoá riêng tư Có khoá riêng tư Khoá công khai Dữ liệu thô Số Sêri Tên chủ thể Phiên bản Vân tay khoá công khai Thuật toán chữ ký ================================================ FILE: source/BulkCrapUninstaller/Properties/Localisable.zh-Hans.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 创建新的还原点... 搜索残余... 正在填充卸载程序列表... 删除残余... 搜索更新... 没有与你的搜索条件匹配的条目。 BCUninstaller导出 发布者 | 版本 | 日期 | 大小 | 注册表 | 卸载程序类型 | 卸载字符串 | 静默卸载字符串 | 注释 便携 keep space in front 调用API失败 注册表备份失败,还要继续吗? 错误详细信息: 删除残余 错误详细信息: Add space or newline afterwards and two newlines before 要在继续之前创建注册表备份吗? 你可以在之后双击它来回滚所有更改。 文件和目录将被移动到回收站,你可以从那里还原它们。 操作失败 你只需要为此操作选择一个条目 从列表中只选择一个卸载程序。如果你正在使用复选框,请确保选中它们。 搜索更新 打开联机内容 无法连接到互联网,没有可用的网络。 确保网线已接入。如果你使用Wi-Fi,请确保信号良好。 提交反馈 你想发送有关BCU的反馈吗? 默认 Used in language select box when you want to use the system language 这只花费你不到一分钟,但大大有助于开发!感谢所有反馈,无论是错误报告、功能请求还是简单的感谢! 你可以稍后从顶部菜单栏(帮助->提交反馈)发送。 当前版本为最新 当前未找到更新,你拥有最新版本。 想要添加一些功能或者修复一个bug吗?请使用"帮助->提交反馈"菜单将你的反馈发送给我。 检查更新时遇到错误 确保BCUninstaller没有在防火墙中被阻止,并且互联网连接正常。 新版本{0}可用,现在更新吗? 0 is version number BCUninstaller将自动下载更新并在重新启动后应用它。请注意,在此过程中你可能会丢失设置。 更新日志: - {0} 警告:在更新过程中,BCU目录中的文件夹"update"和文件"update.zip"将被删除。 0 is a list of changes separated by "- " 使用Msi卸载 无法使用MsiExec安装程序卸载所选条目 选中的卸载程序没有用于MsiExec的有效Guid。 停止当前卸载任务 确定要停止当前正在运行的任务吗? 过早停止任务不会还原任何更改。当前正在运行的卸载程序不会停止,任务将等待它完成。 创建还原点 无法创建新的还原点 x64 keep space in front 调试 keep space in front 卸载进度 你现在可以离开电脑 其余的卸载程序应该能够在没有任何用户干预的情况下完成。你仍然应该不时检查,以防其中一个卸载程序崩溃。 垃圾/残余删除 确定要修改低置信度项? 删除置信度标记为低于好的项目可能是非常危险的!建议你确认每个项目都可以安全删除。 从注册表删除键 确定要删除选定的卸载程序条目吗? 下列项目将从注册表中删除,并将从卸载程序列表中消失,但不会卸载。 {0} 导出失败 保存导出的数据时遇到错误 如果错误仍然存在,请尝试保存到其他目录,例如桌面。 BCUninstaller正在卸载{0}个应用程序 0 is the uninstaller count 重命名卸载程序 提供的名称为空或包含无效字符 确保未包含以下任何字符: {0} 0 is list of characters separated by spaces 是否要查找已执行卸载的残余内容? 请注意,此功能仅适用于了解其工作原理的高级用户。不需要删除这些文件,它们不会以任何有意义的方式影响系统性能。 没有找到残余 没有发现残余。可能还有一些残留,所以可以运行一个临时文件清理程序,如BleachBit。 没有可复制到剪贴板的内容。没有选定的卸载程序包含此信息,或者你没有选择任何内容。 复制到剪贴板 打开目录 此操作将立即打开{0}个目录,确定要继续吗? 0 is number of directories to open 联机搜索 没有可搜索的 卸载BCUninstaller 你确定要卸载BCUninstaller吗? 很遗憾看到你离开!如果你有一两分钟的时间,请在我的网站上留言说明你为什么卸载BCU(http://klocmansoftware.weebly.com/)。我会尽力解决任何合理的问题。 要在继续之前创建还原点吗? 如果你不确定要卸载的应用程序对系统稳定性是否重要或必需,建议创建还原点。 如果在此过程之后出现任何中断,则可以使用系统还原回滚更改。 打开搜索页面时遇到错误 保存卸载列表 保存列表到文件失败 确定要重置所有应用程序设置? 有些应用程序无法静默卸载 某些条目受保护,无法修改 所选条目受保护,无法修改 打开URL时遇到错误 是否保留当前选择? 打开目录时遇到错误 无法加载选中的文件 没有选择卸载程序,没有要卸载的内容 运行卸载程序 要卸载应用程序,必须首先从列表视图中选择它们。如果要使用复选框,请确保选中了它们。 如果选择保留当前选择,它将与打开的列表合并 此操作将一次打开{0}个URL,确定要继续吗? 打开URLs 没有URL可打开 修改受保护项目 受影响的条目: {0} 要修改这些条目,你需要从设置侧边栏中禁用卸载程序保护。你可以从任务中删除它们,如果需要可以继续选择其他项目。 0 names of protected uninstallers 受保护的条目: {0} 要修改此条目,你需要从设置面板中禁用卸载程序保护。 0 name of protected uninstaller 错误 名称 找到GUID GUID丢失 文件未找到。 准备 Shows up when nothing else is displayed on the status bar. 已选中{0}个卸载程序 {0} is a number of selected uninstallers 跳过当前运行任务 评分: {0} 积极: {1} 消极: {2} {0} - Rating as a string {1} - List of strings of positive parts of the rating {2} - List of strings of negative parts of the rating The lists are separated by a single newline. 评分详细信息 没有目录可以打开 不可用 Used on application list when value is not available 评分不可用 你必须先从设置启用评分 你不能给未正确安装的应用程序评分 {0}应用程序 {0} is number of apps to rate, "Rate " will be automatically put in front of this string 平均评分:{0};我的评分:{1} 强制卸载 未找到.NET Framework v4.0 未找到.NET Framework v4.0,某些功能将禁用 部分卸载程序失败 扫描特定目录... 从目录卸载 Issuer 主题 存档 BCU已更新到v{0}! 欢迎使用BCU版本{0}! PC{0}秒后进入睡眠状态。取消选择睡眠复选框以取消。 以下项目缺少静默卸载程序: {0} 你是否想要为这些项目使用交互卸载程序,或者从任务中删除它们? 0 is names of non-quiet uninstallers 静默卸载 还原默认设置 你的所有设置将永久丢失。 BCUnInstaller将必须重新启动以完成此操作。 打开卸载列表 还原点未创建,你将无法还原更改!继续卸载吗? 重命名"0" 重命名选中条目 任务完成 Shown on the status bar 卸载 Shown on the status bar 记住选择 文件不存在。 无内容显示。使用Windows Installer(MSIexec)卸载此应用程序。 选择至... 运行卸载后命令... 运行卸载前命令 共{0}卸载程序,{1} {0} is a number of all uninstallers, {1} is a long file size (123 Megabytes) 以下命令无法执行: {0} {0} is a command line (c:\example.exe /help) 外部执行失败 在重新启动应用程序之前,某些设置不会生效。 想重新启动BCU以应用新设置吗? 更改应用程序设置 证书丢失 正在处理检测到的应用程序,剩余{0}个... {1} = how many application uninstallers still need to be processed 选择“终止”将立即关闭运行的卸载程序,并且可能导致卸载不完整。通常可以再次运行卸载程序以完成卸载。 或者,你可以跳过等待此过程。跳过将让卸载程序继续工作,而任务移动到下一个项目。请记住,在跳过的过程完成之前,一些卸载程序无法运行。 你想跳过等待目前运行的卸载程序吗? 另一个卸载任务已在运行。请等待它完成,然后再试一次。 此应用程序没有有效的注册表项 此应用程序没有有效的卸载程序 加载Windows功能... 刷新开机启动项信息... Shown when refreshing autostart information of the uninstallers 在卸载程序执行失败后,可能是因为冲突。请等待其他卸载程序完成并再试一次。 {0} 你可以尝试在设置中禁用冲突检测,但不建议使用。 部分卸载程序无法运行 V4.0框架是可选的,但推荐。依赖框架的功能将被禁用,直到你安装它。 交互卸载失败后你想尝试运行静默卸载吗? 以下卸载程序将重启为交互式: 选择有要删除的应用程序的目录。 在指定的目录中找不到任何应用程序 确保你选择了正确的目录,并且仍然存在应用程序的可执行文件。 找到了{0}的卸载程序 你想运行这个卸载程序吗? 扩展名 友好名称 Issuer名 不晚于 不早于 私有键 有私有键 公开键 Raw数据 序列号 主题名 签名算法 版本 凭证指纹 保存设置失败 完成中... 加载图标 查找应用程序 未选择有效的文件或目录。确保你有权访问它们,并且它们没有被标记为系统文件。 查找应用程序 在{0}内找不到任何应用程序 修改应用程序 无法修改选中的应用程序 所选应用程序未指定修改命令。可能需要卸载,然后重新安装以更改安装设置。 保存卸载列表 保存更改到打开的卸载列表? 打开的卸载列表中有未保存的更改,关闭该列表将丢失这些更改。 选择包含要卸载的应用程序的目录。 选择保存备份的位置。将创建一个新目录。 Option for "Double clicking in application list..." 打开属性 Option for "Double clicking in application list..." 卸载 Option for "Double clicking in application list..." ================================================ FILE: source/BulkCrapUninstaller/Properties/Localisable.zh-Hant.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 建立新的還原點... 搜尋剩餘檔案... 正在填充應用程式清單... 刪除剩餘檔案... 搜尋更新... 沒有與你的搜尋件相同的項目。 BCUninstaller匯出 發布者 | 版本 | 日期 | 大小 | 註册表 | 移除程式類型 | 移除字串 | 最小化移除字串 | 建議 免安裝 keep space in front 呼叫API失敗 註冊表備份失敗, 還要繼續嗎? 錯誤詳細訊息: 移除剩餘檔案 錯誤詳細資訊: Add space or newline afterwards and two newlines before 要在繼續之前建立註冊表備份嗎? 你可以在之後雙擊它來取消所有更改。 檔案和目錄將會被移動到資源回收桶,你可以從那裡還原它們。 操作失敗 你只需要為此操作選擇一個項目 從列表中止選擇一個移除程式。如果你正在使用複選框,請確保選中他們。 搜尋更新 開啟線上內容 無法連接到網路,沒有可用的連線。 確定網路已連結。如果你使用Wi-Fi,請確保訊號良 好。 傳送回饋 你想傳送有關BCU的回饋嗎? 這只花費你不到一分鐘,但大大有助於開發!感謝所有回饋,無論是錯誤報告、功能請求還是簡單的感謝! 你可以稍後從頂部選單列(關於->提交回饋)傳送。 目前版本為最新版 目前未找到更新,你用的是最版本。 想要添加一些功能或者修復一個BUG嗎?請使用關於->提交回饋"選單將你的回饋傳送給我。 檢查更新時遇到錯誤 確保BCUninstaller沒有在防火牆鐘被阻擋連接,且網路連接正常。 新版本{0}可用,現在更新嗎? 0 is version number BCUninstaller將自動下載更新並在重新啟動後應用它。請注意,在此過程中你可能會丢失設定。 更新日誌: - {0} 警告:在更新過程中,BCU目錄中的資料夾"update"和檔案"update.zip"將被删除。 0 is a list of changes separated by "- " 使用MSI移除 無法使用MSIExec安裝程式移除所選項目 選中的移除程式沒有用於MSIExec的有效GUID。 停止目前移除任務 確定要停止目前正在執行的任務嗎? 提早停止任務不會還原任何變更。目前正在運行的移除任務不會停止,任務將等待其完成。 建立還原點 無法建立新的還原點 x64 keep space in front 偵錯 keep space in front 移除進度 你現在可以離開電腦 其餘的移除程式應該能夠在沒有任何使用者干預的情況下完成,你仍應該不時檢查,以防其中一個移除程式當機。 垃圾/剩餘檔案刪除 確定要修改低信任度項目? 刪除信任度標記為低於好的項目可能是非常危險的!建議確認每個項目都可以安全刪除。 從註冊表刪除鍵 確定要刪除選定的移除程式項目嗎? 下列項目將從註冊表中刪除,並將從移除程式表中消失,但不會移除。 {0} 匯出失敗 儲存匯出的資料時遇到錯誤 如果錯誤仍然存在,請嘗試保存到其他目錄,例如桌面。 BCUninstaller正在移除{0}個應用程式 0 is the uninstaller count 重新命名移除程式 提供的名稱為空或包含無效符號 確認未包含以下任何符號: {0} 0 is list of characters separated by spaces 是否要尋找已執行移除的剩餘檔案內容? 請注意,此功能僅使適用於了解其工作原理的進階使用者。不需要刪除這些文件,它們不會以任何有意義的方式影響系統效能。 沒有找到剩餘檔案 沒有發現剩餘檔案。可能還有一些檔案殘留,所以可以執行一個臨時資料清理程式,如BleachBit。 沒有可複製到剪貼簿的內容。沒有選定的移除程式包含此訊息,或者你沒有選擇任何內容。 複製到剪貼簿 開啟目錄 此操作將立即開啟{0}個目錄,確定要繼續嗎? 0 is number of directories to open 線上尋找 沒有可尋找的 移除BCUninstaller 你確定要移除BCUninstaller嗎? 很遺憾看到你離開!如果你有一兩分鐘的時間,請至我的網站上說明你為什麼移除BCU(http://klocmansoftware.weebly.com/)。我會盡力解決任何合理的問題。 要在繼續之前建立還原點嗎? 如果你不確定要移除的應用程式對系統穩定性是否重要或必需,建議建立還原點。 如果於此過程之後出現任何中斷,則可以使用系統還原回復更改。 開啟搜尋頁面時遇到錯誤 儲存移除清單 儲存清單到檔案失敗 確定要重置所有應用程式設定? 有些應用程式無法最小化移除 某些項目受保護,無法修改 所選項目受保護,無法修改 開啟網址時遇到錯誤 是否保存目前選擇? 開啟目錄時遇到錯誤 無法載入選中的檔案 沒有選擇移除程式,沒有要移除的內容 執行移除程式 未找到.NET Framework V4.0,某些功能將禁用。 V4.0Framework是可選擇的,但推薦。依賴Framework的功能將被禁止,直到你安裝它。 部分應用程式失敗 交互移除失敗後你想嘗試執行最小化移除嗎? 以下移除程式將充新啟動為交互式: 掃描特定目錄... 選擇要刪除的應用程式目錄。 從目錄移除 在指定的目錄中找不到任何應用程式 確定你選擇了正確的目錄,並且仍然存在應用程式的可執行文件。 找到了{0}個移除程式 你想執行這個移除程示嗎? Issuer 主題 壓縮 擴充元件 好記的名稱 Issuer名稱 不晚於 不早於 私有金鑰 有私有金鑰 公開金鑰 原始資料 序號 主題名稱 簽名算法 版本 憑證指紋 儲存設定失敗 完成中... 載入圖示 尋找應用程式 尋找應用程式 修改應用程式 無法修改選中的應用程式 儲存移除清單 要移除應用程式,必須先從列表中選擇它們。如果要使用複選框,請確保選中它們。 如果選擇保留目前選擇,它們將與開啟的列表合併 此操作將一次打開{0}個網址,確定要繼續嗎? 開啟網址 沒有網址可開啟 修改受保護項目 受影響的項目: {0} 要修改這些項目,你需要從設定側邊列中禁用移除程式保護。你可以從任務中刪除它們,如果需要可以繼續學則其他項目。 0 names of protected uninstallers 受保護的項目:{0} 要修改此項目,你需要從設定面板中禁用移除程式保護。 0 name of protected uninstaller 以下項目缺少最小化移除程式: {0} 你是否想要為這些項目使用交互移除程式,或者從任務中刪除它們? 0 is names of non-quiet uninstallers 最小化移除 還原預設設定 你的所有設定將永久遺失。BCUninstaller必須重新啟動以完成此操作。 開啟移除清單 還原點未建立,你將無法還原變更!繼續移除嗎? 重新命名"0" 重新命名選中項目 任務完成 Shown on the status bar 移除 Shown on the status bar 記住選擇 錯誤 檔案不存在。 無內容顯示。使用Windows Installer(MSIexec)移除此應用程式。 名稱 找到GUID GUID遺失 選擇至... 檔案未找到。 執行移除後指令... 執行移除前指令 準備 Shows up when nothing else is displayed on the status bar. 已選取{0}個移除程式 {0} is a number of selected uninstallers 共{0}移除程式,{1} {0} is a number of all uninstallers, {1} is a long file size (123 Megabytes) 以下指令無法執行: {0} {0} is a command line (c:\example.exe /help) 外部執行失敗 預設 Used in language select box when you want to use the system language 在重新啟動應用程式之前,某些設定不會生效。 重新啟動BCU以應用新設定? 更改應用程式設定 證書遺失 正在處理檢測到的應用程式,剩下{0}個... {1} = how many application uninstallers still need to be processed 選擇"中止"將立即關閉執行的移除程式,並且可能導致移除不完全。通常可以再次執行移除程式以完成移除。 或者,你可以略過等待此過程。略過將讓移除程式繼續工作,而任務移動到下一個項目。請記住,在略過的過程完成之前,一些移除程式無法執行。 略過等待目前執行的移除程式? 跳過目前執行任務 另一個移除任務已在執行。請等待它完成,然後再試一次。 評分:{0} 積極: {1} 消極: {2} {0} - Rating as a string {1} - List of strings of positive parts of the rating {2} - List of strings of negative parts of the rating The lists are separated by a single newline. 評分詳細訊息 此應用程式沒有有效的註冊表項目 此應用程式沒有有效的移除程式 載入Windows功能... 重整開機啟動項資訊 Shown when refreshing autostart information of the uninstallers 沒有目錄可以開啟 不可用 Used on application list when value is not available 評分不可用 你必須先從設定啟用評分 你不能給未正確安裝的應用程式評分 {0}應用程式 {0} is number of apps to rate, "Rate " will be automatically put in front of this string 平均評分:{0};我的評分:{1} 在移除程式執行失敗後,可能是因為衝突。請等待其他移除程式完成後再試一次。 {0} 你可以嘗試在設定中禁用衝突檢測,但不建議使用。 強制移除 部分移除程式無法執行 未找到.NET Framework V4.0 未選擇有效的檔案或目錄。確定你有權限訪問它們,並且它們沒有被標記為系統檔案。 在{0}內找不到任何應用程式 所選應用程式未指定修改指令。可能需要移除,然後重新安裝來更改安裝設定。 儲存變更到開啟的移除列表? 開啟的移除列表中有未儲存的變更,關閉該列表將遺失這些變更。 選擇要移除的應用程式目錄。 選擇儲存備份的位置。將建立一個新目錄。 BCU已更新到v{0}! 歡迎使用BCU版本{0}! PC{0}秒後進入睡眠狀態。取消選擇睡眠複選框來取消。 不進行任何動作 Option for "Double clicking in application list..." 開啟詳細內容 Option for "Double clicking in application list..." 解除安裝 Option for "Double clicking in application list..." ================================================ FILE: source/BulkCrapUninstaller/Properties/Resources.Designer.cs ================================================ //------------------------------------------------------------------------------ // // This code was generated by a tool. // Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ namespace BulkCrapUninstaller.Properties { using System; /// /// A strongly-typed resource class, for looking up localized strings, etc. /// // This class was auto-generated by the StronglyTypedResourceBuilder // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { private static global::System.Resources.ResourceManager resourceMan; private static global::System.Globalization.CultureInfo resourceCulture; [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] internal Resources() { } /// /// Returns the cached ResourceManager instance used by this class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("BulkCrapUninstaller.Properties.Resources", typeof(Resources).Assembly); resourceMan = temp; } return resourceMan; } } /// /// Overrides the current thread's CurrentUICulture property for all /// resource lookups using this strongly typed resource class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Globalization.CultureInfo Culture { get { return resourceCulture; } set { resourceCulture = value; } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap _bcu_logo { get { object obj = ResourceManager.GetObject("_bcu_logo", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap add { get { object obj = ResourceManager.GetObject("add", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap add_multiple { get { object obj = ResourceManager.GetObject("add.multiple", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap bigImage { get { object obj = ResourceManager.GetObject("bigImage", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap centerline { get { object obj = ResourceManager.GetObject("centerline", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap check { get { object obj = ResourceManager.GetObject("check", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap checkmark { get { object obj = ResourceManager.GetObject("checkmark", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap checkmarkpencil { get { object obj = ResourceManager.GetObject("checkmarkpencil", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap checkmarkuncrossed { get { object obj = ResourceManager.GetObject("checkmarkuncrossed", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap clean { get { object obj = ResourceManager.GetObject("clean", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized string similar to https://github.com/Klocman/Bulk-Crap-Uninstaller/discussions. /// internal static string ContactUrl { get { return ResourceManager.GetString("ContactUrl", resourceCulture); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap control_fastforward { get { object obj = ResourceManager.GetObject("control.fastforward", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap control_fastforward_variant { get { object obj = ResourceManager.GetObject("control.fastforward.variant", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized string similar to Default.bcul. /// internal static string DefaultUninstallListFilename { get { return ResourceManager.GetString("DefaultUninstallListFilename", resourceCulture); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap delete { get { object obj = ResourceManager.GetObject("delete", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap diagram { get { object obj = ResourceManager.GetObject("diagram", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap donate_button { get { object obj = ResourceManager.GetObject("donate_button", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized string similar to http://klocmansoftware.weebly.com/donate.html. /// internal static string DonateLink { get { return ResourceManager.GetString("DonateLink", resourceCulture); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap edit_box { get { object obj = ResourceManager.GetObject("edit.box", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap filter { get { object obj = ResourceManager.GetObject("filter", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap folderopen { get { object obj = ResourceManager.GetObject("folderopen", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap fullscreen { get { object obj = ResourceManager.GetObject("fullscreen", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized string similar to https://github.com/Klocman/Bulk-Crap-Uninstaller/issues. /// internal static string GithubIssuesLink { get { return ResourceManager.GetString("GithubIssuesLink", resourceCulture); } } /// /// Looks up a localized string similar to https://github.com/Klocman/Bulk-Crap-Uninstaller. /// internal static string GithubLink { get { return ResourceManager.GetString("GithubLink", resourceCulture); } } /// /// Looks up a localized string similar to https://github.com/Klocman/Bulk-Crap-Uninstaller/issues/new. /// internal static string GithubNewIssueLink { get { return ResourceManager.GetString("GithubNewIssueLink", resourceCulture); } } /// /// Looks up a localized string similar to https://github.com/Klocman/Bulk-Crap-Uninstaller/releases. /// internal static string GithubReleasesLink { get { return ResourceManager.GetString("GithubReleasesLink", resourceCulture); } } /// /// Looks up a localized string similar to BCU_manual.html. /// internal static string HelpFilename { get { return ResourceManager.GetString("HelpFilename", resourceCulture); } } /// /// Looks up a localized string similar to https://www.bcuninstaller.com/. /// internal static string HomepageUrl { get { return ResourceManager.GetString("HomepageUrl", resourceCulture); } } /// /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). /// internal static System.Drawing.Icon Icon_Logo { get { object obj = ResourceManager.GetObject("Icon_Logo", resourceCulture); return ((System.Drawing.Icon)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap information { get { object obj = ResourceManager.GetObject("information", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap information_circle { get { object obj = ResourceManager.GetObject("information_circle", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap layer { get { object obj = ResourceManager.GetObject("layer", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap layer_add { get { object obj = ResourceManager.GetObject("layer.add", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap layer1 { get { object obj = ResourceManager.GetObject("layer1", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap layerdelete { get { object obj = ResourceManager.GetObject("layerdelete", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap layerdown { get { object obj = ResourceManager.GetObject("layerdown", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized string similar to Licence.txt. /// internal static string LicenceFilename { get { return ResourceManager.GetString("LicenceFilename", resourceCulture); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap list { get { object obj = ResourceManager.GetObject("list", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap list_reorder { get { object obj = ResourceManager.GetObject("list.reorder", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap magnify { get { object obj = ResourceManager.GetObject("magnify", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap magnifybrowse { get { object obj = ResourceManager.GetObject("magnifybrowse", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap magnifyforward { get { object obj = ResourceManager.GetObject("magnifyforward", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap message { get { object obj = ResourceManager.GetObject("message", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap moon_full { get { object obj = ResourceManager.GetObject("moon_full", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap oswindows8 { get { object obj = ResourceManager.GetObject("oswindows8", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap pagecopy { get { object obj = ResourceManager.GetObject("pagecopy", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized string similar to PrivacyPolicy.txt. /// internal static string PrivacyPolicyFilename { get { return ResourceManager.GetString("PrivacyPolicyFilename", resourceCulture); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap properties { get { object obj = ResourceManager.GetObject("properties", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap rating1 { get { object obj = ResourceManager.GetObject("rating1", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap rating3 { get { object obj = ResourceManager.GetObject("rating3", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap rating4 { get { object obj = ResourceManager.GetObject("rating4", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap rating5 { get { object obj = ResourceManager.GetObject("rating5", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap refresh { get { object obj = ResourceManager.GetObject("refresh", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized string similar to https://dappcdn.com/download/utilities/bulk-crap-uninstaller. /// internal static string ReviewLink { get { return ResourceManager.GetString("ReviewLink", resourceCulture); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap save { get { object obj = ResourceManager.GetObject("save", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap settings { get { object obj = ResourceManager.GetObject("settings", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap star { get { object obj = ResourceManager.GetObject("star", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap stop { get { object obj = ResourceManager.GetObject("stop", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized string similar to https://github.com/Klocman/Bulk-Crap-Uninstaller/discussions. /// internal static string SubmitFeedbackLink { get { return ResourceManager.GetString("SubmitFeedbackLink", resourceCulture); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap table_add { get { object obj = ResourceManager.GetObject("table.add", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap target { get { object obj = ResourceManager.GetObject("target", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap timer { get { object obj = ResourceManager.GetObject("timer", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized string similar to https://github.com/Klocman/Bulk-Crap-Uninstaller/blob/master/CONTRIBUTING.md. /// internal static string TranslateLink { get { return ResourceManager.GetString("TranslateLink", resourceCulture); } } /// /// Looks up a localized string similar to https://twitter.com/intent/tweet?text=Check+out+this+cool+uninstaller+that+I+found!+sourceforge.net/projects/bulk-crap-uninstaller/. /// internal static string TwitterLink { get { return ResourceManager.GetString("TwitterLink", resourceCulture); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap warning { get { object obj = ResourceManager.GetObject("warning", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap weather_sun_set { get { object obj = ResourceManager.GetObject("weather.sun.set", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } } } ================================================ FILE: source/BulkCrapUninstaller/Properties/Resources.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 https://github.com/Klocman/Bulk-Crap-Uninstaller/releases ..\Resources\layer.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a Default.bcul ..\Resources\add.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\logo.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\layer.delete1.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\save.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\table.add.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\fullscreen.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\os.windows.8.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\rating4.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\magnify.browse.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\settings.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\checkmark.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a https://twitter.com/intent/tweet?text=Check+out+this+cool+uninstaller+that+I+found!+sourceforge.net/projects/bulk-crap-uninstaller/ ..\Resources\diagram.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a Licence.txt ..\Resources\refresh.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a https://github.com/Klocman/Bulk-Crap-Uninstaller/issues ..\Resources\information.circle.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\layer.down.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a https://github.com/Klocman/Bulk-Crap-Uninstaller/issues/new ..\Resources\information.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\rating3.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\3.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\moon.full.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\magnify.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a http://klocmansoftware.weebly.com/donate.html iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO vAAADrwBlbxySQAAAwFJREFUaEPdlz9rFFEUxbP/WFwLbVwLP4CFaGEh6DewsNMina1fwl4FO6sUgnYp BCvbSeEnEBEkiKCQYGMKEXGD47nLXrl757gz71/c9cKP3ZzcOfedbN7Om62qqv4LqLiJUHEToeImQkUF VRdkbzwen2ZzY6Ci4gaXIFsYKipuaCmyhKGi4gaWJDkMFRU3rGY9XfFehKQwVFTcoNxBXhItOgwVFTck a5DJZDLGa7YwVFTcgKxBRMsZhoqKM88eRMgVhoqKMy4SRMgRhoqKMy0WREgNQ0XFGRYNIqSEoaLizIoH EVaFYf0KFRVnlDVIDMxXoaISYtSG94qB+SpUVEKM2vBeMTBfhYpKiFEb3isG5qtQUQkxKkHIfCoqIUYl CJlPRSXEqAQh86mohBiVAPW663wqKtakzSgUufH1er3b8H0O3oOv4Dv4CF6Be/j9WXkFR2D9gqBugQ/q u4JDhLk7HA7P4/0u81KoqBjDOawnhOl0OoDPA/DL+nZgB4GGzFOhouLMkoOgHlu/QJ4wT4WKijNKCoLa tl4LjsEzcF32w2w2O4X3l8Ej8A34/m3mLVBRcSbRQeQIjus/O78DcIP1CygJJBvfXnP4t+N8Q7A4k+gg smGd13Fd19dYrwU9V9C79MmIF+ttCBZrILCeLqB2rQ94yvoYKL+v6LdXQ7A4g5Qgn6yP/KVZH2Pxqdh1 vGV9DcHiDFKC/Ij1QZBz9lrwhfU1BIszSAkS7TMajc64649YX0OwOIN1+dfaZ30NweIMUoL4zb7D+hgo v9lf0D4mKs4gJcgd6wM6ff2i5F6yPl+/ck7C9fvO7wBhrrJ+AbV+N8TBYHAB1/sgwp8jiixQjvb9fv8S fl6/I8oihDxvLHlFkO/QGMjDjCHyHuMDaAshB8g3TmPMH6zY2jxUVJxpV1pDYB9cXDxk3QTyqPsOyJ74 CSTk/FFXboZsXQwqKii2kFV0CsFmpULFWP5VCIGKsaD2zMJPLIRAxVhQS6fcBcVDCFSMBXXfBDixEFVV bf0GeDTIxb8Pvs8AAAAASUVORK5CYII= ..\Resources\layer.add.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\timer.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\star.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\target.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\list.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\add.multiple.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\centerline.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a https://github.com/Klocman/Bulk-Crap-Uninstaller/discussions ..\Resources\stop.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a BCU_manual.html ..\Resources\page.copy.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\bigImage.bmp;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a PrivacyPolicy.txt ..\Resources\list.reorder.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\checkmark.uncrossed.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\layer.delete.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\delete.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\message.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\control.fastforward.variant.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\magnify.forward.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\weather.sun.set.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\warning.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\rating1.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\donate_button.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a https://github.com/Klocman/Bulk-Crap-Uninstaller/discussions ..\Resources\clean.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\rating5.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a https://dappcdn.com/download/utilities/bulk-crap-uninstaller ..\Resources\folder.open.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\edit.box.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a https://www.bcuninstaller.com/ https://github.com/Klocman/Bulk-Crap-Uninstaller ..\Resources\control.fastforward.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\checkmark.pencil.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\filter.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\check.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a https://github.com/Klocman/Bulk-Crap-Uninstaller/blob/master/CONTRIBUTING.md ================================================ FILE: source/BulkCrapUninstaller/Properties/Settings.Designer.cs ================================================ //------------------------------------------------------------------------------ // // This code was generated by a tool. // Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ namespace BulkCrapUninstaller.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.14.0.0")] internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); public static Settings Default { get { return defaultInstance; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("False")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool UninstallerListUseCheckboxes { get { return ((bool)(this["UninstallerListUseCheckboxes"])); } set { this["UninstallerListUseCheckboxes"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("True")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool UninstallerListUseGroups { get { return ((bool)(this["UninstallerListUseGroups"])); } set { this["UninstallerListUseGroups"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("False")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool FilterHideMicrosoft { get { return ((bool)(this["FilterHideMicrosoft"])); } set { this["FilterHideMicrosoft"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("False")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool AdvancedDisableProtection { get { return ((bool)(this["AdvancedDisableProtection"])); } set { this["AdvancedDisableProtection"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("0, 0")] public global::System.Drawing.Point WindowPosition { get { return ((global::System.Drawing.Point)(this["WindowPosition"])); } set { this["WindowPosition"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("0, 0")] public global::System.Drawing.Size WindowSize { get { return ((global::System.Drawing.Size)(this["WindowSize"])); } set { this["WindowSize"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("True")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool MiscFirstRun { get { return ((bool)(this["MiscFirstRun"])); } set { this["MiscFirstRun"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("True")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool AdvancedIntelligentUninstallerSorting { get { return ((bool)(this["AdvancedIntelligentUninstallerSorting"])); } set { this["AdvancedIntelligentUninstallerSorting"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("Normal")] public global::System.Windows.Forms.FormWindowState WindowState { get { return ((global::System.Windows.Forms.FormWindowState)(this["WindowState"])); } set { this["WindowState"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public string UninstallerListViewState { get { return ((string)(this["UninstallerListViewState"])); } set { this["UninstallerListViewState"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("True")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool ToolbarsShowToolbar { get { return ((bool)(this["ToolbarsShowToolbar"])); } set { this["ToolbarsShowToolbar"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("True")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool ToolbarsShowSettings { get { return ((bool)(this["ToolbarsShowSettings"])); } set { this["ToolbarsShowSettings"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("False")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool FilterShowSystemComponents { get { return ((bool)(this["FilterShowSystemComponents"])); } set { this["FilterShowSystemComponents"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("False")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool WindowUseSystemTheme { get { return ((bool)(this["WindowUseSystemTheme"])); } set { this["WindowUseSystemTheme"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("False")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool FilterShowProtected { get { return ((bool)(this["FilterShowProtected"])); } set { this["FilterShowProtected"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("False")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool FilterShowUpdates { get { return ((bool)(this["FilterShowUpdates"])); } set { this["FilterShowUpdates"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("Ask")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public global::Klocman.YesNoAsk MessagesRestorePoints { get { return ((global::Klocman.YesNoAsk)(this["MessagesRestorePoints"])); } set { this["MessagesRestorePoints"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("False")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool AdvancedSimulate { get { return ((bool)(this["AdvancedSimulate"])); } set { this["AdvancedSimulate"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public string MiscVersion { get { return ((string)(this["MiscVersion"])); } set { this["MiscVersion"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("False")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool Debug { get { return ((bool)(this["Debug"])); } set { this["Debug"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("Ask")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public global::Klocman.YesNoAsk MessagesRemoveJunk { get { return ((global::Klocman.YesNoAsk)(this["MessagesRemoveJunk"])); } set { this["MessagesRemoveJunk"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("False")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool MiscCheckForUpdates { get { return ((bool)(this["MiscCheckForUpdates"])); } set { this["MiscCheckForUpdates"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("Ask")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public global::Klocman.YesNoAsk BackupLeftovers { get { return ((global::Klocman.YesNoAsk)(this["BackupLeftovers"])); } set { this["BackupLeftovers"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("True")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool MessagesAskRemoveLoudItems { get { return ((bool)(this["MessagesAskRemoveLoudItems"])); } set { this["MessagesAskRemoveLoudItems"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("False")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool MiscFeedbackNagShown { get { return ((bool)(this["MiscFeedbackNagShown"])); } set { this["MiscFeedbackNagShown"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("False")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool MiscSendStatistics { get { return ((bool)(this["MiscSendStatistics"])); } set { this["MiscSendStatistics"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public string ExternalPreCommands { get { return ((string)(this["ExternalPreCommands"])); } set { this["ExternalPreCommands"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("../BleachBit/bleachbit_console.exe --clean system.tmp system.logs system.memory_d" + "ump system.muicache system.prefetch system.recycle_bin")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public string ExternalPostCommands { get { return ((string)(this["ExternalPostCommands"])); } set { this["ExternalPostCommands"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("True")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool ToolbarsShowStatusbar { get { return ((bool)(this["ToolbarsShowStatusbar"])); } set { this["ToolbarsShowStatusbar"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("False")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool ExternalEnable { get { return ((bool)(this["ExternalEnable"])); } set { this["ExternalEnable"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public string Language { get { return ((string)(this["Language"])); } set { this["Language"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("0")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public ulong MiscUserId { get { return ((ulong)(this["MiscUserId"])); } set { this["MiscUserId"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("True")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool AdvancedTestCertificates { get { return ((bool)(this["AdvancedTestCertificates"])); } set { this["AdvancedTestCertificates"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("True")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool AdvancedTestInvalid { get { return ((bool)(this["AdvancedTestInvalid"])); } set { this["AdvancedTestInvalid"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("True")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool AdvancedDisplayOrphans { get { return ((bool)(this["AdvancedDisplayOrphans"])); } set { this["AdvancedDisplayOrphans"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("None")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public global::System.Windows.Forms.SortOrder UninstallerListSortOrder { get { return ((global::System.Windows.Forms.SortOrder)(this["UninstallerListSortOrder"])); } set { this["UninstallerListSortOrder"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("0")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public int UninstallerListSortColumn { get { return ((int)(this["UninstallerListSortColumn"])); } set { this["UninstallerListSortColumn"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("True")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool UninstallerListShowLegend { get { return ((bool)(this["UninstallerListShowLegend"])); } set { this["UninstallerListShowLegend"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public string FoldersCustomProgramDirs { get { return ((string)(this["FoldersCustomProgramDirs"])); } set { this["FoldersCustomProgramDirs"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("True")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool MiscAutoLoadDefaultList { get { return ((bool)(this["MiscAutoLoadDefaultList"])); } set { this["MiscAutoLoadDefaultList"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("False")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool MiscUserRatings { get { return ((bool)(this["MiscUserRatings"])); } set { this["MiscUserRatings"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("1990-01-01")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public global::System.DateTime MiscRatingCacheDate { get { return ((global::System.DateTime)(this["MiscRatingCacheDate"])); } set { this["MiscRatingCacheDate"] = value; } } [global::System.Configuration.ApplicationScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("10.00:00:00")] public global::System.TimeSpan _CacheUpdateRate { get { return ((global::System.TimeSpan)(this["_CacheUpdateRate"])); } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("True")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool UninstallPreventShutdown { get { return ((bool)(this["UninstallPreventShutdown"])); } set { this["UninstallPreventShutdown"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("True")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool UninstallConcurrency { get { return ((bool)(this["UninstallConcurrency"])); } set { this["UninstallConcurrency"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("2")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public int UninstallConcurrentMaxCount { get { return ((int)(this["UninstallConcurrentMaxCount"])); } set { this["UninstallConcurrentMaxCount"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("True")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool UninstallConcurrentOneLoud { get { return ((bool)(this["UninstallConcurrentOneLoud"])); } set { this["UninstallConcurrentOneLoud"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("False")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool UninstallConcurrentDisableManualCollisionProtection { get { return ((bool)(this["UninstallConcurrentDisableManualCollisionProtection"])); } set { this["UninstallConcurrentDisableManualCollisionProtection"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("True")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool FilterShowStoreApps { get { return ((bool)(this["FilterShowStoreApps"])); } set { this["FilterShowStoreApps"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("True")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool QuietRetryFailedOnce { get { return ((bool)(this["QuietRetryFailedOnce"])); } set { this["QuietRetryFailedOnce"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("True")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool QuietAutoKillStuck { get { return ((bool)(this["QuietAutoKillStuck"])); } set { this["QuietAutoKillStuck"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("True")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool QuietAutomatization { get { return ((bool)(this["QuietAutomatization"])); } set { this["QuietAutomatization"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("True")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool QuietAutomatizationKillStuck { get { return ((bool)(this["QuietAutomatizationKillStuck"])); } set { this["QuietAutomatizationKillStuck"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("False")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool FilterShowWinFeatures { get { return ((bool)(this["FilterShowWinFeatures"])); } set { this["FilterShowWinFeatures"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("False")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool MessagesShowAllBadJunk { get { return ((bool)(this["MessagesShowAllBadJunk"])); } set { this["MessagesShowAllBadJunk"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("False")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool MiscFeedbackNagNeverShow { get { return ((bool)(this["MiscFeedbackNagNeverShow"])); } set { this["MiscFeedbackNagNeverShow"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("False")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool ScanWinUpdates { get { return ((bool)(this["ScanWinUpdates"])); } set { this["ScanWinUpdates"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("False")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool ScanWinFeatures { get { return ((bool)(this["ScanWinFeatures"])); } set { this["ScanWinFeatures"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("True")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool ScanSteam { get { return ((bool)(this["ScanSteam"])); } set { this["ScanSteam"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("True")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool ScanStoreApps { get { return ((bool)(this["ScanStoreApps"])); } set { this["ScanStoreApps"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("True")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool FoldersAutoDetect { get { return ((bool)(this["FoldersAutoDetect"])); } set { this["FoldersAutoDetect"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("True")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool ScanDrives { get { return ((bool)(this["ScanDrives"])); } set { this["ScanDrives"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("True")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool ScanRegistry { get { return ((bool)(this["ScanRegistry"])); } set { this["ScanRegistry"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("True")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool ScanPreDefined { get { return ((bool)(this["ScanPreDefined"])); } set { this["ScanPreDefined"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("")] public string BackupLeftoversDirectory { get { return ((string)(this["BackupLeftoversDirectory"])); } set { this["BackupLeftoversDirectory"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("True")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool ShowTreeMap { get { return ((bool)(this["ShowTreeMap"])); } set { this["ShowTreeMap"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("True")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool CacheCertificates { get { return ((bool)(this["CacheCertificates"])); } set { this["CacheCertificates"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("True")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool CacheAppInfo { get { return ((bool)(this["CacheAppInfo"])); } set { this["CacheAppInfo"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("True")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool ScanChocolatey { get { return ((bool)(this["ScanChocolatey"])); } set { this["ScanChocolatey"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("True")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool QuietUseDaemon { get { return ((bool)(this["QuietUseDaemon"])); } set { this["QuietUseDaemon"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("True")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool ScanOculus { get { return ((bool)(this["ScanOculus"])); } set { this["ScanOculus"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("True")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool AdvancedHighlightSpecial { get { return ((bool)(this["AdvancedHighlightSpecial"])); } set { this["AdvancedHighlightSpecial"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("False")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool FoldersScanRemovable { get { return ((bool)(this["FoldersScanRemovable"])); } set { this["FoldersScanRemovable"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("True")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool FilterShowTweaks { get { return ((bool)(this["FilterShowTweaks"])); } set { this["FilterShowTweaks"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("False")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool MiscColorblind { get { return ((bool)(this["MiscColorblind"])); } set { this["MiscColorblind"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("True")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool ScanScoop { get { return ((bool)(this["ScanScoop"])); } set { this["ScanScoop"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("True")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public bool WindowDpiAware { get { return ((bool)(this["WindowDpiAware"])); } set { this["WindowDpiAware"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Configuration.SettingsProviderAttribute(typeof(PortableSettingsProvider.PortableSettingsProvider))] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("OpenProperties")] [global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)] public global::BulkCrapUninstaller.Forms.UninstallerListDoubleClickAction UninstallerListDoubleClickAction { get { return ((global::BulkCrapUninstaller.Forms.UninstallerListDoubleClickAction)(this["UninstallerListDoubleClickAction"])); } set { this["UninstallerListDoubleClickAction"] = value; } } } } ================================================ FILE: source/BulkCrapUninstaller/Properties/Settings.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using Klocman.Binding.Settings; namespace BulkCrapUninstaller.Properties { // This class allows you to handle specific events on the settings class: // The SettingChanging event is raised before a setting's value is changed. // The PropertyChanged event is raised after a setting's value is changed. // The SettingsLoaded event is raised after the setting values are loaded. // The SettingsSaving event is raised before the setting values are saved. internal sealed partial class Settings { private SettingBinder _settingManager; public SettingBinder SettingBinder => _settingManager ?? (_settingManager = new SettingBinder(this)); } } ================================================ FILE: source/BulkCrapUninstaller/Properties/Settings.settings ================================================  False True False False 0, 0 0, 0 True True Normal True True False False False False Ask False False Ask False Ask True False False ../BleachBit/bleachbit_console.exe --clean system.tmp system.logs system.memory_dump system.muicache system.prefetch system.recycle_bin True False 0 True True True None 0 True True False 1990-01-01 10.00:00:00 True True 2 True False True True True True True False False False False False True True True True True True True True True True True True True False True False True True OpenProperties ================================================ FILE: source/BulkCrapUninstaller.sln ================================================  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.5.33424.131 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BulkCrapUninstaller", "BulkCrapUninstaller\BulkCrapUninstaller.csproj", "{5086CDDE-5B1D-485B-AABC-A63C633579B6}" ProjectSection(ProjectDependencies) = postProject {129CBF33-9E19-4D26-A601-5E8394907AE1} = {129CBF33-9E19-4D26-A601-5E8394907AE1} {2E8CECA3-4872-439E-9A47-5304FB4BF705} = {2E8CECA3-4872-439E-9A47-5304FB4BF705} {319C4596-0EE6-4392-9D7B-F937794133C7} = {319C4596-0EE6-4392-9D7B-F937794133C7} {43022440-594D-437C-96C8-6AA24F6CEE63} = {43022440-594D-437C-96C8-6AA24F6CEE63} {5247BD39-5DEB-4F14-AF4B-9598A8544D06} = {5247BD39-5DEB-4F14-AF4B-9598A8544D06} {52FCBDB1-48D8-448D-B8CA-07F10AB3CA25} = {52FCBDB1-48D8-448D-B8CA-07F10AB3CA25} {9C818D14-22AE-46DB-B179-119069AE6116} = {9C818D14-22AE-46DB-B179-119069AE6116} {DCA3F6AD-0A1A-4E14-894A-114CC9B3B3E5} = {DCA3F6AD-0A1A-4E14-894A-114CC9B3B3E5} {FA4F2993-A7F5-4738-9FE1-81F34DB032A7} = {FA4F2993-A7F5-4738-9FE1-81F34DB032A7} EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UninstallTools", "UninstallTools\UninstallTools.csproj", "{87091C84-B671-4269-ABE4-D0F818AB201C}" ProjectSection(ProjectDependencies) = postProject {DCA3F6AD-0A1A-4E14-894A-114CC9B3B3E5} = {DCA3F6AD-0A1A-4E14-894A-114CC9B3B3E5} EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{CF548671-BB38-48B1-9664-C737E971FC07}" ProjectSection(SolutionItems) = preProject app.manifest = app.manifest Directory.Build.props = Directory.Build.props GlobalAssemblyInfo.cs = GlobalAssemblyInfo.cs Licence.licenseheader = Licence.licenseheader ..\publish.bat = ..\publish.bat ..\README.md = ..\README.md EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KlocTools", "KlocTools\KlocTools.csproj", "{4F843421-01D4-48E8-B88B-CDF30DD671A4}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BulkCrapUninstallerTests", "BulkCrapUninstallerTests\BulkCrapUninstallerTests.csproj", "{C631EFBE-0463-417D-AEBE-A4BE3E660C43}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StoreAppHelper", "StoreAppHelper\StoreAppHelper.csproj", "{DCA3F6AD-0A1A-4E14-894A-114CC9B3B3E5}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UninstallerAutomatizer", "UninstallerAutomatizer\UninstallerAutomatizer.csproj", "{9C818D14-22AE-46DB-B179-119069AE6116}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SteamHelper", "SteamHelper\SteamHelper.csproj", "{43022440-594D-437C-96C8-6AA24F6CEE63}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ObjectListView", "ObjectListView\ObjectListView.csproj", "{18FEDA0C-D147-4286-B39A-01204808106A}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WinUpdateHelper", "WinUpdateHelper\WinUpdateHelper.csproj", "{5247BD39-5DEB-4F14-AF4B-9598A8544D06}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UniversalUninstaller", "UniversalUninstaller\UniversalUninstaller.csproj", "{129CBF33-9E19-4D26-A601-5E8394907AE1}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PortableSettingsProvider", "PortableSettingsProvider\PortableSettingsProvider.csproj", "{495A9EA6-B13C-48F9-A2E2-6667CECEBFDE}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SimpleTreeMap", "SimpleTreeMap\SimpleTreeMap.csproj", "{52FCBDB1-48D8-448D-B8CA-07F10AB3CA25}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SimpleTreeMapTestApp", "SimpleTreeMapTests\SimpleTreeMapTestApp.csproj", "{3F3D249F-885B-4AF5-B760-3900D077D66B}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BCU-console", "BCU-console\BCU-console.csproj", "{2E8CECA3-4872-439E-9A47-5304FB4BF705}" ProjectSection(ProjectDependencies) = postProject {129CBF33-9E19-4D26-A601-5E8394907AE1} = {129CBF33-9E19-4D26-A601-5E8394907AE1} {18FEDA0C-D147-4286-B39A-01204808106A} = {18FEDA0C-D147-4286-B39A-01204808106A} {319C4596-0EE6-4392-9D7B-F937794133C7} = {319C4596-0EE6-4392-9D7B-F937794133C7} {43022440-594D-437C-96C8-6AA24F6CEE63} = {43022440-594D-437C-96C8-6AA24F6CEE63} {495A9EA6-B13C-48F9-A2E2-6667CECEBFDE} = {495A9EA6-B13C-48F9-A2E2-6667CECEBFDE} {4F843421-01D4-48E8-B88B-CDF30DD671A4} = {4F843421-01D4-48E8-B88B-CDF30DD671A4} {5247BD39-5DEB-4F14-AF4B-9598A8544D06} = {5247BD39-5DEB-4F14-AF4B-9598A8544D06} {52FCBDB1-48D8-448D-B8CA-07F10AB3CA25} = {52FCBDB1-48D8-448D-B8CA-07F10AB3CA25} {9C818D14-22AE-46DB-B179-119069AE6116} = {9C818D14-22AE-46DB-B179-119069AE6116} {B5F0E648-A6E8-4D63-842C-90562148A930} = {B5F0E648-A6E8-4D63-842C-90562148A930} {C28A3493-8FCA-4571-8F9E-27B8420C0720} = {C28A3493-8FCA-4571-8F9E-27B8420C0720} {DCA3F6AD-0A1A-4E14-894A-114CC9B3B3E5} = {DCA3F6AD-0A1A-4E14-894A-114CC9B3B3E5} {FA4F2993-A7F5-4738-9FE1-81F34DB032A7} = {FA4F2993-A7F5-4738-9FE1-81F34DB032A7} EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OculusHelper", "OculusHelper\OculusHelper.csproj", "{319C4596-0EE6-4392-9D7B-F937794133C7}" EndProject Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "HelperTools", "HelperTools\HelperTools.shproj", "{73A9796D-334C-400C-87AC-1DFDD613266E}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ScriptHelper", "ScriptHelper\ScriptHelper.csproj", "{FA4F2993-A7F5-4738-9FE1-81F34DB032A7}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NetSettingBinder", "NetSettingBinder\NetSettingBinder.csproj", "{C28A3493-8FCA-4571-8F9E-27B8420C0720}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NBug", "NBug_custom\NBug.csproj", "{B5F0E648-A6E8-4D63-842C-90562148A930}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BCU-launcher", "BCU-launcher\BCU-launcher.vcxproj", "{C54B5AFD-C079-4852-960E-906B8CEE0E07}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Debug|ARM64 = Debug|ARM64 Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 Release|Any CPU = Release|Any CPU Release|ARM64 = Release|ARM64 Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {5086CDDE-5B1D-485B-AABC-A63C633579B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {5086CDDE-5B1D-485B-AABC-A63C633579B6}.Debug|Any CPU.Build.0 = Debug|Any CPU {5086CDDE-5B1D-485B-AABC-A63C633579B6}.Debug|ARM64.ActiveCfg = Debug|ARM64 {5086CDDE-5B1D-485B-AABC-A63C633579B6}.Debug|ARM64.Build.0 = Debug|ARM64 {5086CDDE-5B1D-485B-AABC-A63C633579B6}.Debug|x64.ActiveCfg = Debug|x64 {5086CDDE-5B1D-485B-AABC-A63C633579B6}.Debug|x64.Build.0 = Debug|x64 {5086CDDE-5B1D-485B-AABC-A63C633579B6}.Debug|x86.ActiveCfg = Debug|x86 {5086CDDE-5B1D-485B-AABC-A63C633579B6}.Debug|x86.Build.0 = Debug|x86 {5086CDDE-5B1D-485B-AABC-A63C633579B6}.Release|Any CPU.ActiveCfg = Release|Any CPU {5086CDDE-5B1D-485B-AABC-A63C633579B6}.Release|Any CPU.Build.0 = Release|Any CPU {5086CDDE-5B1D-485B-AABC-A63C633579B6}.Release|ARM64.ActiveCfg = Release|ARM64 {5086CDDE-5B1D-485B-AABC-A63C633579B6}.Release|ARM64.Build.0 = Release|ARM64 {5086CDDE-5B1D-485B-AABC-A63C633579B6}.Release|x64.ActiveCfg = Release|x64 {5086CDDE-5B1D-485B-AABC-A63C633579B6}.Release|x64.Build.0 = Release|x64 {5086CDDE-5B1D-485B-AABC-A63C633579B6}.Release|x86.ActiveCfg = Release|x86 {5086CDDE-5B1D-485B-AABC-A63C633579B6}.Release|x86.Build.0 = Release|x86 {87091C84-B671-4269-ABE4-D0F818AB201C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {87091C84-B671-4269-ABE4-D0F818AB201C}.Debug|Any CPU.Build.0 = Debug|Any CPU {87091C84-B671-4269-ABE4-D0F818AB201C}.Debug|ARM64.ActiveCfg = Debug|ARM64 {87091C84-B671-4269-ABE4-D0F818AB201C}.Debug|ARM64.Build.0 = Debug|ARM64 {87091C84-B671-4269-ABE4-D0F818AB201C}.Debug|x64.ActiveCfg = Debug|x64 {87091C84-B671-4269-ABE4-D0F818AB201C}.Debug|x64.Build.0 = Debug|x64 {87091C84-B671-4269-ABE4-D0F818AB201C}.Debug|x86.ActiveCfg = Debug|x86 {87091C84-B671-4269-ABE4-D0F818AB201C}.Debug|x86.Build.0 = Debug|x86 {87091C84-B671-4269-ABE4-D0F818AB201C}.Release|Any CPU.ActiveCfg = Release|Any CPU {87091C84-B671-4269-ABE4-D0F818AB201C}.Release|Any CPU.Build.0 = Release|Any CPU {87091C84-B671-4269-ABE4-D0F818AB201C}.Release|ARM64.ActiveCfg = Release|ARM64 {87091C84-B671-4269-ABE4-D0F818AB201C}.Release|ARM64.Build.0 = Release|ARM64 {87091C84-B671-4269-ABE4-D0F818AB201C}.Release|x64.ActiveCfg = Release|x64 {87091C84-B671-4269-ABE4-D0F818AB201C}.Release|x64.Build.0 = Release|x64 {87091C84-B671-4269-ABE4-D0F818AB201C}.Release|x86.ActiveCfg = Release|x86 {87091C84-B671-4269-ABE4-D0F818AB201C}.Release|x86.Build.0 = Release|x86 {4F843421-01D4-48E8-B88B-CDF30DD671A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {4F843421-01D4-48E8-B88B-CDF30DD671A4}.Debug|Any CPU.Build.0 = Debug|Any CPU {4F843421-01D4-48E8-B88B-CDF30DD671A4}.Debug|ARM64.ActiveCfg = Debug|ARM64 {4F843421-01D4-48E8-B88B-CDF30DD671A4}.Debug|ARM64.Build.0 = Debug|ARM64 {4F843421-01D4-48E8-B88B-CDF30DD671A4}.Debug|x64.ActiveCfg = Debug|x64 {4F843421-01D4-48E8-B88B-CDF30DD671A4}.Debug|x64.Build.0 = Debug|x64 {4F843421-01D4-48E8-B88B-CDF30DD671A4}.Debug|x86.ActiveCfg = Debug|x86 {4F843421-01D4-48E8-B88B-CDF30DD671A4}.Debug|x86.Build.0 = Debug|x86 {4F843421-01D4-48E8-B88B-CDF30DD671A4}.Release|Any CPU.ActiveCfg = Release|Any CPU {4F843421-01D4-48E8-B88B-CDF30DD671A4}.Release|Any CPU.Build.0 = Release|Any CPU {4F843421-01D4-48E8-B88B-CDF30DD671A4}.Release|ARM64.ActiveCfg = Release|ARM64 {4F843421-01D4-48E8-B88B-CDF30DD671A4}.Release|ARM64.Build.0 = Release|ARM64 {4F843421-01D4-48E8-B88B-CDF30DD671A4}.Release|x64.ActiveCfg = Release|x64 {4F843421-01D4-48E8-B88B-CDF30DD671A4}.Release|x64.Build.0 = Release|x64 {4F843421-01D4-48E8-B88B-CDF30DD671A4}.Release|x86.ActiveCfg = Release|x86 {4F843421-01D4-48E8-B88B-CDF30DD671A4}.Release|x86.Build.0 = Release|x86 {C631EFBE-0463-417D-AEBE-A4BE3E660C43}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {C631EFBE-0463-417D-AEBE-A4BE3E660C43}.Debug|ARM64.ActiveCfg = Debug|ARM64 {C631EFBE-0463-417D-AEBE-A4BE3E660C43}.Debug|ARM64.Build.0 = Debug|ARM64 {C631EFBE-0463-417D-AEBE-A4BE3E660C43}.Debug|x64.ActiveCfg = Debug|x64 {C631EFBE-0463-417D-AEBE-A4BE3E660C43}.Debug|x64.Build.0 = Debug|x64 {C631EFBE-0463-417D-AEBE-A4BE3E660C43}.Debug|x86.ActiveCfg = Debug|x86 {C631EFBE-0463-417D-AEBE-A4BE3E660C43}.Debug|x86.Build.0 = Debug|x86 {C631EFBE-0463-417D-AEBE-A4BE3E660C43}.Release|Any CPU.ActiveCfg = Release|Any CPU {C631EFBE-0463-417D-AEBE-A4BE3E660C43}.Release|ARM64.ActiveCfg = Release|ARM64 {C631EFBE-0463-417D-AEBE-A4BE3E660C43}.Release|x64.ActiveCfg = Release|x64 {C631EFBE-0463-417D-AEBE-A4BE3E660C43}.Release|x86.ActiveCfg = Release|x86 {DCA3F6AD-0A1A-4E14-894A-114CC9B3B3E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {DCA3F6AD-0A1A-4E14-894A-114CC9B3B3E5}.Debug|Any CPU.Build.0 = Debug|Any CPU {DCA3F6AD-0A1A-4E14-894A-114CC9B3B3E5}.Debug|ARM64.ActiveCfg = Debug|ARM64 {DCA3F6AD-0A1A-4E14-894A-114CC9B3B3E5}.Debug|ARM64.Build.0 = Debug|ARM64 {DCA3F6AD-0A1A-4E14-894A-114CC9B3B3E5}.Debug|x64.ActiveCfg = Debug|x64 {DCA3F6AD-0A1A-4E14-894A-114CC9B3B3E5}.Debug|x64.Build.0 = Debug|x64 {DCA3F6AD-0A1A-4E14-894A-114CC9B3B3E5}.Debug|x86.ActiveCfg = Debug|x86 {DCA3F6AD-0A1A-4E14-894A-114CC9B3B3E5}.Debug|x86.Build.0 = Debug|x86 {DCA3F6AD-0A1A-4E14-894A-114CC9B3B3E5}.Release|Any CPU.ActiveCfg = Release|Any CPU {DCA3F6AD-0A1A-4E14-894A-114CC9B3B3E5}.Release|Any CPU.Build.0 = Release|Any CPU {DCA3F6AD-0A1A-4E14-894A-114CC9B3B3E5}.Release|ARM64.ActiveCfg = Release|ARM64 {DCA3F6AD-0A1A-4E14-894A-114CC9B3B3E5}.Release|ARM64.Build.0 = Release|ARM64 {DCA3F6AD-0A1A-4E14-894A-114CC9B3B3E5}.Release|x64.ActiveCfg = Release|x64 {DCA3F6AD-0A1A-4E14-894A-114CC9B3B3E5}.Release|x64.Build.0 = Release|x64 {DCA3F6AD-0A1A-4E14-894A-114CC9B3B3E5}.Release|x86.ActiveCfg = Release|x86 {DCA3F6AD-0A1A-4E14-894A-114CC9B3B3E5}.Release|x86.Build.0 = Release|x86 {9C818D14-22AE-46DB-B179-119069AE6116}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {9C818D14-22AE-46DB-B179-119069AE6116}.Debug|Any CPU.Build.0 = Debug|Any CPU {9C818D14-22AE-46DB-B179-119069AE6116}.Debug|ARM64.ActiveCfg = Debug|ARM64 {9C818D14-22AE-46DB-B179-119069AE6116}.Debug|ARM64.Build.0 = Debug|ARM64 {9C818D14-22AE-46DB-B179-119069AE6116}.Debug|x64.ActiveCfg = Debug|x64 {9C818D14-22AE-46DB-B179-119069AE6116}.Debug|x64.Build.0 = Debug|x64 {9C818D14-22AE-46DB-B179-119069AE6116}.Debug|x86.ActiveCfg = Debug|x86 {9C818D14-22AE-46DB-B179-119069AE6116}.Debug|x86.Build.0 = Debug|x86 {9C818D14-22AE-46DB-B179-119069AE6116}.Release|Any CPU.ActiveCfg = Release|Any CPU {9C818D14-22AE-46DB-B179-119069AE6116}.Release|Any CPU.Build.0 = Release|Any CPU {9C818D14-22AE-46DB-B179-119069AE6116}.Release|ARM64.ActiveCfg = Release|ARM64 {9C818D14-22AE-46DB-B179-119069AE6116}.Release|ARM64.Build.0 = Release|ARM64 {9C818D14-22AE-46DB-B179-119069AE6116}.Release|x64.ActiveCfg = Release|x64 {9C818D14-22AE-46DB-B179-119069AE6116}.Release|x64.Build.0 = Release|x64 {9C818D14-22AE-46DB-B179-119069AE6116}.Release|x86.ActiveCfg = Release|x86 {9C818D14-22AE-46DB-B179-119069AE6116}.Release|x86.Build.0 = Release|x86 {43022440-594D-437C-96C8-6AA24F6CEE63}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {43022440-594D-437C-96C8-6AA24F6CEE63}.Debug|Any CPU.Build.0 = Debug|Any CPU {43022440-594D-437C-96C8-6AA24F6CEE63}.Debug|ARM64.ActiveCfg = Debug|ARM64 {43022440-594D-437C-96C8-6AA24F6CEE63}.Debug|ARM64.Build.0 = Debug|ARM64 {43022440-594D-437C-96C8-6AA24F6CEE63}.Debug|x64.ActiveCfg = Debug|x64 {43022440-594D-437C-96C8-6AA24F6CEE63}.Debug|x64.Build.0 = Debug|x64 {43022440-594D-437C-96C8-6AA24F6CEE63}.Debug|x86.ActiveCfg = Debug|x86 {43022440-594D-437C-96C8-6AA24F6CEE63}.Debug|x86.Build.0 = Debug|x86 {43022440-594D-437C-96C8-6AA24F6CEE63}.Release|Any CPU.ActiveCfg = Release|Any CPU {43022440-594D-437C-96C8-6AA24F6CEE63}.Release|Any CPU.Build.0 = Release|Any CPU {43022440-594D-437C-96C8-6AA24F6CEE63}.Release|ARM64.ActiveCfg = Release|ARM64 {43022440-594D-437C-96C8-6AA24F6CEE63}.Release|ARM64.Build.0 = Release|ARM64 {43022440-594D-437C-96C8-6AA24F6CEE63}.Release|x64.ActiveCfg = Release|x64 {43022440-594D-437C-96C8-6AA24F6CEE63}.Release|x64.Build.0 = Release|x64 {43022440-594D-437C-96C8-6AA24F6CEE63}.Release|x86.ActiveCfg = Release|x86 {43022440-594D-437C-96C8-6AA24F6CEE63}.Release|x86.Build.0 = Release|x86 {18FEDA0C-D147-4286-B39A-01204808106A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {18FEDA0C-D147-4286-B39A-01204808106A}.Debug|Any CPU.Build.0 = Debug|Any CPU {18FEDA0C-D147-4286-B39A-01204808106A}.Debug|ARM64.ActiveCfg = Debug|ARM64 {18FEDA0C-D147-4286-B39A-01204808106A}.Debug|ARM64.Build.0 = Debug|ARM64 {18FEDA0C-D147-4286-B39A-01204808106A}.Debug|x64.ActiveCfg = Debug|x64 {18FEDA0C-D147-4286-B39A-01204808106A}.Debug|x64.Build.0 = Debug|x64 {18FEDA0C-D147-4286-B39A-01204808106A}.Debug|x86.ActiveCfg = Debug|x86 {18FEDA0C-D147-4286-B39A-01204808106A}.Debug|x86.Build.0 = Debug|x86 {18FEDA0C-D147-4286-B39A-01204808106A}.Release|Any CPU.ActiveCfg = Release|Any CPU {18FEDA0C-D147-4286-B39A-01204808106A}.Release|Any CPU.Build.0 = Release|Any CPU {18FEDA0C-D147-4286-B39A-01204808106A}.Release|ARM64.ActiveCfg = Release|ARM64 {18FEDA0C-D147-4286-B39A-01204808106A}.Release|ARM64.Build.0 = Release|ARM64 {18FEDA0C-D147-4286-B39A-01204808106A}.Release|x64.ActiveCfg = Release|x64 {18FEDA0C-D147-4286-B39A-01204808106A}.Release|x64.Build.0 = Release|x64 {18FEDA0C-D147-4286-B39A-01204808106A}.Release|x86.ActiveCfg = Release|x86 {18FEDA0C-D147-4286-B39A-01204808106A}.Release|x86.Build.0 = Release|x86 {5247BD39-5DEB-4F14-AF4B-9598A8544D06}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {5247BD39-5DEB-4F14-AF4B-9598A8544D06}.Debug|Any CPU.Build.0 = Debug|Any CPU {5247BD39-5DEB-4F14-AF4B-9598A8544D06}.Debug|ARM64.ActiveCfg = Debug|ARM64 {5247BD39-5DEB-4F14-AF4B-9598A8544D06}.Debug|ARM64.Build.0 = Debug|ARM64 {5247BD39-5DEB-4F14-AF4B-9598A8544D06}.Debug|x64.ActiveCfg = Debug|x64 {5247BD39-5DEB-4F14-AF4B-9598A8544D06}.Debug|x64.Build.0 = Debug|x64 {5247BD39-5DEB-4F14-AF4B-9598A8544D06}.Debug|x86.ActiveCfg = Debug|x86 {5247BD39-5DEB-4F14-AF4B-9598A8544D06}.Debug|x86.Build.0 = Debug|x86 {5247BD39-5DEB-4F14-AF4B-9598A8544D06}.Release|Any CPU.ActiveCfg = Release|Any CPU {5247BD39-5DEB-4F14-AF4B-9598A8544D06}.Release|Any CPU.Build.0 = Release|Any CPU {5247BD39-5DEB-4F14-AF4B-9598A8544D06}.Release|ARM64.ActiveCfg = Release|ARM64 {5247BD39-5DEB-4F14-AF4B-9598A8544D06}.Release|ARM64.Build.0 = Release|ARM64 {5247BD39-5DEB-4F14-AF4B-9598A8544D06}.Release|x64.ActiveCfg = Release|x64 {5247BD39-5DEB-4F14-AF4B-9598A8544D06}.Release|x64.Build.0 = Release|x64 {5247BD39-5DEB-4F14-AF4B-9598A8544D06}.Release|x86.ActiveCfg = Release|x86 {5247BD39-5DEB-4F14-AF4B-9598A8544D06}.Release|x86.Build.0 = Release|x86 {129CBF33-9E19-4D26-A601-5E8394907AE1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {129CBF33-9E19-4D26-A601-5E8394907AE1}.Debug|Any CPU.Build.0 = Debug|Any CPU {129CBF33-9E19-4D26-A601-5E8394907AE1}.Debug|ARM64.ActiveCfg = Debug|ARM64 {129CBF33-9E19-4D26-A601-5E8394907AE1}.Debug|ARM64.Build.0 = Debug|ARM64 {129CBF33-9E19-4D26-A601-5E8394907AE1}.Debug|x64.ActiveCfg = Debug|x64 {129CBF33-9E19-4D26-A601-5E8394907AE1}.Debug|x64.Build.0 = Debug|x64 {129CBF33-9E19-4D26-A601-5E8394907AE1}.Debug|x86.ActiveCfg = Debug|x86 {129CBF33-9E19-4D26-A601-5E8394907AE1}.Debug|x86.Build.0 = Debug|x86 {129CBF33-9E19-4D26-A601-5E8394907AE1}.Release|Any CPU.ActiveCfg = Release|Any CPU {129CBF33-9E19-4D26-A601-5E8394907AE1}.Release|Any CPU.Build.0 = Release|Any CPU {129CBF33-9E19-4D26-A601-5E8394907AE1}.Release|ARM64.ActiveCfg = Release|ARM64 {129CBF33-9E19-4D26-A601-5E8394907AE1}.Release|ARM64.Build.0 = Release|ARM64 {129CBF33-9E19-4D26-A601-5E8394907AE1}.Release|x64.ActiveCfg = Release|x64 {129CBF33-9E19-4D26-A601-5E8394907AE1}.Release|x64.Build.0 = Release|x64 {129CBF33-9E19-4D26-A601-5E8394907AE1}.Release|x86.ActiveCfg = Release|x86 {129CBF33-9E19-4D26-A601-5E8394907AE1}.Release|x86.Build.0 = Release|x86 {495A9EA6-B13C-48F9-A2E2-6667CECEBFDE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {495A9EA6-B13C-48F9-A2E2-6667CECEBFDE}.Debug|Any CPU.Build.0 = Debug|Any CPU {495A9EA6-B13C-48F9-A2E2-6667CECEBFDE}.Debug|ARM64.ActiveCfg = Debug|ARM64 {495A9EA6-B13C-48F9-A2E2-6667CECEBFDE}.Debug|ARM64.Build.0 = Debug|ARM64 {495A9EA6-B13C-48F9-A2E2-6667CECEBFDE}.Debug|x64.ActiveCfg = Debug|x64 {495A9EA6-B13C-48F9-A2E2-6667CECEBFDE}.Debug|x64.Build.0 = Debug|x64 {495A9EA6-B13C-48F9-A2E2-6667CECEBFDE}.Debug|x86.ActiveCfg = Debug|x86 {495A9EA6-B13C-48F9-A2E2-6667CECEBFDE}.Debug|x86.Build.0 = Debug|x86 {495A9EA6-B13C-48F9-A2E2-6667CECEBFDE}.Release|Any CPU.ActiveCfg = Release|Any CPU {495A9EA6-B13C-48F9-A2E2-6667CECEBFDE}.Release|Any CPU.Build.0 = Release|Any CPU {495A9EA6-B13C-48F9-A2E2-6667CECEBFDE}.Release|ARM64.ActiveCfg = Release|ARM64 {495A9EA6-B13C-48F9-A2E2-6667CECEBFDE}.Release|ARM64.Build.0 = Release|ARM64 {495A9EA6-B13C-48F9-A2E2-6667CECEBFDE}.Release|x64.ActiveCfg = Release|x64 {495A9EA6-B13C-48F9-A2E2-6667CECEBFDE}.Release|x64.Build.0 = Release|x64 {495A9EA6-B13C-48F9-A2E2-6667CECEBFDE}.Release|x86.ActiveCfg = Release|x86 {495A9EA6-B13C-48F9-A2E2-6667CECEBFDE}.Release|x86.Build.0 = Release|x86 {52FCBDB1-48D8-448D-B8CA-07F10AB3CA25}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {52FCBDB1-48D8-448D-B8CA-07F10AB3CA25}.Debug|Any CPU.Build.0 = Debug|Any CPU {52FCBDB1-48D8-448D-B8CA-07F10AB3CA25}.Debug|ARM64.ActiveCfg = Debug|ARM64 {52FCBDB1-48D8-448D-B8CA-07F10AB3CA25}.Debug|ARM64.Build.0 = Debug|ARM64 {52FCBDB1-48D8-448D-B8CA-07F10AB3CA25}.Debug|x64.ActiveCfg = Debug|x64 {52FCBDB1-48D8-448D-B8CA-07F10AB3CA25}.Debug|x64.Build.0 = Debug|x64 {52FCBDB1-48D8-448D-B8CA-07F10AB3CA25}.Debug|x86.ActiveCfg = Debug|x86 {52FCBDB1-48D8-448D-B8CA-07F10AB3CA25}.Debug|x86.Build.0 = Debug|x86 {52FCBDB1-48D8-448D-B8CA-07F10AB3CA25}.Release|Any CPU.ActiveCfg = Release|Any CPU {52FCBDB1-48D8-448D-B8CA-07F10AB3CA25}.Release|Any CPU.Build.0 = Release|Any CPU {52FCBDB1-48D8-448D-B8CA-07F10AB3CA25}.Release|ARM64.ActiveCfg = Release|ARM64 {52FCBDB1-48D8-448D-B8CA-07F10AB3CA25}.Release|ARM64.Build.0 = Release|ARM64 {52FCBDB1-48D8-448D-B8CA-07F10AB3CA25}.Release|x64.ActiveCfg = Release|x64 {52FCBDB1-48D8-448D-B8CA-07F10AB3CA25}.Release|x64.Build.0 = Release|x64 {52FCBDB1-48D8-448D-B8CA-07F10AB3CA25}.Release|x86.ActiveCfg = Release|x86 {52FCBDB1-48D8-448D-B8CA-07F10AB3CA25}.Release|x86.Build.0 = Release|x86 {3F3D249F-885B-4AF5-B760-3900D077D66B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {3F3D249F-885B-4AF5-B760-3900D077D66B}.Debug|Any CPU.Build.0 = Debug|Any CPU {3F3D249F-885B-4AF5-B760-3900D077D66B}.Debug|ARM64.ActiveCfg = Debug|ARM64 {3F3D249F-885B-4AF5-B760-3900D077D66B}.Debug|ARM64.Build.0 = Debug|ARM64 {3F3D249F-885B-4AF5-B760-3900D077D66B}.Debug|x64.ActiveCfg = Debug|x64 {3F3D249F-885B-4AF5-B760-3900D077D66B}.Debug|x64.Build.0 = Debug|x64 {3F3D249F-885B-4AF5-B760-3900D077D66B}.Debug|x86.ActiveCfg = Debug|x86 {3F3D249F-885B-4AF5-B760-3900D077D66B}.Debug|x86.Build.0 = Debug|x86 {3F3D249F-885B-4AF5-B760-3900D077D66B}.Release|Any CPU.ActiveCfg = Release|Any CPU {3F3D249F-885B-4AF5-B760-3900D077D66B}.Release|Any CPU.Build.0 = Release|Any CPU {3F3D249F-885B-4AF5-B760-3900D077D66B}.Release|ARM64.ActiveCfg = Release|ARM64 {3F3D249F-885B-4AF5-B760-3900D077D66B}.Release|ARM64.Build.0 = Release|ARM64 {3F3D249F-885B-4AF5-B760-3900D077D66B}.Release|x64.ActiveCfg = Release|x64 {3F3D249F-885B-4AF5-B760-3900D077D66B}.Release|x64.Build.0 = Release|x64 {3F3D249F-885B-4AF5-B760-3900D077D66B}.Release|x86.ActiveCfg = Release|x86 {3F3D249F-885B-4AF5-B760-3900D077D66B}.Release|x86.Build.0 = Release|x86 {2E8CECA3-4872-439E-9A47-5304FB4BF705}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2E8CECA3-4872-439E-9A47-5304FB4BF705}.Debug|Any CPU.Build.0 = Debug|Any CPU {2E8CECA3-4872-439E-9A47-5304FB4BF705}.Debug|ARM64.ActiveCfg = Debug|ARM64 {2E8CECA3-4872-439E-9A47-5304FB4BF705}.Debug|ARM64.Build.0 = Debug|ARM64 {2E8CECA3-4872-439E-9A47-5304FB4BF705}.Debug|x64.ActiveCfg = Debug|x64 {2E8CECA3-4872-439E-9A47-5304FB4BF705}.Debug|x64.Build.0 = Debug|x64 {2E8CECA3-4872-439E-9A47-5304FB4BF705}.Debug|x86.ActiveCfg = Debug|x86 {2E8CECA3-4872-439E-9A47-5304FB4BF705}.Debug|x86.Build.0 = Debug|x86 {2E8CECA3-4872-439E-9A47-5304FB4BF705}.Release|Any CPU.ActiveCfg = Release|Any CPU {2E8CECA3-4872-439E-9A47-5304FB4BF705}.Release|Any CPU.Build.0 = Release|Any CPU {2E8CECA3-4872-439E-9A47-5304FB4BF705}.Release|ARM64.ActiveCfg = Release|ARM64 {2E8CECA3-4872-439E-9A47-5304FB4BF705}.Release|ARM64.Build.0 = Release|ARM64 {2E8CECA3-4872-439E-9A47-5304FB4BF705}.Release|x64.ActiveCfg = Release|x64 {2E8CECA3-4872-439E-9A47-5304FB4BF705}.Release|x64.Build.0 = Release|x64 {2E8CECA3-4872-439E-9A47-5304FB4BF705}.Release|x86.ActiveCfg = Release|x86 {2E8CECA3-4872-439E-9A47-5304FB4BF705}.Release|x86.Build.0 = Release|x86 {319C4596-0EE6-4392-9D7B-F937794133C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {319C4596-0EE6-4392-9D7B-F937794133C7}.Debug|Any CPU.Build.0 = Debug|Any CPU {319C4596-0EE6-4392-9D7B-F937794133C7}.Debug|ARM64.ActiveCfg = Debug|ARM64 {319C4596-0EE6-4392-9D7B-F937794133C7}.Debug|ARM64.Build.0 = Debug|ARM64 {319C4596-0EE6-4392-9D7B-F937794133C7}.Debug|x64.ActiveCfg = Debug|x64 {319C4596-0EE6-4392-9D7B-F937794133C7}.Debug|x64.Build.0 = Debug|x64 {319C4596-0EE6-4392-9D7B-F937794133C7}.Debug|x86.ActiveCfg = Debug|x86 {319C4596-0EE6-4392-9D7B-F937794133C7}.Debug|x86.Build.0 = Debug|x86 {319C4596-0EE6-4392-9D7B-F937794133C7}.Release|Any CPU.ActiveCfg = Release|Any CPU {319C4596-0EE6-4392-9D7B-F937794133C7}.Release|Any CPU.Build.0 = Release|Any CPU {319C4596-0EE6-4392-9D7B-F937794133C7}.Release|ARM64.ActiveCfg = Release|ARM64 {319C4596-0EE6-4392-9D7B-F937794133C7}.Release|ARM64.Build.0 = Release|ARM64 {319C4596-0EE6-4392-9D7B-F937794133C7}.Release|x64.ActiveCfg = Release|x64 {319C4596-0EE6-4392-9D7B-F937794133C7}.Release|x64.Build.0 = Release|x64 {319C4596-0EE6-4392-9D7B-F937794133C7}.Release|x86.ActiveCfg = Release|x86 {319C4596-0EE6-4392-9D7B-F937794133C7}.Release|x86.Build.0 = Release|x86 {FA4F2993-A7F5-4738-9FE1-81F34DB032A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {FA4F2993-A7F5-4738-9FE1-81F34DB032A7}.Debug|Any CPU.Build.0 = Debug|Any CPU {FA4F2993-A7F5-4738-9FE1-81F34DB032A7}.Debug|ARM64.ActiveCfg = Debug|ARM64 {FA4F2993-A7F5-4738-9FE1-81F34DB032A7}.Debug|ARM64.Build.0 = Debug|ARM64 {FA4F2993-A7F5-4738-9FE1-81F34DB032A7}.Debug|x64.ActiveCfg = Debug|x64 {FA4F2993-A7F5-4738-9FE1-81F34DB032A7}.Debug|x64.Build.0 = Debug|x64 {FA4F2993-A7F5-4738-9FE1-81F34DB032A7}.Debug|x86.ActiveCfg = Debug|x86 {FA4F2993-A7F5-4738-9FE1-81F34DB032A7}.Debug|x86.Build.0 = Debug|x86 {FA4F2993-A7F5-4738-9FE1-81F34DB032A7}.Release|Any CPU.ActiveCfg = Release|Any CPU {FA4F2993-A7F5-4738-9FE1-81F34DB032A7}.Release|Any CPU.Build.0 = Release|Any CPU {FA4F2993-A7F5-4738-9FE1-81F34DB032A7}.Release|ARM64.ActiveCfg = Release|ARM64 {FA4F2993-A7F5-4738-9FE1-81F34DB032A7}.Release|ARM64.Build.0 = Release|ARM64 {FA4F2993-A7F5-4738-9FE1-81F34DB032A7}.Release|x64.ActiveCfg = Release|x64 {FA4F2993-A7F5-4738-9FE1-81F34DB032A7}.Release|x64.Build.0 = Release|x64 {FA4F2993-A7F5-4738-9FE1-81F34DB032A7}.Release|x86.ActiveCfg = Release|x86 {FA4F2993-A7F5-4738-9FE1-81F34DB032A7}.Release|x86.Build.0 = Release|x86 {C28A3493-8FCA-4571-8F9E-27B8420C0720}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {C28A3493-8FCA-4571-8F9E-27B8420C0720}.Debug|Any CPU.Build.0 = Debug|Any CPU {C28A3493-8FCA-4571-8F9E-27B8420C0720}.Debug|ARM64.ActiveCfg = Debug|ARM64 {C28A3493-8FCA-4571-8F9E-27B8420C0720}.Debug|ARM64.Build.0 = Debug|ARM64 {C28A3493-8FCA-4571-8F9E-27B8420C0720}.Debug|x64.ActiveCfg = Debug|x64 {C28A3493-8FCA-4571-8F9E-27B8420C0720}.Debug|x64.Build.0 = Debug|x64 {C28A3493-8FCA-4571-8F9E-27B8420C0720}.Debug|x86.ActiveCfg = Debug|x86 {C28A3493-8FCA-4571-8F9E-27B8420C0720}.Debug|x86.Build.0 = Debug|x86 {C28A3493-8FCA-4571-8F9E-27B8420C0720}.Release|Any CPU.ActiveCfg = Release|Any CPU {C28A3493-8FCA-4571-8F9E-27B8420C0720}.Release|Any CPU.Build.0 = Release|Any CPU {C28A3493-8FCA-4571-8F9E-27B8420C0720}.Release|ARM64.ActiveCfg = Release|ARM64 {C28A3493-8FCA-4571-8F9E-27B8420C0720}.Release|ARM64.Build.0 = Release|ARM64 {C28A3493-8FCA-4571-8F9E-27B8420C0720}.Release|x64.ActiveCfg = Release|x64 {C28A3493-8FCA-4571-8F9E-27B8420C0720}.Release|x64.Build.0 = Release|x64 {C28A3493-8FCA-4571-8F9E-27B8420C0720}.Release|x86.ActiveCfg = Release|x86 {C28A3493-8FCA-4571-8F9E-27B8420C0720}.Release|x86.Build.0 = Release|x86 {B5F0E648-A6E8-4D63-842C-90562148A930}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B5F0E648-A6E8-4D63-842C-90562148A930}.Debug|Any CPU.Build.0 = Debug|Any CPU {B5F0E648-A6E8-4D63-842C-90562148A930}.Debug|ARM64.ActiveCfg = Debug|ARM64 {B5F0E648-A6E8-4D63-842C-90562148A930}.Debug|ARM64.Build.0 = Debug|ARM64 {B5F0E648-A6E8-4D63-842C-90562148A930}.Debug|x64.ActiveCfg = Debug|x64 {B5F0E648-A6E8-4D63-842C-90562148A930}.Debug|x64.Build.0 = Debug|x64 {B5F0E648-A6E8-4D63-842C-90562148A930}.Debug|x86.ActiveCfg = Debug|x86 {B5F0E648-A6E8-4D63-842C-90562148A930}.Debug|x86.Build.0 = Debug|x86 {B5F0E648-A6E8-4D63-842C-90562148A930}.Release|Any CPU.ActiveCfg = Release|Any CPU {B5F0E648-A6E8-4D63-842C-90562148A930}.Release|Any CPU.Build.0 = Release|Any CPU {B5F0E648-A6E8-4D63-842C-90562148A930}.Release|ARM64.ActiveCfg = Release|ARM64 {B5F0E648-A6E8-4D63-842C-90562148A930}.Release|ARM64.Build.0 = Release|ARM64 {B5F0E648-A6E8-4D63-842C-90562148A930}.Release|x64.ActiveCfg = Release|x64 {B5F0E648-A6E8-4D63-842C-90562148A930}.Release|x64.Build.0 = Release|x64 {B5F0E648-A6E8-4D63-842C-90562148A930}.Release|x86.ActiveCfg = Release|x86 {B5F0E648-A6E8-4D63-842C-90562148A930}.Release|x86.Build.0 = Release|x86 {C54B5AFD-C079-4852-960E-906B8CEE0E07}.Debug|Any CPU.ActiveCfg = Debug|Win32 {C54B5AFD-C079-4852-960E-906B8CEE0E07}.Debug|ARM64.ActiveCfg = Debug|Win32 {C54B5AFD-C079-4852-960E-906B8CEE0E07}.Debug|ARM64.Build.0 = Debug|Win32 {C54B5AFD-C079-4852-960E-906B8CEE0E07}.Debug|x64.ActiveCfg = Debug|Win32 {C54B5AFD-C079-4852-960E-906B8CEE0E07}.Debug|x64.Build.0 = Debug|Win32 {C54B5AFD-C079-4852-960E-906B8CEE0E07}.Debug|x86.ActiveCfg = Debug|Win32 {C54B5AFD-C079-4852-960E-906B8CEE0E07}.Debug|x86.Build.0 = Debug|Win32 {C54B5AFD-C079-4852-960E-906B8CEE0E07}.Release|Any CPU.ActiveCfg = Release|Win32 {C54B5AFD-C079-4852-960E-906B8CEE0E07}.Release|ARM64.ActiveCfg = Release|Win32 {C54B5AFD-C079-4852-960E-906B8CEE0E07}.Release|ARM64.Build.0 = Release|Win32 {C54B5AFD-C079-4852-960E-906B8CEE0E07}.Release|x64.ActiveCfg = Release|Win32 {C54B5AFD-C079-4852-960E-906B8CEE0E07}.Release|x64.Build.0 = Release|Win32 {C54B5AFD-C079-4852-960E-906B8CEE0E07}.Release|x86.ActiveCfg = Release|Win32 {C54B5AFD-C079-4852-960E-906B8CEE0E07}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {6E45D37F-C2A8-4E8E-B8FE-19F1D8A5B010} EndGlobalSection GlobalSection(SharedMSBuildProjectFiles) = preSolution HelperTools\HelperTools.projitems*{129cbf33-9e19-4d26-a601-5e8394907ae1}*SharedItemsImports = 5 HelperTools\HelperTools.projitems*{18feda0c-d147-4286-b39a-01204808106a}*SharedItemsImports = 5 HelperTools\HelperTools.projitems*{2e8ceca3-4872-439e-9a47-5304fb4bf705}*SharedItemsImports = 5 HelperTools\HelperTools.projitems*{319c4596-0ee6-4392-9d7b-f937794133c7}*SharedItemsImports = 5 HelperTools\HelperTools.projitems*{3f3d249f-885b-4af5-b760-3900d077d66b}*SharedItemsImports = 5 HelperTools\HelperTools.projitems*{43022440-594d-437c-96c8-6aa24f6cee63}*SharedItemsImports = 5 HelperTools\HelperTools.projitems*{495a9ea6-b13c-48f9-a2e2-6667cecebfde}*SharedItemsImports = 5 HelperTools\HelperTools.projitems*{4f843421-01d4-48e8-b88b-cdf30dd671a4}*SharedItemsImports = 5 HelperTools\HelperTools.projitems*{5086cdde-5b1d-485b-aabc-a63c633579b6}*SharedItemsImports = 5 HelperTools\HelperTools.projitems*{5247bd39-5deb-4f14-af4b-9598a8544d06}*SharedItemsImports = 5 HelperTools\HelperTools.projitems*{52fcbdb1-48d8-448d-b8ca-07f10ab3ca25}*SharedItemsImports = 5 HelperTools\HelperTools.projitems*{73a9796d-334c-400c-87ac-1dfdd613266e}*SharedItemsImports = 13 HelperTools\HelperTools.projitems*{87091c84-b671-4269-abe4-d0f818ab201c}*SharedItemsImports = 5 HelperTools\HelperTools.projitems*{9c818d14-22ae-46db-b179-119069ae6116}*SharedItemsImports = 5 HelperTools\HelperTools.projitems*{b5f0e648-a6e8-4d63-842c-90562148a930}*SharedItemsImports = 5 HelperTools\HelperTools.projitems*{c28a3493-8fca-4571-8f9e-27b8420c0720}*SharedItemsImports = 5 HelperTools\HelperTools.projitems*{c631efbe-0463-417d-aebe-a4be3e660c43}*SharedItemsImports = 5 HelperTools\HelperTools.projitems*{dca3f6ad-0a1a-4e14-894a-114cc9b3b3e5}*SharedItemsImports = 5 HelperTools\HelperTools.projitems*{fa4f2993-a7f5-4738-9fe1-81f34db032a7}*SharedItemsImports = 5 EndGlobalSection EndGlobal ================================================ FILE: source/BulkCrapUninstallerTests/BulkCrapUninstallerTests.csproj ================================================  Library false bin ================================================ FILE: source/BulkCrapUninstallerTests/DynamicStringArrayConverterTests.cs ================================================ using System; using System.Text.Json; using System.Text.Json.Serialization; using Microsoft.VisualStudio.TestTools.UnitTesting; using UninstallTools.Factory.Json; namespace BulkCrapUninstallerTests { [TestClass] public class DynamicStringArrayConverterTests { private static readonly JsonSerializerOptions Options = new() { Converters = { new DynamicStringArrayConverter() } }; private static string[] Deserialize(string json) { return JsonSerializer.Deserialize(json, Options); } // --- 0-dimension (bare string) --- [TestMethod] public void BareString_ReturnsSingleElementArray() { var result = Deserialize("\"foo\""); CollectionAssert.AreEqual(new[] { "foo" }, result); } // --- Flat arrays --- [TestMethod] public void FlatArray_ReturnsAllStrings() { var result = Deserialize("[\"a\", \"b\", \"c\"]"); CollectionAssert.AreEqual(new[] { "a", "b", "c" }, result); } [TestMethod] public void EmptyArray_ReturnsEmpty() { var result = Deserialize("[]"); CollectionAssert.AreEqual(Array.Empty(), result); } [TestMethod] public void SingleElementArray_ReturnsSingleElement() { var result = Deserialize("[\"a\"]"); CollectionAssert.AreEqual(new[] { "a" }, result); } // --- One-level nested arrays --- [TestMethod] public void NestedArray_TakesFirstStringOnly() { var result = Deserialize("[[\"a\", \"b\"], \"c\"]"); CollectionAssert.AreEqual(new[] { "a", "c" }, result); } [TestMethod] public void MultipleNestedArrays_TakesFirstFromEach() { var result = Deserialize("[[\"a\", \"b\"], [\"c\", \"d\"]]"); CollectionAssert.AreEqual(new[] { "a", "c" }, result); } [TestMethod] public void EmptyNestedArray_IsSkipped() { var result = Deserialize("[[], \"c\"]"); CollectionAssert.AreEqual(new[] { "c" }, result); } [TestMethod] public void AllEmptyNestedArrays_ReturnsEmpty() { var result = Deserialize("[[], []]"); CollectionAssert.AreEqual(Array.Empty(), result); } // --- Non-string tokens --- [TestMethod] public void NonStringFirstInNested_SkipsToFirstString() { var result = Deserialize("[[42, \"a\"], \"c\"]"); CollectionAssert.AreEqual(new[] { "a", "c" }, result); } [TestMethod] public void NestedWithOnlyNonStrings_IsSkipped() { var result = Deserialize("[[42, true, null]]"); CollectionAssert.AreEqual(Array.Empty(), result); } [TestMethod] public void NullAtTopLevel_IsSkipped() { var result = Deserialize("[null, \"a\"]"); CollectionAssert.AreEqual(new[] { "a" }, result); } [TestMethod] public void NullInNestedArray_SkipsToFirstString() { var result = Deserialize("[[null, \"a\"]]"); CollectionAssert.AreEqual(new[] { "a" }, result); } // --- Deep nesting --- [TestMethod] public void TwoDeepNesting_RecursivelyUnwraps() { var result = Deserialize("[[[\"a\"]]]"); CollectionAssert.AreEqual(new[] { "a" }, result); } [TestMethod] public void ThreeDeepNesting_RecursivelyUnwraps() { var result = Deserialize("[[[[\"a\"]]]]"); CollectionAssert.AreEqual(new[] { "a" }, result); } [TestMethod] public void DeeplyNestedEmpty_ReturnsEmpty() { var result = Deserialize("[[[[]]]]"); CollectionAssert.AreEqual(Array.Empty(), result); } [TestMethod] public void EmptyThenNonEmptyInNested_FindsString() { var result = Deserialize("[[[], [\"x\"]], \"y\"]"); CollectionAssert.AreEqual(new[] { "x", "y" }, result); } // --- Mixed flat and nested --- [TestMethod] public void MixedFlatAndNested_CollectsAll() { var result = Deserialize("[\"a\", [\"b\"], [[\"c\"]], \"d\"]"); CollectionAssert.AreEqual(new[] { "a", "b", "c", "d" }, result); } // --- Objects --- [TestMethod] public void ObjectAtTopLevel_IsSkipped() { var result = Deserialize("[{\"k\":\"v\"}, \"a\"]"); CollectionAssert.AreEqual(new[] { "a" }, result); } [TestMethod] public void ObjectInNestedArray_IsSkipped() { var result = Deserialize("[[{\"k\":\"v\"}, \"a\"]]"); CollectionAssert.AreEqual(new[] { "a" }, result); } // --- Invalid root token --- [TestMethod] public void InvalidRootToken_ThrowsJsonException() { Assert.Throws(() => Deserialize("42")); } [TestMethod] public void RootObject_ThrowsJsonException() { Assert.Throws(() => Deserialize("{\"x\":1}")); } [TestMethod] public void RootNull_ReturnsNull() { var result = Deserialize("null"); Assert.IsNull(result); } // --- Additional adversarial edge cases --- [TestMethod] public void EmptyStringPreserved_TopLevel() { var result = Deserialize("[\"\"]"); CollectionAssert.AreEqual(new[] { "" }, result); } [TestMethod] public void EmptyStringPreserved_InNested() { var result = Deserialize("[[\"\", \"b\"]]"); CollectionAssert.AreEqual(new[] { "" }, result); } [TestMethod] public void BooleanAtTopLevel_IsSkipped() { var result = Deserialize("[true, false, \"a\"]"); CollectionAssert.AreEqual(new[] { "a" }, result); } [TestMethod] public void NumberAtTopLevel_IsSkipped() { var result = Deserialize("[42, \"a\"]"); CollectionAssert.AreEqual(new[] { "a" }, result); } [TestMethod] public void ScoopRealisticBinFormat() { // Scoop manifests: ["app.exe", ["tool.exe", "alias", "--args"]] var result = Deserialize("[\"app.exe\", [\"tool.exe\", \"alias\", \"--args\"]]"); CollectionAssert.AreEqual(new[] { "app.exe", "tool.exe" }, result); } [TestMethod] public void NestedObjectFollowedByString() { var result = Deserialize("[[{\"x\":1}, \"after\"]]"); CollectionAssert.AreEqual(new[] { "after" }, result); } [TestMethod] public void RecursiveNullThenNestedString() { // ReadFirstString must continue past null recursive result var result = Deserialize("[[[], [\"x\"]], \"y\"]"); CollectionAssert.AreEqual(new[] { "x", "y" }, result); } [TestMethod] public void AdjacentNestedWithEmptyBetween() { var result = Deserialize("[[\"a\"], [], [\"b\"]]"); CollectionAssert.AreEqual(new[] { "a", "b" }, result); } [TestMethod] public void NestedWithNonStringsThenDeeperString() { // ReadFirstString must skip 42, skip empty inner, then find "x" in deeper array var result = Deserialize("[[42, [], [\"x\"]], \"y\"]"); CollectionAssert.AreEqual(new[] { "x", "y" }, result); } } } ================================================ FILE: source/BulkCrapUninstallerTests/Functions/UninstallerRatingManagerTests.cs ================================================ using System; using System.IO; using BulkCrapUninstaller; using BulkCrapUninstaller.Functions.Ratings; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace BulkCrapUninstallerTests.Functions { [TestClass] public class UninstallerRatingManagerTests { private static readonly string[] TestEntryNames = {"Test_1", "Test_2", "Test_3", "Test_4"}; private UninstallerRatingManager _manager; [TestInitialize] public void TestInitialize() { _manager = new UninstallerRatingManager(1); } [TestCleanup] public void TestCleanup() { _manager?.ClearRatings(); } [TestMethod] public void RefreshStatsTest() { Assert.Inconclusive("Expensive, no need to always test"); _manager.FetchRatings(); if (_manager.RemoteRatingCount == 0) Assert.Fail(); } [TestMethod] public void GetRatingTest() { _manager.FetchRatings(); var rating = _manager.GetRating(TestEntryNames[0]); if (rating.IsEmpty) Assert.Fail(); } [TestMethod] public void SetMyRatingTest() { _manager.FetchRatings(); try { _manager.SetMyRating(null, UninstallerRating.Bad); Assert.Fail(); } catch (ArgumentNullException) { } try { _manager.SetMyRating(TestEntryNames[0], UninstallerRating.Unknown); Assert.Fail(); } catch (ArgumentException) { } _manager.SetMyRating(TestEntryNames[0], UninstallerRating.Good); Assert.AreEqual((int) UninstallerRating.Good, _manager.GetRating(TestEntryNames[0]).MyRating); var rating = _manager.GetRating("Test_SetMyRatingTest"); var newRating = rating.MyRating == (int) UninstallerRating.Bad ? UninstallerRating.Good : UninstallerRating.Bad; _manager.SetMyRating("Test_SetMyRatingTest", newRating); Assert.AreEqual((int) newRating, _manager.GetRating("Test_SetMyRatingTest").MyRating); } [TestMethod] public void SerializeDeserializeCasheTest() { _manager.FetchRatings(); var count = _manager.RemoteRatingCount + _manager.UserRatingCount; if (count == 0) Assert.Fail("No items received"); var filename = Path.Combine(Program.AssemblyLocation.FullName, "TestTempDir"); var dir = new DirectoryInfo(filename); dir.Create(); _manager.SerializeCache(dir); TestCleanup(); TestInitialize(); _manager.DeserializeCache(dir); Assert.AreEqual(count, _manager.RemoteRatingCount + _manager.UserRatingCount); } } } ================================================ FILE: source/BulkCrapUninstallerTests/Properties/AssemblyInfo.cs ================================================ using System.Reflection; 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("BulkCrapUninstallerTests")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("BulkCrapUninstallerTests")] [assembly: AssemblyCopyright("Copyright © 2015")] [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("c631efbe-0463-417d-aebe-a4be3e660c43")] // 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.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")] ================================================ FILE: source/Directory.Build.props ================================================ 6.1 https://github.com/Klocman/Bulk-Crap-Uninstaller Copyright Apache-2.0 © 2026 AnyCPU;x64;x86;ARM64 net8.0-windows10.0.18362.0 8.0 ..\..\bin\$(Configuration)\$(Platform)\ false false true true true LocalIntranet false false ..\app.manifest true 512 true false win-x86 win-x64 win-arm64 embedded full ExtendedDesignGuidelineRules.ruleset true False ================================================ FILE: source/GlobalAssemblyInfo.cs ================================================ using System.Diagnostics.CodeAnalysis; using System.Resources; [assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "Windows-only app")] [assembly: SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Address properly at some point? Almost all of these get logged")] [assembly: SuppressMessage("Style", "IDE0057:Use range operator", Justification = "Keep code portable")] [assembly: SuppressMessage("Style", "IDE0063:Use simple 'using' statement", Justification = "Keep code portable")] [assembly: SuppressMessage("Style", "IDE0090:Use 'new(...)'", Justification = "Keep code portable")] [assembly: SuppressMessage("Style", "IDE0066:Convert switch statement to expression", Justification = "Keep code portable")] [assembly: SuppressMessage("Performance", "CA1510:Use throw helper methods", Justification = "Keep code consistent with existing patterns")] [assembly: NeutralResourcesLanguage("en")] ================================================ FILE: source/HelperTools/HelperTools.cs ================================================ using System; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Text; using System.Text.RegularExpressions; using Microsoft.Win32.Interop; namespace Klocman { internal static partial class HelperTools { public static void SetupEncoding() { try { Console.OutputEncoding = Encoding.Unicode; } catch (IOException) { /*Old .NET v4 without support for unicode output*/ } } [GeneratedRegex(@"0x[\d\w]{8}")] private static partial Regex HrefRegex(); /// /// Try to extract the error code from an exception. The message is expected to contain a code in the format 0xXXXXXXXX /// otherwise HResult is returned as-is instead. /// public static ResultWin32 ExtractHrefCode(Exception error) { if (error == null) throw new ArgumentNullException(nameof(error)); var code = ExtractHrefCode(error.Message); if (code == ResultWin32.INVALID_ERROR_CODE) return (ResultWin32)error.HResult; return code; } /// /// Try to extract the error code from an error message. The message is expected to contain a code in the format 0xXXXXXXXX /// where X is a hexadecimal digit. If the code is not found or is invalid, ResultWin32.INVALID_ERROR_CODE is returned. /// public static ResultWin32 ExtractHrefCode(string errorMessage) { if (errorMessage == null) throw new ArgumentNullException(nameof(errorMessage)); var errorCode = HrefRegex().Match(errorMessage).Captures.FirstOrDefault()?.Value; if (string.IsNullOrEmpty(errorCode) || errorCode.Length < 8) return ResultWin32.INVALID_ERROR_CODE; int.TryParse(errorCode[2..], NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var errorNumber); var code = (ResultWin32)errorNumber; return Enum.IsDefined(code) ? code : ResultWin32.INVALID_ERROR_CODE; } /// /// Convert object to PropertyName: Value format for writing it to console. /// Only public properties with getters are processed. /// Can be written directly with Console.WriteLine for an empty line after object. /// /// Object to convert to string /// Provider used for converting values to strings public static string ObjectToConsoleOutput(object obj, IFormatProvider provider = null) { if (obj == null) throw new ArgumentNullException(nameof(obj)); provider ??= CultureInfo.InvariantCulture; var propInfos = obj.GetType() .GetProperties(BindingFlags.Instance | BindingFlags.Public) .Where(prop => prop.CanRead) .ToDictionary(prop => prop.Name, prop => prop.GetValue(obj, null)); return KeyValueListToConsoleOutput(propInfos, provider); } public static string KeyValueListToConsoleOutput(ICollection> propertyKeyValues, IFormatProvider provider = null) { if (propertyKeyValues == null) throw new ArgumentNullException(nameof(propertyKeyValues)); provider ??= CultureInfo.InvariantCulture; var maxLen = propertyKeyValues.Max(x => x.Key.Length) + 2; var sb = new StringBuilder(); foreach (var prop in propertyKeyValues) { sb.Append(prop.Key); sb.Append(':'); sb.Append(' ', maxLen - prop.Key.Length); if (prop.Value is string s) sb.Append(s.Replace("\r\n", " ").Replace('\n', ' ').Replace('\r', ' ')); else if (prop.Value is IConvertible convertible) sb.Append(convertible.ToString(provider)); else sb.Append(prop.Value); sb.AppendLine(); } return sb.ToString(); } } } ================================================ FILE: source/HelperTools/HelperTools.projitems ================================================  $(MSBuildAllProjects);$(MSBuildThisFileFullPath) true 73a9796d-334c-400c-87ac-1dfdd613266e Klocman ================================================ FILE: source/HelperTools/HelperTools.shproj ================================================ 73a9796d-334c-400c-87ac-1dfdd613266e 14.0 ================================================ FILE: source/HelperTools/LogWriter.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Diagnostics; using System.IO; using System.Reflection; using System.Text; namespace Klocman { internal sealed class LogWriter(string path) : StreamWriter(path, true, Encoding.UTF8) { private static LogWriter _currentLogger; public static void WriteExceptionToLog(Exception ex) { if (ex == null) throw new ArgumentNullException(nameof(ex)); WriteMessageToLog(ex.ToString()); } /// /// Writes a message to the log file with a UTC timestamp. /// public static void WriteMessageToLog(string message) { if (message == null) throw new ArgumentNullException(nameof(message)); StreamWriter writer = _currentLogger; try { var location = CreateLogFilenameForAssembly(Assembly.GetCallingAssembly()); if (writer == null || !writer.BaseStream.CanWrite) writer = new StreamWriter(location, true); writer.Write(DateTime.UtcNow.ToLongTimeString()); writer.Write(" - "); writer.WriteLine(message); } catch (Exception ex) { Console.WriteLine(@"Failed to write to log file:\n" + ex); } finally { if (writer != null && writer != _currentLogger) writer.Dispose(); } } private static string CreateLogFilenameForAssembly(Assembly assembly) { var location = assembly.Location; if (location.EndsWith(".exe", StringComparison.OrdinalIgnoreCase) || location.EndsWith(".dll", StringComparison.OrdinalIgnoreCase)) location = location.Remove(location.Length - 4); location += ".log"; return location; } protected override void Dispose(bool disposing) { base.Dispose(disposing); if (disposing) Disposed = true; } private bool Disposed { get; set; } /// /// Start logging to a file reflecting the calling assembly name. /// Hooks console out and error. Dispose before exiting. /// If logging is already active, it will be restarted with the new calling assembly name. /// public static LogWriter StartLogging() { _currentLogger?.Dispose(); var location = CreateLogFilenameForAssembly(Assembly.GetCallingAssembly()); return _currentLogger = StartLogging(location); } /// /// Start logging to a file. /// Hooks console out and error. Dispose before exiting. /// private static LogWriter StartLogging(string logPath) { try { // Limit log size to 100 kb var fileInfo = new FileInfo(logPath); if (fileInfo.Exists && fileInfo.Length > 1024 * 100) fileInfo.Delete(); // Create new log writer var logWriter = new LogWriter(logPath); // Make sure we can write to the file logWriter.WriteSeparator(); logWriter.WriteLine("Application startup"); logWriter.Flush(); Console.SetOut(logWriter); Console.SetError(logWriter); Trace.Listeners.Add(new TextWriterTraceListener(logWriter)); return logWriter; } catch (Exception ex) { // Ignore logging errors Console.WriteLine(ex); return null; } } public void WriteSeparator() { if (Disposed) return; base.WriteLine("--------------------------------------------------"); } public override void WriteLine(string value) { if (Disposed) return; value = DateTime.UtcNow.ToLongTimeString() + " - " + value; base.WriteLine(value); base.Flush(); } } } ================================================ FILE: source/HelperTools/ResultWin32.cs ================================================ /* Taken from https://www.pinvoke.net/default.aspx/Constants/WINERROR.html It is documented that you should NOT use the pinvoke GetLastError() due to the fact that the runtime makes it's own API calls without any notification to the application at all. And since most user-API calls are made through a call setup with DllImportAttribute, the .NET framework has made available a method that will record your call's ErrorCode until such time as you need to get it (although, most times, subsequent calls to other API's that you make will overwrite the previous - read ahead to find out why). Use Marshal.GetLastWin32Error() to get the last ErrorCode recorded by your most recent API call. You will also need to make sure you change SetLastError=true when you define your Pinvoke signature, unless you purposely don't want it or don't care or need the lasterror preserved. If you have questions on this remit to: http://www.paradisim.net in the FAQ forums or gabriel@paradisim.net. With this said, you can still use the following code to identify the errorcode: */ /******************************************************************************/ /* _ */ /* \`*-. */ /* ) _`-. */ /* . : `. . */ /* : _ ' \ */ /* ; *` _. `*-._ */ /* `-.-' `-. */ /* ; ` `. */ /* :. . \ */ /* . \ . : .-' . NABU Project */ /* ' `+.; ; ' : Microsoft.Win32.Interop Library */ /* : ' | ; ;-. Copyright 2005, adontz */ /* ; ' : :`-: _.`* ; */ /* .*' / .*' ; .*`- +' `*' */ /* `*-* `*-* `*-*' */ /* */ /******************************************************************************/ using System; using System.Runtime; using System.Runtime.InteropServices; using System.Reflection; namespace Microsoft.Win32.Interop { internal enum ResultWin32 { /// /// Failed to parse the code /// INVALID_ERROR_CODE = -1, /// /// The operation completed successfully. /// ERROR_SUCCESS = 0, /// /// Incorrect function. /// ERROR_INVALID_FUNCTION = 1, /// /// The system cannot find the file specified. /// ERROR_FILE_NOT_FOUND = 2, /// /// The system cannot find the path specified. /// ERROR_PATH_NOT_FOUND = 3, /// /// The system cannot open the file. /// ERROR_TOO_MANY_OPEN_FILES = 4, /// /// Access is denied. /// ERROR_ACCESS_DENIED = 5, /// /// The handle is invalid. /// ERROR_INVALID_HANDLE = 6, /// /// The storage control blocks were destroyed. /// ERROR_ARENA_TRASHED = 7, /// /// Not enough storage is available to process this command. /// ERROR_NOT_ENOUGH_MEMORY = 8, /// /// The storage control block address is invalid. /// ERROR_INVALID_BLOCK = 9, /// /// The environment is incorrect. /// ERROR_BAD_ENVIRONMENT = 10, /// /// An attempt was made to load a program with an incorrect format. /// ERROR_BAD_FORMAT = 11, /// /// The access code is invalid. /// ERROR_INVALID_ACCESS = 12, /// /// The data is invalid. /// ERROR_INVALID_DATA = 13, /// /// Not enough storage is available to complete this operation. /// ERROR_OUTOFMEMORY = 14, /// /// The system cannot find the drive specified. /// ERROR_INVALID_DRIVE = 15, /// /// The directory cannot be removed. /// ERROR_CURRENT_DIRECTORY = 16, /// /// The system cannot move the file to a different disk drive. /// ERROR_NOT_SAME_DEVICE = 17, /// /// There are no more files. /// ERROR_NO_MORE_FILES = 18, /// /// The media is write protected. /// ERROR_WRITE_PROTECT = 19, /// /// The system cannot find the device specified. /// ERROR_BAD_UNIT = 20, /// /// The device is not ready. /// ERROR_NOT_READY = 21, /// /// The device does not recognize the command. /// ERROR_BAD_COMMAND = 22, /// /// Data error (cyclic redundancy check). /// ERROR_CRC = 23, /// /// The program issued a command but the command length is incorrect. /// ERROR_BAD_LENGTH = 24, /// /// The drive cannot locate a specific area or track on the disk. /// ERROR_SEEK = 25, /// /// The specified disk or diskette cannot be accessed. /// ERROR_NOT_DOS_DISK = 26, /// /// The drive cannot find the sector requested. /// ERROR_SECTOR_NOT_FOUND = 27, /// /// The printer is out of paper. /// ERROR_OUT_OF_PAPER = 28, /// /// The system cannot write to the specified device. /// ERROR_WRITE_FAULT = 29, /// /// The system cannot read from the specified device. /// ERROR_READ_FAULT = 30, /// /// A device attached to the system is not functioning. /// ERROR_GEN_FAILURE = 31, /// /// The process cannot access the file because it is being used by another process. /// ERROR_SHARING_VIOLATION = 32, /// /// The process cannot access the file because another process has locked a portion of the file. /// ERROR_LOCK_VIOLATION = 33, /// /// The wrong diskette is in the drive. /// Insert %2 (Volume Serial Number: %3) into drive %1. /// ERROR_WRONG_DISK = 34, /// /// Too many files opened for sharing. /// ERROR_SHARING_BUFFER_EXCEEDED = 36, /// /// Reached the end of the file. /// ERROR_HANDLE_EOF = 38, /// /// The disk is full. /// ERROR_HANDLE_DISK_FULL = 39, /// /// The request is not supported. /// ERROR_NOT_SUPPORTED = 50, /// /// Windows cannot find the network path. Verify that the network path is correct and the destination computer is not busy or turned off. If Windows still cannot find the network path, contact your network administrator. /// ERROR_REM_NOT_LIST = 51, /// /// You were not connected because a duplicate name exists on the network. Go to System in Control Panel to change the computer name and try again. /// ERROR_DUP_NAME = 52, /// /// The network path was not found. /// ERROR_BAD_NETPATH = 53, /// /// The network is busy. /// ERROR_NETWORK_BUSY = 54, /// /// The specified network resource or device is no longer available. /// ERROR_DEV_NOT_EXIST = 55, /// /// The network BIOS command limit has been reached. /// ERROR_TOO_MANY_CMDS = 56, /// /// A network adapter hardware error occurred. /// ERROR_ADAP_HDW_ERR = 57, /// /// The specified server cannot perform the requested operation. /// ERROR_BAD_NET_RESP = 58, /// /// An unexpected network error occurred. /// ERROR_UNEXP_NET_ERR = 59, /// /// The remote adapter is not compatible. /// ERROR_BAD_REM_ADAP = 60, /// /// The printer queue is full. /// ERROR_PRINTQ_FULL = 61, /// /// Space to store the file waiting to be printed is not available on the server. /// ERROR_NO_SPOOL_SPACE = 62, /// /// Your file waiting to be printed was deleted. /// ERROR_PRINT_CANCELLED = 63, /// /// The specified network name is no longer available. /// ERROR_NETNAME_DELETED = 64, /// /// Network access is denied. /// ERROR_NETWORK_ACCESS_DENIED = 65, /// /// The network resource type is not correct. /// ERROR_BAD_DEV_TYPE = 66, /// /// The network name cannot be found. /// ERROR_BAD_NET_NAME = 67, /// /// The name limit for the local computer network adapter card was exceeded. /// ERROR_TOO_MANY_NAMES = 68, /// /// The network BIOS session limit was exceeded. /// ERROR_TOO_MANY_SESS = 69, /// /// The remote server has been paused or is in the process of being started. /// ERROR_SHARING_PAUSED = 70, /// /// No more connections can be made to this remote computer at this time because there are already as many connections as the computer can accept. /// ERROR_REQ_NOT_ACCEP = 71, /// /// The specified printer or disk device has been paused. /// ERROR_REDIR_PAUSED = 72, /// /// The file exists. /// ERROR_FILE_EXISTS = 80, /// /// The directory or file cannot be created. /// ERROR_CANNOT_MAKE = 82, /// /// Fail on INT 24. /// ERROR_FAIL_I24 = 83, /// /// Storage to process this request is not available. /// ERROR_OUT_OF_STRUCTURES = 84, /// /// The local device name is already in use. /// ERROR_ALREADY_ASSIGNED = 85, /// /// The specified network password is not correct. /// ERROR_INVALID_PASSWORD = 86, /// /// The parameter is incorrect. /// ERROR_INVALID_PARAMETER = 87, /// /// A write fault occurred on the network. /// ERROR_NET_WRITE_FAULT = 88, /// /// The system cannot start another process at this time. /// ERROR_NO_PROC_SLOTS = 89, /// /// Cannot create another system semaphore. /// ERROR_TOO_MANY_SEMAPHORES = 100, /// /// The exclusive semaphore is owned by another process. /// ERROR_EXCL_SEM_ALREADY_OWNED = 101, /// /// The semaphore is set and cannot be closed. /// ERROR_SEM_IS_SET = 102, /// /// The semaphore cannot be set again. /// ERROR_TOO_MANY_SEM_REQUESTS = 103, /// /// Cannot request exclusive semaphores at interrupt time. /// ERROR_INVALID_AT_INTERRUPT_TIME = 104, /// /// The previous ownership of this semaphore has ended. /// ERROR_SEM_OWNER_DIED = 105, /// /// Insert the diskette for drive %1. /// ERROR_SEM_USER_LIMIT = 106, /// /// The program stopped because an alternate diskette was not inserted. /// ERROR_DISK_CHANGE = 107, /// /// The disk is in use or locked by another process. /// ERROR_DRIVE_LOCKED = 108, /// /// The pipe has been ended. /// ERROR_BROKEN_PIPE = 109, /// /// The system cannot open the device or file specified. /// ERROR_OPEN_FAILED = 110, /// /// The file name is too long. /// ERROR_BUFFER_OVERFLOW = 111, /// /// There is not enough space on the disk. /// ERROR_DISK_FULL = 112, /// /// No more internal file identifiers available. /// ERROR_NO_MORE_SEARCH_HANDLES = 113, /// /// The target internal file identifier is incorrect. /// ERROR_INVALID_TARGET_HANDLE = 114, /// /// The IOCTL call made by the application program is not correct. /// ERROR_INVALID_CATEGORY = 117, /// /// The verify-on-write switch parameter value is not correct. /// ERROR_INVALID_VERIFY_SWITCH = 118, /// /// The system does not support the command requested. /// ERROR_BAD_DRIVER_LEVEL = 119, /// /// This function is not supported on this system. /// ERROR_CALL_NOT_IMPLEMENTED = 120, /// /// The semaphore timeout period has expired. /// ERROR_SEM_TIMEOUT = 121, /// /// The data area passed to a system call is too small. /// ERROR_INSUFFICIENT_BUFFER = 122, /// /// The filename, directory name, or volume label syntax is incorrect. /// ERROR_INVALID_NAME = 123, /// /// The system call level is not correct. /// ERROR_INVALID_LEVEL = 124, /// /// The disk has no volume label. /// ERROR_NO_VOLUME_LABEL = 125, /// /// The specified module could not be found. /// ERROR_MOD_NOT_FOUND = 126, /// /// The specified procedure could not be found. /// ERROR_PROC_NOT_FOUND = 127, /// /// There are no child processes to wait for. /// ERROR_WAIT_NO_CHILDREN = 128, /// /// The %1 application cannot be run in Win32 mode. /// ERROR_CHILD_NOT_COMPLETE = 129, /// /// Attempt to use a file handle to an open disk partition for an operation other than raw disk I/O. /// ERROR_DIRECT_ACCESS_HANDLE = 130, /// /// An attempt was made to move the file pointer before the beginning of the file. /// ERROR_NEGATIVE_SEEK = 131, /// /// The file pointer cannot be set on the specified device or file. /// ERROR_SEEK_ON_DEVICE = 132, /// /// A JOIN or SUBST command cannot be used for a drive that contains previously joined drives. /// ERROR_IS_JOIN_TARGET = 133, /// /// An attempt was made to use a JOIN or SUBST command on a drive that has already been joined. /// ERROR_IS_JOINED = 134, /// /// An attempt was made to use a JOIN or SUBST command on a drive that has already been substituted. /// ERROR_IS_SUBSTED = 135, /// /// The system tried to delete the JOIN of a drive that is not joined. /// ERROR_NOT_JOINED = 136, /// /// The system tried to delete the substitution of a drive that is not substituted. /// ERROR_NOT_SUBSTED = 137, /// /// The system tried to join a drive to a directory on a joined drive. /// ERROR_JOIN_TO_JOIN = 138, /// /// The system tried to substitute a drive to a directory on a substituted drive. /// ERROR_SUBST_TO_SUBST = 139, /// /// The system tried to join a drive to a directory on a substituted drive. /// ERROR_JOIN_TO_SUBST = 140, /// /// The system tried to SUBST a drive to a directory on a joined drive. /// ERROR_SUBST_TO_JOIN = 141, /// /// The system cannot perform a JOIN or SUBST at this time. /// ERROR_BUSY_DRIVE = 142, /// /// The system cannot join or substitute a drive to or for a directory on the same drive. /// ERROR_SAME_DRIVE = 143, /// /// The directory is not a subdirectory of the root directory. /// ERROR_DIR_NOT_ROOT = 144, /// /// The directory is not empty. /// ERROR_DIR_NOT_EMPTY = 145, /// /// The path specified is being used in a substitute. /// ERROR_IS_SUBST_PATH = 146, /// /// Not enough resources are available to process this command. /// ERROR_IS_JOIN_PATH = 147, /// /// The path specified cannot be used at this time. /// ERROR_PATH_BUSY = 148, /// /// An attempt was made to join or substitute a drive for which a directory on the drive is the target of a previous substitute. /// ERROR_IS_SUBST_TARGET = 149, /// /// System trace information was not specified in your CONFIG.SYS file, or tracing is disallowed. /// ERROR_SYSTEM_TRACE = 150, /// /// The number of specified semaphore events for DosMuxSemWait is not correct. /// ERROR_INVALID_EVENT_COUNT = 151, /// /// DosMuxSemWait did not execute, too many semaphores are already set. /// ERROR_TOO_MANY_MUXWAITERS = 152, /// /// The DosMuxSemWait list is not correct. /// ERROR_INVALID_LIST_FORMAT = 153, /// /// The volume label you entered exceeds the label character limit of the target file system. /// ERROR_LABEL_TOO_Int32 = 154, /// /// Cannot create another thread. /// ERROR_TOO_MANY_TCBS = 155, /// /// The recipient process has refused the signal. /// ERROR_SIGNAL_REFUSED = 156, /// /// The segment is already discarded and cannot be locked. /// ERROR_DISCARDED = 157, /// /// The segment is already unlocked. /// ERROR_NOT_LOCKED = 158, /// /// The address for the thread ID is not correct. /// ERROR_BAD_THREADID_ADDR = 159, /// /// One or more arguments are not correct. /// ERROR_BAD_ARGUMENTS = 160, /// /// The specified path is invalid. /// ERROR_BAD_PATHNAME = 161, /// /// A signal is already pending. /// ERROR_SIGNAL_PENDING = 162, /// /// No more threads can be created in the system. /// ERROR_MAX_THRDS_REACHED = 164, /// /// Unable to lock a region of a file. /// ERROR_LOCK_FAILED = 167, /// /// The requested resource is in use. /// ERROR_BUSY = 170, /// /// A lock request was not outstanding for the supplied cancel region. /// ERROR_CANCEL_VIOLATION = 173, /// /// The file system does not support atomic changes to the lock type. /// ERROR_ATOMIC_LOCKS_NOT_SUPPORTED = 174, /// /// The system detected a segment number that was not correct. /// ERROR_INVALID_SEGMENT_NUMBER = 180, /// /// The operating system cannot run %1. /// ERROR_INVALID_ORDINAL = 182, /// /// Cannot create a file when that file already exists. /// ERROR_ALREADY_EXISTS = 183, /// /// The flag passed is not correct. /// ERROR_INVALID_FLAG_NUMBER = 186, /// /// The specified system semaphore name was not found. /// ERROR_SEM_NOT_FOUND = 187, /// /// The operating system cannot run %1. /// ERROR_INVALID_STARTING_CODESEG = 188, /// /// The operating system cannot run %1. /// ERROR_INVALID_STACKSEG = 189, /// /// The operating system cannot run %1. /// ERROR_INVALID_MODULETYPE = 190, /// /// Cannot run %1 in Win32 mode. /// ERROR_INVALID_EXE_SIGNATURE = 191, /// /// The operating system cannot run %1. /// ERROR_EXE_MARKED_INVALID = 192, /// /// %1 is not a valid Win32 application. /// ERROR_BAD_EXE_FORMAT = 193, /// /// The operating system cannot run %1. /// ERROR_ITERATED_DATA_EXCEEDS_64k = 194, /// /// The operating system cannot run %1. /// ERROR_INVALID_MINALLOCSIZE = 195, /// /// The operating system cannot run this application program. /// ERROR_DYNLINK_FROM_INVALID_RING = 196, /// /// The operating system is not presently configured to run this application. /// ERROR_IOPL_NOT_ENABLED = 197, /// /// The operating system cannot run %1. /// ERROR_INVALID_SEGDPL = 198, /// /// The operating system cannot run this application program. /// ERROR_AUTODATASEG_EXCEEDS_64k = 199, /// /// The code segment cannot be greater than or equal to 64K. /// ERROR_RING2SEG_MUST_BE_MOVABLE = 200, /// /// The operating system cannot run %1. /// ERROR_RELOC_CHAIN_XEEDS_SEGLIM = 201, /// /// The operating system cannot run %1. /// ERROR_INFLOOP_IN_RELOC_CHAIN = 202, /// /// The system could not find the environment option that was entered. /// ERROR_ENVVAR_NOT_FOUND = 203, /// /// No process in the command subtree has a signal handler. /// ERROR_NO_SIGNAL_SENT = 205, /// /// The filename or extension is too long. /// ERROR_FILENAME_EXCED_RANGE = 206, /// /// The ring 2 stack is in use. /// ERROR_RING2_STACK_IN_USE = 207, /// /// The global filename characters, * or ?, are entered incorrectly or too many global filename characters are specified. /// ERROR_META_EXPANSION_TOO_Int32 = 208, /// /// The signal being posted is not correct. /// ERROR_INVALID_SIGNAL_NUMBER = 209, /// /// The signal handler cannot be set. /// ERROR_THREAD_1_INACTIVE = 210, /// /// The segment is locked and cannot be reallocated. /// ERROR_LOCKED = 212, /// /// Too many dynamic-link modules are attached to this program or dynamic-link module. /// ERROR_TOO_MANY_MODULES = 214, /// /// Cannot nest calls to LoadModule. /// ERROR_NESTING_NOT_ALLOWED = 215, /// /// The image file %1 is valid, but is for a machine type other than the current machine. /// ERROR_EXE_MACHINE_TYPE_MISMATCH = 216, /// /// No information avialable. /// ERROR_EXE_CANNOT_MODIFY_SIGNED_BINARY = 217, /// /// No information avialable. /// ERROR_EXE_CANNOT_MODIFY_STRONG_SIGNED_BINARY = 218, /// /// The pipe state is invalid. /// ERROR_BAD_PIPE = 230, /// /// All pipe instances are busy. /// ERROR_PIPE_BUSY = 231, /// /// The pipe is being closed. /// ERROR_NO_DATA = 232, /// /// No process is on the other end of the pipe. /// ERROR_PIPE_NOT_CONNECTED = 233, /// /// More data is available. /// ERROR_MORE_DATA = 234, /// /// The session was canceled. /// ERROR_VC_DISCONNECTED = 240, /// /// The specified extended attribute name was invalid. /// ERROR_INVALID_EA_NAME = 254, /// /// The extended attributes are inconsistent. /// ERROR_EA_LIST_INCONSISTENT = 255, /// /// The wait operation timed out. /// WAIT_TIMEOUT = 258, /// /// No more data is available. /// ERROR_NO_MORE_ITEMS = 259, /// /// The copy functions cannot be used. /// ERROR_CANNOT_COPY = 266, /// /// The directory name is invalid. /// ERROR_DIRECTORY = 267, /// /// The extended attributes did not fit in the buffer. /// ERROR_EAS_DIDNT_FIT = 275, /// /// The extended attribute file on the mounted file system is corrupt. /// ERROR_EA_FILE_CORRUPT = 276, /// /// The extended attribute table file is full. /// ERROR_EA_TABLE_FULL = 277, /// /// The specified extended attribute handle is invalid. /// ERROR_INVALID_EA_HANDLE = 278, /// /// The mounted file system does not support extended attributes. /// ERROR_EAS_NOT_SUPPORTED = 282, /// /// Attempt to release mutex not owned by caller. /// ERROR_NOT_OWNER = 288, /// /// Too many posts were made to a semaphore. /// ERROR_TOO_MANY_POSTS = 298, /// /// Only part of a ReadProcessMemory or WriteProcessMemory request was completed. /// ERROR_PARTIAL_COPY = 299, /// /// The oplock request is denied. /// ERROR_OPLOCK_NOT_GRANTED = 300, /// /// An invalid oplock acknowledgment was received by the system. /// ERROR_INVALID_OPLOCK_PROTOCOL = 301, /// /// The volume is too fragmented to complete this operation. /// ERROR_DISK_TOO_FRAGMENTED = 302, /// /// The file cannot be opened because it is in the process of being deleted. /// ERROR_DELETE_PENDING = 303, /// /// The system cannot find message text for message number 0x%1 in the message file for %2. /// ERROR_MR_MID_NOT_FOUND = 317, /// /// No information avialable. /// ERROR_SCOPE_NOT_FOUND = 318, /// /// Attempt to access invalid address. /// ERROR_INVALID_ADDRESS = 487, /// /// Arithmetic result exceeded 32 bits. /// ERROR_ARITHMETIC_OVERFLOW = 534, /// /// There is a process on other end of the pipe. /// ERROR_PIPE_CONNECTED = 535, /// /// Waiting for a process to open the other end of the pipe. /// ERROR_PIPE_LISTENING = 536, /// /// Access to the extended attribute was denied. /// ERROR_EA_ACCESS_DENIED = 994, /// /// The I/O operation has been aborted because of either a thread exit or an application request. /// ERROR_OPERATION_ABORTED = 995, /// /// Overlapped I/O event is not in a signaled state. /// ERROR_IO_INCOMPLETE = 996, /// /// Overlapped I/O operation is in progress. /// ERROR_IO_PENDING = 997, /// /// Invalid access to memory location. /// ERROR_NOACCESS = 998, /// /// Error performing inpage operation. /// ERROR_SWAPERROR = 999, /// /// Recursion too deep, the stack overflowed. /// ERROR_STACK_OVERFLOW = 1001, /// /// The window cannot act on the sent message. /// ERROR_INVALID_MESSAGE = 1002, /// /// Cannot complete this function. /// ERROR_CAN_NOT_COMPLETE = 1003, /// /// Invalid flags. /// ERROR_INVALID_FLAGS = 1004, /// /// The volume does not contain a recognized file system. /// Please make sure that all required file system drivers are loaded and that the volume is not corrupted. /// ERROR_UNRECOGNIZED_VOLUME = 1005, /// /// The volume for a file has been externally altered so that the opened file is no longer valid. /// ERROR_FILE_INVALID = 1006, /// /// The requested operation cannot be performed in full-screen mode. /// ERROR_FULLSCREEN_MODE = 1007, /// /// An attempt was made to reference a token that does not exist. /// ERROR_NO_TOKEN = 1008, /// /// The configuration registry database is corrupt. /// ERROR_BADDB = 1009, /// /// The configuration registry key is invalid. /// ERROR_BADKEY = 1010, /// /// The configuration registry key could not be opened. /// ERROR_CANTOPEN = 1011, /// /// The configuration registry key could not be read. /// ERROR_CANTREAD = 1012, /// /// The configuration registry key could not be written. /// ERROR_CANTWRITE = 1013, /// /// One of the files in the registry database had to be recovered by use of a log or alternate copy. The recovery was successful. /// ERROR_REGISTRY_RECOVERED = 1014, /// /// The registry is corrupted. The structure of one of the files containing registry data is corrupted, or the system's memory image of the file is corrupted, or the file could not be recovered because the alternate copy or log was absent or corrupted. /// ERROR_REGISTRY_CORRUPT = 1015, /// /// An I/O operation initiated by the registry failed unrecoverably. The registry could not read in, or write out, or flush, one of the files that contain the system's image of the registry. /// ERROR_REGISTRY_IO_FAILED = 1016, /// /// The system has attempted to load or restore a file into the registry, but the specified file is not in a registry file format. /// ERROR_NOT_REGISTRY_FILE = 1017, /// /// Illegal operation attempted on a registry key that has been marked for deletion. /// ERROR_KEY_DELETED = 1018, /// /// System could not allocate the required space in a registry log. /// ERROR_NO_LOG_SPACE = 1019, /// /// Cannot create a symbolic link in a registry key that already has subkeys or values. /// ERROR_KEY_HAS_CHILDREN = 1020, /// /// Cannot create a stable subkey under a volatile parent key. /// ERROR_CHILD_MUST_BE_VOLATILE = 1021, /// /// A notify change request is being completed and the information is not being returned in the caller's buffer. The caller now needs to enumerate the files to find the changes. /// ERROR_NOTIFY_ENUM_DIR = 1022, /// /// A stop control has been sent to a service that other running services are dependent on. /// ERROR_DEPENDENT_SERVICES_RUNNING = 1051, /// /// The requested control is not valid for this service. /// ERROR_INVALID_SERVICE_CONTROL = 1052, /// /// The service did not respond to the start or control request in a timely fashion. /// ERROR_SERVICE_REQUEST_TIMEOUT = 1053, /// /// A thread could not be created for the service. /// ERROR_SERVICE_NO_THREAD = 1054, /// /// The service database is locked. /// ERROR_SERVICE_DATABASE_LOCKED = 1055, /// /// An instance of the service is already running. /// ERROR_SERVICE_ALREADY_RUNNING = 1056, /// /// The account name is invalid or does not exist, or the password is invalid for the account name specified. /// ERROR_INVALID_SERVICE_ACCOUNT = 1057, /// /// The service cannot be started, either because it is disabled or because it has no enabled devices associated with it. /// ERROR_SERVICE_DISABLED = 1058, /// /// Circular service dependency was specified. /// ERROR_CIRCULAR_DEPENDENCY = 1059, /// /// The specified service does not exist as an installed service. /// ERROR_SERVICE_DOES_NOT_EXIST = 1060, /// /// The service cannot accept control messages at this time. /// ERROR_SERVICE_CANNOT_ACCEPT_CTRL = 1061, /// /// The service has not been started. /// ERROR_SERVICE_NOT_ACTIVE = 1062, /// /// The service process could not connect to the service controller. /// ERROR_FAILED_SERVICE_CONTROLLER_CONNECT = 1063, /// /// An exception occurred in the service when handling the control request. /// ERROR_EXCEPTION_IN_SERVICE = 1064, /// /// The database specified does not exist. /// ERROR_DATABASE_DOES_NOT_EXIST = 1065, /// /// The service has returned a service-specific error code. /// ERROR_SERVICE_SPECIFIC_ERROR = 1066, /// /// The process terminated unexpectedly. /// ERROR_PROCESS_ABORTED = 1067, /// /// The dependency service or group failed to start. /// ERROR_SERVICE_DEPENDENCY_FAIL = 1068, /// /// The service did not start due to a logon failure. /// ERROR_SERVICE_LOGON_FAILED = 1069, /// /// After starting, the service hung in a start-pending state. /// ERROR_SERVICE_START_HANG = 1070, /// /// The specified service database lock is invalid. /// ERROR_INVALID_SERVICE_LOCK = 1071, /// /// The specified service has been marked for deletion. /// ERROR_SERVICE_MARKED_FOR_DELETE = 1072, /// /// The specified service already exists. /// ERROR_SERVICE_EXISTS = 1073, /// /// The system is currently running with the last-known-good configuration. /// ERROR_ALREADY_RUNNING_LKG = 1074, /// /// The dependency service does not exist or has been marked for deletion. /// ERROR_SERVICE_DEPENDENCY_DELETED = 1075, /// /// The current boot has already been accepted for use as the last-known-good control set. /// ERROR_BOOT_ALREADY_ACCEPTED = 1076, /// /// No attempts to start the service have been made since the last boot. /// ERROR_SERVICE_NEVER_STARTED = 1077, /// /// The name is already in use as either a service name or a service display name. /// ERROR_DUPLICATE_SERVICE_NAME = 1078, /// /// The account specified for this service is different from the account specified for other services running in the same process. /// ERROR_DIFFERENT_SERVICE_ACCOUNT = 1079, /// /// Failure actions can only be set for Win32 services, not for drivers. /// ERROR_CANNOT_DETECT_DRIVER_FAILURE = 1080, /// /// This service runs in the same process as the service control manager. /// Therefore, the service control manager cannot take action if this service's process terminates unexpectedly. /// ERROR_CANNOT_DETECT_PROCESS_ABORT = 1081, /// /// No recovery program has been configured for this service. /// ERROR_NO_RECOVERY_PROGRAM = 1082, /// /// The executable program that this service is configured to run in does not implement the service. /// ERROR_SERVICE_NOT_IN_EXE = 1083, /// /// This service cannot be started in Safe Mode /// ERROR_NOT_SAFEBOOT_SERVICE = 1084, /// /// The physical end of the tape has been reached. /// ERROR_END_OF_MEDIA = 1100, /// /// A tape access reached a filemark. /// ERROR_FILEMARK_DETECTED = 1101, /// /// The beginning of the tape or a partition was encountered. /// ERROR_BEGINNING_OF_MEDIA = 1102, /// /// A tape access reached the end of a set of files. /// ERROR_SETMARK_DETECTED = 1103, /// /// No more data is on the tape. /// ERROR_NO_DATA_DETECTED = 1104, /// /// Tape could not be partitioned. /// ERROR_PARTITION_FAILURE = 1105, /// /// When accessing a new tape of a multivolume partition, the current block size is incorrect. /// ERROR_INVALID_BLOCK_LENGTH = 1106, /// /// Tape partition information could not be found when loading a tape. /// ERROR_DEVICE_NOT_PARTITIONED = 1107, /// /// Unable to lock the media eject mechanism. /// ERROR_UNABLE_TO_LOCK_MEDIA = 1108, /// /// Unable to unload the media. /// ERROR_UNABLE_TO_UNLOAD_MEDIA = 1109, /// /// The media in the drive may have changed. /// ERROR_MEDIA_CHANGED = 1110, /// /// The I/O bus was reset. /// ERROR_BUS_RESET = 1111, /// /// No media in drive. /// ERROR_NO_MEDIA_IN_DRIVE = 1112, /// /// No mapping for the Unicode character exists in the target multi-byte code page. /// ERROR_NO_UNICODE_TRANSLATION = 1113, /// /// A dynamic link library (DLL) initialization routine failed. /// ERROR_DLL_INIT_FAILED = 1114, /// /// A system shutdown is in progress. /// ERROR_SHUTDOWN_IN_PROGRESS = 1115, /// /// Unable to abort the system shutdown because no shutdown was in progress. /// ERROR_NO_SHUTDOWN_IN_PROGRESS = 1116, /// /// The request could not be performed because of an I/O device error. /// ERROR_IO_DEVICE = 1117, /// /// No serial device was successfully initialized. The serial driver will unload. /// ERROR_SERIAL_NO_DEVICE = 1118, /// /// Unable to open a device that was sharing an interrupt request (IRQ) with other devices. At least one other device that uses that IRQ was already opened. /// ERROR_IRQ_BUSY = 1119, /// /// A serial I/O operation was completed by another write to the serial port. /// (The IOCTL_SERIAL_XOFF_COUNTER reached zero.) /// ERROR_MORE_WRITES = 1120, /// /// A serial I/O operation completed because the timeout period expired. /// (The IOCTL_SERIAL_XOFF_COUNTER did not reach zero.) /// ERROR_COUNTER_TIMEOUT = 1121, /// /// No ID address mark was found on the floppy disk. /// ERROR_FLOPPY_ID_MARK_NOT_FOUND = 1122, /// /// Mismatch between the floppy disk sector ID field and the floppy disk controller track address. /// ERROR_FLOPPY_WRONG_CYLINDER = 1123, /// /// The floppy disk controller reported an error that is not recognized by the floppy disk driver. /// ERROR_FLOPPY_UNKNOWN_ERROR = 1124, /// /// The floppy disk controller returned inconsistent results in its registers. /// ERROR_FLOPPY_BAD_REGISTERS = 1125, /// /// While accessing the hard disk, a recalibrate operation failed, even after retries. /// ERROR_DISK_RECALIBRATE_FAILED = 1126, /// /// While accessing the hard disk, a disk operation failed even after retries. /// ERROR_DISK_OPERATION_FAILED = 1127, /// /// While accessing the hard disk, a disk controller reset was needed, but even that failed. /// ERROR_DISK_RESET_FAILED = 1128, /// /// Physical end of tape encountered. /// ERROR_EOM_OVERFLOW = 1129, /// /// Not enough server storage is available to process this command. /// ERROR_NOT_ENOUGH_SERVER_MEMORY = 1130, /// /// A potential deadlock condition has been detected. /// ERROR_POSSIBLE_DEADLOCK = 1131, /// /// The base address or the file offset specified does not have the proper alignment. /// ERROR_MAPPED_ALIGNMENT = 1132, /// /// An attempt to change the system power state was vetoed by another application or driver. /// ERROR_SET_POWER_STATE_VETOED = 1140, /// /// The system BIOS failed an attempt to change the system power state. /// ERROR_SET_POWER_STATE_FAILED = 1141, /// /// An attempt was made to create more links on a file than the file system supports. /// ERROR_TOO_MANY_LINKS = 1142, /// /// The specified program requires a newer version of Windows. /// ERROR_OLD_WIN_VERSION = 1150, /// /// The specified program is not a Windows or MS-DOS program. /// ERROR_APP_WRONG_OS = 1151, /// /// Cannot start more than one instance of the specified program. /// ERROR_SINGLE_INSTANCE_APP = 1152, /// /// The specified program was written for an earlier version of Windows. /// ERROR_RMODE_APP = 1153, /// /// One of the library files needed to run this application is damaged. /// ERROR_INVALID_DLL = 1154, /// /// No application is associated with the specified file for this operation. /// ERROR_NO_ASSOCIATION = 1155, /// /// An error occurred in sending the command to the application. /// ERROR_DDE_FAIL = 1156, /// /// One of the library files needed to run this application cannot be found. /// ERROR_DLL_NOT_FOUND = 1157, /// /// The current process has used all of its system allowance of handles for Window Manager objects. /// ERROR_NO_MORE_USER_HANDLES = 1158, /// /// The message can be used only with synchronous operations. /// ERROR_MESSAGE_SYNC_ONLY = 1159, /// /// The indicated source element has no media. /// ERROR_SOURCE_ELEMENT_EMPTY = 1160, /// /// The indicated destination element already contains media. /// ERROR_DESTINATION_ELEMENT_FULL = 1161, /// /// The indicated element does not exist. /// ERROR_ILLEGAL_ELEMENT_ADDRESS = 1162, /// /// The indicated element is part of a magazine that is not present. /// ERROR_MAGAZINE_NOT_PRESENT = 1163, /// /// The indicated device requires reinitialization due to hardware errors. /// ERROR_DEVICE_REINITIALIZATION_NEEDED = 1164, /// /// The device has indicated that cleaning is required before further operations are attempted. /// ERROR_DEVICE_REQUIRES_CLEANING = 1165, /// /// The device has indicated that its door is open. /// ERROR_DEVICE_DOOR_OPEN = 1166, /// /// The device is not connected. /// ERROR_DEVICE_NOT_CONNECTED = 1167, /// /// Element not found. /// ERROR_NOT_FOUND = 1168, /// /// There was no match for the specified key in the index. /// ERROR_NO_MATCH = 1169, /// /// The property set specified does not exist on the object. /// ERROR_SET_NOT_FOUND = 1170, /// /// The point passed to GetMouseMovePoints is not in the buffer. /// ERROR_POINT_NOT_FOUND = 1171, /// /// The tracking (workstation) service is not running. /// ERROR_NO_TRACKING_SERVICE = 1172, /// /// The Volume ID could not be found. /// ERROR_NO_VOLUME_ID = 1173, /// /// Unable to remove the file to be replaced. /// ERROR_UNABLE_TO_REMOVE_REPLACED = 1175, /// /// Unable to move the replacement file to the file to be replaced. The file to be replaced has retained its original name. /// ERROR_UNABLE_TO_MOVE_REPLACEMENT = 1176, /// /// Unable to move the replacement file to the file to be replaced. The file to be replaced has been renamed using the backup name. /// ERROR_UNABLE_TO_MOVE_REPLACEMENT_2 = 1177, /// /// The volume change journal is being deleted. /// ERROR_JOURNAL_DELETE_IN_PROGRESS = 1178, /// /// The volume change journal is not active. /// ERROR_JOURNAL_NOT_ACTIVE = 1179, /// /// A file was found, but it may not be the correct file. /// ERROR_POTENTIAL_FILE_FOUND = 1180, /// /// The journal entry has been deleted from the journal. /// ERROR_JOURNAL_ENTRY_DELETED = 1181, /// /// The specified device name is invalid. /// ERROR_BAD_DEVICE = 1200, /// /// The device is not currently connected but it is a remembered connection. /// ERROR_CONNECTION_UNAVAIL = 1201, /// /// The local device name has a remembered connection to another network resource. /// ERROR_DEVICE_ALREADY_REMEMBERED = 1202, /// /// No network provider accepted the given network path. /// ERROR_NO_NET_OR_BAD_PATH = 1203, /// /// The specified network provider name is invalid. /// ERROR_BAD_PROVIDER = 1204, /// /// Unable to open the network connection profile. /// ERROR_CANNOT_OPEN_PROFILE = 1205, /// /// The network connection profile is corrupted. /// ERROR_BAD_PROFILE = 1206, /// /// Cannot enumerate a noncontainer. /// ERROR_NOT_CONTAINER = 1207, /// /// An extended error has occurred. /// ERROR_EXTENDED_ERROR = 1208, /// /// The format of the specified group name is invalid. /// ERROR_INVALID_GROUPNAME = 1209, /// /// The format of the specified computer name is invalid. /// ERROR_INVALID_COMPUTERNAME = 1210, /// /// The format of the specified event name is invalid. /// ERROR_INVALID_EVENTNAME = 1211, /// /// The format of the specified domain name is invalid. /// ERROR_INVALID_DOMAINNAME = 1212, /// /// The format of the specified service name is invalid. /// ERROR_INVALID_SERVICENAME = 1213, /// /// The format of the specified network name is invalid. /// ERROR_INVALID_NETNAME = 1214, /// /// The format of the specified share name is invalid. /// ERROR_INVALID_SHARENAME = 1215, /// /// The format of the specified password is invalid. /// ERROR_INVALID_PASSUInt16NAME = 1216, /// /// The format of the specified message name is invalid. /// ERROR_INVALID_MESSAGENAME = 1217, /// /// The format of the specified message destination is invalid. /// ERROR_INVALID_MESSAGEDEST = 1218, /// /// Multiple connections to a server or shared resource by the same user, using more than one user name, are not allowed. Disconnect all previous connections to the server or shared resource and try again.. /// ERROR_SESSION_CREDENTIAL_CONFLICT = 1219, /// /// An attempt was made to establish a session to a network server, but there are already too many sessions established to that server. /// ERROR_REMOTE_SESSION_LIMIT_EXCEEDED = 1220, /// /// The workgroup or domain name is already in use by another computer on the network. /// ERROR_DUP_DOMAINNAME = 1221, /// /// The network is not present or not started. /// ERROR_NO_NETWORK = 1222, /// /// The operation was canceled by the user. /// ERROR_CANCELLED = 1223, /// /// The requested operation cannot be performed on a file with a user-mapped section open. /// ERROR_USER_MAPPED_FILE = 1224, /// /// The remote system refused the network connection. /// ERROR_CONNECTION_REFUSED = 1225, /// /// The network connection was gracefully closed. /// ERROR_GRACEFUL_DISCONNECT = 1226, /// /// The network transport endpoint already has an address associated with it. /// ERROR_ADDRESS_ALREADY_ASSOCIATED = 1227, /// /// An address has not yet been associated with the network endpoint. /// ERROR_ADDRESS_NOT_ASSOCIATED = 1228, /// /// An operation was attempted on a nonexistent network connection. /// ERROR_CONNECTION_INVALID = 1229, /// /// An invalid operation was attempted on an active network connection. /// ERROR_CONNECTION_ACTIVE = 1230, /// /// The network location cannot be reached. For information about network troubleshooting, see Windows Help. /// ERROR_NETWORK_UNREACHABLE = 1231, /// /// The network location cannot be reached. For information about network troubleshooting, see Windows Help. /// ERROR_HOST_UNREACHABLE = 1232, /// /// The network location cannot be reached. For information about network troubleshooting, see Windows Help. /// ERROR_PROTOCOL_UNREACHABLE = 1233, /// /// No service is operating at the destination network endpoint on the remote system. /// ERROR_PORT_UNREACHABLE = 1234, /// /// The request was aborted. /// ERROR_REQUEST_ABORTED = 1235, /// /// The network connection was aborted by the local system. /// ERROR_CONNECTION_ABORTED = 1236, /// /// The operation could not be completed. A retry should be performed. /// ERROR_RETRY = 1237, /// /// A connection to the server could not be made because the limit on the number of concurrent connections for this account has been reached. /// ERROR_CONNECTION_COUNT_LIMIT = 1238, /// /// Attempting to log in during an unauthorized time of day for this account. /// ERROR_LOGIN_TIME_RESTRICTION = 1239, /// /// The account is not authorized to log in from this station. /// ERROR_LOGIN_WKSTA_RESTRICTION = 1240, /// /// The network address could not be used for the operation requested. /// ERROR_INCORRECT_ADDRESS = 1241, /// /// The service is already registered. /// ERROR_ALREADY_REGISTERED = 1242, /// /// The specified service does not exist. /// ERROR_SERVICE_NOT_FOUND = 1243, /// /// The operation being requested was not performed because the user has not been authenticated. /// ERROR_NOT_AUTHENTICATED = 1244, /// /// The operation being requested was not performed because the user has not logged on to the network. /// The specified service does not exist. /// ERROR_NOT_LOGGED_ON = 1245, /// /// Continue with work in progress. /// ERROR_CONTINUE = 1246, /// /// An attempt was made to perform an initialization operation when initialization has already been completed. /// ERROR_ALREADY_INITIALIZED = 1247, /// /// No more local devices. /// ERROR_NO_MORE_DEVICES = 1248, /// /// The specified site does not exist. /// ERROR_NO_SUCH_SITE = 1249, /// /// A domain controller with the specified name already exists. /// ERROR_DOMAIN_CONTROLLER_EXISTS = 1250, /// /// This operation is supported only when you are connected to the server. /// ERROR_ONLY_IF_CONNECTED = 1251, /// /// The group policy framework should call the extension even if there are no changes. /// ERROR_OVERRIDE_NOCHANGES = 1252, /// /// The specified user does not have a valid profile. /// ERROR_BAD_USER_PROFILE = 1253, /// /// This operation is not supported on a Microsoft Small Business Server /// ERROR_NOT_SUPPORTED_ON_SBS = 1254, /// /// The server machine is shutting down. /// ERROR_SERVER_SHUTDOWN_IN_PROGRESS = 1255, /// /// The remote system is not available. For information about network troubleshooting, see Windows Help. /// ERROR_HOST_DOWN = 1256, /// /// The security identifier provided is not from an account domain. /// ERROR_NON_ACCOUNT_SID = 1257, /// /// The security identifier provided does not have a domain component. /// ERROR_NON_DOMAIN_SID = 1258, /// /// AppHelp dialog canceled thus preventing the application from starting. /// ERROR_APPHELP_BLOCK = 1259, /// /// Windows cannot open this program because it has been prevented by a software restriction policy. For more information, open Event Viewer or contact your system administrator. /// ERROR_ACCESS_DISABLED_BY_POLICY = 1260, /// /// A program attempt to use an invalid register value. Normally caused by an uninitialized register. This error is Itanium specific. /// ERROR_REG_NAT_CONSUMPTION = 1261, /// /// The share is currently offline or does not exist. /// ERROR_CSCSHARE_OFFLINE = 1262, /// /// The kerberos protocol encountered an error while validating the /// KDC certificate during smartcard logon. /// ERROR_PKINIT_FAILURE = 1263, /// /// The kerberos protocol encountered an error while attempting to utilize /// the smartcard subsystem. /// ERROR_SMARTCARD_SUBSYSTEM_FAILURE = 1264, /// /// The system detected a possible attempt to compromise security. Please ensure that you can contact the server that authenticated you. /// ERROR_DOWNGRADE_DETECTED = 1265, /// /// The machine is locked and can not be shut down without the force option. /// ERROR_MACHINE_LOCKED = 1271, /// /// An application-defined callback gave invalid data when called. /// ERROR_CALLBACK_SUPPLIED_INVALID_DATA = 1273, /// /// The group policy framework should call the extension in the synchronous foreground policy refresh. /// ERROR_SYNC_FOREGROUND_REFRESH_REQUIRED = 1274, /// /// This driver has been blocked from loading /// ERROR_DRIVER_BLOCKED = 1275, /// /// A dynamic link library (DLL) referenced a module that was neither a DLL nor the process's executable image. /// ERROR_INVALID_IMPORT_OF_NON_DLL = 1276, /// /// No information avialable. /// ERROR_ACCESS_DISABLED_WEBBLADE = 1277, /// /// No information avialable. /// ERROR_ACCESS_DISABLED_WEBBLADE_TAMPER = 1278, /// /// No information avialable. /// ERROR_RECOVERY_FAILURE = 1279, /// /// No information avialable. /// ERROR_ALREADY_FIBER = 1280, /// /// No information avialable. /// ERROR_ALREADY_THREAD = 1281, /// /// No information avialable. /// ERROR_STACK_BUFFER_OVERRUN = 1282, /// /// No information avialable. /// ERROR_PARAMETER_QUOTA_EXCEEDED = 1283, /// /// No information avialable. /// ERROR_DEBUGGER_INACTIVE = 1284, /// /// No information avialable. /// ERROR_DELAY_LOAD_FAILED = 1285, /// /// No information avialable. /// ERROR_VDM_DISALLOWED = 1286, /// /// Not all privileges referenced are assigned to the caller. /// ERROR_NOT_ALL_ASSIGNED = 1300, /// /// Some mapping between account names and security IDs was not done. /// ERROR_SOME_NOT_MAPPED = 1301, /// /// No system quota limits are specifically set for this account. /// ERROR_NO_QUOTAS_FOR_ACCOUNT = 1302, /// /// No encryption key is available. A well-known encryption key was returned. /// ERROR_LOCAL_USER_SESSION_KEY = 1303, /// /// The password is too complex to be converted to a LAN Manager password. The LAN Manager password returned is a NULL string. /// ERROR_NULL_LM_PASSUInt16 = 1304, /// /// The revision level is unknown. /// ERROR_UNKNOWN_REVISION = 1305, /// /// Indicates two revision levels are incompatible. /// ERROR_REVISION_MISMATCH = 1306, /// /// This security ID may not be assigned as the owner of this object. /// ERROR_INVALID_OWNER = 1307, /// /// This security ID may not be assigned as the primary group of an object. /// ERROR_INVALID_PRIMARY_GROUP = 1308, /// /// An attempt has been made to operate on an impersonation token by a thread that is not currently impersonating a client. /// ERROR_NO_IMPERSONATION_TOKEN = 1309, /// /// The group may not be disabled. /// ERROR_CANT_DISABLE_MANDATORY = 1310, /// /// There are currently no logon servers available to service the logon request. /// ERROR_NO_LOGON_SERVERS = 1311, /// /// A specified logon session does not exist. It may already have been terminated. /// ERROR_NO_SUCH_LOGON_SESSION = 1312, /// /// A specified privilege does not exist. /// ERROR_NO_SUCH_PRIVILEGE = 1313, /// /// A required privilege is not held by the client. /// ERROR_PRIVILEGE_NOT_HELD = 1314, /// /// The name provided is not a properly formed account name. /// ERROR_INVALID_ACCOUNT_NAME = 1315, /// /// The specified user already exists. /// ERROR_USER_EXISTS = 1316, /// /// The specified user does not exist. /// ERROR_NO_SUCH_USER = 1317, /// /// The specified group already exists. /// ERROR_GROUP_EXISTS = 1318, /// /// The specified group does not exist. /// ERROR_NO_SUCH_GROUP = 1319, /// /// Either the specified user account is already a member of the specified group, or the specified group cannot be deleted because it contains a member. /// ERROR_MEMBER_IN_GROUP = 1320, /// /// The specified user account is not a member of the specified group account. /// ERROR_MEMBER_NOT_IN_GROUP = 1321, /// /// The last remaining administration account cannot be disabled or deleted. /// ERROR_LAST_ADMIN = 1322, /// /// Unable to update the password. The value provided as the current password is incorrect. /// ERROR_WRONG_PASSWORD = 1323, /// /// Unable to update the password. The value provided for the new password contains values that are not allowed in passwords. /// ERROR_ILL_FORMED_PASSWORD = 1324, /// /// Unable to update the password. The value provided for the new password does not meet the length, complexity, or history requirement of the domain. /// ERROR_PASSWORD_RESTRICTION = 1325, /// /// Logon failure: unknown user name or bad password. /// ERROR_LOGON_FAILURE = 1326, /// /// Logon failure: user account restriction. Possible reasons are blank passwords not allowed, logon hour restrictions, or a policy restriction has been enforced. /// ERROR_ACCOUNT_RESTRICTION = 1327, /// /// Logon failure: account logon time restriction violation. /// ERROR_INVALID_LOGON_HOURS = 1328, /// /// Logon failure: user not allowed to log on to this computer. /// ERROR_INVALID_WORKSTATION = 1329, /// /// Logon failure: the specified account password has expired. /// ERROR_PASSUInt16_EXPIRED = 1330, /// /// Logon failure: account currently disabled. /// ERROR_ACCOUNT_DISABLED = 1331, /// /// No mapping between account names and security IDs was done. /// ERROR_NONE_MAPPED = 1332, /// /// Too many local user identifiers (LUIDs) were requested at one time. /// ERROR_TOO_MANY_LUIDS_REQUESTED = 1333, /// /// No more local user identifiers (LUIDs) are available. /// ERROR_LUIDS_EXHAUSTED = 1334, /// /// The subauthority part of a security ID is invalid for this particular use. /// ERROR_INVALID_SUB_AUTHORITY = 1335, /// /// The access control list (ACL) structure is invalid. /// ERROR_INVALID_ACL = 1336, /// /// The security ID structure is invalid. /// ERROR_INVALID_SID = 1337, /// /// The security descriptor structure is invalid. /// ERROR_INVALID_SECURITY_DESCR = 1338, /// /// The inherited access control list (ACL) or access control entry (ACE) could not be built. /// ERROR_BAD_INHERITANCE_ACL = 1340, /// /// The server is currently disabled. /// ERROR_SERVER_DISABLED = 1341, /// /// The server is currently enabled. /// ERROR_SERVER_NOT_DISABLED = 1342, /// /// The value provided was an invalid value for an identifier authority. /// ERROR_INVALID_ID_AUTHORITY = 1343, /// /// No more memory is available for security information updates. /// ERROR_ALLOTTED_SPACE_EXCEEDED = 1344, /// /// The specified attributes are invalid, or incompatible with the attributes for the group as a whole. /// ERROR_INVALID_GROUP_ATTRIBUTES = 1345, /// /// Either a required impersonation level was not provided, or the provided impersonation level is invalid. /// ERROR_BAD_IMPERSONATION_LEVEL = 1346, /// /// Cannot open an anonymous level security token. /// ERROR_CANT_OPEN_ANONYMOUS = 1347, /// /// The validation information class requested was invalid. /// ERROR_BAD_VALIDATION_CLASS = 1348, /// /// The type of the token is inappropriate for its attempted use. /// ERROR_BAD_TOKEN_TYPE = 1349, /// /// Unable to perform a security operation on an object that has no associated security. /// ERROR_NO_SECURITY_ON_OBJECT = 1350, /// /// Configuration information could not be read from the domain controller, either because the machine is unavailable, or access has been denied. /// ERROR_CANT_ACCESS_DOMAIN_INFO = 1351, /// /// The security account manager (SAM) or local security authority (LSA) server was in the wrong state to perform the security operation. /// ERROR_INVALID_SERVER_STATE = 1352, /// /// The domain was in the wrong state to perform the security operation. /// ERROR_INVALID_DOMAIN_STATE = 1353, /// /// This operation is only allowed for the Primary Domain Controller of the domain. /// ERROR_INVALID_DOMAIN_ROLE = 1354, /// /// The specified domain either does not exist or could not be contacted. /// ERROR_NO_SUCH_DOMAIN = 1355, /// /// The specified domain already exists. /// ERROR_DOMAIN_EXISTS = 1356, /// /// An attempt was made to exceed the limit on the number of domains per server. /// ERROR_DOMAIN_LIMIT_EXCEEDED = 1357, /// /// Unable to complete the requested operation because of either a catastrophic media failure or a data structure corruption on the disk. /// ERROR_INTERNAL_DB_CORRUPTION = 1358, /// /// An internal error occurred. /// ERROR_INTERNAL_ERROR = 1359, /// /// Generic access types were contained in an access mask which should already be mapped to nongeneric types. /// ERROR_GENERIC_NOT_MAPPED = 1360, /// /// A security descriptor is not in the right format (absolute or self-relative). /// ERROR_BAD_DESCRIPTOR_FORMAT = 1361, /// /// The requested action is restricted for use by logon processes only. The calling process has not registered as a logon process. /// ERROR_NOT_LOGON_PROCESS = 1362, /// /// Cannot start a new logon session with an ID that is already in use. /// ERROR_LOGON_SESSION_EXISTS = 1363, /// /// A specified authentication package is unknown. /// ERROR_NO_SUCH_PACKAGE = 1364, /// /// The logon session is not in a state that is consistent with the requested operation. /// ERROR_BAD_LOGON_SESSION_STATE = 1365, /// /// The logon session ID is already in use. /// ERROR_LOGON_SESSION_COLLISION = 1366, /// /// A logon request contained an invalid logon type value. /// ERROR_INVALID_LOGON_TYPE = 1367, /// /// Unable to impersonate using a named pipe until data has been read from that pipe. /// ERROR_CANNOT_IMPERSONATE = 1368, /// /// The transaction state of a registry subtree is incompatible with the requested operation. /// ERROR_RXACT_INVALID_STATE = 1369, /// /// An internal security database corruption has been encountered. /// ERROR_RXACT_COMMIT_FAILURE = 1370, /// /// Cannot perform this operation on built-in accounts. /// ERROR_SPECIAL_ACCOUNT = 1371, /// /// Cannot perform this operation on this built-in special group. /// ERROR_SPECIAL_GROUP = 1372, /// /// Cannot perform this operation on this built-in special user. /// ERROR_SPECIAL_USER = 1373, /// /// The user cannot be removed from a group because the group is currently the user's primary group. /// ERROR_MEMBERS_PRIMARY_GROUP = 1374, /// /// The token is already in use as a primary token. /// ERROR_TOKEN_ALREADY_IN_USE = 1375, /// /// The specified local group does not exist. /// ERROR_NO_SUCH_ALIAS = 1376, /// /// The specified account name is not a member of the local group. /// ERROR_MEMBER_NOT_IN_ALIAS = 1377, /// /// The specified account name is already a member of the local group. /// ERROR_MEMBER_IN_ALIAS = 1378, /// /// The specified local group already exists. /// ERROR_ALIAS_EXISTS = 1379, /// /// Logon failure: the user has not been granted the requested logon type at this computer. /// ERROR_LOGON_NOT_GRANTED = 1380, /// /// The maximum number of secrets that may be stored in a single system has been exceeded. /// ERROR_TOO_MANY_SECRETS = 1381, /// /// The length of a secret exceeds the maximum length allowed. /// ERROR_SECRET_TOO_Int32 = 1382, /// /// The local security authority database contains an internal inconsistency. /// ERROR_INTERNAL_DB_ERROR = 1383, /// /// During a logon attempt, the user's security context accumulated too many security IDs. /// ERROR_TOO_MANY_CONTEXT_IDS = 1384, /// /// Logon failure: the user has not been granted the requested logon type at this computer. /// ERROR_LOGON_TYPE_NOT_GRANTED = 1385, /// /// A cross-encrypted password is necessary to change a user password. /// ERROR_NT_CROSS_ENCRYPTION_REQUIRED = 1386, /// /// A member could not be added to or removed from the local group because the member does not exist. /// ERROR_NO_SUCH_MEMBER = 1387, /// /// A new member could not be added to a local group because the member has the wrong account type. /// ERROR_INVALID_MEMBER = 1388, /// /// Too many security IDs have been specified. /// ERROR_TOO_MANY_SIDS = 1389, /// /// A cross-encrypted password is necessary to change this user password. /// ERROR_LM_CROSS_ENCRYPTION_REQUIRED = 1390, /// /// Indicates an ACL contains no inheritable components. /// ERROR_NO_INHERITANCE = 1391, /// /// The file or directory is corrupted and unreadable. /// ERROR_FILE_CORRUPT = 1392, /// /// The disk structure is corrupted and unreadable. /// ERROR_DISK_CORRUPT = 1393, /// /// There is no user session key for the specified logon session. /// ERROR_NO_USER_SESSION_KEY = 1394, /// /// The service being accessed is licensed for a particular number of connections. /// No more connections can be made to the service at this time because there are already as many connections as the service can accept. /// ERROR_LICENSE_QUOTA_EXCEEDED = 1395, /// /// Logon Failure: The target account name is incorrect. /// ERROR_WRONG_TARGET_NAME = 1396, /// /// Mutual Authentication failed. The server's password is out of date at the domain controller. /// ERROR_MUTUAL_AUTH_FAILED = 1397, /// /// There is a time and/or date difference between the client and server. /// ERROR_TIME_SKEW = 1398, /// /// This operation can not be performed on the current domain. /// ERROR_CURRENT_DOMAIN_NOT_ALLOWED = 1399, /// /// Invalid window handle. /// ERROR_INVALID_WINDOW_HANDLE = 1400, /// /// Invalid menu handle. /// ERROR_INVALID_MENU_HANDLE = 1401, /// /// Invalid cursor handle. /// ERROR_INVALID_CURSOR_HANDLE = 1402, /// /// Invalid accelerator table handle. /// ERROR_INVALID_ACCEL_HANDLE = 1403, /// /// Invalid hook handle. /// ERROR_INVALID_HOOK_HANDLE = 1404, /// /// Invalid handle to a multiple-window position structure. /// ERROR_INVALID_DWP_HANDLE = 1405, /// /// Cannot create a top-level child window. /// ERROR_TLW_WITH_WSCHILD = 1406, /// /// Cannot find window class. /// ERROR_CANNOT_FIND_WND_CLASS = 1407, /// /// Invalid window, it belongs to other thread. /// ERROR_WINDOW_OF_OTHER_THREAD = 1408, /// /// Hot key is already registered. /// ERROR_HOTKEY_ALREADY_REGISTERED = 1409, /// /// Class already exists. /// ERROR_CLASS_ALREADY_EXISTS = 1410, /// /// Class does not exist. /// ERROR_CLASS_DOES_NOT_EXIST = 1411, /// /// Class still has open windows. /// ERROR_CLASS_HAS_WINDOWS = 1412, /// /// Invalid index. /// ERROR_INVALID_INDEX = 1413, /// /// Invalid icon handle. /// ERROR_INVALID_ICON_HANDLE = 1414, /// /// Using private DIALOG window words. /// ERROR_PRIVATE_DIALOG_INDEX = 1415, /// /// The list box identifier was not found. /// ERROR_LISTBOX_ID_NOT_FOUND = 1416, /// /// No wildcards were found. /// ERROR_NO_WILDCARD_CHARACTERS = 1417, /// /// Thread does not have a clipboard open. /// ERROR_CLIPBOARD_NOT_OPEN = 1418, /// /// Hot key is not registered. /// ERROR_HOTKEY_NOT_REGISTERED = 1419, /// /// The window is not a valid dialog window. /// ERROR_WINDOW_NOT_DIALOG = 1420, /// /// Control ID not found. /// ERROR_CONTROL_ID_NOT_FOUND = 1421, /// /// Invalid message for a combo box because it does not have an edit control. /// ERROR_INVALID_COMBOBOX_MESSAGE = 1422, /// /// The window is not a combo box. /// ERROR_WINDOW_NOT_COMBOBOX = 1423, /// /// Height must be less than 256. /// ERROR_INVALID_EDIT_HEIGHT = 1424, /// /// Invalid device context (DC) handle. /// ERROR_DC_NOT_FOUND = 1425, /// /// Invalid hook procedure type. /// ERROR_INVALID_HOOK_FILTER = 1426, /// /// Invalid hook procedure. /// ERROR_INVALID_FILTER_PROC = 1427, /// /// Cannot set nonlocal hook without a module handle. /// ERROR_HOOK_NEEDS_HMOD = 1428, /// /// This hook procedure can only be set globally. /// ERROR_GLOBAL_ONLY_HOOK = 1429, /// /// The journal hook procedure is already installed. /// ERROR_JOURNAL_HOOK_SET = 1430, /// /// The hook procedure is not installed. /// ERROR_HOOK_NOT_INSTALLED = 1431, /// /// Invalid message for single-selection list box. /// ERROR_INVALID_LB_MESSAGE = 1432, /// /// LB_SETCOUNT sent to non-lazy list box. /// ERROR_SETCOUNT_ON_BAD_LB = 1433, /// /// This list box does not support tab stops. /// ERROR_LB_WITHOUT_TABSTOPS = 1434, /// /// Cannot destroy object created by another thread. /// ERROR_DESTROY_OBJECT_OF_OTHER_THREAD = 1435, /// /// Child windows cannot have menus. /// ERROR_CHILD_WINDOW_MENU = 1436, /// /// The window does not have a system menu. /// ERROR_NO_SYSTEM_MENU = 1437, /// /// Invalid message box style. /// ERROR_INVALID_MSGBOX_STYLE = 1438, /// /// Invalid system-wide (SPI_*) parameter. /// ERROR_INVALID_SPI_VALUE = 1439, /// /// Screen already locked. /// ERROR_SCREEN_ALREADY_LOCKED = 1440, /// /// All handles to windows in a multiple-window position structure must have the same parent. /// ERROR_HWNDS_HAVE_DIFF_PARENT = 1441, /// /// The window is not a child window. /// ERROR_NOT_CHILD_WINDOW = 1442, /// /// Invalid GW_* command. /// ERROR_INVALID_GW_COMMAND = 1443, /// /// Invalid thread identifier. /// ERROR_INVALID_THREAD_ID = 1444, /// /// Cannot process a message from a window that is not a multiple document interface (MDI) window. /// ERROR_NON_MDICHILD_WINDOW = 1445, /// /// Popup menu already active. /// ERROR_POPUP_ALREADY_ACTIVE = 1446, /// /// The window does not have scroll bars. /// ERROR_NO_SCROLLBARS = 1447, /// /// Scroll bar range cannot be greater than MAXLONG. /// ERROR_INVALID_SCROLLBAR_RANGE = 1448, /// /// Cannot show or remove the window in the way specified. /// ERROR_INVALID_SHOWWIN_COMMAND = 1449, /// /// Insufficient system resources exist to complete the requested service. /// ERROR_NO_SYSTEM_RESOURCES = 1450, /// /// Insufficient system resources exist to complete the requested service. /// ERROR_NONPAGED_SYSTEM_RESOURCES = 1451, /// /// Insufficient system resources exist to complete the requested service. /// ERROR_PAGED_SYSTEM_RESOURCES = 1452, /// /// Insufficient quota to complete the requested service. /// ERROR_WORKING_SET_QUOTA = 1453, /// /// Insufficient quota to complete the requested service. /// ERROR_PAGEFILE_QUOTA = 1454, /// /// The paging file is too small for this operation to complete. /// ERROR_COMMITMENT_LIMIT = 1455, /// /// A menu item was not found. /// ERROR_MENU_ITEM_NOT_FOUND = 1456, /// /// Invalid keyboard layout handle. /// ERROR_INVALID_KEYBOARD_HANDLE = 1457, /// /// Hook type not allowed. /// ERROR_HOOK_TYPE_NOT_ALLOWED = 1458, /// /// This operation requires an interactive window station. /// ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION = 1459, /// /// This operation returned because the timeout period expired. /// ERROR_TIMEOUT = 1460, /// /// Invalid monitor handle. /// ERROR_INVALID_MONITOR_HANDLE = 1461, /// /// The event log file is corrupted. /// ERROR_EVENTLOG_FILE_CORRUPT = 1500, /// /// No event log file could be opened, so the event logging service did not start. /// ERROR_EVENTLOG_CANT_START = 1501, /// /// The event log file is full. /// ERROR_LOG_FILE_FULL = 1502, /// /// The event log file has changed between read operations. /// ERROR_EVENTLOG_FILE_CHANGED = 1503, /// /// The Windows Installer Service could not be accessed. This can occur if you are running Windows in safe mode, or if the Windows Installer is not correctly installed. Contact your support personnel for assistance. /// ERROR_INSTALL_SERVICE_FAILURE = 1601, /// /// User cancelled installation. /// ERROR_INSTALL_USEREXIT = 1602, /// /// Fatal error during installation. /// ERROR_INSTALL_FAILURE = 1603, /// /// Installation suspended, incomplete. /// ERROR_INSTALL_SUSPEND = 1604, /// /// This action is only valid for products that are currently installed. /// ERROR_UNKNOWN_PRODUCT = 1605, /// /// Feature ID not registered. /// ERROR_UNKNOWN_FEATURE = 1606, /// /// Component ID not registered. /// ERROR_UNKNOWN_COMPONENT = 1607, /// /// Unknown property. /// ERROR_UNKNOWN_PROPERTY = 1608, /// /// Handle is in an invalid state. /// ERROR_INVALID_HANDLE_STATE = 1609, /// /// The configuration data for this product is corrupt. Contact your support personnel. /// ERROR_BAD_CONFIGURATION = 1610, /// /// Component qualifier not present. /// ERROR_INDEX_ABSENT = 1611, /// /// The installation source for this product is not available. Verify that the source exists and that you can access it. /// ERROR_INSTALL_SOURCE_ABSENT = 1612, /// /// This installation package cannot be installed by the Windows Installer service. You must install a Windows service pack that contains a newer version of the Windows Installer service. /// ERROR_INSTALL_PACKAGE_VERSION = 1613, /// /// Product is uninstalled. /// ERROR_PRODUCT_UNINSTALLED = 1614, /// /// SQL query syntax invalid or unsupported. /// ERROR_BAD_QUERY_SYNTAX = 1615, /// /// Record field does not exist. /// ERROR_INVALID_FIELD = 1616, /// /// The device has been removed. /// ERROR_DEVICE_REMOVED = 1617, /// /// Another installation is already in progress. Complete that installation before proceeding with this install. /// ERROR_INSTALL_ALREADY_RUNNING = 1618, /// /// This installation package could not be opened. Verify that the package exists and that you can access it, or contact the application vendor to verify that this is a valid Windows Installer package. /// ERROR_INSTALL_PACKAGE_OPEN_FAILED = 1619, /// /// This installation package could not be opened. Contact the application vendor to verify that this is a valid Windows Installer package. /// ERROR_INSTALL_PACKAGE_INVALID = 1620, /// /// There was an error starting the Windows Installer service user interface. Contact your support personnel. /// ERROR_INSTALL_UI_FAILURE = 1621, /// /// Error opening installation log file. Verify that the specified log file location exists and that you can write to it. /// ERROR_INSTALL_LOG_FAILURE = 1622, /// /// The language of this installation package is not supported by your system. /// ERROR_INSTALL_LANGUAGE_UNSUPPORTED = 1623, /// /// Error applying transforms. Verify that the specified transform paths are valid. /// ERROR_INSTALL_TRANSFORM_FAILURE = 1624, /// /// This installation is forbidden by system policy. Contact your system administrator. /// ERROR_INSTALL_PACKAGE_REJECTED = 1625, /// /// Function could not be executed. /// ERROR_FUNCTION_NOT_CALLED = 1626, /// /// Function failed during execution. /// ERROR_FUNCTION_FAILED = 1627, /// /// Invalid or unknown table specified. /// ERROR_INVALID_TABLE = 1628, /// /// Data supplied is of wrong type. /// ERROR_DATATYPE_MISMATCH = 1629, /// /// Data of this type is not supported. /// ERROR_UNSUPPORTED_TYPE = 1630, /// /// The Windows Installer service failed to start. Contact your support personnel. /// ERROR_CREATE_FAILED = 1631, /// /// The Temp folder is on a drive that is full or is inaccessible. Free up space on the drive or verify that you have write permission on the Temp folder. /// ERROR_INSTALL_TEMP_UNWRITABLE = 1632, /// /// This installation package is not supported by this processor type. Contact your product vendor. /// ERROR_INSTALL_PLATFORM_UNSUPPORTED = 1633, /// /// Component not used on this computer. /// ERROR_INSTALL_NOTUSED = 1634, /// /// This patch package could not be opened. Verify that the patch package exists and that you can access it, or contact the application vendor to verify that this is a valid Windows Installer patch package. /// ERROR_PATCH_PACKAGE_OPEN_FAILED = 1635, /// /// This patch package could not be opened. Contact the application vendor to verify that this is a valid Windows Installer patch package. /// ERROR_PATCH_PACKAGE_INVALID = 1636, /// /// This patch package cannot be processed by the Windows Installer service. You must install a Windows service pack that contains a newer version of the Windows Installer service. /// ERROR_PATCH_PACKAGE_UNSUPPORTED = 1637, /// /// Another version of this product is already installed. Installation of this version cannot continue. To configure or remove the existing version of this product, use Add/Remove Programs on the Control Panel. /// ERROR_PRODUCT_VERSION = 1638, /// /// Invalid command line argument. Consult the Windows Installer SDK for detailed command line help. /// ERROR_INVALID_COMMAND_LINE = 1639, /// /// Only administrators have permission to add, remove, or configure server software during a Terminal services remote session. If you want to install or configure software on the server, contact your network administrator. /// ERROR_INSTALL_REMOTE_DISALLOWED = 1640, /// /// The requested operation completed successfully. The system will be restarted so the changes can take effect. /// ERROR_SUCCESS_REBOOT_INITIATED = 1641, /// /// The upgrade patch cannot be installed by the Windows Installer service because the program to be upgraded may be missing, or the upgrade patch may update a different version of the program. Verify that the program to be upgraded exists on your computer an /// d that you have the correct upgrade patch. /// ERROR_PATCH_TARGET_NOT_FOUND = 1642, /// /// The patch package is not permitted by software restriction policy. /// ERROR_PATCH_PACKAGE_REJECTED = 1643, /// /// One or more customizations are not permitted by software restriction policy. /// ERROR_INSTALL_TRANSFORM_REJECTED = 1644, /// /// No information avialable. /// ERROR_INSTALL_REMOTE_PROHIBITED = 1645, /// /// The string binding is invalid. /// RPC_S_INVALID_STRING_BINDING = 1700, /// /// The binding handle is not the correct type. /// RPC_S_WRONG_KIND_OF_BINDING = 1701, /// /// The binding handle is invalid. /// RPC_S_INVALID_BINDING = 1702, /// /// The RPC protocol sequence is not supported. /// RPC_S_PROTSEQ_NOT_SUPPORTED = 1703, /// /// The RPC protocol sequence is invalid. /// RPC_S_INVALID_RPC_PROTSEQ = 1704, /// /// The string universal unique identifier (UUID) is invalid. /// RPC_S_INVALID_STRING_UUID = 1705, /// /// The endpoint format is invalid. /// RPC_S_INVALID_ENDPOINT_FORMAT = 1706, /// /// The network address is invalid. /// RPC_S_INVALID_NET_ADDR = 1707, /// /// No endpoint was found. /// RPC_S_NO_ENDPOINT_FOUND = 1708, /// /// The timeout value is invalid. /// RPC_S_INVALID_TIMEOUT = 1709, /// /// The object universal unique identifier (UUID) was not found. /// RPC_S_OBJECT_NOT_FOUND = 1710, /// /// The object universal unique identifier (UUID) has already been registered. /// RPC_S_ALREADY_REGISTERED = 1711, /// /// The type universal unique identifier (UUID) has already been registered. /// RPC_S_TYPE_ALREADY_REGISTERED = 1712, /// /// The RPC server is already listening. /// RPC_S_ALREADY_LISTENING = 1713, /// /// No protocol sequences have been registered. /// RPC_S_NO_PROTSEQS_REGISTERED = 1714, /// /// The RPC server is not listening. /// RPC_S_NOT_LISTENING = 1715, /// /// The manager type is unknown. /// RPC_S_UNKNOWN_MGR_TYPE = 1716, /// /// The interface is unknown. /// RPC_S_UNKNOWN_IF = 1717, /// /// There are no bindings. /// RPC_S_NO_BINDINGS = 1718, /// /// There are no protocol sequences. /// RPC_S_NO_PROTSEQS = 1719, /// /// The endpoint cannot be created. /// RPC_S_CANT_CREATE_ENDPOINT = 1720, /// /// Not enough resources are available to complete this operation. /// RPC_S_OUT_OF_RESOURCES = 1721, /// /// The RPC server is unavailable. /// RPC_S_SERVER_UNAVAILABLE = 1722, /// /// The RPC server is too busy to complete this operation. /// RPC_S_SERVER_TOO_BUSY = 1723, /// /// The network options are invalid. /// RPC_S_INVALID_NETWORK_OPTIONS = 1724, /// /// There are no remote procedure calls active on this thread. /// RPC_S_NO_CALL_ACTIVE = 1725, /// /// The remote procedure call failed. /// RPC_S_CALL_FAILED = 1726, /// /// The remote procedure call failed and did not execute. /// RPC_S_CALL_FAILED_DNE = 1727, /// /// A remote procedure call (RPC) protocol error occurred. /// RPC_S_PROTOCOL_ERROR = 1728, /// /// The transfer syntax is not supported by the RPC server. /// RPC_S_UNSUPPORTED_TRANS_SYN = 1730, /// /// The universal unique identifier (UUID) type is not supported. /// RPC_S_UNSUPPORTED_TYPE = 1732, /// /// The tag is invalid. /// RPC_S_INVALID_TAG = 1733, /// /// The array bounds are invalid. /// RPC_S_INVALID_BOUND = 1734, /// /// The binding does not contain an entry name. /// RPC_S_NO_ENTRY_NAME = 1735, /// /// The name syntax is invalid. /// RPC_S_INVALID_NAME_SYNTAX = 1736, /// /// The name syntax is not supported. /// RPC_S_UNSUPPORTED_NAME_SYNTAX = 1737, /// /// No network address is available to use to construct a universal unique identifier (UUID). /// RPC_S_UUID_NO_ADDRESS = 1739, /// /// The endpoint is a duplicate. /// RPC_S_DUPLICATE_ENDPOINT = 1740, /// /// The authentication type is unknown. /// RPC_S_UNKNOWN_AUTHN_TYPE = 1741, /// /// The maximum number of calls is too small. /// RPC_S_MAX_CALLS_TOO_SMALL = 1742, /// /// The string is too long. /// RPC_S_STRING_TOO_Int32 = 1743, /// /// The RPC protocol sequence was not found. /// RPC_S_PROTSEQ_NOT_FOUND = 1744, /// /// The procedure number is out of range. /// RPC_S_PROCNUM_OUT_OF_RANGE = 1745, /// /// The binding does not contain any authentication information. /// RPC_S_BINDING_HAS_NO_AUTH = 1746, /// /// The authentication service is unknown. /// RPC_S_UNKNOWN_AUTHN_SERVICE = 1747, /// /// The authentication level is unknown. /// RPC_S_UNKNOWN_AUTHN_LEVEL = 1748, /// /// The security context is invalid. /// RPC_S_INVALID_AUTH_IDENTITY = 1749, /// /// The authorization service is unknown. /// RPC_S_UNKNOWN_AUTHZ_SERVICE = 1750, /// /// The entry is invalid. /// EPT_S_INVALID_ENTRY = 1751, /// /// The server endpoint cannot perform the operation. /// EPT_S_CANT_PERFORM_OP = 1752, /// /// There are no more endpoints available from the endpoint mapper. /// EPT_S_NOT_REGISTERED = 1753, /// /// No interfaces have been exported. /// RPC_S_NOTHING_TO_EXPORT = 1754, /// /// The entry name is incomplete. /// RPC_S_INCOMPLETE_NAME = 1755, /// /// The version option is invalid. /// RPC_S_INVALID_VERS_OPTION = 1756, /// /// There are no more members. /// RPC_S_NO_MORE_MEMBERS = 1757, /// /// There is nothing to unexport. /// RPC_S_NOT_ALL_OBJS_UNEXPORTED = 1758, /// /// The interface was not found. /// RPC_S_INTERFACE_NOT_FOUND = 1759, /// /// The entry already exists. /// RPC_S_ENTRY_ALREADY_EXISTS = 1760, /// /// The entry is not found. /// RPC_S_ENTRY_NOT_FOUND = 1761, /// /// The name service is unavailable. /// RPC_S_NAME_SERVICE_UNAVAILABLE = 1762, /// /// The network address family is invalid. /// RPC_S_INVALID_NAF_ID = 1763, /// /// The requested operation is not supported. /// RPC_S_CANNOT_SUPPORT = 1764, /// /// No security context is available to allow impersonation. /// RPC_S_NO_CONTEXT_AVAILABLE = 1765, /// /// An internal error occurred in a remote procedure call (RPC). /// RPC_S_INTERNAL_ERROR = 1766, /// /// The RPC server attempted an integer division by zero. /// RPC_S_ZERO_DIVIDE = 1767, /// /// An addressing error occurred in the RPC server. /// RPC_S_ADDRESS_ERROR = 1768, /// /// A floating-point operation at the RPC server caused a division by zero. /// RPC_S_FP_DIV_ZERO = 1769, /// /// A floating-point underflow occurred at the RPC server. /// RPC_S_FP_UNDERFLOW = 1770, /// /// A floating-point overflow occurred at the RPC server. /// RPC_S_FP_OVERFLOW = 1771, /// /// The list of RPC servers available for the binding of auto handles has been exhausted. /// RPC_X_NO_MORE_ENTRIES = 1772, /// /// Unable to open the character translation table file. /// RPC_X_SS_CHAR_TRANS_OPEN_FAIL = 1773, /// /// The file containing the character translation table has fewer than 512 bytes. /// RPC_X_SS_CHAR_TRANS_Int16_FILE = 1774, /// /// A null context handle was passed from the client to the host during a remote procedure call. /// RPC_X_SS_IN_NULL_CONTEXT = 1775, /// /// The context handle changed during a remote procedure call. /// RPC_X_SS_CONTEXT_DAMAGED = 1777, /// /// The binding handles passed to a remote procedure call do not match. /// RPC_X_SS_HANDLES_MISMATCH = 1778, /// /// The stub is unable to get the remote procedure call handle. /// RPC_X_SS_CANNOT_GET_CALL_HANDLE = 1779, /// /// A null reference pointer was passed to the stub. /// RPC_X_NULL_REF_POINTER = 1780, /// /// The enumeration value is out of range. /// RPC_X_ENUM_VALUE_OUT_OF_RANGE = 1781, /// /// The byte count is too small. /// RPC_X_BYTE_COUNT_TOO_SMALL = 1782, /// /// The stub received bad data. /// RPC_X_BAD_STUB_DATA = 1783, /// /// The supplied user buffer is not valid for the requested operation. /// ERROR_INVALID_USER_BUFFER = 1784, /// /// The disk media is not recognized. It may not be formatted. /// ERROR_UNRECOGNIZED_MEDIA = 1785, /// /// The workstation does not have a trust secret. /// ERROR_NO_TRUST_LSA_SECRET = 1786, /// /// The security database on the server does not have a computer account for this workstation trust relationship. /// ERROR_NO_TRUST_SAM_ACCOUNT = 1787, /// /// The trust relationship between the primary domain and the trusted domain failed. /// ERROR_TRUSTED_DOMAIN_FAILURE = 1788, /// /// The trust relationship between this workstation and the primary domain failed. /// ERROR_TRUSTED_RELATIONSHIP_FAILURE = 1789, /// /// The network logon failed. /// ERROR_TRUST_FAILURE = 1790, /// /// A remote procedure call is already in progress for this thread. /// RPC_S_CALL_IN_PROGRESS = 1791, /// /// An attempt was made to logon, but the network logon service was not started. /// ERROR_NETLOGON_NOT_STARTED = 1792, /// /// The user's account has expired. /// ERROR_ACCOUNT_EXPIRED = 1793, /// /// The redirector is in use and cannot be unloaded. /// ERROR_REDIRECTOR_HAS_OPEN_HANDLES = 1794, /// /// The specified printer driver is already installed. /// ERROR_PRINTER_DRIVER_ALREADY_INSTALLED = 1795, /// /// The specified port is unknown. /// ERROR_UNKNOWN_PORT = 1796, /// /// The printer driver is unknown. /// ERROR_UNKNOWN_PRINTER_DRIVER = 1797, /// /// The print processor is unknown. /// ERROR_UNKNOWN_PRINTPROCESSOR = 1798, /// /// The specified separator file is invalid. /// ERROR_INVALID_SEPARATOR_FILE = 1799, /// /// The specified priority is invalid. /// ERROR_INVALID_PRIORITY = 1800, /// /// The printer name is invalid. /// ERROR_INVALID_PRINTER_NAME = 1801, /// /// The printer already exists. /// ERROR_PRINTER_ALREADY_EXISTS = 1802, /// /// The printer command is invalid. /// ERROR_INVALID_PRINTER_COMMAND = 1803, /// /// The specified datatype is invalid. /// ERROR_INVALID_DATATYPE = 1804, /// /// The environment specified is invalid. /// ERROR_INVALID_ENVIRONMENT = 1805, /// /// There are no more bindings. /// RPC_S_NO_MORE_BINDINGS = 1806, /// /// The account used is an interdomain trust account. Use your global user account or local user account to access this server. /// ERROR_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT = 1807, /// /// The account used is a computer account. Use your global user account or local user account to access this server. /// ERROR_NOLOGON_WORKSTATION_TRUST_ACCOUNT = 1808, /// /// The account used is a server trust account. Use your global user account or local user account to access this server. /// ERROR_NOLOGON_SERVER_TRUST_ACCOUNT = 1809, /// /// The name or security ID (SID) of the domain specified is inconsistent with the trust information for that domain. /// ERROR_DOMAIN_TRUST_INCONSISTENT = 1810, /// /// The server is in use and cannot be unloaded. /// ERROR_SERVER_HAS_OPEN_HANDLES = 1811, /// /// The specified image file did not contain a resource section. /// ERROR_RESOURCE_DATA_NOT_FOUND = 1812, /// /// The specified resource type cannot be found in the image file. /// ERROR_RESOURCE_TYPE_NOT_FOUND = 1813, /// /// The specified resource name cannot be found in the image file. /// ERROR_RESOURCE_NAME_NOT_FOUND = 1814, /// /// The specified resource language ID cannot be found in the image file. /// ERROR_RESOURCE_LANG_NOT_FOUND = 1815, /// /// Not enough quota is available to process this command. /// ERROR_NOT_ENOUGH_QUOTA = 1816, /// /// No interfaces have been registered. /// RPC_S_NO_INTERFACES = 1817, /// /// The remote procedure call was cancelled. /// RPC_S_CALL_CANCELLED = 1818, /// /// The binding handle does not contain all required information. /// RPC_S_BINDING_INCOMPLETE = 1819, /// /// A communications failure occurred during a remote procedure call. /// RPC_S_COMM_FAILURE = 1820, /// /// The requested authentication level is not supported. /// RPC_S_UNSUPPORTED_AUTHN_LEVEL = 1821, /// /// No principal name registered. /// RPC_S_NO_PRINC_NAME = 1822, /// /// The error specified is not a valid Windows RPC error code. /// RPC_S_NOT_RPC_ERROR = 1823, /// /// A UUID that is valid only on this computer has been allocated. /// RPC_S_UUID_LOCAL_ONLY = 1824, /// /// A security package specific error occurred. /// RPC_S_SEC_PKG_ERROR = 1825, /// /// Thread is not canceled. /// RPC_S_NOT_CANCELLED = 1826, /// /// Invalid operation on the encoding/decoding handle. /// RPC_X_INVALID_ES_ACTION = 1827, /// /// Incompatible version of the serializing package. /// RPC_X_WRONG_ES_VERSION = 1828, /// /// Incompatible version of the RPC stub. /// RPC_X_WRONG_STUB_VERSION = 1829, /// /// The RPC pipe object is invalid or corrupted. /// RPC_X_INVALID_PIPE_OBJECT = 1830, /// /// An invalid operation was attempted on an RPC pipe object. /// RPC_X_WRONG_PIPE_ORDER = 1831, /// /// Unsupported RPC pipe version. /// RPC_X_WRONG_PIPE_VERSION = 1832, /// /// The group member was not found. /// RPC_S_GROUP_MEMBER_NOT_FOUND = 1898, /// /// The endpoint mapper database entry could not be created. /// EPT_S_CANT_CREATE = 1899, /// /// The object universal unique identifier (UUID) is the nil UUID. /// RPC_S_INVALID_OBJECT = 1900, /// /// The specified time is invalid. /// ERROR_INVALID_TIME = 1901, /// /// The specified form name is invalid. /// ERROR_INVALID_FORM_NAME = 1902, /// /// The specified form size is invalid. /// ERROR_INVALID_FORM_SIZE = 1903, /// /// The specified printer handle is already being waited on /// ERROR_ALREADY_WAITING = 1904, /// /// The specified printer has been deleted. /// ERROR_PRINTER_DELETED = 1905, /// /// The state of the printer is invalid. /// ERROR_INVALID_PRINTER_STATE = 1906, /// /// The user's password must be changed before logging on the first time. /// ERROR_PASSUInt16_MUST_CHANGE = 1907, /// /// Could not find the domain controller for this domain. /// ERROR_DOMAIN_CONTROLLER_NOT_FOUND = 1908, /// /// The referenced account is currently locked out and may not be logged on to. /// ERROR_ACCOUNT_LOCKED_OUT = 1909, /// /// The object exporter specified was not found. /// OR_INVALID_OXID = 1910, /// /// The object specified was not found. /// OR_INVALID_OID = 1911, /// /// The object resolver set specified was not found. /// OR_INVALID_SET = 1912, /// /// Some data remains to be sent in the request buffer. /// RPC_S_SEND_INCOMPLETE = 1913, /// /// Invalid asynchronous remote procedure call handle. /// RPC_S_INVALID_ASYNC_HANDLE = 1914, /// /// Invalid asynchronous RPC call handle for this operation. /// RPC_S_INVALID_ASYNC_CALL = 1915, /// /// The RPC pipe object has already been closed. /// RPC_X_PIPE_CLOSED = 1916, /// /// The RPC call completed before all pipes were processed. /// RPC_X_PIPE_DISCIPLINE_ERROR = 1917, /// /// No more data is available from the RPC pipe. /// RPC_X_PIPE_EMPTY = 1918, /// /// No site name is available for this machine. /// ERROR_NO_SITENAME = 1919, /// /// The file can not be accessed by the system. /// ERROR_CANT_ACCESS_FILE = 1920, /// /// The name of the file cannot be resolved by the system. /// ERROR_CANT_RESOLVE_FILENAME = 1921, /// /// The entry is not of the expected type. /// RPC_S_ENTRY_TYPE_MISMATCH = 1922, /// /// Not all object UUIDs could be exported to the specified entry. /// RPC_S_NOT_ALL_OBJS_EXPORTED = 1923, /// /// Interface could not be exported to the specified entry. /// RPC_S_INTERFACE_NOT_EXPORTED = 1924, /// /// The specified profile entry could not be added. /// RPC_S_PROFILE_NOT_ADDED = 1925, /// /// The specified profile element could not be added. /// RPC_S_PRF_ELT_NOT_ADDED = 1926, /// /// The specified profile element could not be removed. /// RPC_S_PRF_ELT_NOT_REMOVED = 1927, /// /// The group element could not be added. /// RPC_S_GRP_ELT_NOT_ADDED = 1928, /// /// The group element could not be removed. /// RPC_S_GRP_ELT_NOT_REMOVED = 1929, /// /// The printer driver is not compatible with a policy enabled on your computer that blocks NT 4.0 drivers. /// ERROR_KM_DRIVER_BLOCKED = 1930, /// /// The context has expired and can no longer be used. /// ERROR_CONTEXT_EXPIRED = 1931, /// /// No information avialable. /// ERROR_PER_USER_TRUST_QUOTA_EXCEEDED = 1932, /// /// No information avialable. /// ERROR_ALL_USER_TRUST_QUOTA_EXCEEDED = 1933, /// /// No information avialable. /// ERROR_USER_DELETE_TRUST_QUOTA_EXCEEDED = 1934, /// /// No information avialable. /// ERROR_AUTHENTICATION_FIREWALL_FAILED = 1935, /// /// No information avialable. /// ERROR_REMOTE_PRINT_CONNECTIONS_BLOCKED = 1936, /// /// The pixel format is invalid. /// ERROR_INVALID_PIXEL_FORMAT = 2000, /// /// The specified driver is invalid. /// ERROR_BAD_DRIVER = 2001, /// /// The window style or class attribute is invalid for this operation. /// ERROR_INVALID_WINDOW_STYLE = 2002, /// /// The requested metafile operation is not supported. /// ERROR_METAFILE_NOT_SUPPORTED = 2003, /// /// The requested transformation operation is not supported. /// ERROR_TRANSFORM_NOT_SUPPORTED = 2004, /// /// The requested clipping operation is not supported. /// ERROR_CLIPPING_NOT_SUPPORTED = 2005, /// /// The specified color management module is invalid. /// ERROR_INVALID_CMM = 2010, /// /// The specified color profile is invalid. /// ERROR_INVALID_PROFILE = 2011, /// /// The specified tag was not found. /// ERROR_TAG_NOT_FOUND = 2012, /// /// A required tag is not present. /// ERROR_TAG_NOT_PRESENT = 2013, /// /// The specified tag is already present. /// ERROR_DUPLICATE_TAG = 2014, /// /// The specified color profile is not associated with any device. /// ERROR_PROFILE_NOT_ASSOCIATED_WITH_DEVICE = 2015, /// /// The specified color profile was not found. /// ERROR_PROFILE_NOT_FOUND = 2016, /// /// The specified color space is invalid. /// ERROR_INVALID_COLORSPACE = 2017, /// /// Image Color Management is not enabled. /// ERROR_ICM_NOT_ENABLED = 2018, /// /// There was an error while deleting the color transform. /// ERROR_DELETING_ICM_XFORM = 2019, /// /// The specified color transform is invalid. /// ERROR_INVALID_TRANSFORM = 2020, /// /// The specified transform does not match the bitmap's color space. /// ERROR_COLORSPACE_MISMATCH = 2021, /// /// The specified named color index is not present in the profile. /// ERROR_INVALID_COLORINDEX = 2022, /// /// The network connection was made successfully, but the user had to be prompted for a password other than the one originally specified. /// ERROR_CONNECTED_OTHER_PASSUInt16 = 2108, /// /// The network connection was made successfully using default credentials. /// ERROR_CONNECTED_OTHER_PASSUInt16_DEFAULT = 2109, /// /// The specified username is invalid. /// ERROR_BAD_USERNAME = 2202, /// /// This network connection does not exist. /// ERROR_NOT_CONNECTED = 2250, /// /// This network connection has files open or requests pending. /// ERROR_OPEN_FILES = 2401, /// /// Active connections still exist. /// ERROR_ACTIVE_CONNECTIONS = 2402, /// /// The device is in use by an active process and cannot be disconnected. /// ERROR_DEVICE_IN_USE = 2404, /// /// The specified print monitor is unknown. /// ERROR_UNKNOWN_PRINT_MONITOR = 3000, /// /// The specified printer driver is currently in use. /// ERROR_PRINTER_DRIVER_IN_USE = 3001, /// /// The spool file was not found. /// ERROR_SPOOL_FILE_NOT_FOUND = 3002, /// /// A StartDocPrinter call was not issued. /// ERROR_SPL_NO_STARTDOC = 3003, /// /// An AddJob call was not issued. /// ERROR_SPL_NO_ADDJOB = 3004, /// /// The specified print processor has already been installed. /// ERROR_PRINT_PROCESSOR_ALREADY_INSTALLED = 3005, /// /// The specified print monitor has already been installed. /// ERROR_PRINT_MONITOR_ALREADY_INSTALLED = 3006, /// /// The specified print monitor does not have the required functions. /// ERROR_INVALID_PRINT_MONITOR = 3007, /// /// The specified print monitor is currently in use. /// ERROR_PRINT_MONITOR_IN_USE = 3008, /// /// The requested operation is not allowed when there are jobs queued to the printer. /// ERROR_PRINTER_HAS_JOBS_QUEUED = 3009, /// /// The requested operation is successful. Changes will not be effective until the system is rebooted. /// ERROR_SUCCESS_REBOOT_REQUIRED = 3010, /// /// The requested operation is successful. Changes will not be effective until the service is restarted. /// ERROR_SUCCESS_RESTART_REQUIRED = 3011, /// /// No printers were found. /// ERROR_PRINTER_NOT_FOUND = 3012, /// /// The printer driver is known to be unreliable. /// ERROR_PRINTER_DRIVER_WARNED = 3013, /// /// The printer driver is known to harm the system. /// ERROR_PRINTER_DRIVER_BLOCKED = 3014, /// /// WINS encountered an error while processing the command. /// ERROR_WINS_INTERNAL = 4000, /// /// The local WINS can not be deleted. /// ERROR_CAN_NOT_DEL_LOCAL_WINS = 4001, /// /// The importation from the file failed. /// ERROR_STATIC_INIT = 4002, /// /// The backup failed. Was a full backup done before? /// ERROR_INC_BACKUP = 4003, /// /// The backup failed. Check the directory to which you are backing the database. /// ERROR_FULL_BACKUP = 4004, /// /// The name does not exist in the WINS database. /// ERROR_REC_NON_EXISTENT = 4005, /// /// Replication with a nonconfigured partner is not allowed. /// ERROR_RPL_NOT_ALLOWED = 4006, /// /// The DHCP client has obtained an IP address that is already in use on the network. The local interface will be disabled until the DHCP client can obtain a new address. /// ERROR_DHCP_ADDRESS_CONFLICT = 4100, /// /// The GUID passed was not recognized as valid by a WMI data provider. /// ERROR_WMI_GUID_NOT_FOUND = 4200, /// /// The instance name passed was not recognized as valid by a WMI data provider. /// ERROR_WMI_INSTANCE_NOT_FOUND = 4201, /// /// The data item ID passed was not recognized as valid by a WMI data provider. /// ERROR_WMI_ITEMID_NOT_FOUND = 4202, /// /// The WMI request could not be completed and should be retried. /// ERROR_WMI_TRY_AGAIN = 4203, /// /// The WMI data provider could not be located. /// ERROR_WMI_DP_NOT_FOUND = 4204, /// /// The WMI data provider references an instance set that has not been registered. /// ERROR_WMI_UNRESOLVED_INSTANCE_REF = 4205, /// /// The WMI data block or event notification has already been enabled. /// ERROR_WMI_ALREADY_ENABLED = 4206, /// /// The WMI data block is no longer available. /// ERROR_WMI_GUID_DISCONNECTED = 4207, /// /// The WMI data service is not available. /// ERROR_WMI_SERVER_UNAVAILABLE = 4208, /// /// The WMI data provider failed to carry out the request. /// ERROR_WMI_DP_FAILED = 4209, /// /// The WMI MOF information is not valid. /// ERROR_WMI_INVALID_MOF = 4210, /// /// The WMI registration information is not valid. /// ERROR_WMI_INVALID_REGINFO = 4211, /// /// The WMI data block or event notification has already been disabled. /// ERROR_WMI_ALREADY_DISABLED = 4212, /// /// The WMI data item or data block is read only. /// ERROR_WMI_READ_ONLY = 4213, /// /// The WMI data item or data block could not be changed. /// ERROR_WMI_SET_FAILURE = 4214, /// /// The media identifier does not represent a valid medium. /// ERROR_INVALID_MEDIA = 4300, /// /// The library identifier does not represent a valid library. /// ERROR_INVALID_LIBRARY = 4301, /// /// The media pool identifier does not represent a valid media pool. /// ERROR_INVALID_MEDIA_POOL = 4302, /// /// The drive and medium are not compatible or exist in different libraries. /// ERROR_DRIVE_MEDIA_MISMATCH = 4303, /// /// The medium currently exists in an offline library and must be online to perform this operation. /// ERROR_MEDIA_OFFLINE = 4304, /// /// The operation cannot be performed on an offline library. /// ERROR_LIBRARY_OFFLINE = 4305, /// /// The library, drive, or media pool is empty. /// ERROR_EMPTY = 4306, /// /// The library, drive, or media pool must be empty to perform this operation. /// ERROR_NOT_EMPTY = 4307, /// /// No media is currently available in this media pool or library. /// ERROR_MEDIA_UNAVAILABLE = 4308, /// /// A resource required for this operation is disabled. /// ERROR_RESOURCE_DISABLED = 4309, /// /// The media identifier does not represent a valid cleaner. /// ERROR_INVALID_CLEANER = 4310, /// /// The drive cannot be cleaned or does not support cleaning. /// ERROR_UNABLE_TO_CLEAN = 4311, /// /// The object identifier does not represent a valid object. /// ERROR_OBJECT_NOT_FOUND = 4312, /// /// Unable to read from or write to the database. /// ERROR_DATABASE_FAILURE = 4313, /// /// The database is full. /// ERROR_DATABASE_FULL = 4314, /// /// The medium is not compatible with the device or media pool. /// ERROR_MEDIA_INCOMPATIBLE = 4315, /// /// The resource required for this operation does not exist. /// ERROR_RESOURCE_NOT_PRESENT = 4316, /// /// The operation identifier is not valid. /// ERROR_INVALID_OPERATION = 4317, /// /// The media is not mounted or ready for use. /// ERROR_MEDIA_NOT_AVAILABLE = 4318, /// /// The device is not ready for use. /// ERROR_DEVICE_NOT_AVAILABLE = 4319, /// /// The operator or administrator has refused the request. /// ERROR_REQUEST_REFUSED = 4320, /// /// The drive identifier does not represent a valid drive. /// ERROR_INVALID_DRIVE_OBJECT = 4321, /// /// Library is full. No slot is available for use. /// ERROR_LIBRARY_FULL = 4322, /// /// The transport cannot access the medium. /// ERROR_MEDIUM_NOT_ACCESSIBLE = 4323, /// /// Unable to load the medium into the drive. /// ERROR_UNABLE_TO_LOAD_MEDIUM = 4324, /// /// Unable to retrieve the drive status. /// ERROR_UNABLE_TO_INVENTORY_DRIVE = 4325, /// /// Unable to retrieve the slot status. /// ERROR_UNABLE_TO_INVENTORY_SLOT = 4326, /// /// Unable to retrieve status about the transport. /// ERROR_UNABLE_TO_INVENTORY_TRANSPORT = 4327, /// /// Cannot use the transport because it is already in use. /// ERROR_TRANSPORT_FULL = 4328, /// /// Unable to open or close the inject/eject port. /// ERROR_CONTROLLING_IEPORT = 4329, /// /// Unable to eject the medium because it is in a drive. /// ERROR_UNABLE_TO_EJECT_MOUNTED_MEDIA = 4330, /// /// A cleaner slot is already reserved. /// ERROR_CLEANER_SLOT_SET = 4331, /// /// A cleaner slot is not reserved. /// ERROR_CLEANER_SLOT_NOT_SET = 4332, /// /// The cleaner cartridge has performed the maximum number of drive cleanings. /// ERROR_CLEANER_CARTRIDGE_SPENT = 4333, /// /// Unexpected on-medium identifier. /// ERROR_UNEXPECTED_OMID = 4334, /// /// The last remaining item in this group or resource cannot be deleted. /// ERROR_CANT_DELETE_LAST_ITEM = 4335, /// /// The message provided exceeds the maximum size allowed for this parameter. /// ERROR_MESSAGE_EXCEEDS_MAX_SIZE = 4336, /// /// The volume contains system or paging files. /// ERROR_VOLUME_CONTAINS_SYS_FILES = 4337, /// /// The media type cannot be removed from this library since at least one drive in the library reports it can support this media type. /// ERROR_INDIGENOUS_TYPE = 4338, /// /// This offline media cannot be mounted on this system since no enabled drives are present which can be used. /// ERROR_NO_SUPPORTING_DRIVES = 4339, /// /// A cleaner cartridge is present in the tape library. /// ERROR_CLEANER_CARTRIDGE_INSTALLED = 4340, /// /// The remote storage service was not able to recall the file. /// ERROR_FILE_OFFLINE = 4350, /// /// The remote storage service is not operational at this time. /// ERROR_REMOTE_STORAGE_NOT_ACTIVE = 4351, /// /// The remote storage service encountered a media error. /// ERROR_REMOTE_STORAGE_MEDIA_ERROR = 4352, /// /// The file or directory is not a reparse point. /// ERROR_NOT_A_REPARSE_POINT = 4390, /// /// The reparse point attribute cannot be set because it conflicts with an existing attribute. /// ERROR_REPARSE_ATTRIBUTE_CONFLICT = 4391, /// /// The data present in the reparse point buffer is invalid. /// ERROR_INVALID_REPARSE_DATA = 4392, /// /// The tag present in the reparse point buffer is invalid. /// ERROR_REPARSE_TAG_INVALID = 4393, /// /// There is a mismatch between the tag specified in the request and the tag present in the reparse point. /// ERROR_REPARSE_TAG_MISMATCH = 4394, /// /// Single Instance Storage is not available on this volume. /// ERROR_VOLUME_NOT_SIS_ENABLED = 4500, /// /// The cluster resource cannot be moved to another group because other resources are dependent on it. /// ERROR_DEPENDENT_RESOURCE_EXISTS = 5001, /// /// The cluster resource dependency cannot be found. /// ERROR_DEPENDENCY_NOT_FOUND = 5002, /// /// The cluster resource cannot be made dependent on the specified resource because it is already dependent. /// ERROR_DEPENDENCY_ALREADY_EXISTS = 5003, /// /// The cluster resource is not online. /// ERROR_RESOURCE_NOT_ONLINE = 5004, /// /// A cluster node is not available for this operation. /// ERROR_HOST_NODE_NOT_AVAILABLE = 5005, /// /// The cluster resource is not available. /// ERROR_RESOURCE_NOT_AVAILABLE = 5006, /// /// The cluster resource could not be found. /// ERROR_RESOURCE_NOT_FOUND = 5007, /// /// The cluster is being shut down. /// ERROR_SHUTDOWN_CLUSTER = 5008, /// /// A cluster node cannot be evicted from the cluster unless the node is down or it is the last node. /// ERROR_CANT_EVICT_ACTIVE_NODE = 5009, /// /// The object already exists. /// ERROR_OBJECT_ALREADY_EXISTS = 5010, /// /// The object is already in the list. /// ERROR_OBJECT_IN_LIST = 5011, /// /// The cluster group is not available for any new requests. /// ERROR_GROUP_NOT_AVAILABLE = 5012, /// /// The cluster group could not be found. /// ERROR_GROUP_NOT_FOUND = 5013, /// /// The operation could not be completed because the cluster group is not online. /// ERROR_GROUP_NOT_ONLINE = 5014, /// /// The cluster node is not the owner of the resource. /// ERROR_HOST_NODE_NOT_RESOURCE_OWNER = 5015, /// /// The cluster node is not the owner of the group. /// ERROR_HOST_NODE_NOT_GROUP_OWNER = 5016, /// /// The cluster resource could not be created in the specified resource monitor. /// ERROR_RESMON_CREATE_FAILED = 5017, /// /// The cluster resource could not be brought online by the resource monitor. /// ERROR_RESMON_ONLINE_FAILED = 5018, /// /// The operation could not be completed because the cluster resource is online. /// ERROR_RESOURCE_ONLINE = 5019, /// /// The cluster resource could not be deleted or brought offline because it is the quorum resource. /// ERROR_QUORUM_RESOURCE = 5020, /// /// The cluster could not make the specified resource a quorum resource because it is not capable of being a quorum resource. /// ERROR_NOT_QUORUM_CAPABLE = 5021, /// /// The cluster software is shutting down. /// ERROR_CLUSTER_SHUTTING_DOWN = 5022, /// /// The group or resource is not in the correct state to perform the requested operation. /// ERROR_INVALID_STATE = 5023, /// /// The properties were stored but not all changes will take effect until the next time the resource is brought online. /// ERROR_RESOURCE_PROPERTIES_STORED = 5024, /// /// The cluster could not make the specified resource a quorum resource because it does not belong to a shared storage class. /// ERROR_NOT_QUORUM_CLASS = 5025, /// /// The cluster resource could not be deleted since it is a core resource. /// ERROR_CORE_RESOURCE = 5026, /// /// The quorum resource failed to come online. /// ERROR_QUORUM_RESOURCE_ONLINE_FAILED = 5027, /// /// The quorum log could not be created or mounted successfully. /// ERROR_QUORUMLOG_OPEN_FAILED = 5028, /// /// The cluster log is corrupt. /// ERROR_CLUSTERLOG_CORRUPT = 5029, /// /// The record could not be written to the cluster log since it exceeds the maximum size. /// ERROR_CLUSTERLOG_RECORD_EXCEEDS_MAXSIZE = 5030, /// /// The cluster log exceeds its maximum size. /// ERROR_CLUSTERLOG_EXCEEDS_MAXSIZE = 5031, /// /// No checkpoint record was found in the cluster log. /// ERROR_CLUSTERLOG_CHKPOINT_NOT_FOUND = 5032, /// /// The minimum required disk space needed for logging is not available. /// ERROR_CLUSTERLOG_NOT_ENOUGH_SPACE = 5033, /// /// The cluster node failed to take control of the quorum resource because the resource is owned by another active node. /// ERROR_QUORUM_OWNER_ALIVE = 5034, /// /// A cluster network is not available for this operation. /// ERROR_NETWORK_NOT_AVAILABLE = 5035, /// /// A cluster node is not available for this operation. /// ERROR_NODE_NOT_AVAILABLE = 5036, /// /// All cluster nodes must be running to perform this operation. /// ERROR_ALL_NODES_NOT_AVAILABLE = 5037, /// /// A cluster resource failed. /// ERROR_RESOURCE_FAILED = 5038, /// /// The cluster node is not valid. /// ERROR_CLUSTER_INVALID_NODE = 5039, /// /// The cluster node already exists. /// ERROR_CLUSTER_NODE_EXISTS = 5040, /// /// A node is in the process of joining the cluster. /// ERROR_CLUSTER_JOIN_IN_PROGRESS = 5041, /// /// The cluster node was not found. /// ERROR_CLUSTER_NODE_NOT_FOUND = 5042, /// /// The cluster local node information was not found. /// ERROR_CLUSTER_LOCAL_NODE_NOT_FOUND = 5043, /// /// The cluster network already exists. /// ERROR_CLUSTER_NETWORK_EXISTS = 5044, /// /// The cluster network was not found. /// ERROR_CLUSTER_NETWORK_NOT_FOUND = 5045, /// /// The cluster network interface already exists. /// ERROR_CLUSTER_NETINTERFACE_EXISTS = 5046, /// /// The cluster network interface was not found. /// ERROR_CLUSTER_NETINTERFACE_NOT_FOUND = 5047, /// /// The cluster request is not valid for this object. /// ERROR_CLUSTER_INVALID_REQUEST = 5048, /// /// The cluster network provider is not valid. /// ERROR_CLUSTER_INVALID_NETWORK_PROVIDER = 5049, /// /// The cluster node is down. /// ERROR_CLUSTER_NODE_DOWN = 5050, /// /// The cluster node is not reachable. /// ERROR_CLUSTER_NODE_UNREACHABLE = 5051, /// /// The cluster node is not a member of the cluster. /// ERROR_CLUSTER_NODE_NOT_MEMBER = 5052, /// /// A cluster join operation is not in progress. /// ERROR_CLUSTER_JOIN_NOT_IN_PROGRESS = 5053, /// /// The cluster network is not valid. /// ERROR_CLUSTER_INVALID_NETWORK = 5054, /// /// The cluster node is up. /// ERROR_CLUSTER_NODE_UP = 5056, /// /// The cluster IP address is already in use. /// ERROR_CLUSTER_IPADDR_IN_USE = 5057, /// /// The cluster node is not paused. /// ERROR_CLUSTER_NODE_NOT_PAUSED = 5058, /// /// No cluster security context is available. /// ERROR_CLUSTER_NO_SECURITY_CONTEXT = 5059, /// /// The cluster network is not configured for internal cluster communication. /// ERROR_CLUSTER_NETWORK_NOT_INTERNAL = 5060, /// /// The cluster node is already up. /// ERROR_CLUSTER_NODE_ALREADY_UP = 5061, /// /// The cluster node is already down. /// ERROR_CLUSTER_NODE_ALREADY_DOWN = 5062, /// /// The cluster network is already online. /// ERROR_CLUSTER_NETWORK_ALREADY_ONLINE = 5063, /// /// The cluster network is already offline. /// ERROR_CLUSTER_NETWORK_ALREADY_OFFLINE = 5064, /// /// The cluster node is already a member of the cluster. /// ERROR_CLUSTER_NODE_ALREADY_MEMBER = 5065, /// /// The cluster network is the only one configured for internal cluster communication between two or more active cluster nodes. The internal communication capability cannot be removed from the network. /// ERROR_CLUSTER_LAST_INTERNAL_NETWORK = 5066, /// /// One or more cluster resources depend on the network to provide service to clients. The client access capability cannot be removed from the network. /// ERROR_CLUSTER_NETWORK_HAS_DEPENDENTS = 5067, /// /// This operation cannot be performed on the cluster resource as it the quorum resource. You may not bring the quorum resource offline or modify its possible owners list. /// ERROR_INVALID_OPERATION_ON_QUORUM = 5068, /// /// The cluster quorum resource is not allowed to have any dependencies. /// ERROR_DEPENDENCY_NOT_ALLOWED = 5069, /// /// The cluster node is paused. /// ERROR_CLUSTER_NODE_PAUSED = 5070, /// /// The cluster resource cannot be brought online. The owner node cannot run this resource. /// ERROR_NODE_CANT_HOST_RESOURCE = 5071, /// /// The cluster node is not ready to perform the requested operation. /// ERROR_CLUSTER_NODE_NOT_READY = 5072, /// /// The cluster node is shutting down. /// ERROR_CLUSTER_NODE_SHUTTING_DOWN = 5073, /// /// The cluster join operation was aborted. /// ERROR_CLUSTER_JOIN_ABORTED = 5074, /// /// The cluster join operation failed due to incompatible software versions between the joining node and its sponsor. /// ERROR_CLUSTER_INCOMPATIBLE_VERSIONS = 5075, /// /// This resource cannot be created because the cluster has reached the limit on the number of resources it can monitor. /// ERROR_CLUSTER_MAXNUM_OF_RESOURCES_EXCEEDED = 5076, /// /// The system configuration changed during the cluster join or form operation. The join or form operation was aborted. /// ERROR_CLUSTER_SYSTEM_CONFIG_CHANGED = 5077, /// /// The specified resource type was not found. /// ERROR_CLUSTER_RESOURCE_TYPE_NOT_FOUND = 5078, /// /// The specified node does not support a resource of this type. This may be due to version inconsistencies or due to the absence of the resource DLL on this node. /// ERROR_CLUSTER_RESTYPE_NOT_SUPPORTED = 5079, /// /// The specified resource name is not supported by this resource DLL. This may be due to a bad (or changed) name supplied to the resource DLL. /// ERROR_CLUSTER_RESNAME_NOT_FOUND = 5080, /// /// No authentication package could be registered with the RPC server. /// ERROR_CLUSTER_NO_RPC_PACKAGES_REGISTERED = 5081, /// /// You cannot bring the group online because the owner of the group is not in the preferred list for the group. To change the owner node for the group, move the group. /// ERROR_CLUSTER_OWNER_NOT_IN_PREFLIST = 5082, /// /// The join operation failed because the cluster database sequence number has changed or is incompatible with the locker node. This may happen during a join operation if the cluster database was changing during the join. /// ERROR_CLUSTER_DATABASE_SEQMISMATCH = 5083, /// /// The resource monitor will not allow the fail operation to be performed while the resource is in its current state. This may happen if the resource is in a pending state. /// ERROR_RESMON_INVALID_STATE = 5084, /// /// A non locker code got a request to reserve the lock for making global updates. /// ERROR_CLUSTER_GUM_NOT_LOCKER = 5085, /// /// The quorum disk could not be located by the cluster service. /// ERROR_QUORUM_DISK_NOT_FOUND = 5086, /// /// The backed up cluster database is possibly corrupt. /// ERROR_DATABASE_BACKUP_CORRUPT = 5087, /// /// A DFS root already exists in this cluster node. /// ERROR_CLUSTER_NODE_ALREADY_HAS_DFS_ROOT = 5088, /// /// An attempt to modify a resource property failed because it conflicts with another existing property. /// ERROR_RESOURCE_PROPERTY_UNCHANGEABLE = 5089, /// /// An operation was attempted that is incompatible with the current membership state of the node. /// ERROR_CLUSTER_MEMBERSHIP_INVALID_STATE = 5890, /// /// The quorum resource does not contain the quorum log. /// ERROR_CLUSTER_QUORUMLOG_NOT_FOUND = 5891, /// /// The membership engine requested shutdown of the cluster service on this node. /// ERROR_CLUSTER_MEMBERSHIP_HALT = 5892, /// /// The join operation failed because the cluster instance ID of the joining node does not match the cluster instance ID of the sponsor node. /// ERROR_CLUSTER_INSTANCE_ID_MISMATCH = 5893, /// /// A matching network for the specified IP address could not be found. Please also specify a subnet mask and a cluster network. /// ERROR_CLUSTER_NETWORK_NOT_FOUND_FOR_IP = 5894, /// /// The actual data type of the property did not match the expected data type of the property. /// ERROR_CLUSTER_PROPERTY_DATA_TYPE_MISMATCH = 5895, /// /// The cluster node was evicted from the cluster successfully, but the node was not cleaned up. Extended status information explaining why the node was not cleaned up is available. /// ERROR_CLUSTER_EVICT_WITHOUT_CLEANUP = 5896, /// /// Two or more parameter values specified for a resource's properties are in conflict. /// ERROR_CLUSTER_PARAMETER_MISMATCH = 5897, /// /// This computer cannot be made a member of a cluster. /// ERROR_NODE_CANNOT_BE_CLUSTERED = 5898, /// /// This computer cannot be made a member of a cluster because it does not have the correct version of Windows installed. /// ERROR_CLUSTER_WRONG_OS_VERSION = 5899, /// /// A cluster cannot be created with the specified cluster name because that cluster name is already in use. Specify a different name for the cluster. /// ERROR_CLUSTER_CANT_CREATE_DUP_CLUSTER_NAME = 5900, /// /// No information avialable. /// ERROR_CLUSCFG_ALREADY_COMMITTED = 5901, /// /// No information avialable. /// ERROR_CLUSCFG_ROLLBACK_FAILED = 5902, /// /// No information avialable. /// ERROR_CLUSCFG_SYSTEM_DISK_DRIVE_LETTER_CONFLICT = 5903, /// /// No information avialable. /// ERROR_CLUSTER_OLD_VERSION = 5904, /// /// No information avialable. /// ERROR_CLUSTER_MISMATCHED_COMPUTER_ACCT_NAME = 5905, /// /// The specified file could not be encrypted. /// ERROR_ENCRYPTION_FAILED = 6000, /// /// The specified file could not be decrypted. /// ERROR_DECRYPTION_FAILED = 6001, /// /// The specified file is encrypted and the user does not have the ability to decrypt it. /// ERROR_FILE_ENCRYPTED = 6002, /// /// There is no valid encryption recovery policy configured for this system. /// ERROR_NO_RECOVERY_POLICY = 6003, /// /// The required encryption driver is not loaded for this system. /// ERROR_NO_EFS = 6004, /// /// The file was encrypted with a different encryption driver than is currently loaded. /// ERROR_WRONG_EFS = 6005, /// /// There are no EFS keys defined for the user. /// ERROR_NO_USER_KEYS = 6006, /// /// The specified file is not encrypted. /// ERROR_FILE_NOT_ENCRYPTED = 6007, /// /// The specified file is not in the defined EFS export format. /// ERROR_NOT_EXPORT_FORMAT = 6008, /// /// The specified file is read only. /// ERROR_FILE_READ_ONLY = 6009, /// /// The directory has been disabled for encryption. /// ERROR_DIR_EFS_DISALLOWED = 6010, /// /// The server is not trusted for remote encryption operation. /// ERROR_EFS_SERVER_NOT_TRUSTED = 6011, /// /// Recovery policy configured for this system contains invalid recovery certificate. /// ERROR_BAD_RECOVERY_POLICY = 6012, /// /// The encryption algorithm used on the source file needs a bigger key buffer than the one on the destination file. /// ERROR_EFS_ALG_BLOB_TOO_BIG = 6013, /// /// The disk partition does not support file encryption. /// ERROR_VOLUME_NOT_SUPPORT_EFS = 6014, /// /// This machine is disabled for file encryption. /// ERROR_EFS_DISABLED = 6015, /// /// A newer system is required to decrypt this encrypted file. /// ERROR_EFS_VERSION_NOT_SUPPORT = 6016, /// /// The list of servers for this workgroup is not currently available /// ERROR_NO_BROWSER_SERVERS_FOUND = 6118, /// /// The Task Scheduler service must be configured to run in the System account to function properly. Individual tasks may be configured to run in other accounts. /// SCHED_E_SERVICE_NOT_LOCALSYSTEM = 6200, /// /// The specified session name is invalid. /// ERROR_CTX_WINSTATION_NAME_INVALID = 7001, /// /// The specified protocol driver is invalid. /// ERROR_CTX_INVALID_PD = 7002, /// /// The specified protocol driver was not found in the system path. /// ERROR_CTX_PD_NOT_FOUND = 7003, /// /// The specified terminal connection driver was not found in the system path. /// ERROR_CTX_WD_NOT_FOUND = 7004, /// /// A registry key for event logging could not be created for this session. /// ERROR_CTX_CANNOT_MAKE_EVENTLOG_ENTRY = 7005, /// /// A service with the same name already exists on the system. /// ERROR_CTX_SERVICE_NAME_COLLISION = 7006, /// /// A close operation is pending on the session. /// ERROR_CTX_CLOSE_PENDING = 7007, /// /// There are no free output buffers available. /// ERROR_CTX_NO_OUTBUF = 7008, /// /// The MODEM.INF file was not found. /// ERROR_CTX_MODEM_INF_NOT_FOUND = 7009, /// /// The modem name was not found in MODEM.INF. /// ERROR_CTX_INVALID_MODEMNAME = 7010, /// /// The modem did not accept the command sent to it. Verify that the configured modem name matches the attached modem. /// ERROR_CTX_MODEM_RESPONSE_ERROR = 7011, /// /// The modem did not respond to the command sent to it. Verify that the modem is properly cabled and powered on. /// ERROR_CTX_MODEM_RESPONSE_TIMEOUT = 7012, /// /// Carrier detect has failed or carrier has been dropped due to disconnect. /// ERROR_CTX_MODEM_RESPONSE_NO_CARRIER = 7013, /// /// Dial tone not detected within the required time. Verify that the phone cable is properly attached and functional. /// ERROR_CTX_MODEM_RESPONSE_NO_DIALTONE = 7014, /// /// Busy signal detected at remote site on callback. /// ERROR_CTX_MODEM_RESPONSE_BUSY = 7015, /// /// Voice detected at remote site on callback. /// ERROR_CTX_MODEM_RESPONSE_VOICE = 7016, /// /// Transport driver error /// ERROR_CTX_TD_ERROR = 7017, /// /// The specified session cannot be found. /// ERROR_CTX_WINSTATION_NOT_FOUND = 7022, /// /// The specified session name is already in use. /// ERROR_CTX_WINSTATION_ALREADY_EXISTS = 7023, /// /// The requested operation cannot be completed because the terminal connection is currently busy processing a connect, disconnect, reset, or delete operation. /// ERROR_CTX_WINSTATION_BUSY = 7024, /// /// An attempt has been made to connect to a session whose video mode is not supported by the current client. /// ERROR_CTX_BAD_VIDEO_MODE = 7025, /// /// The application attempted to enable DOS graphics mode. /// DOS graphics mode is not supported. /// ERROR_CTX_GRAPHICS_INVALID = 7035, /// /// Your interactive logon privilege has been disabled. /// Please contact your administrator. /// ERROR_CTX_LOGON_DISABLED = 7037, /// /// The requested operation can be performed only on the system console. /// This is most often the result of a driver or system DLL requiring direct console access. /// ERROR_CTX_NOT_CONSOLE = 7038, /// /// The client failed to respond to the server connect message. /// ERROR_CTX_CLIENT_QUERY_TIMEOUT = 7040, /// /// Disconnecting the console session is not supported. /// ERROR_CTX_CONSOLE_DISCONNECT = 7041, /// /// Reconnecting a disconnected session to the console is not supported. /// ERROR_CTX_CONSOLE_CONNECT = 7042, /// /// The request to control another session remotely was denied. /// ERROR_CTX_SHADOW_DENIED = 7044, /// /// The requested session access is denied. /// ERROR_CTX_WINSTATION_ACCESS_DENIED = 7045, /// /// The specified terminal connection driver is invalid. /// ERROR_CTX_INVALID_WD = 7049, /// /// The requested session cannot be controlled remotely. /// This may be because the session is disconnected or does not currently have a user logged on. /// ERROR_CTX_SHADOW_INVALID = 7050, /// /// The requested session is not configured to allow remote control. /// ERROR_CTX_SHADOW_DISABLED = 7051, /// /// Your request to connect to this Terminal Server has been rejected. Your Terminal Server client license number is currently being used by another user. /// Please call your system administrator to obtain a unique license number. /// ERROR_CTX_CLIENT_LICENSE_IN_USE = 7052, /// /// Your request to connect to this Terminal Server has been rejected. Your Terminal Server client license number has not been entered for this copy of the Terminal Server client. /// Please contact your system administrator. /// ERROR_CTX_CLIENT_LICENSE_NOT_SET = 7053, /// /// The system has reached its licensed logon limit. /// Please try again later. /// ERROR_CTX_LICENSE_NOT_AVAILABLE = 7054, /// /// The client you are using is not licensed to use this system. Your logon request is denied. /// ERROR_CTX_LICENSE_CLIENT_INVALID = 7055, /// /// The system license has expired. Your logon request is denied. /// ERROR_CTX_LICENSE_EXPIRED = 7056, /// /// Remote control could not be terminated because the specified session is not currently being remotely controlled. /// ERROR_CTX_SHADOW_NOT_RUNNING = 7057, /// /// The remote control of the console was terminated because the display mode was changed. Changing the display mode in a remote control session is not supported. /// ERROR_CTX_SHADOW_ENDED_BY_MODE_CHANGE = 7058, /// /// No information avialable. /// ERROR_ACTIVATION_COUNT_EXCEEDED = 7059, /// /// The file replication service API was called incorrectly. /// FRS_ERR_INVALID_API_SEQUENCE = 8001, /// /// The file replication service cannot be started. /// FRS_ERR_STARTING_SERVICE = 8002, /// /// The file replication service cannot be stopped. /// FRS_ERR_STOPPING_SERVICE = 8003, /// /// The file replication service API terminated the request. /// The event log may have more information. /// FRS_ERR_INTERNAL_API = 8004, /// /// The file replication service terminated the request. /// The event log may have more information. /// FRS_ERR_INTERNAL = 8005, /// /// The file replication service cannot be contacted. /// The event log may have more information. /// FRS_ERR_SERVICE_COMM = 8006, /// /// The file replication service cannot satisfy the request because the user has insufficient privileges. /// The event log may have more information. /// FRS_ERR_INSUFFICIENT_PRIV = 8007, /// /// The file replication service cannot satisfy the request because authenticated RPC is not available. /// The event log may have more information. /// FRS_ERR_AUTHENTICATION = 8008, /// /// The file replication service cannot satisfy the request because the user has insufficient privileges on the domain controller. /// The event log may have more information. /// FRS_ERR_PARENT_INSUFFICIENT_PRIV = 8009, /// /// The file replication service cannot satisfy the request because authenticated RPC is not available on the domain controller. /// The event log may have more information. /// FRS_ERR_PARENT_AUTHENTICATION = 8010, /// /// The file replication service cannot communicate with the file replication service on the domain controller. /// The event log may have more information. /// FRS_ERR_CHILD_TO_PARENT_COMM = 8011, /// /// The file replication service on the domain controller cannot communicate with the file replication service on this computer. /// The event log may have more information. /// FRS_ERR_PARENT_TO_CHILD_COMM = 8012, /// /// The file replication service cannot populate the system volume because of an internal error. /// The event log may have more information. /// FRS_ERR_SYSVOL_POPULATE = 8013, /// /// The file replication service cannot populate the system volume because of an internal timeout. /// The event log may have more information. /// FRS_ERR_SYSVOL_POPULATE_TIMEOUT = 8014, /// /// The file replication service cannot process the request. The system volume is busy with a previous request. /// FRS_ERR_SYSVOL_IS_BUSY = 8015, /// /// The file replication service cannot stop replicating the system volume because of an internal error. /// The event log may have more information. /// FRS_ERR_SYSVOL_DEMOTE = 8016, /// /// The file replication service detected an invalid parameter. /// FRS_ERR_INVALID_SERVICE_PARAMETER = 8017, /// /// An error occurred while installing the directory service. For more information, see the event log. /// ERROR_DS_NOT_INSTALLED = 8200, /// /// The directory service evaluated group memberships locally. /// ERROR_DS_MEMBERSHIP_EVALUATED_LOCALLY = 8201, /// /// The specified directory service attribute or value does not exist. /// ERROR_DS_NO_ATTRIBUTE_OR_VALUE = 8202, /// /// The attribute syntax specified to the directory service is invalid. /// ERROR_DS_INVALID_ATTRIBUTE_SYNTAX = 8203, /// /// The attribute type specified to the directory service is not defined. /// ERROR_DS_ATTRIBUTE_TYPE_UNDEFINED = 8204, /// /// The specified directory service attribute or value already exists. /// ERROR_DS_ATTRIBUTE_OR_VALUE_EXISTS = 8205, /// /// The directory service is busy. /// ERROR_DS_BUSY = 8206, /// /// The directory service is unavailable. /// ERROR_DS_UNAVAILABLE = 8207, /// /// The directory service was unable to allocate a relative identifier. /// ERROR_DS_NO_RIDS_ALLOCATED = 8208, /// /// The directory service has exhausted the pool of relative identifiers. /// ERROR_DS_NO_MORE_RIDS = 8209, /// /// The requested operation could not be performed because the directory service is not the master for that type of operation. /// ERROR_DS_INCORRECT_ROLE_OWNER = 8210, /// /// The directory service was unable to initialize the subsystem that allocates relative identifiers. /// ERROR_DS_RIDMGR_INIT_ERROR = 8211, /// /// The requested operation did not satisfy one or more constraints associated with the class of the object. /// ERROR_DS_OBJ_CLASS_VIOLATION = 8212, /// /// The directory service can perform the requested operation only on a leaf object. /// ERROR_DS_CANT_ON_NON_LEAF = 8213, /// /// The directory service cannot perform the requested operation on the RDN attribute of an object. /// ERROR_DS_CANT_ON_RDN = 8214, /// /// The directory service detected an attempt to modify the object class of an object. /// ERROR_DS_CANT_MOD_OBJ_CLASS = 8215, /// /// The requested cross-domain move operation could not be performed. /// ERROR_DS_CROSS_DOM_MOVE_ERROR = 8216, /// /// Unable to contact the global catalog server. /// ERROR_DS_GC_NOT_AVAILABLE = 8217, /// /// The policy object is shared and can only be modified at the root. /// ERROR_SHARED_POLICY = 8218, /// /// The policy object does not exist. /// ERROR_POLICY_OBJECT_NOT_FOUND = 8219, /// /// The requested policy information is only in the directory service. /// ERROR_POLICY_ONLY_IN_DS = 8220, /// /// A domain controller promotion is currently active. /// ERROR_PROMOTION_ACTIVE = 8221, /// /// A domain controller promotion is not currently active /// ERROR_NO_PROMOTION_ACTIVE = 8222, /// /// An operations error occurred. /// ERROR_DS_OPERATIONS_ERROR = 8224, /// /// A protocol error occurred. /// ERROR_DS_PROTOCOL_ERROR = 8225, /// /// The time limit for this request was exceeded. /// ERROR_DS_TIMELIMIT_EXCEEDED = 8226, /// /// The size limit for this request was exceeded. /// ERROR_DS_SIZELIMIT_EXCEEDED = 8227, /// /// The administrative limit for this request was exceeded. /// ERROR_DS_ADMIN_LIMIT_EXCEEDED = 8228, /// /// The compare response was false. /// ERROR_DS_COMPARE_FALSE = 8229, /// /// The compare response was true. /// ERROR_DS_COMPARE_TRUE = 8230, /// /// The requested authentication method is not supported by the server. /// ERROR_DS_AUTH_METHOD_NOT_SUPPORTED = 8231, /// /// A more secure authentication method is required for this server. /// ERROR_DS_STRONG_AUTH_REQUIRED = 8232, /// /// Inappropriate authentication. /// ERROR_DS_INAPPROPRIATE_AUTH = 8233, /// /// The authentication mechanism is unknown. /// ERROR_DS_AUTH_UNKNOWN = 8234, /// /// A referral was returned from the server. /// ERROR_DS_REFERRAL = 8235, /// /// The server does not support the requested critical extension. /// ERROR_DS_UNAVAILABLE_CRIT_EXTENSION = 8236, /// /// This request requires a secure connection. /// ERROR_DS_CONFIDENTIALITY_REQUIRED = 8237, /// /// Inappropriate matching. /// ERROR_DS_INAPPROPRIATE_MATCHING = 8238, /// /// A constraint violation occurred. /// ERROR_DS_CONSTRAINT_VIOLATION = 8239, /// /// There is no such object on the server. /// ERROR_DS_NO_SUCH_OBJECT = 8240, /// /// There is an alias problem. /// ERROR_DS_ALIAS_PROBLEM = 8241, /// /// An invalid dn syntax has been specified. /// ERROR_DS_INVALID_DN_SYNTAX = 8242, /// /// The object is a leaf object. /// ERROR_DS_IS_LEAF = 8243, /// /// There is an alias dereferencing problem. /// ERROR_DS_ALIAS_DEREF_PROBLEM = 8244, /// /// The server is unwilling to process the request. /// ERROR_DS_UNWILLING_TO_PERFORM = 8245, /// /// A loop has been detected. /// ERROR_DS_LOOP_DETECT = 8246, /// /// There is a naming violation. /// ERROR_DS_NAMING_VIOLATION = 8247, /// /// The result set is too large. /// ERROR_DS_OBJECT_RESULTS_TOO_LARGE = 8248, /// /// The operation affects multiple DSAs /// ERROR_DS_AFFECTS_MULTIPLE_DSAS = 8249, /// /// The server is not operational. /// ERROR_DS_SERVER_DOWN = 8250, /// /// A local error has occurred. /// ERROR_DS_LOCAL_ERROR = 8251, /// /// An encoding error has occurred. /// ERROR_DS_ENCODING_ERROR = 8252, /// /// A decoding error has occurred. /// ERROR_DS_DECODING_ERROR = 8253, /// /// The search filter cannot be recognized. /// ERROR_DS_FILTER_UNKNOWN = 8254, /// /// One or more parameters are illegal. /// ERROR_DS_PARAM_ERROR = 8255, /// /// The specified method is not supported. /// ERROR_DS_NOT_SUPPORTED = 8256, /// /// No results were returned. /// ERROR_DS_NO_RESULTS_RETURNED = 8257, /// /// The specified control is not supported by the server. /// ERROR_DS_CONTROL_NOT_FOUND = 8258, /// /// A referral loop was detected by the client. /// ERROR_DS_CLIENT_LOOP = 8259, /// /// The preset referral limit was exceeded. /// ERROR_DS_REFERRAL_LIMIT_EXCEEDED = 8260, /// /// The search requires a SORT control. /// ERROR_DS_SORT_CONTROL_MISSING = 8261, /// /// The search results exceed the offset range specified. /// ERROR_DS_OFFSET_RANGE_ERROR = 8262, /// /// The root object must be the head of a naming context. The root object cannot have an instantiated parent. /// ERROR_DS_ROOT_MUST_BE_NC = 8301, /// /// The add replica operation cannot be performed. The naming context must be writable in order to create the replica. /// ERROR_DS_ADD_REPLICA_INHIBITED = 8302, /// /// A reference to an attribute that is not defined in the schema occurred. /// ERROR_DS_ATT_NOT_DEF_IN_SCHEMA = 8303, /// /// The maximum size of an object has been exceeded. /// ERROR_DS_MAX_OBJ_SIZE_EXCEEDED = 8304, /// /// An attempt was made to add an object to the directory with a name that is already in use. /// ERROR_DS_OBJ_STRING_NAME_EXISTS = 8305, /// /// An attempt was made to add an object of a class that does not have an RDN defined in the schema. /// ERROR_DS_NO_RDN_DEFINED_IN_SCHEMA = 8306, /// /// An attempt was made to add an object using an RDN that is not the RDN defined in the schema. /// ERROR_DS_RDN_DOESNT_MATCH_SCHEMA = 8307, /// /// None of the requested attributes were found on the objects. /// ERROR_DS_NO_REQUESTED_ATTS_FOUND = 8308, /// /// The user buffer is too small. /// ERROR_DS_USER_BUFFER_TO_SMALL = 8309, /// /// The attribute specified in the operation is not present on the object. /// ERROR_DS_ATT_IS_NOT_ON_OBJ = 8310, /// /// Illegal modify operation. Some aspect of the modification is not permitted. /// ERROR_DS_ILLEGAL_MOD_OPERATION = 8311, /// /// The specified object is too large. /// ERROR_DS_OBJ_TOO_LARGE = 8312, /// /// The specified instance type is not valid. /// ERROR_DS_BAD_INSTANCE_TYPE = 8313, /// /// The operation must be performed at a master DSA. /// ERROR_DS_MASTERDSA_REQUIRED = 8314, /// /// The object class attribute must be specified. /// ERROR_DS_OBJECT_CLASS_REQUIRED = 8315, /// /// A required attribute is missing. /// ERROR_DS_MISSING_REQUIRED_ATT = 8316, /// /// An attempt was made to modify an object to include an attribute that is not legal for its class. /// ERROR_DS_ATT_NOT_DEF_FOR_CLASS = 8317, /// /// The specified attribute is already present on the object. /// ERROR_DS_ATT_ALREADY_EXISTS = 8318, /// /// The specified attribute is not present, or has no values. /// ERROR_DS_CANT_ADD_ATT_VALUES = 8320, /// /// Mutliple values were specified for an attribute that can have only one value. /// ERROR_DS_SINGLE_VALUE_CONSTRAINT = 8321, /// /// A value for the attribute was not in the acceptable range of values. /// ERROR_DS_RANGE_CONSTRAINT = 8322, /// /// The specified value already exists. /// ERROR_DS_ATT_VAL_ALREADY_EXISTS = 8323, /// /// The attribute cannot be removed because it is not present on the object. /// ERROR_DS_CANT_REM_MISSING_ATT = 8324, /// /// The attribute value cannot be removed because it is not present on the object. /// ERROR_DS_CANT_REM_MISSING_ATT_VAL = 8325, /// /// The specified root object cannot be a subref. /// ERROR_DS_ROOT_CANT_BE_SUBREF = 8326, /// /// Chaining is not permitted. /// ERROR_DS_NO_CHAINING = 8327, /// /// Chained evaluation is not permitted. /// ERROR_DS_NO_CHAINED_EVAL = 8328, /// /// The operation could not be performed because the object's parent is either uninstantiated or deleted. /// ERROR_DS_NO_PARENT_OBJECT = 8329, /// /// Having a parent that is an alias is not permitted. Aliases are leaf objects. /// ERROR_DS_PARENT_IS_AN_ALIAS = 8330, /// /// The object and parent must be of the same type, either both masters or both replicas. /// ERROR_DS_CANT_MIX_MASTER_AND_REPS = 8331, /// /// The operation cannot be performed because child objects exist. This operation can only be performed on a leaf object. /// ERROR_DS_CHILDREN_EXIST = 8332, /// /// Directory object not found. /// ERROR_DS_OBJ_NOT_FOUND = 8333, /// /// The aliased object is missing. /// ERROR_DS_ALIASED_OBJ_MISSING = 8334, /// /// The object name has bad syntax. /// ERROR_DS_BAD_NAME_SYNTAX = 8335, /// /// It is not permitted for an alias to refer to another alias. /// ERROR_DS_ALIAS_POINTS_TO_ALIAS = 8336, /// /// The alias cannot be dereferenced. /// ERROR_DS_CANT_DEREF_ALIAS = 8337, /// /// The operation is out of scope. /// ERROR_DS_OUT_OF_SCOPE = 8338, /// /// The operation cannot continue because the object is in the process of being removed. /// ERROR_DS_OBJECT_BEING_REMOVED = 8339, /// /// The DSA object cannot be deleted. /// ERROR_DS_CANT_DELETE_DSA_OBJ = 8340, /// /// A directory service error has occurred. /// ERROR_DS_GENERIC_ERROR = 8341, /// /// The operation can only be performed on an internal master DSA object. /// ERROR_DS_DSA_MUST_BE_INT_MASTER = 8342, /// /// The object must be of class DSA. /// ERROR_DS_CLASS_NOT_DSA = 8343, /// /// Insufficient access rights to perform the operation. /// ERROR_DS_INSUFF_ACCESS_RIGHTS = 8344, /// /// The object cannot be added because the parent is not on the list of possible superiors. /// ERROR_DS_ILLEGAL_SUPERIOR = 8345, /// /// Access to the attribute is not permitted because the attribute is owned by the Security Accounts Manager (SAM). /// ERROR_DS_ATTRIBUTE_OWNED_BY_SAM = 8346, /// /// The name has too many parts. /// ERROR_DS_NAME_TOO_MANY_PARTS = 8347, /// /// The name is too long. /// ERROR_DS_NAME_TOO_Int32 = 8348, /// /// The name value is too long. /// ERROR_DS_NAME_VALUE_TOO_Int32 = 8349, /// /// The directory service encountered an error parsing a name. /// ERROR_DS_NAME_UNPARSEABLE = 8350, /// /// The directory service cannot get the attribute type for a name. /// ERROR_DS_NAME_TYPE_UNKNOWN = 8351, /// /// The name does not identify an object, the name identifies a phantom. /// ERROR_DS_NOT_AN_OBJECT = 8352, /// /// The security descriptor is too short. /// ERROR_DS_SEC_DESC_TOO_Int16 = 8353, /// /// The security descriptor is invalid. /// ERROR_DS_SEC_DESC_INVALID = 8354, /// /// Failed to create name for deleted object. /// ERROR_DS_NO_DELETED_NAME = 8355, /// /// The parent of a new subref must exist. /// ERROR_DS_SUBREF_MUST_HAVE_PARENT = 8356, /// /// The object must be a naming context. /// ERROR_DS_NCNAME_MUST_BE_NC = 8357, /// /// It is not permitted to add an attribute which is owned by the system. /// ERROR_DS_CANT_ADD_SYSTEM_ONLY = 8358, /// /// The class of the object must be structural, you cannot instantiate an abstract class. /// ERROR_DS_CLASS_MUST_BE_CONCRETE = 8359, /// /// The schema object could not be found. /// ERROR_DS_INVALID_DMD = 8360, /// /// A local object with this GUID (dead or alive) already exists. /// ERROR_DS_OBJ_GUID_EXISTS = 8361, /// /// The operation cannot be performed on a back link. /// ERROR_DS_NOT_ON_BACKLINK = 8362, /// /// The cross reference for the specified naming context could not be found. /// ERROR_DS_NO_CROSSREF_FOR_NC = 8363, /// /// The operation could not be performed because the directory service is shutting down. /// ERROR_DS_SHUTTING_DOWN = 8364, /// /// The directory service request is invalid. /// ERROR_DS_UNKNOWN_OPERATION = 8365, /// /// The role owner attribute could not be read. /// ERROR_DS_INVALID_ROLE_OWNER = 8366, /// /// The requested FSMO operation failed. The current FSMO holder could not be contacted. /// ERROR_DS_COULDNT_CONTACT_FSMO = 8367, /// /// Modification of a DN across a naming context is not permitted. /// ERROR_DS_CROSS_NC_DN_RENAME = 8368, /// /// The attribute cannot be modified because it is owned by the system. /// ERROR_DS_CANT_MOD_SYSTEM_ONLY = 8369, /// /// Only the replicator can perform this function. /// ERROR_DS_REPLICATOR_ONLY = 8370, /// /// The specified class is not defined. /// ERROR_DS_OBJ_CLASS_NOT_DEFINED = 8371, /// /// The specified class is not a subclass. /// ERROR_DS_OBJ_CLASS_NOT_SUBCLASS = 8372, /// /// The name reference is invalid. /// ERROR_DS_NAME_REFERENCE_INVALID = 8373, /// /// A cross reference already exists. /// ERROR_DS_CROSS_REF_EXISTS = 8374, /// /// It is not permitted to delete a master cross reference. /// ERROR_DS_CANT_DEL_MASTER_CROSSREF = 8375, /// /// Subtree notifications are only supported on NC heads. /// ERROR_DS_SUBTREE_NOTIFY_NOT_NC_HEAD = 8376, /// /// Notification filter is too complex. /// ERROR_DS_NOTIFY_FILTER_TOO_COMPLEX = 8377, /// /// Schema update failed: duplicate RDN. /// ERROR_DS_DUP_RDN = 8378, /// /// Schema update failed: duplicate OID. /// ERROR_DS_DUP_OID = 8379, /// /// Schema update failed: duplicate MAPI identifier. /// ERROR_DS_DUP_MAPI_ID = 8380, /// /// Schema update failed: duplicate schema-id GUID. /// ERROR_DS_DUP_SCHEMA_ID_GUID = 8381, /// /// Schema update failed: duplicate LDAP display name. /// ERROR_DS_DUP_LDAP_DISPLAY_NAME = 8382, /// /// Schema update failed: range-lower less than range upper. /// ERROR_DS_SEMANTIC_ATT_TEST = 8383, /// /// Schema update failed: syntax mismatch. /// ERROR_DS_SYNTAX_MISMATCH = 8384, /// /// Schema deletion failed: attribute is used in must-contain. /// ERROR_DS_EXISTS_IN_MUST_HAVE = 8385, /// /// Schema deletion failed: attribute is used in may-contain. /// ERROR_DS_EXISTS_IN_MAY_HAVE = 8386, /// /// Schema update failed: attribute in may-contain does not exist. /// ERROR_DS_NONEXISTENT_MAY_HAVE = 8387, /// /// Schema update failed: attribute in must-contain does not exist. /// ERROR_DS_NONEXISTENT_MUST_HAVE = 8388, /// /// Schema update failed: class in aux-class list does not exist or is not an auxiliary class. /// ERROR_DS_AUX_CLS_TEST_FAIL = 8389, /// /// Schema update failed: class in poss-superiors does not exist. /// ERROR_DS_NONEXISTENT_POSS_SUP = 8390, /// /// Schema update failed: class in subclassof list does not exist or does not satisfy hierarchy rules. /// ERROR_DS_SUB_CLS_TEST_FAIL = 8391, /// /// Schema update failed: Rdn-Att-Id has wrong syntax. /// ERROR_DS_BAD_RDN_ATT_ID_SYNTAX = 8392, /// /// Schema deletion failed: class is used as auxiliary class. /// ERROR_DS_EXISTS_IN_AUX_CLS = 8393, /// /// Schema deletion failed: class is used as sub class. /// ERROR_DS_EXISTS_IN_SUB_CLS = 8394, /// /// Schema deletion failed: class is used as poss superior. /// ERROR_DS_EXISTS_IN_POSS_SUP = 8395, /// /// Schema update failed in recalculating validation cache. /// ERROR_DS_RECALCSCHEMA_FAILED = 8396, /// /// The tree deletion is not finished. The request must be made again to continue deleting the tree. /// ERROR_DS_TREE_DELETE_NOT_FINISHED = 8397, /// /// The requested delete operation could not be performed. /// ERROR_DS_CANT_DELETE = 8398, /// /// Cannot read the governs class identifier for the schema record. /// ERROR_DS_ATT_SCHEMA_REQ_ID = 8399, /// /// The attribute schema has bad syntax. /// ERROR_DS_BAD_ATT_SCHEMA_SYNTAX = 8400, /// /// The attribute could not be cached. /// ERROR_DS_CANT_CACHE_ATT = 8401, /// /// The class could not be cached. /// ERROR_DS_CANT_CACHE_CLASS = 8402, /// /// The attribute could not be removed from the cache. /// ERROR_DS_CANT_REMOVE_ATT_CACHE = 8403, /// /// The class could not be removed from the cache. /// ERROR_DS_CANT_REMOVE_CLASS_CACHE = 8404, /// /// The distinguished name attribute could not be read. /// ERROR_DS_CANT_RETRIEVE_DN = 8405, /// /// A required subref is missing. /// ERROR_DS_MISSING_SUPREF = 8406, /// /// The instance type attribute could not be retrieved. /// ERROR_DS_CANT_RETRIEVE_INSTANCE = 8407, /// /// An internal error has occurred. /// ERROR_DS_CODE_INCONSISTENCY = 8408, /// /// A database error has occurred. /// ERROR_DS_DATABASE_ERROR = 8409, /// /// The attribute GOVERNSID is missing. /// ERROR_DS_GOVERNSID_MISSING = 8410, /// /// An expected attribute is missing. /// ERROR_DS_MISSING_EXPECTED_ATT = 8411, /// /// The specified naming context is missing a cross reference. /// ERROR_DS_NCNAME_MISSING_CR_REF = 8412, /// /// A security checking error has occurred. /// ERROR_DS_SECURITY_CHECKING_ERROR = 8413, /// /// The schema is not loaded. /// ERROR_DS_SCHEMA_NOT_LOADED = 8414, /// /// Schema allocation failed. Please check if the machine is running low on memory. /// ERROR_DS_SCHEMA_ALLOC_FAILED = 8415, /// /// Failed to obtain the required syntax for the attribute schema. /// ERROR_DS_ATT_SCHEMA_REQ_SYNTAX = 8416, /// /// The global catalog verification failed. The global catalog is not available or does not support the operation. Some part of the directory is currently not available. /// ERROR_DS_GCVERIFY_ERROR = 8417, /// /// The replication operation failed because of a schema mismatch between the servers involved. /// ERROR_DS_DRA_SCHEMA_MISMATCH = 8418, /// /// The DSA object could not be found. /// ERROR_DS_CANT_FIND_DSA_OBJ = 8419, /// /// The naming context could not be found. /// ERROR_DS_CANT_FIND_EXPECTED_NC = 8420, /// /// The naming context could not be found in the cache. /// ERROR_DS_CANT_FIND_NC_IN_CACHE = 8421, /// /// The child object could not be retrieved. /// ERROR_DS_CANT_RETRIEVE_CHILD = 8422, /// /// The modification was not permitted for security reasons. /// ERROR_DS_SECURITY_ILLEGAL_MODIFY = 8423, /// /// The operation cannot replace the hidden record. /// ERROR_DS_CANT_REPLACE_HIDDEN_REC = 8424, /// /// The hierarchy file is invalid. /// ERROR_DS_BAD_HIERARCHY_FILE = 8425, /// /// The attempt to build the hierarchy table failed. /// ERROR_DS_BUILD_HIERARCHY_TABLE_FAILED = 8426, /// /// The directory configuration parameter is missing from the registry. /// ERROR_DS_CONFIG_PARAM_MISSING = 8427, /// /// The attempt to count the address book indices failed. /// ERROR_DS_COUNTING_AB_INDICES_FAILED = 8428, /// /// The allocation of the hierarchy table failed. /// ERROR_DS_HIERARCHY_TABLE_MALLOC_FAILED = 8429, /// /// The directory service encountered an internal failure. /// ERROR_DS_INTERNAL_FAILURE = 8430, /// /// The directory service encountered an unknown failure. /// ERROR_DS_UNKNOWN_ERROR = 8431, /// /// A root object requires a class of 'top'. /// ERROR_DS_ROOT_REQUIRES_CLASS_TOP = 8432, /// /// This directory server is shutting down, and cannot take ownership of new floating single-master operation roles. /// ERROR_DS_REFUSING_FSMO_ROLES = 8433, /// /// The directory service is missing mandatory configuration information, and is unable to determine the ownership of floating single-master operation roles. /// ERROR_DS_MISSING_FSMO_SETTINGS = 8434, /// /// The directory service was unable to transfer ownership of one or more floating single-master operation roles to other servers. /// ERROR_DS_UNABLE_TO_SURRENDER_ROLES = 8435, /// /// The replication operation failed. /// ERROR_DS_DRA_GENERIC = 8436, /// /// An invalid parameter was specified for this replication operation. /// ERROR_DS_DRA_INVALID_PARAMETER = 8437, /// /// The directory service is too busy to complete the replication operation at this time. /// ERROR_DS_DRA_BUSY = 8438, /// /// The distinguished name specified for this replication operation is invalid. /// ERROR_DS_DRA_BAD_DN = 8439, /// /// The naming context specified for this replication operation is invalid. /// ERROR_DS_DRA_BAD_NC = 8440, /// /// The distinguished name specified for this replication operation already exists. /// ERROR_DS_DRA_DN_EXISTS = 8441, /// /// The replication system encountered an internal error. /// ERROR_DS_DRA_INTERNAL_ERROR = 8442, /// /// The replication operation encountered a database inconsistency. /// ERROR_DS_DRA_INCONSISTENT_DIT = 8443, /// /// The server specified for this replication operation could not be contacted. /// ERROR_DS_DRA_CONNECTION_FAILED = 8444, /// /// The replication operation encountered an object with an invalid instance type. /// ERROR_DS_DRA_BAD_INSTANCE_TYPE = 8445, /// /// The replication operation failed to allocate memory. /// ERROR_DS_DRA_OUT_OF_MEM = 8446, /// /// The replication operation encountered an error with the mail system. /// ERROR_DS_DRA_MAIL_PROBLEM = 8447, /// /// The replication reference information for the target server already exists. /// ERROR_DS_DRA_REF_ALREADY_EXISTS = 8448, /// /// The replication reference information for the target server does not exist. /// ERROR_DS_DRA_REF_NOT_FOUND = 8449, /// /// The naming context cannot be removed because it is replicated to another server. /// ERROR_DS_DRA_OBJ_IS_REP_SOURCE = 8450, /// /// The replication operation encountered a database error. /// ERROR_DS_DRA_DB_ERROR = 8451, /// /// The naming context is in the process of being removed or is not replicated from the specified server. /// ERROR_DS_DRA_NO_REPLICA = 8452, /// /// Replication access was denied. /// ERROR_DS_DRA_ACCESS_DENIED = 8453, /// /// The requested operation is not supported by this version of the directory service. /// ERROR_DS_DRA_NOT_SUPPORTED = 8454, /// /// The replication remote procedure call was cancelled. /// ERROR_DS_DRA_RPC_CANCELLED = 8455, /// /// The source server is currently rejecting replication requests. /// ERROR_DS_DRA_SOURCE_DISABLED = 8456, /// /// The destination server is currently rejecting replication requests. /// ERROR_DS_DRA_SINK_DISABLED = 8457, /// /// The replication operation failed due to a collision of object names. /// ERROR_DS_DRA_NAME_COLLISION = 8458, /// /// The replication source has been reinstalled. /// ERROR_DS_DRA_SOURCE_REINSTALLED = 8459, /// /// The replication operation failed because a required parent object is missing. /// ERROR_DS_DRA_MISSING_PARENT = 8460, /// /// The replication operation was preempted. /// ERROR_DS_DRA_PREEMPTED = 8461, /// /// The replication synchronization attempt was abandoned because of a lack of updates. /// ERROR_DS_DRA_ABANDON_SYNC = 8462, /// /// The replication operation was terminated because the system is shutting down. /// ERROR_DS_DRA_SHUTDOWN = 8463, /// /// The replication synchronization attempt failed as the destination partial attribute set is not a subset of source partial attribute set. /// ERROR_DS_DRA_INCOMPATIBLE_PARTIAL_SET = 8464, /// /// The replication synchronization attempt failed because a master replica attempted to sync from a partial replica. /// ERROR_DS_DRA_SOURCE_IS_PARTIAL_REPLICA = 8465, /// /// The server specified for this replication operation was contacted, but that server was unable to contact an additional server needed to complete the operation. /// ERROR_DS_DRA_EXTN_CONNECTION_FAILED = 8466, /// /// The version of the Active Directory schema of the source forest is not compatible with the version of Active Directory on this computer. You must upgrade the operating system on a domain controller in the source forest before this computer can be added as a domain controller to that forest. /// ERROR_DS_INSTALL_SCHEMA_MISMATCH = 8467, /// /// Schema update failed: An attribute with the same link identifier already exists. /// ERROR_DS_DUP_LINK_ID = 8468, /// /// Name translation: Generic processing error. /// ERROR_DS_NAME_ERROR_RESOLVING = 8469, /// /// Name translation: Could not find the name or insufficient right to see name. /// ERROR_DS_NAME_ERROR_NOT_FOUND = 8470, /// /// Name translation: Input name mapped to more than one output name. /// ERROR_DS_NAME_ERROR_NOT_UNIQUE = 8471, /// /// Name translation: Input name found, but not the associated output format. /// ERROR_DS_NAME_ERROR_NO_MAPPING = 8472, /// /// Name translation: Unable to resolve completely, only the domain was found. /// ERROR_DS_NAME_ERROR_DOMAIN_ONLY = 8473, /// /// Name translation: Unable to perform purely syntactical mapping at the client without going out to the wire. /// ERROR_DS_NAME_ERROR_NO_SYNTACTICAL_MAPPING = 8474, /// /// Modification of a constructed att is not allowed. /// ERROR_DS_CONSTRUCTED_ATT_MOD = 8475, /// /// The OM-Object-Class specified is incorrect for an attribute with the specified syntax. /// ERROR_DS_WRONG_OM_OBJ_CLASS = 8476, /// /// The replication request has been posted, waiting for reply. /// ERROR_DS_DRA_REPL_PENDING = 8477, /// /// The requested operation requires a directory service, and none was available. /// ERROR_DS_DS_REQUIRED = 8478, /// /// The LDAP display name of the class or attribute contains non-ASCII characters. /// ERROR_DS_INVALID_LDAP_DISPLAY_NAME = 8479, /// /// The requested search operation is only supported for base searches. /// ERROR_DS_NON_BASE_SEARCH = 8480, /// /// The search failed to retrieve attributes from the database. /// ERROR_DS_CANT_RETRIEVE_ATTS = 8481, /// /// The schema update operation tried to add a backward link attribute that has no corresponding forward link. /// ERROR_DS_BACKLINK_WITHOUT_LINK = 8482, /// /// Source and destination of a cross-domain move do not agree on the object's epoch number. Either source or destination does not have the latest version of the object. /// ERROR_DS_EPOCH_MISMATCH = 8483, /// /// Source and destination of a cross-domain move do not agree on the object's current name. Either source or destination does not have the latest version of the object. /// ERROR_DS_SRC_NAME_MISMATCH = 8484, /// /// Source and destination for the cross-domain move operation are identical. Caller should use local move operation instead of cross-domain move operation. /// ERROR_DS_SRC_AND_DST_NC_IDENTICAL = 8485, /// /// Source and destination for a cross-domain move are not in agreement on the naming contexts in the forest. Either source or destination does not have the latest version of the Partitions container. /// ERROR_DS_DST_NC_MISMATCH = 8486, /// /// Destination of a cross-domain move is not authoritative for the destination naming context. /// ERROR_DS_NOT_AUTHORITIVE_FOR_DST_NC = 8487, /// /// Source and destination of a cross-domain move do not agree on the identity of the source object. Either source or destination does not have the latest version of the source object. /// ERROR_DS_SRC_GUID_MISMATCH = 8488, /// /// Object being moved across-domains is already known to be deleted by the destination server. The source server does not have the latest version of the source object. /// ERROR_DS_CANT_MOVE_DELETED_OBJECT = 8489, /// /// Another operation which requires exclusive access to the PDC FSMO is already in progress. /// ERROR_DS_PDC_OPERATION_IN_PROGRESS = 8490, /// /// A cross-domain move operation failed such that two versions of the moved object exist - one each in the source and destination domains. The destination object needs to be removed to restore the system to a consistent state. /// ERROR_DS_CROSS_DOMAIN_CLEANUP_REQD = 8491, /// /// This object may not be moved across domain boundaries either because cross-domain moves for this class are disallowed, or the object has some special characteristics, eg: trust account or restricted RID, which prevent its move. /// ERROR_DS_ILLEGAL_XDOM_MOVE_OPERATION = 8492, /// /// Can't move objects with memberships across domain boundaries as once moved, this would violate the membership conditions of the account group. Remove the object from any account group memberships and retry. /// ERROR_DS_CANT_WITH_ACCT_GROUP_MEMBERSHPS = 8493, /// /// A naming context head must be the immediate child of another naming context head, not of an interior node. /// ERROR_DS_NC_MUST_HAVE_NC_PARENT = 8494, /// /// The directory cannot validate the proposed naming context name because it does not hold a replica of the naming context above the proposed naming context. Please ensure that the domain naming master role is held by a server that is configured as a global catalog server, and that the server is up to date with its replication partners. (Applies only to Windows 2000 Domain Naming masters) /// ERROR_DS_CR_IMPOSSIBLE_TO_VALIDATE = 8495, /// /// Destination domain must be in native mode. /// ERROR_DS_DST_DOMAIN_NOT_NATIVE = 8496, /// /// The operation can not be performed because the server does not have an infrastructure container in the domain of interest. /// ERROR_DS_MISSING_INFRASTRUCTURE_CONTAINER = 8497, /// /// Cross-domain move of non-empty account groups is not allowed. /// ERROR_DS_CANT_MOVE_ACCOUNT_GROUP = 8498, /// /// Cross-domain move of non-empty resource groups is not allowed. /// ERROR_DS_CANT_MOVE_RESOURCE_GROUP = 8499, /// /// The search flags for the attribute are invalid. The ANR bit is valid only on attributes of Unicode or Teletex strings. /// ERROR_DS_INVALID_SEARCH_FLAG = 8500, /// /// Tree deletions starting at an object which has an NC head as a descendant are not allowed. /// ERROR_DS_NO_TREE_DELETE_ABOVE_NC = 8501, /// /// The directory service failed to lock a tree in preparation for a tree deletion because the tree was in use. /// ERROR_DS_COULDNT_LOCK_TREE_FOR_DELETE = 8502, /// /// The directory service failed to identify the list of objects to delete while attempting a tree deletion. /// ERROR_DS_COULDNT_IDENTIFY_OBJECTS_FOR_TREE_DELETE = 8503, /// /// Security Accounts Manager initialization failed because of the following error: %1. /// Error Status: 0x%2. Click OK to shut down the system and reboot into Directory Services Restore Mode. Check the event log for detailed information. /// ERROR_DS_SAM_INIT_FAILURE = 8504, /// /// Only an administrator can modify the membership list of an administrative group. /// ERROR_DS_SENSITIVE_GROUP_VIOLATION = 8505, /// /// Cannot change the primary group ID of a domain controller account. /// ERROR_DS_CANT_MOD_PRIMARYGROUPID = 8506, /// /// An attempt is made to modify the base schema. /// ERROR_DS_ILLEGAL_BASE_SCHEMA_MOD = 8507, /// /// Adding a new mandatory attribute to an existing class, deleting a mandatory attribute from an existing class, or adding an optional attribute to the special class Top that is not a backlink attribute (directly or through inheritance, for example, by adding or deleting an auxiliary class) is not allowed. /// ERROR_DS_NONSAFE_SCHEMA_CHANGE = 8508, /// /// Schema update is not allowed on this DC because the DC is not the schema FSMO Role Owner. /// ERROR_DS_SCHEMA_UPDATE_DISALLOWED = 8509, /// /// An object of this class cannot be created under the schema container. You can only create attribute-schema and class-schema objects under the schema container. /// ERROR_DS_CANT_CREATE_UNDER_SCHEMA = 8510, /// /// The replica/child install failed to get the objectVersion attribute on the schema container on the source DC. Either the attribute is missing on the schema container or the credentials supplied do not have permission to read it. /// ERROR_DS_INSTALL_NO_SRC_SCH_VERSION = 8511, /// /// The replica/child install failed to read the objectVersion attribute in the SCHEMA section of the file schema.ini in the system32 directory. /// ERROR_DS_INSTALL_NO_SCH_VERSION_IN_INIFILE = 8512, /// /// The specified group type is invalid. /// ERROR_DS_INVALID_GROUP_TYPE = 8513, /// /// You cannot nest global groups in a mixed domain if the group is security-enabled. /// ERROR_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN = 8514, /// /// You cannot nest local groups in a mixed domain if the group is security-enabled. /// ERROR_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN = 8515, /// /// A global group cannot have a local group as a member. /// ERROR_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER = 8516, /// /// A global group cannot have a universal group as a member. /// ERROR_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER = 8517, /// /// A universal group cannot have a local group as a member. /// ERROR_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER = 8518, /// /// A global group cannot have a cross-domain member. /// ERROR_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER = 8519, /// /// A local group cannot have another cross domain local group as a member. /// ERROR_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER = 8520, /// /// A group with primary members cannot change to a security-disabled group. /// ERROR_DS_HAVE_PRIMARY_MEMBERS = 8521, /// /// The schema cache load failed to convert the string default SD on a class-schema object. /// ERROR_DS_STRING_SD_CONVERSION_FAILED = 8522, /// /// Only DSAs configured to be Global Catalog servers should be allowed to hold the Domain Naming Master FSMO role. (Applies only to Windows 2000 servers) /// ERROR_DS_NAMING_MASTER_GC = 8523, /// /// The DSA operation is unable to proceed because of a DNS lookup failure. /// ERROR_DS_DNS_LOOKUP_FAILURE = 8524, /// /// While processing a change to the DNS Host Name for an object, the Service Principal Name values could not be kept in sync. /// ERROR_DS_COULDNT_UPDATE_SPNS = 8525, /// /// The Security Descriptor attribute could not be read. /// ERROR_DS_CANT_RETRIEVE_SD = 8526, /// /// The object requested was not found, but an object with that key was found. /// ERROR_DS_KEY_NOT_UNIQUE = 8527, /// /// The syntax of the linked attribute being added is incorrect. Forward links can only have syntax 2.5.5.1, 2.5.5.7, and 2.5.5.14, and backlinks can only have syntax 2.5.5.1 /// ERROR_DS_WRONG_LINKED_ATT_SYNTAX = 8528, /// /// Security Account Manager needs to get the boot password. /// ERROR_DS_SAM_NEED_BOOTKEY_PASSUInt16 = 8529, /// /// Security Account Manager needs to get the boot key from floppy disk. /// ERROR_DS_SAM_NEED_BOOTKEY_FLOPPY = 8530, /// /// Directory Service cannot start. /// ERROR_DS_CANT_START = 8531, /// /// Directory Services could not start. /// ERROR_DS_INIT_FAILURE = 8532, /// /// The connection between client and server requires packet privacy or better. /// ERROR_DS_NO_PKT_PRIVACY_ON_CONNECTION = 8533, /// /// The source domain may not be in the same forest as destination. /// ERROR_DS_SOURCE_DOMAIN_IN_FOREST = 8534, /// /// The destination domain must be in the forest. /// ERROR_DS_DESTINATION_DOMAIN_NOT_IN_FOREST = 8535, /// /// The operation requires that destination domain auditing be enabled. /// ERROR_DS_DESTINATION_AUDITING_NOT_ENABLED = 8536, /// /// The operation couldn't locate a DC for the source domain. /// ERROR_DS_CANT_FIND_DC_FOR_SRC_DOMAIN = 8537, /// /// The source object must be a group or user. /// ERROR_DS_SRC_OBJ_NOT_GROUP_OR_USER = 8538, /// /// The source object's SID already exists in destination forest. /// ERROR_DS_SRC_SID_EXISTS_IN_FOREST = 8539, /// /// The source and destination object must be of the same type. /// ERROR_DS_SRC_AND_DST_OBJECT_CLASS_MISMATCH = 8540, /// /// Security Accounts Manager initialization failed because of the following error: %1. /// Error Status: 0x%2. Click OK to shut down the system and reboot into Safe Mode. Check the event log for detailed information. /// ERROR_SAM_INIT_FAILURE = 8541, /// /// Schema information could not be included in the replication request. /// ERROR_DS_DRA_SCHEMA_INFO_SHIP = 8542, /// /// The replication operation could not be completed due to a schema incompatibility. /// ERROR_DS_DRA_SCHEMA_CONFLICT = 8543, /// /// The replication operation could not be completed due to a previous schema incompatibility. /// ERROR_DS_DRA_EARLIER_SCHEMA_CONFLICT = 8544, /// /// The replication update could not be applied because either the source or the destination has not yet received information regarding a recent cross-domain move operation. /// ERROR_DS_DRA_OBJ_NC_MISMATCH = 8545, /// /// The requested domain could not be deleted because there exist domain controllers that still host this domain. /// ERROR_DS_NC_STILL_HAS_DSAS = 8546, /// /// The requested operation can be performed only on a global catalog server. /// ERROR_DS_GC_REQUIRED = 8547, /// /// A local group can only be a member of other local groups in the same domain. /// ERROR_DS_LOCAL_MEMBER_OF_LOCAL_ONLY = 8548, /// /// Foreign security principals cannot be members of universal groups. /// ERROR_DS_NO_FPO_IN_UNIVERSAL_GROUPS = 8549, /// /// The attribute is not allowed to be replicated to the GC because of security reasons. /// ERROR_DS_CANT_ADD_TO_GC = 8550, /// /// The checkpoint with the PDC could not be taken because there too many modifications being processed currently. /// ERROR_DS_NO_CHECKPOINT_WITH_PDC = 8551, /// /// The operation requires that source domain auditing be enabled. /// ERROR_DS_SOURCE_AUDITING_NOT_ENABLED = 8552, /// /// Security principal objects can only be created inside domain naming contexts. /// ERROR_DS_CANT_CREATE_IN_NONDOMAIN_NC = 8553, /// /// A Service Principal Name (SPN) could not be constructed because the provided hostname is not in the necessary format. /// ERROR_DS_INVALID_NAME_FOR_SPN = 8554, /// /// A Filter was passed that uses constructed attributes. /// ERROR_DS_FILTER_USES_CONTRUCTED_ATTRS = 8555, /// /// The unicodePwd attribute value must be enclosed in double quotes. /// ERROR_DS_UNICODEPWD_NOT_IN_QUOTES = 8556, /// /// Your computer could not be joined to the domain. You have exceeded the maximum number of computer accounts you are allowed to create in this domain. Contact your system administrator to have this limit reset or increased. /// ERROR_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED = 8557, /// /// For security reasons, the operation must be run on the destination DC. /// ERROR_DS_MUST_BE_RUN_ON_DST_DC = 8558, /// /// For security reasons, the source DC must be NT4SP4 or greater. /// ERROR_DS_SRC_DC_MUST_BE_SP4_OR_GREATER = 8559, /// /// Critical Directory Service System objects cannot be deleted during tree delete operations. The tree delete may have been partially performed. /// ERROR_DS_CANT_TREE_DELETE_CRITICAL_OBJ = 8560, /// /// Directory Services could not start because of the following error: %1. /// Error Status: 0x%2. Please click OK to shutdown the system. You can use the recovery console to diagnose the system further. /// ERROR_DS_INIT_FAILURE_CONSOLE = 8561, /// /// Security Accounts Manager initialization failed because of the following error: %1. /// Error Status: 0x%2. Please click OK to shutdown the system. You can use the recovery console to diagnose the system further. /// ERROR_DS_SAM_INIT_FAILURE_CONSOLE = 8562, /// /// This version of Windows is too old to support the current directory forest behavior. You must upgrade the operating system on this server before it can become a domain controller in this forest. /// ERROR_DS_FOREST_VERSION_TOO_HIGH = 8563, /// /// This version of Windows is too old to support the current domain behavior. You must upgrade the operating system on this server before it can become a domain controller in this domain. /// ERROR_DS_DOMAIN_VERSION_TOO_HIGH = 8564, /// /// This version of Windows no longer supports the behavior version in use in this directory forest. You must advance the forest behavior version before this server can become a domain controller in the forest. /// ERROR_DS_FOREST_VERSION_TOO_LOW = 8565, /// /// This version of Windows no longer supports the behavior version in use in this domain. You must advance the domain behavior version before this server can become a domain controller in the domain. /// ERROR_DS_DOMAIN_VERSION_TOO_LOW = 8566, /// /// The version of Windows is incompatible with the behavior version of the domain or forest. /// ERROR_DS_INCOMPATIBLE_VERSION = 8567, /// /// The behavior version cannot be increased to the requested value because Domain Controllers still exist with versions lower than the requested value. /// ERROR_DS_LOW_DSA_VERSION = 8568, /// /// The behavior version value cannot be increased while the domain is still in mixed domain mode. You must first change the domain to native mode before increasing the behavior version. /// ERROR_DS_NO_BEHAVIOR_VERSION_IN_MIXEDDOMAIN = 8569, /// /// The sort order requested is not supported. /// ERROR_DS_NOT_SUPPORTED_SORT_ORDER = 8570, /// /// Found an object with a non unique name. /// ERROR_DS_NAME_NOT_UNIQUE = 8571, /// /// The machine account was created pre-NT4. The account needs to be recreated. /// ERROR_DS_MACHINE_ACCOUNT_CREATED_PRENT4 = 8572, /// /// The database is out of version store. /// ERROR_DS_OUT_OF_VERSION_STORE = 8573, /// /// Unable to continue operation because multiple conflicting controls were used. /// ERROR_DS_INCOMPATIBLE_CONTROLS_USED = 8574, /// /// Unable to find a valid security descriptor reference domain for this partition. /// ERROR_DS_NO_REF_DOMAIN = 8575, /// /// Schema update failed: The link identifier is reserved. /// ERROR_DS_RESERVED_LINK_ID = 8576, /// /// Schema update failed: There are no link identifiers available. /// ERROR_DS_LINK_ID_NOT_AVAILABLE = 8577, /// /// A account group can not have a universal group as a member. /// ERROR_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER = 8578, /// /// Rename or move operations on naming context heads or read-only objects are not allowed. /// ERROR_DS_MODIFYDN_DISALLOWED_BY_INSTANCE_TYPE = 8579, /// /// Move operations on objects in the schema naming context are not allowed. /// ERROR_DS_NO_OBJECT_MOVE_IN_SCHEMA_NC = 8580, /// /// A system flag has been set on the object and does not allow the object to be moved or renamed. /// ERROR_DS_MODIFYDN_DISALLOWED_BY_FLAG = 8581, /// /// This object is not allowed to change its grandparent container. Moves are not forbidden on this object, but are restricted to sibling containers. /// ERROR_DS_MODIFYDN_WRONG_GRANDPARENT = 8582, /// /// Unable to resolve completely, a referral to another forest is generated. /// ERROR_DS_NAME_ERROR_TRUST_REFERRAL = 8583, /// /// The requested action is not supported on standard server. /// ERROR_NOT_SUPPORTED_ON_STANDARD_SERVER = 8584, /// /// Could not access a partition of the Active Directory located on a remote server. Make sure at least one server is running for the partition in question. /// ERROR_DS_CANT_ACCESS_REMOTE_PART_OF_AD = 8585, /// /// The directory cannot validate the proposed naming context (or partition) name because it does not hold a replica nor can it contact a replica of the naming context above the proposed naming context. Please ensure that the parent naming context is properly registered in DNS, and at least one replica of this naming context is reachable by the Domain Naming master. /// ERROR_DS_CR_IMPOSSIBLE_TO_VALIDATE_V2 = 8586, /// /// The thread limit for this request was exceeded. /// ERROR_DS_THREAD_LIMIT_EXCEEDED = 8587, /// /// The Global catalog server is not in the closest site. /// ERROR_DS_NOT_CLOSEST = 8588, /// /// The DS cannot derive a service principal name (SPN) with which to mutually authenticate the target server because the corresponding server object in the local DS database has no serverReference attribute. /// ERROR_DS_CANT_DERIVE_SPN_WITHOUT_SERVER_REF = 8589, /// /// The Directory Service failed to enter single user mode. /// ERROR_DS_SINGLE_USER_MODE_FAILED = 8590, /// /// The Directory Service cannot parse the script because of a syntax error. /// ERROR_DS_NTDSCRIPT_SYNTAX_ERROR = 8591, /// /// The Directory Service cannot process the script because of an error. /// ERROR_DS_NTDSCRIPT_PROCESS_ERROR = 8592, /// /// The directory service cannot perform the requested operation because the servers /// involved are of different replication epochs (which is usually related to a /// domain rename that is in progress). /// ERROR_DS_DIFFERENT_REPL_EPOCHS = 8593, /// /// The directory service binding must be renegotiated due to a change in the server /// extensions information. /// ERROR_DS_DRS_EXTENSIONS_CHANGED = 8594, /// /// Operation not allowed on a disabled cross ref. /// ERROR_DS_REPLICA_SET_CHANGE_NOT_ALLOWED_ON_DISABLED_CR = 8595, /// /// Schema update failed: No values for msDS-IntId are available. /// ERROR_DS_NO_MSDS_INTID = 8596, /// /// Schema update failed: Duplicate msDS-INtId. Retry the operation. /// ERROR_DS_DUP_MSDS_INTID = 8597, /// /// Schema deletion failed: attribute is used in rDNAttID. /// ERROR_DS_EXISTS_IN_RDNATTID = 8598, /// /// The directory service failed to authorize the request. /// ERROR_DS_AUTHORIZATION_FAILED = 8599, /// /// The Directory Service cannot process the script because it is invalid. /// ERROR_DS_INVALID_SCRIPT = 8600, /// /// The remote create cross reference operation failed on the Domain Naming Master FSMO. The operation's error is in the extended data. /// ERROR_DS_REMOTE_CROSSREF_OP_FAILED = 8601, /// /// No information avialable. /// ERROR_DS_CROSS_REF_BUSY = 8602, /// /// No information avialable. /// ERROR_DS_CANT_DERIVE_SPN_FOR_DELETED_DOMAIN = 8603, /// /// No information avialable. /// ERROR_DS_CANT_DEMOTE_WITH_WRITEABLE_NC = 8604, /// /// No information avialable. /// ERROR_DS_DUPLICATE_ID_FOUND = 8605, /// /// No information avialable. /// ERROR_DS_INSUFFICIENT_ATTR_TO_CREATE_OBJECT = 8606, /// /// No information avialable. /// ERROR_DS_GROUP_CONVERSION_ERROR = 8607, /// /// No information avialable. /// ERROR_DS_CANT_MOVE_APP_BASIC_GROUP = 8608, /// /// No information avialable. /// ERROR_DS_CANT_MOVE_APP_QUERY_GROUP = 8609, /// /// No information avialable. /// ERROR_DS_ROLE_NOT_VERIFIED = 8610, /// /// No information avialable. /// ERROR_DS_WKO_CONTAINER_CANNOT_BE_SPECIAL = 8611, /// /// No information avialable. /// ERROR_DS_DOMAIN_RENAME_IN_PROGRESS = 8612, /// /// No information avialable. /// ERROR_DS_EXISTING_AD_CHILD_NC = 8613, /// /// No information avialable. /// ERROR_DS_REPL_LIFETIME_EXCEEDED = 8614, /// /// No information avialable. /// ERROR_DS_DISALLOWED_IN_SYSTEM_CONTAINER = 8615, /// /// No information avialable. /// ERROR_DS_LDAP_SEND_QUEUE_FULL = 8616, /// /// No information avialable. /// DNS_ERROR_RESPONSE_CODES_BASE = 9000, /// /// DNS server unable to interpret format. /// DNS_ERROR_RCODE_FORMAT_ERROR = 9001, /// /// DNS server failure. /// DNS_ERROR_RCODE_SERVER_FAILURE = 9002, /// /// DNS name does not exist. /// DNS_ERROR_RCODE_NAME_ERROR = 9003, /// /// DNS request not supported by name server. /// DNS_ERROR_RCODE_NOT_IMPLEMENTED = 9004, /// /// DNS operation refused. /// DNS_ERROR_RCODE_REFUSED = 9005, /// /// DNS name that ought not exist, does exist. /// DNS_ERROR_RCODE_YXDOMAIN = 9006, /// /// DNS RR set that ought not exist, does exist. /// DNS_ERROR_RCODE_YXRRSET = 9007, /// /// DNS RR set that ought to exist, does not exist. /// DNS_ERROR_RCODE_NXRRSET = 9008, /// /// DNS server not authoritative for zone. /// DNS_ERROR_RCODE_NOTAUTH = 9009, /// /// DNS name in update or prereq is not in zone. /// DNS_ERROR_RCODE_NOTZONE = 9010, /// /// DNS signature failed to verify. /// DNS_ERROR_RCODE_BADSIG = 9016, /// /// DNS bad key. /// DNS_ERROR_RCODE_BADKEY = 9017, /// /// DNS signature validity expired. /// DNS_ERROR_RCODE_BADTIME = 9018, /// /// No information avialable. /// DNS_ERROR_PACKET_FMT_BASE = 9500, /// /// No records found for given DNS query. /// DNS_INFO_NO_RECORDS = 9501, /// /// Bad DNS packet. /// DNS_ERROR_BAD_PACKET = 9502, /// /// No DNS packet. /// DNS_ERROR_NO_PACKET = 9503, /// /// DNS error, check rcode. /// DNS_ERROR_RCODE = 9504, /// /// Unsecured DNS packet. /// DNS_ERROR_UNSECURE_PACKET = 9505, /// /// No information avialable. /// DNS_ERROR_NO_MEMORY = ERROR_OUTOFMEMORY, /// /// No information avialable. /// DNS_ERROR_INVALID_NAME = ERROR_INVALID_NAME, /// /// No information avialable. /// DNS_ERROR_INVALID_DATA = ERROR_INVALID_DATA, /// /// No information avialable. /// DNS_ERROR_GENERAL_API_BASE = 9550, /// /// Invalid DNS type. /// DNS_ERROR_INVALID_TYPE = 9551, /// /// Invalid IP address. /// DNS_ERROR_INVALID_IP_ADDRESS = 9552, /// /// Invalid property. /// DNS_ERROR_INVALID_PROPERTY = 9553, /// /// Try DNS operation again later. /// DNS_ERROR_TRY_AGAIN_LATER = 9554, /// /// Record for given name and type is not unique. /// DNS_ERROR_NOT_UNIQUE = 9555, /// /// DNS name does not comply with RFC specifications. /// DNS_ERROR_NON_RFC_NAME = 9556, /// /// DNS name is a fully-qualified DNS name. /// DNS_STATUS_FQDN = 9557, /// /// DNS name is dotted (multi-label). /// DNS_STATUS_DOTTED_NAME = 9558, /// /// DNS name is a single-part name. /// DNS_STATUS_SINGLE_PART_NAME = 9559, /// /// DNS name contains an invalid character. /// DNS_ERROR_INVALID_NAME_CHAR = 9560, /// /// DNS name is entirely numeric. /// DNS_ERROR_NUMERIC_NAME = 9561, /// /// The operation requested is not permitted on a DNS root server. /// DNS_ERROR_NOT_ALLOWED_ON_ROOT_SERVER = 9562, /// /// No information avialable. /// DNS_ERROR_NOT_ALLOWED_UNDER_DELEGATION = 9563, /// /// No information avialable. /// DNS_ERROR_CANNOT_FIND_ROOT_HINTS = 9564, /// /// No information avialable. /// DNS_ERROR_INCONSISTENT_ROOT_HINTS = 9565, /// /// No information avialable. /// DNS_ERROR_ZONE_BASE = 9600, /// /// DNS zone does not exist. /// DNS_ERROR_ZONE_DOES_NOT_EXIST = 9601, /// /// DNS zone information not available. /// DNS_ERROR_NO_ZONE_INFO = 9602, /// /// Invalid operation for DNS zone. /// DNS_ERROR_INVALID_ZONE_OPERATION = 9603, /// /// Invalid DNS zone configuration. /// DNS_ERROR_ZONE_CONFIGURATION_ERROR = 9604, /// /// DNS zone has no start of authority (SOA) record. /// DNS_ERROR_ZONE_HAS_NO_SOA_RECORD = 9605, /// /// DNS zone has no Name Server (NS) record. /// DNS_ERROR_ZONE_HAS_NO_NS_RECORDS = 9606, /// /// DNS zone is locked. /// DNS_ERROR_ZONE_LOCKED = 9607, /// /// DNS zone creation failed. /// DNS_ERROR_ZONE_CREATION_FAILED = 9608, /// /// DNS zone already exists. /// DNS_ERROR_ZONE_ALREADY_EXISTS = 9609, /// /// DNS automatic zone already exists. /// DNS_ERROR_AUTOZONE_ALREADY_EXISTS = 9610, /// /// Invalid DNS zone type. /// DNS_ERROR_INVALID_ZONE_TYPE = 9611, /// /// Secondary DNS zone requires master IP address. /// DNS_ERROR_SECONDARY_REQUIRES_MASTER_IP = 9612, /// /// DNS zone not secondary. /// DNS_ERROR_ZONE_NOT_SECONDARY = 9613, /// /// Need secondary IP address. /// DNS_ERROR_NEED_SECONDARY_ADDRESSES = 9614, /// /// WINS initialization failed. /// DNS_ERROR_WINS_INIT_FAILED = 9615, /// /// Need WINS servers. /// DNS_ERROR_NEED_WINS_SERVERS = 9616, /// /// NBTSTAT initialization call failed. /// DNS_ERROR_NBSTAT_INIT_FAILED = 9617, /// /// Invalid delete of start of authority (SOA) /// DNS_ERROR_SOA_DELETE_INVALID = 9618, /// /// A conditional forwarding zone already exists for that name. /// DNS_ERROR_FORWARDER_ALREADY_EXISTS = 9619, /// /// This zone must be configured with one or more master DNS server IP addresses. /// DNS_ERROR_ZONE_REQUIRES_MASTER_IP = 9620, /// /// The operation cannot be performed because this zone is shutdown. /// DNS_ERROR_ZONE_IS_SHUTDOWN = 9621, /// /// No information avialable. /// DNS_ERROR_DATAFILE_BASE = 9650, /// /// Primary DNS zone requires datafile. /// DNS_ERROR_PRIMARY_REQUIRES_DATAFILE = 9651, /// /// Invalid datafile name for DNS zone. /// DNS_ERROR_INVALID_DATAFILE_NAME = 9652, /// /// Failed to open datafile for DNS zone. /// DNS_ERROR_DATAFILE_OPEN_FAILURE = 9653, /// /// Failed to write datafile for DNS zone. /// DNS_ERROR_FILE_WRITEBACK_FAILED = 9654, /// /// Failure while reading datafile for DNS zone. /// DNS_ERROR_DATAFILE_PARSING = 9655, /// /// No information avialable. /// DNS_ERROR_DATABASE_BASE = 9700, /// /// DNS record does not exist. /// DNS_ERROR_RECORD_DOES_NOT_EXIST = 9701, /// /// DNS record format error. /// DNS_ERROR_RECORD_FORMAT = 9702, /// /// Node creation failure in DNS. /// DNS_ERROR_NODE_CREATION_FAILED = 9703, /// /// Unknown DNS record type. /// DNS_ERROR_UNKNOWN_RECORD_TYPE = 9704, /// /// DNS record timed out. /// DNS_ERROR_RECORD_TIMED_OUT = 9705, /// /// Name not in DNS zone. /// DNS_ERROR_NAME_NOT_IN_ZONE = 9706, /// /// CNAME loop detected. /// DNS_ERROR_CNAME_LOOP = 9707, /// /// Node is a CNAME DNS record. /// DNS_ERROR_NODE_IS_CNAME = 9708, /// /// A CNAME record already exists for given name. /// DNS_ERROR_CNAME_COLLISION = 9709, /// /// Record only at DNS zone root. /// DNS_ERROR_RECORD_ONLY_AT_ZONE_ROOT = 9710, /// /// DNS record already exists. /// DNS_ERROR_RECORD_ALREADY_EXISTS = 9711, /// /// Secondary DNS zone data error. /// DNS_ERROR_SECONDARY_DATA = 9712, /// /// Could not create DNS cache data. /// DNS_ERROR_NO_CREATE_CACHE_DATA = 9713, /// /// DNS name does not exist. /// DNS_ERROR_NAME_DOES_NOT_EXIST = 9714, /// /// Could not create pointer (PTR) record. /// DNS_WARNING_PTR_CREATE_FAILED = 9715, /// /// DNS domain was undeleted. /// DNS_WARNING_DOMAIN_UNDELETED = 9716, /// /// The directory service is unavailable. /// DNS_ERROR_DS_UNAVAILABLE = 9717, /// /// DNS zone already exists in the directory service. /// DNS_ERROR_DS_ZONE_ALREADY_EXISTS = 9718, /// /// DNS server not creating or reading the boot file for the directory service integrated DNS zone. /// DNS_ERROR_NO_BOOTFILE_IF_DS_ZONE = 9719, /// /// No information avialable. /// DNS_ERROR_OPERATION_BASE = 9750, /// /// DNS AXFR (zone transfer) complete. /// DNS_INFO_AXFR_COMPLETE = 9751, /// /// DNS zone transfer failed. /// DNS_ERROR_AXFR = 9752, /// /// Added local WINS server. /// DNS_INFO_ADDED_LOCAL_WINS = 9753, /// /// No information avialable. /// DNS_ERROR_SECURE_BASE = 9800, /// /// Secure update call needs to continue update request. /// DNS_STATUS_CONTINUE_NEEDED = 9801, /// /// No information avialable. /// DNS_ERROR_SETUP_BASE = 9850, /// /// TCP/IP network protocol not installed. /// DNS_ERROR_NO_TCPIP = 9851, /// /// No DNS servers configured for local system. /// DNS_ERROR_NO_DNS_SERVERS = 9852, /// /// No information avialable. /// DNS_ERROR_DP_BASE = 9900, /// /// The specified directory partition does not exist. /// DNS_ERROR_DP_DOES_NOT_EXIST = 9901, /// /// The specified directory partition already exists. /// DNS_ERROR_DP_ALREADY_EXISTS = 9902, /// /// The DS is not enlisted in the specified directory partition. /// DNS_ERROR_DP_NOT_ENLISTED = 9903, /// /// The DS is already enlisted in the specified directory partition. /// DNS_ERROR_DP_ALREADY_ENLISTED = 9904, /// /// No information avialable. /// DNS_ERROR_DP_NOT_AVAILABLE = 9905, /// /// No information avialable. /// WSABASEERR = 10000, /// /// A blocking operation was interrupted by a call to WSACancelBlockingCall. /// WSAEINTR = 10004, /// /// The file handle supplied is not valid. /// WSAEBADF = 10009, /// /// An attempt was made to access a socket in a way forbidden by its access permissions. /// WSAEACCES = 10013, /// /// The system detected an invalid pointer address in attempting to use a pointer argument in a call. /// WSAEFAULT = 10014, /// /// An invalid argument was supplied. /// WSAEINVAL = 10022, /// /// Too many open sockets. /// WSAEMFILE = 10024, /// /// A non-blocking socket operation could not be completed immediately. /// WSAEWOULDBLOCK = 10035, /// /// A blocking operation is currently executing. /// WSAEINPROGRESS = 10036, /// /// An operation was attempted on a non-blocking socket that already had an operation in progress. /// WSAEALREADY = 10037, /// /// An operation was attempted on something that is not a socket. /// WSAENOTSOCK = 10038, /// /// A required address was omitted from an operation on a socket. /// WSAEDESTADDRREQ = 10039, /// /// A message sent on a datagram socket was larger than the internal message buffer or some other network limit, or the buffer used to receive a datagram into was smaller than the datagram itself. /// WSAEMSGSIZE = 10040, /// /// A protocol was specified in the socket function call that does not support the semantics of the socket type requested. /// WSAEPROTOTYPE = 10041, /// /// An unknown, invalid, or unsupported option or level was specified in a getsockopt or setsockopt call. /// WSAENOPROTOOPT = 10042, /// /// The requested protocol has not been configured into the system, or no implementation for it exists. /// WSAEPROTONOSUPPORT = 10043, /// /// The support for the specified socket type does not exist in this address family. /// WSAESOCKTNOSUPPORT = 10044, /// /// The attempted operation is not supported for the type of object referenced. /// WSAEOPNOTSUPP = 10045, /// /// The protocol family has not been configured into the system or no implementation for it exists. /// WSAEPFNOSUPPORT = 10046, /// /// An address incompatible with the requested protocol was used. /// WSAEAFNOSUPPORT = 10047, /// /// Only one usage of each socket address (protocol/network address/port) is normally permitted. /// WSAEADDRINUSE = 10048, /// /// The requested address is not valid in its context. /// WSAEADDRNOTAVAIL = 10049, /// /// A socket operation encountered a dead network. /// WSAENETDOWN = 10050, /// /// A socket operation was attempted to an unreachable network. /// WSAENETUNREACH = 10051, /// /// The connection has been broken due to keep-alive activity detecting a failure while the operation was in progress. /// WSAENETRESET = 10052, /// /// An established connection was aborted by the software in your host machine. /// WSAECONNABORTED = 10053, /// /// An existing connection was forcibly closed by the remote host. /// WSAECONNRESET = 10054, /// /// An operation on a socket could not be performed because the system lacked sufficient buffer space or because a queue was full. /// WSAENOBUFS = 10055, /// /// A connect request was made on an already connected socket. /// WSAEISCONN = 10056, /// /// A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied. /// WSAENOTCONN = 10057, /// /// A request to send or receive data was disallowed because the socket had already been shut down in that direction with a previous shutdown call. /// WSAESHUTDOWN = 10058, /// /// Too many references to some kernel object. /// WSAETOOMANYREFS = 10059, /// /// A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. /// WSAETIMEDOUT = 10060, /// /// No connection could be made because the target machine actively refused it. /// WSAECONNREFUSED = 10061, /// /// Cannot translate name. /// WSAELOOP = 10062, /// /// Name component or name was too long. /// WSAENAMETOOInt32 = 10063, /// /// A socket operation failed because the destination host was down. /// WSAEHOSTDOWN = 10064, /// /// A socket operation was attempted to an unreachable host. /// WSAEHOSTUNREACH = 10065, /// /// Cannot remove a directory that is not empty. /// WSAENOTEMPTY = 10066, /// /// A Windows Sockets implementation may have a limit on the number of applications that may use it simultaneously. /// WSAEPROCLIM = 10067, /// /// Ran out of quota. /// WSAEUSERS = 10068, /// /// Ran out of disk quota. /// WSAEDQUOT = 10069, /// /// File handle reference is no longer available. /// WSAESTALE = 10070, /// /// Item is not available locally. /// WSAEREMOTE = 10071, /// /// WSAStartup cannot function at this time because the underlying system it uses to provide network services is currently unavailable. /// WSASYSNOTREADY = 10091, /// /// The Windows Sockets version requested is not supported. /// WSAVERNOTSUPPORTED = 10092, /// /// Either the application has not called WSAStartup, or WSAStartup failed. /// WSANOTINITIALISED = 10093, /// /// Returned by WSARecv or WSARecvFrom to indicate the remote party has initiated a graceful shutdown sequence. /// WSAEDISCON = 10101, /// /// No more results can be returned by WSALookupServiceNext. /// WSAENOMORE = 10102, /// /// A call to WSALookupServiceEnd was made while this call was still processing. The call has been canceled. /// WSAECANCELLED = 10103, /// /// The procedure call table is invalid. /// WSAEINVALIDPROCTABLE = 10104, /// /// The requested service provider is invalid. /// WSAEINVALIDPROVIDER = 10105, /// /// The requested service provider could not be loaded or initialized. /// WSAEPROVIDERFAILEDINIT = 10106, /// /// A system call that should never fail has failed. /// WSASYSCALLFAILURE = 10107, /// /// No such service is known. The service cannot be found in the specified name space. /// WSASERVICE_NOT_FOUND = 10108, /// /// The specified class was not found. /// WSATYPE_NOT_FOUND = 10109, /// /// No more results can be returned by WSALookupServiceNext. /// WSA_E_NO_MORE = 10110, /// /// A call to WSALookupServiceEnd was made while this call was still processing. The call has been canceled. /// WSA_E_CANCELLED = 10111, /// /// A database query failed because it was actively refused. /// WSAEREFUSED = 10112, /// /// No such host is known. /// WSAHOST_NOT_FOUND = 11001, /// /// This is usually a temporary error during hostname resolution and means that the local server did not receive a response from an authoritative server. /// WSATRY_AGAIN = 11002, /// /// A non-recoverable error occurred during a database lookup. /// WSANO_RECOVERY = 11003, /// /// The requested name is valid and was found in the database, but it does not have the correct associated data being resolved for. /// WSANO_DATA = 11004, /// /// At least one reserve has arrived. /// WSA_QOS_RECEIVERS = 11005, /// /// At least one path has arrived. /// WSA_QOS_SENDERS = 11006, /// /// There are no senders. /// WSA_QOS_NO_SENDERS = 11007, /// /// There are no receivers. /// WSA_QOS_NO_RECEIVERS = 11008, /// /// Reserve has been confirmed. /// WSA_QOS_REQUEST_CONFIRMED = 11009, /// /// Error due to lack of resources. /// WSA_QOS_ADMISSION_FAILURE = 11010, /// /// Rejected for administrative reasons - bad credentials. /// WSA_QOS_POLICY_FAILURE = 11011, /// /// Unknown or conflicting style. /// WSA_QOS_BAD_STYLE = 11012, /// /// Problem with some part of the filterspec or providerspecific buffer in general. /// WSA_QOS_BAD_OBJECT = 11013, /// /// Problem with some part of the flowspec. /// WSA_QOS_TRAFFIC_CTRL_ERROR = 11014, /// /// General QOS error. /// WSA_QOS_GENERIC_ERROR = 11015, /// /// An invalid or unrecognized service type was found in the flowspec. /// WSA_QOS_ESERVICETYPE = 11016, /// /// An invalid or inconsistent flowspec was found in the QOS structure. /// WSA_QOS_EFLOWSPEC = 11017, /// /// Invalid QOS provider-specific buffer. /// WSA_QOS_EPROVSPECBUF = 11018, /// /// An invalid QOS filter style was used. /// WSA_QOS_EFILTERSTYLE = 11019, /// /// An invalid QOS filter type was used. /// WSA_QOS_EFILTERTYPE = 11020, /// /// An incorrect number of QOS FILTERSPECs were specified in the FLOWDESCRIPTOR. /// WSA_QOS_EFILTERCOUNT = 11021, /// /// An object with an invalid ObjectLength field was specified in the QOS provider-specific buffer. /// WSA_QOS_EOBJLENGTH = 11022, /// /// An incorrect number of flow descriptors was specified in the QOS structure. /// WSA_QOS_EFLOWCOUNT = 11023, /// /// An unrecognized object was found in the QOS provider-specific buffer. /// WSA_QOS_EUNKOWNPSOBJ = 11024, /// /// An invalid policy object was found in the QOS provider-specific buffer. /// WSA_QOS_EPOLICYOBJ = 11025, /// /// An invalid QOS flow descriptor was found in the flow descriptor list. /// WSA_QOS_EFLOWDESC = 11026, /// /// An invalid or inconsistent flowspec was found in the QOS provider specific buffer. /// WSA_QOS_EPSFLOWSPEC = 11027, /// /// An invalid FILTERSPEC was found in the QOS provider-specific buffer. /// WSA_QOS_EPSFILTERSPEC = 11028, /// /// An invalid shape discard mode object was found in the QOS provider specific buffer. /// WSA_QOS_ESDMODEOBJ = 11029, /// /// An invalid shaping rate object was found in the QOS provider-specific buffer. /// WSA_QOS_ESHAPERATEOBJ = 11030, /// /// A reserved policy element was found in the QOS provider-specific buffer. /// WSA_QOS_RESERVED_PETYPE = 11031, /// /// The requested section was not present in the activation context. /// ERROR_SXS_SECTION_NOT_FOUND = 14000, /// /// This application has failed to start because the application configuration is incorrect. Reinstalling the application may fix this problem. /// ERROR_SXS_CANT_GEN_ACTCTX = 14001, /// /// The application binding data format is invalid. /// ERROR_SXS_INVALID_ACTCTXDATA_FORMAT = 14002, /// /// The referenced assembly is not installed on your system. /// ERROR_SXS_ASSEMBLY_NOT_FOUND = 14003, /// /// The manifest file does not begin with the required tag and format information. /// ERROR_SXS_MANIFEST_FORMAT_ERROR = 14004, /// /// The manifest file contains one or more syntax errors. /// ERROR_SXS_MANIFEST_PARSE_ERROR = 14005, /// /// The application attempted to activate a disabled activation context. /// ERROR_SXS_ACTIVATION_CONTEXT_DISABLED = 14006, /// /// The requested lookup key was not found in any active activation context. /// ERROR_SXS_KEY_NOT_FOUND = 14007, /// /// A component version required by the application conflicts with another component version already active. /// ERROR_SXS_VERSION_CONFLICT = 14008, /// /// The type requested activation context section does not match the query API used. /// ERROR_SXS_WRONG_SECTION_TYPE = 14009, /// /// Lack of system resources has required isolated activation to be disabled for the current thread of execution. /// ERROR_SXS_THREAD_QUERIES_DISABLED = 14010, /// /// An attempt to set the process default activation context failed because the process default activation context was already set. /// ERROR_SXS_PROCESS_DEFAULT_ALREADY_SET = 14011, /// /// The encoding group identifier specified is not recognized. /// ERROR_SXS_UNKNOWN_ENCODING_GROUP = 14012, /// /// The encoding requested is not recognized. /// ERROR_SXS_UNKNOWN_ENCODING = 14013, /// /// The manifest contains a reference to an invalid URI. /// ERROR_SXS_INVALID_XML_NAMESPACE_URI = 14014, /// /// The application manifest contains a reference to a dependent assembly which is not installed /// ERROR_SXS_ROOT_MANIFEST_DEPENDENCY_NOT_INSTALLED = 14015, /// /// The manifest for an assembly used by the application has a reference to a dependent assembly which is not installed /// ERROR_SXS_LEAF_MANIFEST_DEPENDENCY_NOT_INSTALLED = 14016, /// /// The manifest contains an attribute for the assembly identity which is not valid. /// ERROR_SXS_INVALID_ASSEMBLY_IDENTITY_ATTRIBUTE = 14017, /// /// The manifest is missing the required default namespace specification on the assembly element. /// ERROR_SXS_MANIFEST_MISSING_REQUIRED_DEFAULT_NAMESPACE = 14018, /// /// The manifest has a default namespace specified on the assembly element but its value is not "urn:schemas-microsoft-com:asm.v1". /// ERROR_SXS_MANIFEST_INVALID_REQUIRED_DEFAULT_NAMESPACE = 14019, /// /// The private manifest probed has crossed reparse-point-associated path /// ERROR_SXS_PRIVATE_MANIFEST_CROSS_PATH_WITH_REPARSE_POINT = 14020, /// /// Two or more components referenced directly or indirectly by the application manifest have files by the same name. /// ERROR_SXS_DUPLICATE_DLL_NAME = 14021, /// /// Two or more components referenced directly or indirectly by the application manifest have window classes with the same name. /// ERROR_SXS_DUPLICATE_WINDOWCLASS_NAME = 14022, /// /// Two or more components referenced directly or indirectly by the application manifest have the same COM server CLSIDs. /// ERROR_SXS_DUPLICATE_CLSID = 14023, /// /// Two or more components referenced directly or indirectly by the application manifest have proxies for the same COM interface IIDs. /// ERROR_SXS_DUPLICATE_IID = 14024, /// /// Two or more components referenced directly or indirectly by the application manifest have the same COM type library TLBIDs. /// ERROR_SXS_DUPLICATE_TLBID = 14025, /// /// Two or more components referenced directly or indirectly by the application manifest have the same COM ProgIDs. /// ERROR_SXS_DUPLICATE_PROGID = 14026, /// /// Two or more components referenced directly or indirectly by the application manifest are different versions of the same component which is not permitted. /// ERROR_SXS_DUPLICATE_ASSEMBLY_NAME = 14027, /// /// A component's file does not match the verification information present in the /// component manifest. /// ERROR_SXS_FILE_HASH_MISMATCH = 14028, /// /// The policy manifest contains one or more syntax errors. /// ERROR_SXS_POLICY_PARSE_ERROR = 14029, /// /// Manifest Parse Error : A string literal was expected, but no opening quote character was found. /// ERROR_SXS_XML_E_MISSINGQUOTE = 14030, /// /// Manifest Parse Error : Incorrect syntax was used in a comment. /// ERROR_SXS_XML_E_COMMENTSYNTAX = 14031, /// /// Manifest Parse Error : A name was started with an invalid character. /// ERROR_SXS_XML_E_BADSTARTNAMECHAR = 14032, /// /// Manifest Parse Error : A name contained an invalid character. /// ERROR_SXS_XML_E_BADNAMECHAR = 14033, /// /// Manifest Parse Error : A string literal contained an invalid character. /// ERROR_SXS_XML_E_BADCHARINSTRING = 14034, /// /// Manifest Parse Error : Invalid syntax for an xml declaration. /// ERROR_SXS_XML_E_XMLDECLSYNTAX = 14035, /// /// Manifest Parse Error : An Invalid character was found in text content. /// ERROR_SXS_XML_E_BADCHARDATA = 14036, /// /// Manifest Parse Error : Required white space was missing. /// ERROR_SXS_XML_E_MISSINGWHITESPACE = 14037, /// /// Manifest Parse Error : The character '>' was expected. /// ERROR_SXS_XML_E_EXPECTINGTAGEND = 14038, /// /// Manifest Parse Error : A semi colon character was expected. /// ERROR_SXS_XML_E_MISSINGSEMICOLON = 14039, /// /// Manifest Parse Error : Unbalanced parentheses. /// ERROR_SXS_XML_E_UNBALANCEDPAREN = 14040, /// /// Manifest Parse Error : Internal error. /// ERROR_SXS_XML_E_INTERNALERROR = 14041, /// /// Manifest Parse Error : Whitespace is not allowed at this location. /// ERROR_SXS_XML_E_UNEXPECTED_WHITESPACE = 14042, /// /// Manifest Parse Error : End of file reached in invalid state for current encoding. /// ERROR_SXS_XML_E_INCOMPLETE_ENCODING = 14043, /// /// Manifest Parse Error : Missing parenthesis. /// ERROR_SXS_XML_E_MISSING_PAREN = 14044, /// /// Manifest Parse Error : A single or double closing quote character (\' or \") is missing. /// ERROR_SXS_XML_E_EXPECTINGCLOSEQUOTE = 14045, /// /// Manifest Parse Error : Multiple colons are not allowed in a name. /// ERROR_SXS_XML_E_MULTIPLE_COLONS = 14046, /// /// Manifest Parse Error : Invalid character for decimal digit. /// ERROR_SXS_XML_E_INVALID_DECIMAL = 14047, /// /// Manifest Parse Error : Invalid character for hexidecimal digit. /// ERROR_SXS_XML_E_INVALID_HEXIDECIMAL = 14048, /// /// Manifest Parse Error : Invalid unicode character value for this platform. /// ERROR_SXS_XML_E_INVALID_UNICODE = 14049, /// /// Manifest Parse Error : Expecting whitespace or '?'. /// ERROR_SXS_XML_E_WHITESPACEORQUESTIONMARK = 14050, /// /// Manifest Parse Error : End tag was not expected at this location. /// ERROR_SXS_XML_E_UNEXPECTEDENDTAG = 14051, /// /// Manifest Parse Error : The following tags were not closed: %1. /// ERROR_SXS_XML_E_UNCLOSEDTAG = 14052, /// /// Manifest Parse Error : Duplicate attribute. /// ERROR_SXS_XML_E_DUPLICATEATTRIBUTE = 14053, /// /// Manifest Parse Error : Only one top level element is allowed in an XML document. /// ERROR_SXS_XML_E_MULTIPLEROOTS = 14054, /// /// Manifest Parse Error : Invalid at the top level of the document. /// ERROR_SXS_XML_E_INVALIDATROOTLEVEL = 14055, /// /// Manifest Parse Error : Invalid xml declaration. /// ERROR_SXS_XML_E_BADXMLDECL = 14056, /// /// Manifest Parse Error : XML document must have a top level element. /// ERROR_SXS_XML_E_MISSINGROOT = 14057, /// /// Manifest Parse Error : Unexpected end of file. /// ERROR_SXS_XML_E_UNEXPECTEDEOF = 14058, /// /// Manifest Parse Error : Parameter entities cannot be used inside markup declarations in an internal subset. /// ERROR_SXS_XML_E_BADPEREFINSUBSET = 14059, /// /// Manifest Parse Error : Element was not closed. /// ERROR_SXS_XML_E_UNCLOSEDSTARTTAG = 14060, /// /// Manifest Parse Error : End element was missing the character '>'. /// ERROR_SXS_XML_E_UNCLOSEDENDTAG = 14061, /// /// Manifest Parse Error : A string literal was not closed. /// ERROR_SXS_XML_E_UNCLOSEDSTRING = 14062, /// /// Manifest Parse Error : A comment was not closed. /// ERROR_SXS_XML_E_UNCLOSEDCOMMENT = 14063, /// /// Manifest Parse Error : A declaration was not closed. /// ERROR_SXS_XML_E_UNCLOSEDDECL = 14064, /// /// Manifest Parse Error : A CDATA section was not closed. /// ERROR_SXS_XML_E_UNCLOSEDCDATA = 14065, /// /// Manifest Parse Error : The namespace prefix is not allowed to start with the reserved string "xml". /// ERROR_SXS_XML_E_RESERVEDNAMESPACE = 14066, /// /// Manifest Parse Error : System does not support the specified encoding. /// ERROR_SXS_XML_E_INVALIDENCODING = 14067, /// /// Manifest Parse Error : Switch from current encoding to specified encoding not supported. /// ERROR_SXS_XML_E_INVALIDSWITCH = 14068, /// /// Manifest Parse Error : The name 'xml' is reserved and must be lower case. /// ERROR_SXS_XML_E_BADXMLCASE = 14069, /// /// Manifest Parse Error : The standalone attribute must have the value 'yes' or 'no'. /// ERROR_SXS_XML_E_INVALID_STANDALONE = 14070, /// /// Manifest Parse Error : The standalone attribute cannot be used in external entities. /// ERROR_SXS_XML_E_UNEXPECTED_STANDALONE = 14071, /// /// Manifest Parse Error : Invalid version number. /// ERROR_SXS_XML_E_INVALID_VERSION = 14072, /// /// Manifest Parse Error : Missing equals sign between attribute and attribute value. /// ERROR_SXS_XML_E_MISSINGEQUALS = 14073, /// /// Assembly Protection Error : Unable to recover the specified assembly. /// ERROR_SXS_PROTECTION_RECOVERY_FAILED = 14074, /// /// Assembly Protection Error : The public key for an assembly was too short to be allowed. /// ERROR_SXS_PROTECTION_PUBLIC_KEY_TOO_Int16 = 14075, /// /// Assembly Protection Error : The catalog for an assembly is not valid, or does not match the assembly's manifest. /// ERROR_SXS_PROTECTION_CATALOG_NOT_VALID = 14076, /// /// An HRESULT could not be translated to a corresponding Win32 error code. /// ERROR_SXS_UNTRANSLATABLE_HRESULT = 14077, /// /// Assembly Protection Error : The catalog for an assembly is missing. /// ERROR_SXS_PROTECTION_CATALOG_FILE_MISSING = 14078, /// /// The supplied assembly identity is missing one or more attributes which must be present in this context. /// ERROR_SXS_MISSING_ASSEMBLY_IDENTITY_ATTRIBUTE = 14079, /// /// The supplied assembly identity has one or more attribute names that contain characters not permitted in XML names. /// ERROR_SXS_INVALID_ASSEMBLY_IDENTITY_ATTRIBUTE_NAME = 14080, /// /// The specified quick mode policy already exists. /// ERROR_IPSEC_QM_POLICY_EXISTS = 13000, /// /// The specified quick mode policy was not found. /// ERROR_IPSEC_QM_POLICY_NOT_FOUND = 13001, /// /// The specified quick mode policy is being used. /// ERROR_IPSEC_QM_POLICY_IN_USE = 13002, /// /// The specified main mode policy already exists. /// ERROR_IPSEC_MM_POLICY_EXISTS = 13003, /// /// The specified main mode policy was not found /// ERROR_IPSEC_MM_POLICY_NOT_FOUND = 13004, /// /// The specified main mode policy is being used. /// ERROR_IPSEC_MM_POLICY_IN_USE = 13005, /// /// The specified main mode filter already exists. /// ERROR_IPSEC_MM_FILTER_EXISTS = 13006, /// /// The specified main mode filter was not found. /// ERROR_IPSEC_MM_FILTER_NOT_FOUND = 13007, /// /// The specified transport mode filter already exists. /// ERROR_IPSEC_TRANSPORT_FILTER_EXISTS = 13008, /// /// The specified transport mode filter does not exist. /// ERROR_IPSEC_TRANSPORT_FILTER_NOT_FOUND = 13009, /// /// The specified main mode authentication list exists. /// ERROR_IPSEC_MM_AUTH_EXISTS = 13010, /// /// The specified main mode authentication list was not found. /// ERROR_IPSEC_MM_AUTH_NOT_FOUND = 13011, /// /// The specified quick mode policy is being used. /// ERROR_IPSEC_MM_AUTH_IN_USE = 13012, /// /// The specified main mode policy was not found. /// ERROR_IPSEC_DEFAULT_MM_POLICY_NOT_FOUND = 13013, /// /// The specified quick mode policy was not found /// ERROR_IPSEC_DEFAULT_MM_AUTH_NOT_FOUND = 13014, /// /// The manifest file contains one or more syntax errors. /// ERROR_IPSEC_DEFAULT_QM_POLICY_NOT_FOUND = 13015, /// /// The application attempted to activate a disabled activation context. /// ERROR_IPSEC_TUNNEL_FILTER_EXISTS = 13016, /// /// The requested lookup key was not found in any active activation context. /// ERROR_IPSEC_TUNNEL_FILTER_NOT_FOUND = 13017, /// /// The Main Mode filter is pending deletion. /// ERROR_IPSEC_MM_FILTER_PENDING_DELETION = 13018, /// /// The transport filter is pending deletion. /// ERROR_IPSEC_TRANSPORT_FILTER_PENDING_DELETION = 13019, /// /// The tunnel filter is pending deletion. /// ERROR_IPSEC_TUNNEL_FILTER_PENDING_DELETION = 13020, /// /// The Main Mode policy is pending deletion. /// ERROR_IPSEC_MM_POLICY_PENDING_DELETION = 13021, /// /// The Main Mode authentication bundle is pending deletion. /// ERROR_IPSEC_MM_AUTH_PENDING_DELETION = 13022, /// /// The Quick Mode policy is pending deletion. /// ERROR_IPSEC_QM_POLICY_PENDING_DELETION = 13023, /// /// No information avialable. /// WARNING_IPSEC_MM_POLICY_PRUNED = 13024, /// /// No information avialable. /// WARNING_IPSEC_QM_POLICY_PRUNED = 13025, /// /// ERROR_IPSEC_IKE_NEG_STATUS_BEGIN /// ERROR_IPSEC_IKE_NEG_STATUS_BEGIN = 13800, /// /// IKE authentication credentials are unacceptable /// ERROR_IPSEC_IKE_AUTH_FAIL = 13801, /// /// IKE security attributes are unacceptable /// ERROR_IPSEC_IKE_ATTRIB_FAIL = 13802, /// /// IKE Negotiation in progress /// ERROR_IPSEC_IKE_NEGOTIATION_PENDING = 13803, /// /// General processing error /// ERROR_IPSEC_IKE_GENERAL_PROCESSING_ERROR = 13804, /// /// Negotiation timed out /// ERROR_IPSEC_IKE_TIMED_OUT = 13805, /// /// IKE failed to find valid machine certificate /// ERROR_IPSEC_IKE_NO_CERT = 13806, /// /// IKE SA deleted by peer before establishment completed /// ERROR_IPSEC_IKE_SA_DELETED = 13807, /// /// IKE SA deleted before establishment completed /// ERROR_IPSEC_IKE_SA_REAPED = 13808, /// /// Negotiation request sat in Queue too long /// ERROR_IPSEC_IKE_MM_ACQUIRE_DROP = 13809, /// /// Negotiation request sat in Queue too long /// ERROR_IPSEC_IKE_QM_ACQUIRE_DROP = 13810, /// /// Negotiation request sat in Queue too long /// ERROR_IPSEC_IKE_QUEUE_DROP_MM = 13811, /// /// Negotiation request sat in Queue too long /// ERROR_IPSEC_IKE_QUEUE_DROP_NO_MM = 13812, /// /// No response from peer /// ERROR_IPSEC_IKE_DROP_NO_RESPONSE = 13813, /// /// Negotiation took too long /// ERROR_IPSEC_IKE_MM_DELAY_DROP = 13814, /// /// Negotiation took too long /// ERROR_IPSEC_IKE_QM_DELAY_DROP = 13815, /// /// Unknown error occurred /// ERROR_IPSEC_IKE_ERROR = 13816, /// /// Certificate Revocation Check failed /// ERROR_IPSEC_IKE_CRL_FAILED = 13817, /// /// Invalid certificate key usage /// ERROR_IPSEC_IKE_INVALID_KEY_USAGE = 13818, /// /// Invalid certificate type /// ERROR_IPSEC_IKE_INVALID_CERT_TYPE = 13819, /// /// No private key associated with machine certificate /// ERROR_IPSEC_IKE_NO_PRIVATE_KEY = 13820, /// /// Failure in Diffie-Helman computation /// ERROR_IPSEC_IKE_DH_FAIL = 13822, /// /// Invalid header /// ERROR_IPSEC_IKE_INVALID_HEADER = 13824, /// /// No policy configured /// ERROR_IPSEC_IKE_NO_POLICY = 13825, /// /// Failed to verify signature /// ERROR_IPSEC_IKE_INVALID_SIGNATURE = 13826, /// /// Failed to authenticate using kerberos /// ERROR_IPSEC_IKE_KERBEROS_ERROR = 13827, /// /// Peer's certificate did not have a public key /// ERROR_IPSEC_IKE_NO_PUBLIC_KEY = 13828, /// /// Error processing error payload /// ERROR_IPSEC_IKE_PROCESS_ERR = 13829, /// /// Error processing SA payload /// ERROR_IPSEC_IKE_PROCESS_ERR_SA = 13830, /// /// Error processing Proposal payload /// ERROR_IPSEC_IKE_PROCESS_ERR_PROP = 13831, /// /// Error processing Transform payload /// ERROR_IPSEC_IKE_PROCESS_ERR_TRANS = 13832, /// /// Error processing KE payload /// ERROR_IPSEC_IKE_PROCESS_ERR_KE = 13833, /// /// Error processing ID payload /// ERROR_IPSEC_IKE_PROCESS_ERR_ID = 13834, /// /// Error processing Cert payload /// ERROR_IPSEC_IKE_PROCESS_ERR_CERT = 13835, /// /// Error processing Certificate Request payload /// ERROR_IPSEC_IKE_PROCESS_ERR_CERT_REQ = 13836, /// /// Error processing Hash payload /// ERROR_IPSEC_IKE_PROCESS_ERR_HASH = 13837, /// /// Error processing Signature payload /// ERROR_IPSEC_IKE_PROCESS_ERR_SIG = 13838, /// /// Error processing Nonce payload /// ERROR_IPSEC_IKE_PROCESS_ERR_NONCE = 13839, /// /// Error processing Notify payload /// ERROR_IPSEC_IKE_PROCESS_ERR_NOTIFY = 13840, /// /// Error processing Delete Payload /// ERROR_IPSEC_IKE_PROCESS_ERR_DELETE = 13841, /// /// Error processing VendorId payload /// ERROR_IPSEC_IKE_PROCESS_ERR_VENDOR = 13842, /// /// Invalid payload received /// ERROR_IPSEC_IKE_INVALID_PAYLOAD = 13843, /// /// Soft SA loaded /// ERROR_IPSEC_IKE_LOAD_SOFT_SA = 13844, /// /// Soft SA torn down /// ERROR_IPSEC_IKE_SOFT_SA_TORN_DOWN = 13845, /// /// Invalid cookie received. /// ERROR_IPSEC_IKE_INVALID_COOKIE = 13846, /// /// Peer failed to send valid machine certificate /// ERROR_IPSEC_IKE_NO_PEER_CERT = 13847, /// /// Certification Revocation check of peer's certificate failed /// ERROR_IPSEC_IKE_PEER_CRL_FAILED = 13848, /// /// New policy invalidated SAs formed with old policy /// ERROR_IPSEC_IKE_POLICY_CHANGE = 13849, /// /// There is no available Main Mode IKE policy. /// ERROR_IPSEC_IKE_NO_MM_POLICY = 13850, /// /// Failed to enabled TCB privilege. /// ERROR_IPSEC_IKE_NOTCBPRIV = 13851, /// /// Failed to load SECURITY.DLL. /// ERROR_IPSEC_IKE_SECLOADFAIL = 13852, /// /// Failed to obtain security function table dispatch address from SSPI. /// ERROR_IPSEC_IKE_FAILSSPINIT = 13853, /// /// Failed to query Kerberos package to obtain max token size. /// ERROR_IPSEC_IKE_FAILQUERYSSP = 13854, /// /// Failed to obtain Kerberos server credentials for ISAKMP/ERROR_IPSEC_IKE service. Kerberos authentication will not function. The most likely reason for this is lack of domain membership. This is normal if your computer is a member of a workgroup. /// ERROR_IPSEC_IKE_SRVACQFAIL = 13855, /// /// Failed to determine SSPI principal name for ISAKMP/ERROR_IPSEC_IKE service (QueryCredentialsAttributes). /// ERROR_IPSEC_IKE_SRVQUERYCRED = 13856, /// /// Failed to obtain new SPI for the inbound SA from Ipsec driver. The most common cause for this is that the driver does not have the correct filter. Check your policy to verify the filters. /// ERROR_IPSEC_IKE_GETSPIFAIL = 13857, /// /// Given filter is invalid /// ERROR_IPSEC_IKE_INVALID_FILTER = 13858, /// /// Memory allocation failed. /// ERROR_IPSEC_IKE_OUT_OF_MEMORY = 13859, /// /// Failed to add Security Association to IPSec Driver. The most common cause for this is if the IKE negotiation took too long to complete. If the problem persists, reduce the load on the faulting machine. /// ERROR_IPSEC_IKE_ADD_UPDATE_KEY_FAILED = 13860, /// /// Invalid policy /// ERROR_IPSEC_IKE_INVALID_POLICY = 13861, /// /// Invalid DOI /// ERROR_IPSEC_IKE_UNKNOWN_DOI = 13862, /// /// Invalid situation /// ERROR_IPSEC_IKE_INVALID_SITUATION = 13863, /// /// Diffie-Hellman failure /// ERROR_IPSEC_IKE_DH_FAILURE = 13864, /// /// Invalid Diffie-Hellman group /// ERROR_IPSEC_IKE_INVALID_GROUP = 13865, /// /// Error encrypting payload /// ERROR_IPSEC_IKE_ENCRYPT = 13866, /// /// Error decrypting payload /// ERROR_IPSEC_IKE_DECRYPT = 13867, /// /// Policy match error /// ERROR_IPSEC_IKE_POLICY_MATCH = 13868, /// /// Unsupported ID /// ERROR_IPSEC_IKE_UNSUPPORTED_ID = 13869, /// /// Hash verification failed /// ERROR_IPSEC_IKE_INVALID_HASH = 13870, /// /// Invalid hash algorithm /// ERROR_IPSEC_IKE_INVALID_HASH_ALG = 13871, /// /// Invalid hash size /// ERROR_IPSEC_IKE_INVALID_HASH_SIZE = 13872, /// /// Invalid encryption algorithm /// ERROR_IPSEC_IKE_INVALID_ENCRYPT_ALG = 13873, /// /// Invalid authentication algorithm /// ERROR_IPSEC_IKE_INVALID_AUTH_ALG = 13874, /// /// Invalid certificate signature /// ERROR_IPSEC_IKE_INVALID_SIG = 13875, /// /// Load failed /// ERROR_IPSEC_IKE_LOAD_FAILED = 13876, /// /// Deleted via RPC call /// ERROR_IPSEC_IKE_RPC_DELETE = 13877, /// /// Temporary state created to perform reinit. This is not a real failure. /// ERROR_IPSEC_IKE_BENIGN_REINIT = 13878, /// /// The lifetime value received in the Responder Lifetime Notify is below the Windows 2000 configured minimum value. Please fix the policy on the peer machine. /// ERROR_IPSEC_IKE_INVALID_RESPONDER_LIFETIME_NOTIFY = 13879, /// /// Key length in certificate is too small for configured security requirements. /// ERROR_IPSEC_IKE_INVALID_CERT_KEYLEN = 13881, /// /// Max number of established MM SAs to peer exceeded. /// ERROR_IPSEC_IKE_MM_LIMIT = 13882, /// /// IKE received a policy that disables negotiation. /// ERROR_IPSEC_IKE_NEGOTIATION_DISABLED = 13883, /// /// ERROR_IPSEC_IKE_NEG_STATUS_END /// ERROR_IPSEC_IKE_NEG_STATUS_END = 13884, } /// /// COM error codes. Negative value is failure, positive is success. /// internal enum ResultCom { /// /// Not implemented /// E_NOTIMPL = (int)(0x80000001 - 0x100000000), /// /// Ran out of memory /// E_OUTOFMEMORY = (int)(0x80000002 - 0x100000000), /// /// One or more arguments are invalid /// E_INVALIDARG = (int)(0x80000003 - 0x100000000), /// /// No such interface supported /// E_NOINTERFACE = (int)(0x80000004 - 0x100000000), /// /// Invalid pointer /// E_POINTER = (int)(0x80000005 - 0x100000000), /// /// Invalid handle /// E_HANDLE = (int)(0x80000006 - 0x100000000), /// /// Operation aborted /// E_ABORT = (int)(0x80000007 - 0x100000000), /// /// Unspecified error /// E_FAIL = (int)(0x80000008 - 0x100000000), /// /// General access denied error /// E_ACCESSDENIED = (int)(0x80000009 - 0x100000000), /// /// The data necessary to complete this operation is not yet available. /// E_PENDING = (int)(0x8000000A - 0x100000000), /// /// Thread local storage failure /// CO_E_INIT_TLS = (int)(0x80004006 - 0x100000000), /// /// Get shared memory allocator failure /// CO_E_INIT_SHARED_ALLOCATOR = (int)(0x80004007 - 0x100000000), /// /// Get memory allocator failure /// CO_E_INIT_MEMORY_ALLOCATOR = (int)(0x80004008 - 0x100000000), /// /// Unable to initialize class cache /// CO_E_INIT_CLASS_CACHE = (int)(0x80004009 - 0x100000000), /// /// Unable to initialize RPC services /// CO_E_INIT_RPC_CHANNEL = (int)(0x8000400A - 0x100000000), /// /// Cannot set thread local storage channel control /// CO_E_INIT_TLS_SET_CHANNEL_CONTROL = (int)(0x8000400B - 0x100000000), /// /// Could not allocate thread local storage channel control /// CO_E_INIT_TLS_CHANNEL_CONTROL = (int)(0x8000400C - 0x100000000), /// /// The user supplied memory allocator is unacceptable /// CO_E_INIT_UNACCEPTED_USER_ALLOCATOR = (int)(0x8000400D - 0x100000000), /// /// The OLE service mutex already exists /// CO_E_INIT_SCM_MUTEX_EXISTS = (int)(0x8000400E - 0x100000000), /// /// The OLE service file mapping already exists /// CO_E_INIT_SCM_FILE_MAPPING_EXISTS = (int)(0x8000400F - 0x100000000), /// /// Unable to map view of file for OLE service /// CO_E_INIT_SCM_MAP_VIEW_OF_FILE = (int)(0x80004010 - 0x100000000), /// /// Failure attempting to launch OLE service /// CO_E_INIT_SCM_EXEC_FAILURE = (int)(0x80004011 - 0x100000000), /// /// There was an attempt to call CoInitialize a second time while single threaded /// CO_E_INIT_ONLY_SINGLE_THREADED = (int)(0x80004012 - 0x100000000), /// /// A Remote activation was necessary but was not allowed /// CO_E_CANT_REMOTE = (int)(0x80004013 - 0x100000000), /// /// A Remote activation was necessary but the server name provided was invalid /// CO_E_BAD_SERVER_NAME = (int)(0x80004014 - 0x100000000), /// /// The class is configured to run as a security id different from the caller /// CO_E_WRONG_SERVER_IDENTITY = (int)(0x80004015 - 0x100000000), /// /// Use of Ole1 services requiring DDE windows is disabled /// CO_E_OLE1DDE_DISABLED = (int)(0x80004016 - 0x100000000), /// /// A RunAs specification must be \ or simply /// CO_E_RUNAS_SYNTAX = (int)(0x80004017 - 0x100000000), /// /// The server process could not be started. The pathname may be incorrect. /// CO_E_CREATEPROCESS_FAILURE = (int)(0x80004018 - 0x100000000), /// /// The server process could not be started as the configured identity. The pathname may be incorrect or unavailable. /// CO_E_RUNAS_CREATEPROCESS_FAILURE = (int)(0x80004019 - 0x100000000), /// /// The server process could not be started because the configured identity is incorrect. Check the username and password. /// CO_E_RUNAS_LOGON_FAILURE = (int)(0x8000401A - 0x100000000), /// /// The client is not allowed to launch this server. /// CO_E_LAUNCH_PERMSSION_DENIED = (int)(0x8000401B - 0x100000000), /// /// The service providing this server could not be started. /// CO_E_START_SERVICE_FAILURE = (int)(0x8000401C - 0x100000000), /// /// This computer was unable to communicate with the computer providing the server. /// CO_E_REMOTE_COMMUNICATION_FAILURE = (int)(0x8000401D - 0x100000000), /// /// The server did not respond after being launched. /// CO_E_SERVER_START_TIMEOUT = (int)(0x8000401E - 0x100000000), /// /// The registration information for this server is inconsistent or incomplete. /// CO_E_CLSREG_INCONSISTENT = (int)(0x8000401F - 0x100000000), /// /// The registration information for this interface is inconsistent or incomplete. /// CO_E_IIDREG_INCONSISTENT = (int)(0x80004020 - 0x100000000), /// /// The operation attempted is not supported. /// CO_E_NOT_SUPPORTED = (int)(0x80004021 - 0x100000000), /// /// A dll must be loaded. /// CO_E_RELOAD_DLL = (int)(0x80004022 - 0x100000000), /// /// A Microsoft Software Installer error was encountered. /// CO_E_MSI_ERROR = (int)(0x80004023 - 0x100000000), /// /// The specified activation could not occur in the client context as specified. /// CO_E_ATTEMPT_TO_CREATE_OUTSIDE_CLIENT_CONTEXT = (int)(0x80004024 - 0x100000000), /// /// Activations on the server are paused. /// CO_E_SERVER_PAUSED = (int)(0x80004025 - 0x100000000), /// /// Activations on the server are not paused. /// CO_E_SERVER_NOT_PAUSED = (int)(0x80004026 - 0x100000000), /// /// The component or application containing the component has been disabled. /// CO_E_CLASS_DISABLED = (int)(0x80004027 - 0x100000000), /// /// The common language runtime is not available /// CO_E_CLRNOTAVAILABLE = (int)(0x80004028 - 0x100000000), /// /// The thread-pool rejected the submitted asynchronous work. /// CO_E_ASYNC_WORK_REJECTED = (int)(0x80004029 - 0x100000000), /// /// The server started, but did not finish initializing in a timely fashion. /// CO_E_SERVER_INIT_TIMEOUT = (int)(0x8000402A - 0x100000000), /// /// Unable to complete the call since there is no COM+ security context inside IObjectControl.Activate. /// CO_E_NO_SECCTX_IN_ACTIVATE = (int)(0x8000402B - 0x100000000), /// /// The provided tracker configuration is invalid /// CO_E_TRACKER_CONFIG = (int)(0x80004030 - 0x100000000), /// /// The provided thread pool configuration is invalid /// CO_E_THREADPOOL_CONFIG = (int)(0x80004031 - 0x100000000), /// /// The provided side-by-side configuration is invalid /// CO_E_SXS_CONFIG = (int)(0x80004032 - 0x100000000), /// /// The server principal name (SPN) obtained during security negotiation is malformed. /// CO_E_MALFORMED_SPN = (int)(0x80004033 - 0x100000000), /// /// The operation completed successfully. /// S_OK = 0x00000000, /// /// Incorrect function. /// S_FALSE = 0x00000001, /// /// Invalid OLEVERB structure /// OLE_E_FIRST = (int)(0x80040000 - 0x100000000), /// /// No information avialable. /// OLE_E_LAST = (int)(0x800400FF - 0x100000000), /// /// Use the registry database to provide the requested information /// OLE_S_FIRST = 0x00040000, /// /// No information avialable. /// OLE_S_LAST = 0x000400FF, /// /// Invalid OLEVERB structure /// OLE_E_OLEVERB = (int)(0x80040000 - 0x100000000), /// /// Invalid advise flags /// OLE_E_ADVF = (int)(0x80040001 - 0x100000000), /// /// Can't enumerate any more, because the associated data is missing /// OLE_E_ENUM_NOMORE = (int)(0x80040002 - 0x100000000), /// /// This implementation doesn't take advises /// OLE_E_ADVISENOTSUPPORTED = (int)(0x80040003 - 0x100000000), /// /// There is no connection for this connection ID /// OLE_E_NOCONNECTION = (int)(0x80040004 - 0x100000000), /// /// Need to run the object to perform this operation /// OLE_E_NOTRUNNING = (int)(0x80040005 - 0x100000000), /// /// There is no cache to operate on /// OLE_E_NOCACHE = (int)(0x80040006 - 0x100000000), /// /// Uninitialized object /// OLE_E_BLANK = (int)(0x80040007 - 0x100000000), /// /// Linked object's source class has changed /// OLE_E_CLASSDIFF = (int)(0x80040008 - 0x100000000), /// /// Not able to get the moniker of the object /// OLE_E_CANT_GETMONIKER = (int)(0x80040009 - 0x100000000), /// /// Not able to bind to the source /// OLE_E_CANT_BINDTOSOURCE = (int)(0x8004000A - 0x100000000), /// /// Object is static, operation not allowed /// OLE_E_STATIC = (int)(0x8004000B - 0x100000000), /// /// User canceled out of save dialog /// OLE_E_PROMPTSAVECANCELLED = (int)(0x8004000C - 0x100000000), /// /// Invalid rectangle /// OLE_E_INVALIDRECT = (int)(0x8004000D - 0x100000000), /// /// compobj.dll is too old for the ole2.dll initialized /// OLE_E_WRONGCOMPOBJ = (int)(0x8004000E - 0x100000000), /// /// Invalid window handle /// OLE_E_INVALIDHWND = (int)(0x8004000F - 0x100000000), /// /// Object is not in any of the inplace active states /// OLE_E_NOT_INPLACEACTIVE = (int)(0x80040010 - 0x100000000), /// /// Not able to convert object /// OLE_E_CANTCONVERT = (int)(0x80040011 - 0x100000000), /// /// Not able to perform the operation because object is not given storage yet /// OLE_E_NOSTORAGE = (int)(0x80040012 - 0x100000000), /// /// Invalid FORMATETC structure /// DV_E_FORMATETC = (int)(0x80040064 - 0x100000000), /// /// Invalid DVTARGETDEVICE structure /// DV_E_DVTARGETDEVICE = (int)(0x80040065 - 0x100000000), /// /// Invalid STDGMEDIUM structure /// DV_E_STGMEDIUM = (int)(0x80040066 - 0x100000000), /// /// Invalid STATDATA structure /// DV_E_STATDATA = (int)(0x80040067 - 0x100000000), /// /// Invalid lindex /// DV_E_LINDEX = (int)(0x80040068 - 0x100000000), /// /// Invalid tymed /// DV_E_TYMED = (int)(0x80040069 - 0x100000000), /// /// Invalid clipboard format /// DV_E_CLIPFORMAT = (int)(0x8004006A - 0x100000000), /// /// Invalid aspect(s) /// DV_E_DVASPECT = (int)(0x8004006B - 0x100000000), /// /// tdSize parameter of the DVTARGETDEVICE structure is invalid /// DV_E_DVTARGETDEVICE_SIZE = (int)(0x8004006C - 0x100000000), /// /// Object doesn't support IViewObject interface /// DV_E_NOIVIEWOBJECT = (int)(0x8004006D - 0x100000000), /// /// Trying to revoke a drop target that has not been registered /// DRAGDROP_E_FIRST = (int)(0x80040100 - 0x100000000), /// /// No information avialable. /// DRAGDROP_E_LAST = (int)(0x8004010F - 0x100000000), /// /// Successful drop took place /// DRAGDROP_S_FIRST = 0x00040100, /// /// No information avialable. /// DRAGDROP_S_LAST = 0x0004010F, /// /// Trying to revoke a drop target that has not been registered /// DRAGDROP_E_NOTREGISTERED = (int)(0x80040100 - 0x100000000), /// /// This window has already been registered as a drop target /// DRAGDROP_E_ALREADYREGISTERED = (int)(0x80040101 - 0x100000000), /// /// Invalid window handle /// DRAGDROP_E_INVALIDHWND = (int)(0x80040102 - 0x100000000), /// /// Class does not support aggregation (or class object is remote) /// CLASSFACTORY_E_FIRST = (int)(0x80040110 - 0x100000000), /// /// No information avialable. /// CLASSFACTORY_E_LAST = (int)(0x8004011F - 0x100000000), /// /// No information avialable. /// CLASSFACTORY_S_FIRST = 0x00040110, /// /// No information avialable. /// CLASSFACTORY_S_LAST = 0x0004011F, /// /// Class does not support aggregation (or class object is remote) /// CLASS_E_NOAGGREGATION = (int)(0x80040110 - 0x100000000), /// /// ClassFactory cannot supply requested class /// CLASS_E_CLASSNOTAVAILABLE = (int)(0x80040111 - 0x100000000), /// /// Class is not licensed for use /// CLASS_E_NOTLICENSED = (int)(0x80040112 - 0x100000000), /// /// No information avialable. /// MARSHAL_E_FIRST = (int)(0x80040120 - 0x100000000), /// /// No information avialable. /// MARSHAL_E_LAST = (int)(0x8004012F - 0x100000000), /// /// No information avialable. /// MARSHAL_S_FIRST = 0x00040120, /// /// No information avialable. /// MARSHAL_S_LAST = 0x0004012F, /// /// No information avialable. /// DATA_E_FIRST = (int)(0x80040130 - 0x100000000), /// /// No information avialable. /// DATA_E_LAST = (int)(0x8004013F - 0x100000000), /// /// Data has same FORMATETC /// DATA_S_FIRST = 0x00040130, /// /// No information avialable. /// DATA_S_LAST = 0x0004013F, /// /// Error drawing view /// VIEW_E_FIRST = (int)(0x80040140 - 0x100000000), /// /// No information avialable. /// VIEW_E_LAST = (int)(0x8004014F - 0x100000000), /// /// View is already frozen /// VIEW_S_FIRST = 0x00040140, /// /// No information avialable. /// VIEW_S_LAST = 0x0004014F, /// /// Error drawing view /// VIEW_E_DRAW = (int)(0x80040140 - 0x100000000), /// /// Could not read key from registry /// REGDB_E_FIRST = (int)(0x80040150 - 0x100000000), /// /// No information avialable. /// REGDB_E_LAST = (int)(0x8004015F - 0x100000000), /// /// No information avialable. /// REGDB_S_FIRST = 0x00040150, /// /// No information avialable. /// REGDB_S_LAST = 0x0004015F, /// /// Could not read key from registry /// REGDB_E_READREGDB = (int)(0x80040150 - 0x100000000), /// /// Could not write key to registry /// REGDB_E_WRITEREGDB = (int)(0x80040151 - 0x100000000), /// /// Could not find the key in the registry /// REGDB_E_KEYMISSING = (int)(0x80040152 - 0x100000000), /// /// Invalid value for registry /// REGDB_E_INVALIDVALUE = (int)(0x80040153 - 0x100000000), /// /// Class not registered /// REGDB_E_CLASSNOTREG = (int)(0x80040154 - 0x100000000), /// /// Interface not registered /// REGDB_E_IIDNOTREG = (int)(0x80040155 - 0x100000000), /// /// Threading model entry is not valid /// REGDB_E_BADTHREADINGMODEL = (int)(0x80040156 - 0x100000000), /// /// CATID does not exist /// CAT_E_FIRST = (int)(0x80040160 - 0x100000000), /// /// Description not found /// CAT_E_LAST = (int)(0x80040161 - 0x100000000), /// /// CATID does not exist /// CAT_E_CATIDNOEXIST = (int)(0x80040160 - 0x100000000), /// /// Description not found /// CAT_E_NODESCRIPTION = (int)(0x80040161 - 0x100000000), /// /// No package in the software installation data in the Active Directory meets this criteria. /// CS_E_FIRST = (int)(0x80040164 - 0x100000000), /// /// An error occurred in the software installation data in the Active Directory. /// CS_E_LAST = (int)(0x8004016F - 0x100000000), /// /// No package in the software installation data in the Active Directory meets this criteria. /// CS_E_PACKAGE_NOTFOUND = (int)(0x80040164 - 0x100000000), /// /// Deleting this will break the referential integrity of the software installation data in the Active Directory. /// CS_E_NOT_DELETABLE = (int)(0x80040165 - 0x100000000), /// /// The CLSID was not found in the software installation data in the Active Directory. /// CS_E_CLASS_NOTFOUND = (int)(0x80040166 - 0x100000000), /// /// The software installation data in the Active Directory is corrupt. /// CS_E_INVALID_VERSION = (int)(0x80040167 - 0x100000000), /// /// There is no software installation data in the Active Directory. /// CS_E_NO_CLASSSTORE = (int)(0x80040168 - 0x100000000), /// /// There is no software installation data object in the Active Directory. /// CS_E_OBJECT_NOTFOUND = (int)(0x80040169 - 0x100000000), /// /// The software installation data object in the Active Directory already exists. /// CS_E_OBJECT_ALREADY_EXISTS = (int)(0x8004016A - 0x100000000), /// /// The path to the software installation data in the Active Directory is not correct. /// CS_E_INVALID_PATH = (int)(0x8004016B - 0x100000000), /// /// A network error interrupted the operation. /// CS_E_NETWORK_ERROR = (int)(0x8004016C - 0x100000000), /// /// The size of this object exceeds the maximum size set by the Administrator. /// CS_E_ADMIN_LIMIT_EXCEEDED = (int)(0x8004016D - 0x100000000), /// /// The schema for the software installation data in the Active Directory does not match the required schema. /// CS_E_SCHEMA_MISMATCH = (int)(0x8004016E - 0x100000000), /// /// An error occurred in the software installation data in the Active Directory. /// CS_E_INTERNAL_ERROR = (int)(0x8004016F - 0x100000000), /// /// Cache not updated /// CACHE_E_FIRST = (int)(0x80040170 - 0x100000000), /// /// No information avialable. /// CACHE_E_LAST = (int)(0x8004017F - 0x100000000), /// /// FORMATETC not supported /// CACHE_S_FIRST = 0x00040170, /// /// No information avialable. /// CACHE_S_LAST = 0x0004017F, /// /// Cache not updated /// CACHE_E_NOCACHE_UPDATED = (int)(0x80040170 - 0x100000000), /// /// No verbs for OLE object /// OLEOBJ_E_FIRST = (int)(0x80040180 - 0x100000000), /// /// No information avialable. /// OLEOBJ_E_LAST = (int)(0x8004018F - 0x100000000), /// /// Invalid verb for OLE object /// OLEOBJ_S_FIRST = 0x00040180, /// /// No information avialable. /// OLEOBJ_S_LAST = 0x0004018F, /// /// No verbs for OLE object /// OLEOBJ_E_NOVERBS = (int)(0x80040180 - 0x100000000), /// /// Invalid verb for OLE object /// OLEOBJ_E_INVALIDVERB = (int)(0x80040181 - 0x100000000), /// /// No information avialable. /// CLIENTSITE_E_FIRST = (int)(0x80040190 - 0x100000000), /// /// No information avialable. /// CLIENTSITE_E_LAST = (int)(0x8004019F - 0x100000000), /// /// No information avialable. /// CLIENTSITE_S_FIRST = 0x00040190, /// /// No information avialable. /// CLIENTSITE_S_LAST = 0x0004019F, /// /// Undo is not available /// INPLACE_E_NOTUNDOABLE = (int)(0x800401A0 - 0x100000000), /// /// Space for tools is not available /// INPLACE_E_NOTOOLSPACE = (int)(0x800401A1 - 0x100000000), /// /// Undo is not available /// INPLACE_E_FIRST = (int)(0x800401A0 - 0x100000000), /// /// No information avialable. /// INPLACE_E_LAST = (int)(0x800401AF - 0x100000000), /// /// Message is too long, some of it had to be truncated before displaying /// INPLACE_S_FIRST = 0x000401A0, /// /// No information avialable. /// INPLACE_S_LAST = 0x000401AF, /// /// No information avialable. /// ENUM_E_FIRST = (int)(0x800401B0 - 0x100000000), /// /// No information avialable. /// ENUM_E_LAST = (int)(0x800401BF - 0x100000000), /// /// No information avialable. /// ENUM_S_FIRST = 0x000401B0, /// /// No information avialable. /// ENUM_S_LAST = 0x000401BF, /// /// OLESTREAM Get method failed /// CONVERT10_E_FIRST = (int)(0x800401C0 - 0x100000000), /// /// No information avialable. /// CONVERT10_E_LAST = (int)(0x800401CF - 0x100000000), /// /// Unable to convert OLESTREAM to IStorage /// CONVERT10_S_FIRST = 0x000401C0, /// /// No information avialable. /// CONVERT10_S_LAST = 0x000401CF, /// /// OLESTREAM Get method failed /// CONVERT10_E_OLESTREAM_GET = (int)(0x800401C0 - 0x100000000), /// /// OLESTREAM Put method failed /// CONVERT10_E_OLESTREAM_PUT = (int)(0x800401C1 - 0x100000000), /// /// Contents of the OLESTREAM not in correct format /// CONVERT10_E_OLESTREAM_FMT = (int)(0x800401C2 - 0x100000000), /// /// There was an error in a Windows GDI call while converting the bitmap to a DIB /// CONVERT10_E_OLESTREAM_BITMAP_TO_DIB = (int)(0x800401C3 - 0x100000000), /// /// Contents of the IStorage not in correct format /// CONVERT10_E_STG_FMT = (int)(0x800401C4 - 0x100000000), /// /// Contents of IStorage is missing one of the standard streams /// CONVERT10_E_STG_NO_STD_STREAM = (int)(0x800401C5 - 0x100000000), /// /// There was an error in a Windows GDI call while converting the DIB to a bitmap. /// CONVERT10_E_STG_DIB_TO_BITMAP = (int)(0x800401C6 - 0x100000000), /// /// OpenClipboard Failed /// CLIPBRD_E_FIRST = (int)(0x800401D0 - 0x100000000), /// /// No information avialable. /// CLIPBRD_E_LAST = (int)(0x800401DF - 0x100000000), /// /// No information avialable. /// CLIPBRD_S_FIRST = 0x000401D0, /// /// No information avialable. /// CLIPBRD_S_LAST = 0x000401DF, /// /// OpenClipboard Failed /// CLIPBRD_E_CANT_OPEN = (int)(0x800401D0 - 0x100000000), /// /// EmptyClipboard Failed /// CLIPBRD_E_CANT_EMPTY = (int)(0x800401D1 - 0x100000000), /// /// SetClipboard Failed /// CLIPBRD_E_CANT_SET = (int)(0x800401D2 - 0x100000000), /// /// Data on clipboard is invalid /// CLIPBRD_E_BAD_DATA = (int)(0x800401D3 - 0x100000000), /// /// CloseClipboard Failed /// CLIPBRD_E_CANT_CLOSE = (int)(0x800401D4 - 0x100000000), /// /// Moniker needs to be connected manually /// MK_E_FIRST = (int)(0x800401E0 - 0x100000000), /// /// Moniker could not be enumerated /// MK_E_LAST = (int)(0x800401EF - 0x100000000), /// /// No information avialable. /// MK_S_FIRST = 0x000401E0, /// /// No information avialable. /// MK_S_LAST = 0x000401EF, /// /// Moniker needs to be connected manually /// MK_E_CONNECTMANUALLY = (int)(0x800401E0 - 0x100000000), /// /// Operation exceeded deadline /// MK_E_EXCEEDEDDEADLINE = (int)(0x800401E1 - 0x100000000), /// /// Moniker needs to be generic /// MK_E_NEEDGENERIC = (int)(0x800401E2 - 0x100000000), /// /// Operation unavailable /// MK_E_UNAVAILABLE = (int)(0x800401E3 - 0x100000000), /// /// Invalid syntax /// MK_E_SYNTAX = (int)(0x800401E4 - 0x100000000), /// /// No object for moniker /// MK_E_NOOBJECT = (int)(0x800401E5 - 0x100000000), /// /// Bad extension for file /// MK_E_INVALIDEXTENSION = (int)(0x800401E6 - 0x100000000), /// /// Intermediate operation failed /// MK_E_INTERMEDIATEINTERFACENOTSUPPORTED = (int)(0x800401E7 - 0x100000000), /// /// Moniker is not bindable /// MK_E_NOTBINDABLE = (int)(0x800401E8 - 0x100000000), /// /// Moniker is not bound /// MK_E_NOTBOUND = (int)(0x800401E9 - 0x100000000), /// /// Moniker cannot open file /// MK_E_CANTOPENFILE = (int)(0x800401EA - 0x100000000), /// /// User input required for operation to succeed /// MK_E_MUSTBOTHERUSER = (int)(0x800401EB - 0x100000000), /// /// Moniker class has no inverse /// MK_E_NOINVERSE = (int)(0x800401EC - 0x100000000), /// /// Moniker does not refer to storage /// MK_E_NOSTORAGE = (int)(0x800401ED - 0x100000000), /// /// No common prefix /// MK_E_NOPREFIX = (int)(0x800401EE - 0x100000000), /// /// Moniker could not be enumerated /// MK_E_ENUMERATION_FAILED = (int)(0x800401EF - 0x100000000), /// /// CoInitialize has not been called. /// CO_E_FIRST = (int)(0x800401F0 - 0x100000000), /// /// Object has been released /// CO_E_LAST = (int)(0x800401FF - 0x100000000), /// /// No information avialable. /// CO_S_FIRST = 0x000401F0, /// /// No information avialable. /// CO_S_LAST = 0x000401FF, /// /// CoInitialize has not been called. /// CO_E_NOTINITIALIZED = (int)(0x800401F0 - 0x100000000), /// /// CoInitialize has already been called. /// CO_E_ALREADYINITIALIZED = (int)(0x800401F1 - 0x100000000), /// /// Class of object cannot be determined /// CO_E_CANTDETERMINECLASS = (int)(0x800401F2 - 0x100000000), /// /// Invalid class string /// CO_E_CLASSSTRING = (int)(0x800401F3 - 0x100000000), /// /// Invalid interface string /// CO_E_IIDSTRING = (int)(0x800401F4 - 0x100000000), /// /// Application not found /// CO_E_APPNOTFOUND = (int)(0x800401F5 - 0x100000000), /// /// Application cannot be run more than once /// CO_E_APPSINGLEUSE = (int)(0x800401F6 - 0x100000000), /// /// Some error in application program /// CO_E_ERRORINAPP = (int)(0x800401F7 - 0x100000000), /// /// DLL for class not found /// CO_E_DLLNOTFOUND = (int)(0x800401F8 - 0x100000000), /// /// Error in the DLL /// CO_E_ERRORINDLL = (int)(0x800401F9 - 0x100000000), /// /// Wrong OS or OS version for application /// CO_E_WRONGOSFORAPP = (int)(0x800401FA - 0x100000000), /// /// Object is not registered /// CO_E_OBJNOTREG = (int)(0x800401FB - 0x100000000), /// /// Object is already registered /// CO_E_OBJISREG = (int)(0x800401FC - 0x100000000), /// /// Object is not connected to server /// CO_E_OBJNOTCONNECTED = (int)(0x800401FD - 0x100000000), /// /// Application was launched but it didn't register a class factory /// CO_E_APPDIDNTREG = (int)(0x800401FE - 0x100000000), /// /// Object has been released /// CO_E_RELEASED = (int)(0x800401FF - 0x100000000), /// /// No information avialable. /// EVENT_E_FIRST = (int)(0x80040200 - 0x100000000), /// /// No information avialable. /// EVENT_E_LAST = (int)(0x8004021F - 0x100000000), /// /// An event was able to invoke some but not all of the subscribers /// EVENT_S_FIRST = 0x00040200, /// /// No information avialable. /// EVENT_S_LAST = 0x0004021F, /// /// An event was able to invoke some but not all of the subscribers /// EVENT_S_SOME_SUBSCRIBERS_FAILED = 0x00040200, /// /// An event was unable to invoke any of the subscribers /// EVENT_E_ALL_SUBSCRIBERS_FAILED = (int)(0x80040201 - 0x100000000), /// /// An event was delivered but there were no subscribers /// EVENT_S_NOSUBSCRIBERS = 0x00040202, /// /// A syntax error occurred trying to evaluate a query string /// EVENT_E_QUERYSYNTAX = (int)(0x80040203 - 0x100000000), /// /// An invalid field name was used in a query string /// EVENT_E_QUERYFIELD = (int)(0x80040204 - 0x100000000), /// /// An unexpected exception was raised /// EVENT_E_INTERNALEXCEPTION = (int)(0x80040205 - 0x100000000), /// /// An unexpected internal error was detected /// EVENT_E_INTERNALERROR = (int)(0x80040206 - 0x100000000), /// /// The owner SID on a per-user subscription doesn't exist /// EVENT_E_INVALID_PER_USER_SID = (int)(0x80040207 - 0x100000000), /// /// A user-supplied component or subscriber raised an exception /// EVENT_E_USER_EXCEPTION = (int)(0x80040208 - 0x100000000), /// /// An interface has too many methods to fire events from /// EVENT_E_TOO_MANY_METHODS = (int)(0x80040209 - 0x100000000), /// /// A subscription cannot be stored unless its event class already exists /// EVENT_E_MISSING_EVENTCLASS = (int)(0x8004020A - 0x100000000), /// /// Not all the objects requested could be removed /// EVENT_E_NOT_ALL_REMOVED = (int)(0x8004020B - 0x100000000), /// /// COM+ is required for this operation, but is not installed /// EVENT_E_COMPLUS_NOT_INSTALLED = (int)(0x8004020C - 0x100000000), /// /// Cannot modify or delete an object that was not added using the COM+ Admin SDK /// EVENT_E_CANT_MODIFY_OR_DELETE_UNCONFIGURED_OBJECT = (int)(0x8004020D - 0x100000000), /// /// Cannot modify or delete an object that was added using the COM+ Admin SDK /// EVENT_E_CANT_MODIFY_OR_DELETE_CONFIGURED_OBJECT = (int)(0x8004020E - 0x100000000), /// /// The event class for this subscription is in an invalid partition /// EVENT_E_INVALID_EVENT_CLASS_PARTITION = (int)(0x8004020F - 0x100000000), /// /// The owner of the PerUser subscription is not logged on to the system specified /// EVENT_E_PER_USER_SID_NOT_LOGGED_ON = (int)(0x80040210 - 0x100000000), /// /// Another single phase resource manager has already been enlisted in this transaction. /// XACT_E_FIRST = (int)(0x8004D000 - 0x100000000), /// /// The local transaction has aborted. /// XACT_E_LAST = (int)(0x8004D029 - 0x100000000), /// /// An asynchronous operation was specified. The operation has begun, but its outcome is not known yet. /// XACT_S_FIRST = 0x0004D000, /// /// The resource manager has requested to be the coordinator (last resource manager) for the transaction. /// XACT_S_LAST = 0x0004D010, /// /// Another single phase resource manager has already been enlisted in this transaction. /// XACT_E_ALREADYOTHERSINGLEPHASE = (int)(0x8004D000 - 0x100000000), /// /// A retaining commit or abort is not supported /// XACT_E_CANTRETAIN = (int)(0x8004D001 - 0x100000000), /// /// The transaction failed to commit for an unknown reason. The transaction was aborted. /// XACT_E_COMMITFAILED = (int)(0x8004D002 - 0x100000000), /// /// Cannot call commit on this transaction object because the calling application did not initiate the transaction. /// XACT_E_COMMITPREVENTED = (int)(0x8004D003 - 0x100000000), /// /// Instead of committing, the resource heuristically aborted. /// XACT_E_HEURISTICABORT = (int)(0x8004D004 - 0x100000000), /// /// Instead of aborting, the resource heuristically committed. /// XACT_E_HEURISTICCOMMIT = (int)(0x8004D005 - 0x100000000), /// /// Some of the states of the resource were committed while others were aborted, likely because of heuristic decisions. /// XACT_E_HEURISTICDAMAGE = (int)(0x8004D006 - 0x100000000), /// /// Some of the states of the resource may have been committed while others may have been aborted, likely because of heuristic decisions. /// XACT_E_HEURISTICDANGER = (int)(0x8004D007 - 0x100000000), /// /// The requested isolation level is not valid or supported. /// XACT_E_ISOLATIONLEVEL = (int)(0x8004D008 - 0x100000000), /// /// The transaction manager doesn't support an asynchronous operation for this method. /// XACT_E_NOASYNC = (int)(0x8004D009 - 0x100000000), /// /// Unable to enlist in the transaction. /// XACT_E_NOENLIST = (int)(0x8004D00A - 0x100000000), /// /// The requested semantics of retention of isolation across retaining commit and abort boundaries cannot be supported by this transaction implementation, or isoFlags was not equal to zero. /// XACT_E_NOISORETAIN = (int)(0x8004D00B - 0x100000000), /// /// There is no resource presently associated with this enlistment /// XACT_E_NORESOURCE = (int)(0x8004D00C - 0x100000000), /// /// The transaction failed to commit due to the failure of optimistic concurrency control in at least one of the resource managers. /// XACT_E_NOTCURRENT = (int)(0x8004D00D - 0x100000000), /// /// The transaction has already been implicitly or explicitly committed or aborted /// XACT_E_NOTRANSACTION = (int)(0x8004D00E - 0x100000000), /// /// An invalid combination of flags was specified /// XACT_E_NOTSUPPORTED = (int)(0x8004D00F - 0x100000000), /// /// The resource manager id is not associated with this transaction or the transaction manager. /// XACT_E_UNKNOWNRMGRID = (int)(0x8004D010 - 0x100000000), /// /// This method was called in the wrong state /// XACT_E_WRONGSTATE = (int)(0x8004D011 - 0x100000000), /// /// The indicated unit of work does not match the unit of work expected by the resource manager. /// XACT_E_WRONGUOW = (int)(0x8004D012 - 0x100000000), /// /// An enlistment in a transaction already exists. /// XACT_E_XTIONEXISTS = (int)(0x8004D013 - 0x100000000), /// /// An import object for the transaction could not be found. /// XACT_E_NOIMPORTOBJECT = (int)(0x8004D014 - 0x100000000), /// /// The transaction cookie is invalid. /// XACT_E_INVALIDCOOKIE = (int)(0x8004D015 - 0x100000000), /// /// The transaction status is in doubt. A communication failure occurred, or a transaction manager or resource manager has failed /// XACT_E_INDOUBT = (int)(0x8004D016 - 0x100000000), /// /// A time-out was specified, but time-outs are not supported. /// XACT_E_NOTIMEOUT = (int)(0x8004D017 - 0x100000000), /// /// The requested operation is already in progress for the transaction. /// XACT_E_ALREADYINPROGRESS = (int)(0x8004D018 - 0x100000000), /// /// The transaction has already been aborted. /// XACT_E_ABORTED = (int)(0x8004D019 - 0x100000000), /// /// The Transaction Manager returned a log full error. /// XACT_E_LOGFULL = (int)(0x8004D01A - 0x100000000), /// /// The Transaction Manager is not available. /// XACT_E_TMNOTAVAILABLE = (int)(0x8004D01B - 0x100000000), /// /// A connection with the transaction manager was lost. /// XACT_E_CONNECTION_DOWN = (int)(0x8004D01C - 0x100000000), /// /// A request to establish a connection with the transaction manager was denied. /// XACT_E_CONNECTION_DENIED = (int)(0x8004D01D - 0x100000000), /// /// Resource manager reenlistment to determine transaction status timed out. /// XACT_E_REENLISTTIMEOUT = (int)(0x8004D01E - 0x100000000), /// /// This transaction manager failed to establish a connection with another TIP transaction manager. /// XACT_E_TIP_CONNECT_FAILED = (int)(0x8004D01F - 0x100000000), /// /// This transaction manager encountered a protocol error with another TIP transaction manager. /// XACT_E_TIP_PROTOCOL_ERROR = (int)(0x8004D020 - 0x100000000), /// /// This transaction manager could not propagate a transaction from another TIP transaction manager. /// XACT_E_TIP_PULL_FAILED = (int)(0x8004D021 - 0x100000000), /// /// The Transaction Manager on the destination machine is not available. /// XACT_E_DEST_TMNOTAVAILABLE = (int)(0x8004D022 - 0x100000000), /// /// The Transaction Manager has disabled its support for TIP. /// XACT_E_TIP_DISABLED = (int)(0x8004D023 - 0x100000000), /// /// The transaction manager has disabled its support for remote/network transactions. /// XACT_E_NETWORK_TX_DISABLED = (int)(0x8004D024 - 0x100000000), /// /// The partner transaction manager has disabled its support for remote/network transactions. /// XACT_E_PARTNER_NETWORK_TX_DISABLED = (int)(0x8004D025 - 0x100000000), /// /// The transaction manager has disabled its support for XA transactions. /// XACT_E_XA_TX_DISABLED = (int)(0x8004D026 - 0x100000000), /// /// MSDTC was unable to read its configuration information. /// XACT_E_UNABLE_TO_READ_DTC_CONFIG = (int)(0x8004D027 - 0x100000000), /// /// MSDTC was unable to load the dtc proxy dll. /// XACT_E_UNABLE_TO_LOAD_DTC_PROXY = (int)(0x8004D028 - 0x100000000), /// /// The local transaction has aborted. /// XACT_E_ABORTING = (int)(0x8004D029 - 0x100000000), /// /// XACT_E_CLERKNOTFOUND /// XACT_E_CLERKNOTFOUND = (int)(0x8004D080 - 0x100000000), /// /// XACT_E_CLERKEXISTS /// XACT_E_CLERKEXISTS = (int)(0x8004D081 - 0x100000000), /// /// XACT_E_RECOVERYINPROGRESS /// XACT_E_RECOVERYINPROGRESS = (int)(0x8004D082 - 0x100000000), /// /// XACT_E_TRANSACTIONCLOSED /// XACT_E_TRANSACTIONCLOSED = (int)(0x8004D083 - 0x100000000), /// /// XACT_E_INVALIDLSN /// XACT_E_INVALIDLSN = (int)(0x8004D084 - 0x100000000), /// /// XACT_E_REPLAYREQUEST /// XACT_E_REPLAYREQUEST = (int)(0x8004D085 - 0x100000000), /// /// An asynchronous operation was specified. The operation has begun, but its outcome is not known yet. /// XACT_S_ASYNC = 0x0004D000, /// /// XACT_S_DEFECT /// XACT_S_DEFECT = 0x0004D001, /// /// The method call succeeded because the transaction was read-only. /// XACT_S_READONLY = 0x0004D002, /// /// The transaction was successfully aborted. However, this is a coordinated transaction, and some number of enlisted resources were aborted outright because they could not support abort-retaining semantics /// XACT_S_SOMENORETAIN = 0x0004D003, /// /// No changes were made during this call, but the sink wants another chance to look if any other sinks make further changes. /// XACT_S_OKINFORM = 0x0004D004, /// /// The sink is content and wishes the transaction to proceed. Changes were made to one or more resources during this call. /// XACT_S_MADECHANGESCONTENT = 0x0004D005, /// /// The sink is for the moment and wishes the transaction to proceed, but if other changes are made following this return by other event sinks then this sink wants another chance to look /// XACT_S_MADECHANGESINFORM = 0x0004D006, /// /// The transaction was successfully aborted. However, the abort was non-retaining. /// XACT_S_ALLNORETAIN = 0x0004D007, /// /// An abort operation was already in progress. /// XACT_S_ABORTING = 0x0004D008, /// /// The resource manager has performed a single-phase commit of the transaction. /// XACT_S_SINGLEPHASE = 0x0004D009, /// /// The local transaction has not aborted. /// XACT_S_LOCALLY_OK = 0x0004D00A, /// /// The resource manager has requested to be the coordinator (last resource manager) for the transaction. /// XACT_S_LASTRESOURCEMANAGER = 0x0004D010, /// /// No information avialable. /// CONTEXT_E_FIRST = (int)(0x8004E000 - 0x100000000), /// /// The TxIsolation Level property for the COM+ component being created is stronger than the TxIsolationLevel for the "root" component for the transaction. The creation failed. /// CONTEXT_E_LAST = (int)(0x8004E02F - 0x100000000), /// /// No information avialable. /// CONTEXT_S_FIRST = 0x0004E000, /// /// No information avialable. /// CONTEXT_S_LAST = 0x0004E02F, /// /// The root transaction wanted to commit, but transaction aborted /// CONTEXT_E_ABORTED = (int)(0x8004E002 - 0x100000000), /// /// You made a method call on a COM+ component that has a transaction that has already aborted or in the process of aborting. /// CONTEXT_E_ABORTING = (int)(0x8004E003 - 0x100000000), /// /// There is no MTS object context /// CONTEXT_E_NOCONTEXT = (int)(0x8004E004 - 0x100000000), /// /// No information avialable. /// CONTEXT_E_WOULD_DEADLOCK = (int)(0x8004E005 - 0x100000000), /// /// The component is configured to use synchronization and a thread has timed out waiting to enter the context. /// CONTEXT_E_SYNCH_TIMEOUT = (int)(0x8004E006 - 0x100000000), /// /// You made a method call on a COM+ component that has a transaction that has already committed or aborted. /// CONTEXT_E_OLDREF = (int)(0x8004E007 - 0x100000000), /// /// The specified role was not configured for the application /// CONTEXT_E_ROLENOTFOUND = (int)(0x8004E00C - 0x100000000), /// /// COM+ was unable to talk to the Microsoft Distributed Transaction Coordinator /// CONTEXT_E_TMNOTAVAILABLE = (int)(0x8004E00F - 0x100000000), /// /// An unexpected error occurred during COM+ Activation. /// CO_E_ACTIVATIONFAILED = (int)(0x8004E021 - 0x100000000), /// /// COM+ Activation failed. Check the event log for more information /// CO_E_ACTIVATIONFAILED_EVENTLOGGED = (int)(0x8004E022 - 0x100000000), /// /// COM+ Activation failed due to a catalog or configuration error. /// CO_E_ACTIVATIONFAILED_CATALOGERROR = (int)(0x8004E023 - 0x100000000), /// /// COM+ activation failed because the activation could not be completed in the specified amount of time. /// CO_E_ACTIVATIONFAILED_TIMEOUT = (int)(0x8004E024 - 0x100000000), /// /// COM+ Activation failed because an initialization function failed. Check the event log for more information. /// CO_E_INITIALIZATIONFAILED = (int)(0x8004E025 - 0x100000000), /// /// The requested operation requires that JIT be in the current context and it is not /// CONTEXT_E_NOJIT = (int)(0x8004E026 - 0x100000000), /// /// The requested operation requires that the current context have a Transaction, and it does not /// CONTEXT_E_NOTRANSACTION = (int)(0x8004E027 - 0x100000000), /// /// The components threading model has changed after install into a COM+ Application. Please re-install component. /// CO_E_THREADINGMODEL_CHANGED = (int)(0x8004E028 - 0x100000000), /// /// IIS intrinsics not available. Start your work with IIS. /// CO_E_NOIISINTRINSICS = (int)(0x8004E029 - 0x100000000), /// /// An attempt to write a cookie failed. /// CO_E_NOCOOKIES = (int)(0x8004E02A - 0x100000000), /// /// An attempt to use a database generated a database specific error. /// CO_E_DBERROR = (int)(0x8004E02B - 0x100000000), /// /// The COM+ component you created must use object pooling to work. /// CO_E_NOTPOOLED = (int)(0x8004E02C - 0x100000000), /// /// The COM+ component you created must use object construction to work correctly. /// CO_E_NOTCONSTRUCTED = (int)(0x8004E02D - 0x100000000), /// /// The COM+ component requires synchronization, and it is not configured for it. /// CO_E_NOSYNCHRONIZATION = (int)(0x8004E02E - 0x100000000), /// /// The TxIsolation Level property for the COM+ component being created is stronger than the TxIsolationLevel for the "root" component for the transaction. The creation failed. /// CO_E_ISOLEVELMISMATCH = (int)(0x8004E02F - 0x100000000), /// /// Use the registry database to provide the requested information /// OLE_S_USEREG = 0x00040000, /// /// Success, but static /// OLE_S_STATIC = 0x00040001, /// /// Macintosh clipboard format /// OLE_S_MAC_CLIPFORMAT = 0x00040002, /// /// Successful drop took place /// DRAGDROP_S_DROP = 0x00040100, /// /// Drag-drop operation canceled /// DRAGDROP_S_CANCEL = 0x00040101, /// /// Use the default cursor /// DRAGDROP_S_USEDEFAULTCURSORS = 0x00040102, /// /// Data has same FORMATETC /// DATA_S_SAMEFORMATETC = 0x00040130, /// /// View is already frozen /// VIEW_S_ALREADY_FROZEN = 0x00040140, /// /// FORMATETC not supported /// CACHE_S_FORMATETC_NOTSUPPORTED = 0x00040170, /// /// Same cache /// CACHE_S_SAMECACHE = 0x00040171, /// /// Some cache(s) not updated /// CACHE_S_SOMECACHES_NOTUPDATED = 0x00040172, /// /// Invalid verb for OLE object /// OLEOBJ_S_INVALIDVERB = 0x00040180, /// /// Verb number is valid but verb cannot be done now /// OLEOBJ_S_CANNOT_DOVERB_NOW = 0x00040181, /// /// Invalid window handle passed /// OLEOBJ_S_INVALIDHWND = 0x00040182, /// /// Message is too long, some of it had to be truncated before displaying /// INPLACE_S_TRUNCATED = 0x000401A0, /// /// Unable to convert OLESTREAM to IStorage /// CONVERT10_S_NO_PRESENTATION = 0x000401C0, /// /// Moniker reduced to itself /// MK_S_REDUCED_TO_SELF = 0x000401E2, /// /// Common prefix is this moniker /// MK_S_ME = 0x000401E4, /// /// Common prefix is input moniker /// MK_S_HIM = 0x000401E5, /// /// Common prefix is both monikers /// MK_S_US = 0x000401E6, /// /// Moniker is already registered in running object table /// MK_S_MONIKERALREADYREGISTERED = 0x000401E7, /// /// The task is ready to run at its next scheduled time. /// SCHED_S_TASK_READY = 0x00041300, /// /// The task is currently running. /// SCHED_S_TASK_RUNNING = 0x00041301, /// /// The task will not run at the scheduled times because it has been disabled. /// SCHED_S_TASK_DISABLED = 0x00041302, /// /// The task has not yet run. /// SCHED_S_TASK_HAS_NOT_RUN = 0x00041303, /// /// There are no more runs scheduled for this task. /// SCHED_S_TASK_NO_MORE_RUNS = 0x00041304, /// /// One or more of the properties that are needed to run this task on a schedule have not been set. /// SCHED_S_TASK_NOT_SCHEDULED = 0x00041305, /// /// The last run of the task was terminated by the user. /// SCHED_S_TASK_TERMINATED = 0x00041306, /// /// Either the task has no triggers or the existing triggers are disabled or not set. /// SCHED_S_TASK_NO_VALID_TRIGGERS = 0x00041307, /// /// Event triggers don't have set run times. /// SCHED_S_EVENT_TRIGGER = 0x00041308, /// /// Trigger not found. /// SCHED_E_TRIGGER_NOT_FOUND = (int)(0x80041309 - 0x100000000), /// /// One or more of the properties that are needed to run this task have not been set. /// SCHED_E_TASK_NOT_READY = (int)(0x8004130A - 0x100000000), /// /// There is no running instance of the task to terminate. /// SCHED_E_TASK_NOT_RUNNING = (int)(0x8004130B - 0x100000000), /// /// The Task Scheduler Service is not installed on this computer. /// SCHED_E_SERVICE_NOT_INSTALLED = (int)(0x8004130C - 0x100000000), /// /// The task object could not be opened. /// SCHED_E_CANNOT_OPEN_TASK = (int)(0x8004130D - 0x100000000), /// /// The object is either an invalid task object or is not a task object. /// SCHED_E_INVALID_TASK = (int)(0x8004130E - 0x100000000), /// /// No account information could be found in the Task Scheduler security database for the task indicated. /// SCHED_E_ACCOUNT_INFORMATION_NOT_SET = (int)(0x8004130F - 0x100000000), /// /// Unable to establish existence of the account specified. /// SCHED_E_ACCOUNT_NAME_NOT_FOUND = (int)(0x80041310 - 0x100000000), /// /// Corruption was detected in the Task Scheduler security database, the database has been reset. /// SCHED_E_ACCOUNT_DBASE_CORRUPT = (int)(0x80041311 - 0x100000000), /// /// Task Scheduler security services are available only on Windows NT. /// SCHED_E_NO_SECURITY_SERVICES = (int)(0x80041312 - 0x100000000), /// /// The task object version is either unsupported or invalid. /// SCHED_E_UNKNOWN_OBJECT_VERSION = (int)(0x80041313 - 0x100000000), /// /// The task has been configured with an unsupported combination of account settings and run time options. /// SCHED_E_UNSUPPORTED_ACCOUNT_OPTION = (int)(0x80041314 - 0x100000000), /// /// The Task Scheduler Service is not running. /// SCHED_E_SERVICE_NOT_RUNNING = (int)(0x80041315 - 0x100000000), /// /// Attempt to create a class object failed /// CO_E_CLASS_CREATE_FAILED = (int)(0x80080001 - 0x100000000), /// /// OLE service could not bind object /// CO_E_SCM_ERROR = (int)(0x80080002 - 0x100000000), /// /// RPC communication failed with OLE service /// CO_E_SCM_RPC_FAILURE = (int)(0x80080003 - 0x100000000), /// /// Bad path to object /// CO_E_BAD_PATH = (int)(0x80080004 - 0x100000000), /// /// Server execution failed /// CO_E_SERVER_EXEC_FAILURE = (int)(0x80080005 - 0x100000000), /// /// OLE service could not communicate with the object server /// CO_E_OBJSRV_RPC_FAILURE = (int)(0x80080006 - 0x100000000), /// /// Moniker path could not be normalized /// MK_E_NO_NORMALIZED = (int)(0x80080007 - 0x100000000), /// /// Object server is stopping when OLE service contacts it /// CO_E_SERVER_STOPPING = (int)(0x80080008 - 0x100000000), /// /// An invalid root block pointer was specified /// MEM_E_INVALID_ROOT = (int)(0x80080009 - 0x100000000), /// /// An allocation chain contained an invalid link pointer /// MEM_E_INVALID_LINK = (int)(0x80080010 - 0x100000000), /// /// The requested allocation size was too large /// MEM_E_INVALID_SIZE = (int)(0x80080011 - 0x100000000), /// /// Not all the requested interfaces were available /// CO_S_NOTALLINTERFACES = 0x00080012, /// /// The specified machine name was not found in the cache. /// CO_S_MACHINENAMENOTFOUND = 0x00080013, /// /// Unknown interface. /// DISP_E_UNKNOWNINTERFACE = (int)(0x80020001 - 0x100000000), /// /// Member not found. /// DISP_E_MEMBERNOTFOUND = (int)(0x80020003 - 0x100000000), /// /// Parameter not found. /// DISP_E_PARAMNOTFOUND = (int)(0x80020004 - 0x100000000), /// /// Type mismatch. /// DISP_E_TYPEMISMATCH = (int)(0x80020005 - 0x100000000), /// /// Unknown name. /// DISP_E_UNKNOWNNAME = (int)(0x80020006 - 0x100000000), /// /// No named arguments. /// DISP_E_NONAMEDARGS = (int)(0x80020007 - 0x100000000), /// /// Bad variable type. /// DISP_E_BADVARTYPE = (int)(0x80020008 - 0x100000000), /// /// Exception occurred. /// DISP_E_EXCEPTION = (int)(0x80020009 - 0x100000000), /// /// Out of present range. /// DISP_E_OVERFLOW = (int)(0x8002000A - 0x100000000), /// /// Invalid index. /// DISP_E_BADINDEX = (int)(0x8002000B - 0x100000000), /// /// Unknown language. /// DISP_E_UNKNOWNLCID = (int)(0x8002000C - 0x100000000), /// /// Memory is locked. /// DISP_E_ARRAYISLOCKED = (int)(0x8002000D - 0x100000000), /// /// Invalid number of parameters. /// DISP_E_BADPARAMCOUNT = (int)(0x8002000E - 0x100000000), /// /// Parameter not optional. /// DISP_E_PARAMNOTOPTIONAL = (int)(0x8002000F - 0x100000000), /// /// Invalid callee. /// DISP_E_BADCALLEE = (int)(0x80020010 - 0x100000000), /// /// Does not support a collection. /// DISP_E_NOTACOLLECTION = (int)(0x80020011 - 0x100000000), /// /// Division by zero. /// DISP_E_DIVBYZERO = (int)(0x80020012 - 0x100000000), /// /// Buffer too small /// DISP_E_BUFFERTOOSMALL = (int)(0x80020013 - 0x100000000), /// /// Buffer too small. /// TYPE_E_BUFFERTOOSMALL = (int)(0x80028016 - 0x100000000), /// /// Field name not defined in the record. /// TYPE_E_FIELDNOTFOUND = (int)(0x80028017 - 0x100000000), /// /// Old format or invalid type library. /// TYPE_E_INVDATAREAD = (int)(0x80028018 - 0x100000000), /// /// Old format or invalid type library. /// TYPE_E_UNSUPFORMAT = (int)(0x80028019 - 0x100000000), /// /// Error accessing the OLE registry. /// TYPE_E_REGISTRYACCESS = (int)(0x8002801C - 0x100000000), /// /// Library not registered. /// TYPE_E_LIBNOTREGISTERED = (int)(0x8002801D - 0x100000000), /// /// Bound to unknown type. /// TYPE_E_UNDEFINEDTYPE = (int)(0x80028027 - 0x100000000), /// /// Qualified name disallowed. /// TYPE_E_QUALIFIEDNAMEDISALLOWED = (int)(0x80028028 - 0x100000000), /// /// Invalid forward reference, or reference to uncompiled type. /// TYPE_E_INVALIDSTATE = (int)(0x80028029 - 0x100000000), /// /// Type mismatch. /// TYPE_E_WRONGTYPEKIND = (int)(0x8002802A - 0x100000000), /// /// Element not found. /// TYPE_E_ELEMENTNOTFOUND = (int)(0x8002802B - 0x100000000), /// /// Ambiguous name. /// TYPE_E_AMBIGUOUSNAME = (int)(0x8002802C - 0x100000000), /// /// Name already exists in the library. /// TYPE_E_NAMECONFLICT = (int)(0x8002802D - 0x100000000), /// /// Unknown LCID. /// TYPE_E_UNKNOWNLCID = (int)(0x8002802E - 0x100000000), /// /// Function not defined in specified DLL. /// TYPE_E_DLLFUNCTIONNOTFOUND = (int)(0x8002802F - 0x100000000), /// /// Wrong module kind for the operation. /// TYPE_E_BADMODULEKIND = (int)(0x800288BD - 0x100000000), /// /// Size may not exceed 64K. /// TYPE_E_SIZETOOBIG = (int)(0x800288C5 - 0x100000000), /// /// Duplicate ID in inheritance hierarchy. /// TYPE_E_DUPLICATEID = (int)(0x800288C6 - 0x100000000), /// /// Incorrect inheritance depth in standard OLE hmember. /// TYPE_E_INVALIDID = (int)(0x800288CF - 0x100000000), /// /// Type mismatch. /// TYPE_E_TYPEMISMATCH = (int)(0x80028CA0 - 0x100000000), /// /// Invalid number of arguments. /// TYPE_E_OUTOFBOUNDS = (int)(0x80028CA1 - 0x100000000), /// /// I/O Error. /// TYPE_E_IOERROR = (int)(0x80028CA2 - 0x100000000), /// /// Error creating unique tmp file. /// TYPE_E_CANTCREATETMPFILE = (int)(0x80028CA3 - 0x100000000), /// /// Error loading type library/DLL. /// TYPE_E_CANTLOADLIBRARY = (int)(0x80029C4A - 0x100000000), /// /// Inconsistent property functions. /// TYPE_E_INCONSISTENTPROPFUNCS = (int)(0x80029C83 - 0x100000000), /// /// Circular dependency between types/modules. /// TYPE_E_CIRCULARTYPE = (int)(0x80029C84 - 0x100000000), /// /// Unable to perform requested operation. /// STG_E_INVALIDFUNCTION = (int)(0x80030001 - 0x100000000), /// /// %1 could not be found. /// STG_E_FILENOTFOUND = (int)(0x80030002 - 0x100000000), /// /// The path %1 could not be found. /// STG_E_PATHNOTFOUND = (int)(0x80030003 - 0x100000000), /// /// There are insufficient resources to open another file. /// STG_E_TOOMANYOPENFILES = (int)(0x80030004 - 0x100000000), /// /// Access Denied. /// STG_E_ACCESSDENIED = (int)(0x80030005 - 0x100000000), /// /// Attempted an operation on an invalid object. /// STG_E_INVALIDHANDLE = (int)(0x80030006 - 0x100000000), /// /// There is insufficient memory available to complete operation. /// STG_E_INSUFFICIENTMEMORY = (int)(0x80030008 - 0x100000000), /// /// Invalid pointer error. /// STG_E_INVALIDPOINTER = (int)(0x80030009 - 0x100000000), /// /// There are no more entries to return. /// STG_E_NOMOREFILES = (int)(0x80030012 - 0x100000000), /// /// Disk is write-protected. /// STG_E_DISKISWRITEPROTECTED = (int)(0x80030013 - 0x100000000), /// /// An error occurred during a seek operation. /// STG_E_SEEKERROR = (int)(0x80030019 - 0x100000000), /// /// A disk error occurred during a write operation. /// STG_E_WRITEFAULT = (int)(0x8003001D - 0x100000000), /// /// A disk error occurred during a read operation. /// STG_E_READFAULT = (int)(0x8003001E - 0x100000000), /// /// A share violation has occurred. /// STG_E_SHAREVIOLATION = (int)(0x80030020 - 0x100000000), /// /// A lock violation has occurred. /// STG_E_LOCKVIOLATION = (int)(0x80030021 - 0x100000000), /// /// %1 already exists. /// STG_E_FILEALREADYEXISTS = (int)(0x80030050 - 0x100000000), /// /// Invalid parameter error. /// STG_E_INVALIDPARAMETER = (int)(0x80030057 - 0x100000000), /// /// There is insufficient disk space to complete operation. /// STG_E_MEDIUMFULL = (int)(0x80030070 - 0x100000000), /// /// Illegal write of non-simple property to simple property set. /// STG_E_PROPSETMISMATCHED = (int)(0x800300F0 - 0x100000000), /// /// An API call exited abnormally. /// STG_E_ABNORMALAPIEXIT = (int)(0x800300FA - 0x100000000), /// /// The file %1 is not a valid compound file. /// STG_E_INVALIDHEADER = (int)(0x800300FB - 0x100000000), /// /// The name %1 is not valid. /// STG_E_INVALIDNAME = (int)(0x800300FC - 0x100000000), /// /// An unexpected error occurred. /// STG_E_UNKNOWN = (int)(0x800300FD - 0x100000000), /// /// That function is not implemented. /// STG_E_UNIMPLEMENTEDFUNCTION = (int)(0x800300FE - 0x100000000), /// /// Invalid flag error. /// STG_E_INVALIDFLAG = (int)(0x800300FF - 0x100000000), /// /// Attempted to use an object that is busy. /// STG_E_INUSE = (int)(0x80030100 - 0x100000000), /// /// The storage has been changed since the last commit. /// STG_E_NOTCURRENT = (int)(0x80030101 - 0x100000000), /// /// Attempted to use an object that has ceased to exist. /// STG_E_REVERTED = (int)(0x80030102 - 0x100000000), /// /// Can't save. /// STG_E_CANTSAVE = (int)(0x80030103 - 0x100000000), /// /// The compound file %1 was produced with an incompatible version of storage. /// STG_E_OLDFORMAT = (int)(0x80030104 - 0x100000000), /// /// The compound file %1 was produced with a newer version of storage. /// STG_E_OLDDLL = (int)(0x80030105 - 0x100000000), /// /// Share.exe or equivalent is required for operation. /// STG_E_SHAREREQUIRED = (int)(0x80030106 - 0x100000000), /// /// Illegal operation called on non-file based storage. /// STG_E_NOTFILEBASEDSTORAGE = (int)(0x80030107 - 0x100000000), /// /// Illegal operation called on object with extant marshallings. /// STG_E_EXTANTMARSHALLINGS = (int)(0x80030108 - 0x100000000), /// /// The docfile has been corrupted. /// STG_E_DOCFILECORRUPT = (int)(0x80030109 - 0x100000000), /// /// OLE32.DLL has been loaded at the wrong address. /// STG_E_BADBASEADDRESS = (int)(0x80030110 - 0x100000000), /// /// The compound file is too large for the current implementation /// STG_E_DOCFILETOOLARGE = (int)(0x80030111 - 0x100000000), /// /// The compound file was not created with the STGM_SIMPLE flag /// STG_E_NOTSIMPLEFORMAT = (int)(0x80030112 - 0x100000000), /// /// The file download was aborted abnormally. The file is incomplete. /// STG_E_INCOMPLETE = (int)(0x80030201 - 0x100000000), /// /// The file download has been terminated. /// STG_E_TERMINATED = (int)(0x80030202 - 0x100000000), /// /// The underlying file was converted to compound file format. /// STG_S_CONVERTED = 0x00030200, /// /// The storage operation should block until more data is available. /// STG_S_BLOCK = 0x00030201, /// /// The storage operation should retry immediately. /// STG_S_RETRYNOW = 0x00030202, /// /// The notified event sink will not influence the storage operation. /// STG_S_MONITORING = 0x00030203, /// /// Multiple opens prevent consolidated. (commit succeeded). /// STG_S_MULTIPLEOPENS = 0x00030204, /// /// Consolidation of the storage file failed. (commit succeeded). /// STG_S_CONSOLIDATIONFAILED = 0x00030205, /// /// Consolidation of the storage file is inappropriate. (commit succeeded). /// STG_S_CANNOTCONSOLIDATE = 0x00030206, /// /// Generic Copy Protection Error. /// STG_E_STATUS_COPY_PROTECTION_FAILURE = (int)(0x80030305 - 0x100000000), /// /// Copy Protection Error - DVD CSS Authentication failed. /// STG_E_CSS_AUTHENTICATION_FAILURE = (int)(0x80030306 - 0x100000000), /// /// Copy Protection Error - The given sector does not have a valid CSS key. /// STG_E_CSS_KEY_NOT_PRESENT = (int)(0x80030307 - 0x100000000), /// /// Copy Protection Error - DVD session key not established. /// STG_E_CSS_KEY_NOT_ESTABLISHED = (int)(0x80030308 - 0x100000000), /// /// Copy Protection Error - The read failed because the sector is encrypted. /// STG_E_CSS_SCRAMBLED_SECTOR = (int)(0x80030309 - 0x100000000), /// /// Copy Protection Error - The current DVD's region does not correspond to the region setting of the drive. /// STG_E_CSS_REGION_MISMATCH = (int)(0x8003030A - 0x100000000), /// /// Copy Protection Error - The drive's region setting may be permanent or the number of user resets has been exhausted. /// STG_E_RESETS_EXHAUSTED = (int)(0x8003030B - 0x100000000), /// /// Call was rejected by callee. /// RPC_E_CALL_REJECTED = (int)(0x80010001 - 0x100000000), /// /// Call was canceled by the message filter. /// RPC_E_CALL_CANCELED = (int)(0x80010002 - 0x100000000), /// /// The caller is dispatching an intertask SendMessage call and cannot call out via PostMessage. /// RPC_E_CANTPOST_INSENDCALL = (int)(0x80010003 - 0x100000000), /// /// The caller is dispatching an asynchronous call and cannot make an outgoing call on behalf of this call. /// RPC_E_CANTCALLOUT_INASYNCCALL = (int)(0x80010004 - 0x100000000), /// /// It is illegal to call out while inside message filter. /// RPC_E_CANTCALLOUT_INEXTERNALCALL = (int)(0x80010005 - 0x100000000), /// /// The connection terminated or is in a bogus state and cannot be used any more. Other connections are still valid. /// RPC_E_CONNECTION_TERMINATED = (int)(0x80010006 - 0x100000000), /// /// The callee (server [not server application]) is not available and disappeared, all connections are invalid. The call may have executed. /// RPC_E_SERVER_DIED = (int)(0x80010007 - 0x100000000), /// /// The caller (client) disappeared while the callee (server) was processing a call. /// RPC_E_CLIENT_DIED = (int)(0x80010008 - 0x100000000), /// /// The data packet with the marshalled parameter data is incorrect. /// RPC_E_INVALID_DATAPACKET = (int)(0x80010009 - 0x100000000), /// /// The call was not transmitted properly, the message queue was full and was not emptied after yielding. /// RPC_E_CANTTRANSMIT_CALL = (int)(0x8001000A - 0x100000000), /// /// The client (caller) cannot marshall the parameter data - low memory, etc. /// RPC_E_CLIENT_CANTMARSHAL_DATA = (int)(0x8001000B - 0x100000000), /// /// The client (caller) cannot unmarshall the return data - low memory, etc. /// RPC_E_CLIENT_CANTUNMARSHAL_DATA = (int)(0x8001000C - 0x100000000), /// /// The server (callee) cannot marshall the return data - low memory, etc. /// RPC_E_SERVER_CANTMARSHAL_DATA = (int)(0x8001000D - 0x100000000), /// /// The server (callee) cannot unmarshall the parameter data - low memory, etc. /// RPC_E_SERVER_CANTUNMARSHAL_DATA = (int)(0x8001000E - 0x100000000), /// /// Received data is invalid, could be server or client data. /// RPC_E_INVALID_DATA = (int)(0x8001000F - 0x100000000), /// /// A particular parameter is invalid and cannot be (un)marshalled. /// RPC_E_INVALID_PARAMETER = (int)(0x80010010 - 0x100000000), /// /// There is no second outgoing call on same channel in DDE conversation. /// RPC_E_CANTCALLOUT_AGAIN = (int)(0x80010011 - 0x100000000), /// /// The callee (server [not server application]) is not available and disappeared, all connections are invalid. The call did not execute. /// RPC_E_SERVER_DIED_DNE = (int)(0x80010012 - 0x100000000), /// /// System call failed. /// RPC_E_SYS_CALL_FAILED = (int)(0x80010100 - 0x100000000), /// /// Could not allocate some required resource (memory, events, ...) /// RPC_E_OUT_OF_RESOURCES = (int)(0x80010101 - 0x100000000), /// /// Attempted to make calls on more than one thread in single threaded mode. /// RPC_E_ATTEMPTED_MULTITHREAD = (int)(0x80010102 - 0x100000000), /// /// The requested interface is not registered on the server object. /// RPC_E_NOT_REGISTERED = (int)(0x80010103 - 0x100000000), /// /// RPC could not call the server or could not return the results of calling the server. /// RPC_E_FAULT = (int)(0x80010104 - 0x100000000), /// /// The server threw an exception. /// RPC_E_SERVERFAULT = (int)(0x80010105 - 0x100000000), /// /// Cannot change thread mode after it is set. /// RPC_E_CHANGED_MODE = (int)(0x80010106 - 0x100000000), /// /// The method called does not exist on the server. /// RPC_E_INVALIDMETHOD = (int)(0x80010107 - 0x100000000), /// /// The object invoked has disconnected from its clients. /// RPC_E_DISCONNECTED = (int)(0x80010108 - 0x100000000), /// /// The object invoked chose not to process the call now. Try again later. /// RPC_E_RETRY = (int)(0x80010109 - 0x100000000), /// /// The message filter indicated that the application is busy. /// RPC_E_SERVERCALL_RETRYLATER = (int)(0x8001010A - 0x100000000), /// /// The message filter rejected the call. /// RPC_E_SERVERCALL_REJECTED = (int)(0x8001010B - 0x100000000), /// /// A call control interfaces was called with invalid data. /// RPC_E_INVALID_CALLDATA = (int)(0x8001010C - 0x100000000), /// /// An outgoing call cannot be made since the application is dispatching an input-synchronous call. /// RPC_E_CANTCALLOUT_ININPUTSYNCCALL = (int)(0x8001010D - 0x100000000), /// /// The application called an interface that was marshalled for a different thread. /// RPC_E_WRONG_THREAD = (int)(0x8001010E - 0x100000000), /// /// CoInitialize has not been called on the current thread. /// RPC_E_THREAD_NOT_INIT = (int)(0x8001010F - 0x100000000), /// /// The version of OLE on the client and server machines does not match. /// RPC_E_VERSION_MISMATCH = (int)(0x80010110 - 0x100000000), /// /// OLE received a packet with an invalid header. /// RPC_E_INVALID_HEADER = (int)(0x80010111 - 0x100000000), /// /// OLE received a packet with an invalid extension. /// RPC_E_INVALID_EXTENSION = (int)(0x80010112 - 0x100000000), /// /// The requested object or interface does not exist. /// RPC_E_INVALID_IPID = (int)(0x80010113 - 0x100000000), /// /// The requested object does not exist. /// RPC_E_INVALID_OBJECT = (int)(0x80010114 - 0x100000000), /// /// OLE has sent a request and is waiting for a reply. /// RPC_S_CALLPENDING = (int)(0x80010115 - 0x100000000), /// /// OLE is waiting before retrying a request. /// RPC_S_WAITONTIMER = (int)(0x80010116 - 0x100000000), /// /// Call context cannot be accessed after call completed. /// RPC_E_CALL_COMPLETE = (int)(0x80010117 - 0x100000000), /// /// Impersonate on unsecure calls is not supported. /// RPC_E_UNSECURE_CALL = (int)(0x80010118 - 0x100000000), /// /// Security must be initialized before any interfaces are marshalled or unmarshalled. It cannot be changed once initialized. /// RPC_E_TOO_LATE = (int)(0x80010119 - 0x100000000), /// /// No security packages are installed on this machine or the user is not logged on or there are no compatible security packages between the client and server. /// RPC_E_NO_GOOD_SECURITY_PACKAGES = (int)(0x8001011A - 0x100000000), /// /// Access is denied. /// RPC_E_ACCESS_DENIED = (int)(0x8001011B - 0x100000000), /// /// Remote calls are not allowed for this process. /// RPC_E_REMOTE_DISABLED = (int)(0x8001011C - 0x100000000), /// /// The marshaled interface data packet (OBJREF) has an invalid or unknown format. /// RPC_E_INVALID_OBJREF = (int)(0x8001011D - 0x100000000), /// /// No context is associated with this call. This happens for some custom marshalled calls and on the client side of the call. /// RPC_E_NO_CONTEXT = (int)(0x8001011E - 0x100000000), /// /// This operation returned because the timeout period expired. /// RPC_E_TIMEOUT = (int)(0x8001011F - 0x100000000), /// /// There are no synchronize objects to wait on. /// RPC_E_NO_SYNC = (int)(0x80010120 - 0x100000000), /// /// Full subject issuer chain SSL principal name expected from the server. /// RPC_E_FULLSIC_REQUIRED = (int)(0x80010121 - 0x100000000), /// /// Principal name is not a valid MSSTD name. /// RPC_E_INVALID_STD_NAME = (int)(0x80010122 - 0x100000000), /// /// Unable to impersonate DCOM client /// CO_E_FAILEDTOIMPERSONATE = (int)(0x80010123 - 0x100000000), /// /// Unable to obtain server's security context /// CO_E_FAILEDTOGETSECCTX = (int)(0x80010124 - 0x100000000), /// /// Unable to open the access token of the current thread /// CO_E_FAILEDTOOPENTHREADTOKEN = (int)(0x80010125 - 0x100000000), /// /// Unable to obtain user info from an access token /// CO_E_FAILEDTOGETTOKENINFO = (int)(0x80010126 - 0x100000000), /// /// The client who called IAccessControl::IsAccessPermitted was not the trustee provided to the method /// CO_E_TRUSTEEDOESNTMATCHCLIENT = (int)(0x80010127 - 0x100000000), /// /// Unable to obtain the client's security blanket /// CO_E_FAILEDTOQUERYCLIENTBLANKET = (int)(0x80010128 - 0x100000000), /// /// Unable to set a discretionary ACL into a security descriptor /// CO_E_FAILEDTOSETDACL = (int)(0x80010129 - 0x100000000), /// /// The system function, AccessCheck, returned false /// CO_E_ACCESSCHECKFAILED = (int)(0x8001012A - 0x100000000), /// /// Either NetAccessDel or NetAccessAdd returned an error code. /// CO_E_NETACCESSAPIFAILED = (int)(0x8001012B - 0x100000000), /// /// One of the trustee strings provided by the user did not conform to the \ syntax and it was not the "*" string /// CO_E_WRONGTRUSTEENAMESYNTAX = (int)(0x8001012C - 0x100000000), /// /// One of the security identifiers provided by the user was invalid /// CO_E_INVALIDSID = (int)(0x8001012D - 0x100000000), /// /// Unable to convert a wide character trustee string to a multibyte trustee string /// CO_E_CONVERSIONFAILED = (int)(0x8001012E - 0x100000000), /// /// Unable to find a security identifier that corresponds to a trustee string provided by the user /// CO_E_NOMATCHINGSIDFOUND = (int)(0x8001012F - 0x100000000), /// /// The system function, LookupAccountSID, failed /// CO_E_LOOKUPACCSIDFAILED = (int)(0x80010130 - 0x100000000), /// /// Unable to find a trustee name that corresponds to a security identifier provided by the user /// CO_E_NOMATCHINGNAMEFOUND = (int)(0x80010131 - 0x100000000), /// /// The system function, LookupAccountName, failed /// CO_E_LOOKUPACCNAMEFAILED = (int)(0x80010132 - 0x100000000), /// /// Unable to set or reset a serialization handle /// CO_E_SETSERLHNDLFAILED = (int)(0x80010133 - 0x100000000), /// /// Unable to obtain the Windows directory /// CO_E_FAILEDTOGETWINDIR = (int)(0x80010134 - 0x100000000), /// /// Path too long /// CO_E_PATHTOOInt32 = (int)(0x80010135 - 0x100000000), /// /// Unable to generate a uuid. /// CO_E_FAILEDTOGENUUID = (int)(0x80010136 - 0x100000000), /// /// Unable to create file /// CO_E_FAILEDTOCREATEFILE = (int)(0x80010137 - 0x100000000), /// /// Unable to close a serialization handle or a file handle. /// CO_E_FAILEDTOCLOSEHANDLE = (int)(0x80010138 - 0x100000000), /// /// The number of ACEs in an ACL exceeds the system limit. /// CO_E_EXCEEDSYSACLLIMIT = (int)(0x80010139 - 0x100000000), /// /// Not all the DENY_ACCESS ACEs are arranged in front of the GRANT_ACCESS ACEs in the stream. /// CO_E_ACESINWRONGORDER = (int)(0x8001013A - 0x100000000), /// /// The version of ACL format in the stream is not supported by this implementation of IAccessControl /// CO_E_INCOMPATIBLESTREAMVERSION = (int)(0x8001013B - 0x100000000), /// /// Unable to open the access token of the server process /// CO_E_FAILEDTOOPENPROCESSTOKEN = (int)(0x8001013C - 0x100000000), /// /// Unable to decode the ACL in the stream provided by the user /// CO_E_DECODEFAILED = (int)(0x8001013D - 0x100000000), /// /// The COM IAccessControl object is not initialized /// CO_E_ACNOTINITIALIZED = (int)(0x8001013F - 0x100000000), /// /// Call Cancellation is disabled /// CO_E_CANCEL_DISABLED = (int)(0x80010140 - 0x100000000), /// /// An internal error occurred. /// RPC_E_UNEXPECTED = (int)(0x8001FFFF - 0x100000000), /// /// The specified event is currently not being audited. /// ERROR_AUDITING_DISABLED = (int)(0xC0090001 - 0x100000000), /// /// The SID filtering operation removed all SIDs. /// ERROR_ALL_SIDS_FILTERED = (int)(0xC0090002 - 0x100000000), /// /// Bad UID. /// NTE_BAD_UID = (int)(0x80090001 - 0x100000000), /// /// Bad Hash. /// NTE_BAD_HASH = (int)(0x80090002 - 0x100000000), /// /// Bad Key. /// NTE_BAD_KEY = (int)(0x80090003 - 0x100000000), /// /// Bad Length. /// NTE_BAD_LEN = (int)(0x80090004 - 0x100000000), /// /// Bad Data. /// NTE_BAD_DATA = (int)(0x80090005 - 0x100000000), /// /// Invalid Signature. /// NTE_BAD_SIGNATURE = (int)(0x80090006 - 0x100000000), /// /// Bad Version of provider. /// NTE_BAD_VER = (int)(0x80090007 - 0x100000000), /// /// Invalid algorithm specified. /// NTE_BAD_ALGID = (int)(0x80090008 - 0x100000000), /// /// Invalid flags specified. /// NTE_BAD_FLAGS = (int)(0x80090009 - 0x100000000), /// /// Invalid type specified. /// NTE_BAD_TYPE = (int)(0x8009000A - 0x100000000), /// /// Key not valid for use in specified state. /// NTE_BAD_KEY_STATE = (int)(0x8009000B - 0x100000000), /// /// Hash not valid for use in specified state. /// NTE_BAD_HASH_STATE = (int)(0x8009000C - 0x100000000), /// /// Key does not exist. /// NTE_NO_KEY = (int)(0x8009000D - 0x100000000), /// /// Insufficient memory available for the operation. /// NTE_NO_MEMORY = (int)(0x8009000E - 0x100000000), /// /// Object already exists. /// NTE_EXISTS = (int)(0x8009000F - 0x100000000), /// /// Access denied. /// NTE_PERM = (int)(0x80090010 - 0x100000000), /// /// Object was not found. /// NTE_NOT_FOUND = (int)(0x80090011 - 0x100000000), /// /// Data already encrypted. /// NTE_DOUBLE_ENCRYPT = (int)(0x80090012 - 0x100000000), /// /// Invalid provider specified. /// NTE_BAD_PROVIDER = (int)(0x80090013 - 0x100000000), /// /// Invalid provider type specified. /// NTE_BAD_PROV_TYPE = (int)(0x80090014 - 0x100000000), /// /// Provider's public key is invalid. /// NTE_BAD_PUBLIC_KEY = (int)(0x80090015 - 0x100000000), /// /// Keyset does not exist /// NTE_BAD_KEYSET = (int)(0x80090016 - 0x100000000), /// /// Provider type not defined. /// NTE_PROV_TYPE_NOT_DEF = (int)(0x80090017 - 0x100000000), /// /// Provider type as registered is invalid. /// NTE_PROV_TYPE_ENTRY_BAD = (int)(0x80090018 - 0x100000000), /// /// The keyset is not defined. /// NTE_KEYSET_NOT_DEF = (int)(0x80090019 - 0x100000000), /// /// Keyset as registered is invalid. /// NTE_KEYSET_ENTRY_BAD = (int)(0x8009001A - 0x100000000), /// /// Provider type does not match registered value. /// NTE_PROV_TYPE_NO_MATCH = (int)(0x8009001B - 0x100000000), /// /// The digital signature file is corrupt. /// NTE_SIGNATURE_FILE_BAD = (int)(0x8009001C - 0x100000000), /// /// Provider DLL failed to initialize correctly. /// NTE_PROVIDER_DLL_FAIL = (int)(0x8009001D - 0x100000000), /// /// Provider DLL could not be found. /// NTE_PROV_DLL_NOT_FOUND = (int)(0x8009001E - 0x100000000), /// /// The Keyset parameter is invalid. /// NTE_BAD_KEYSET_PARAM = (int)(0x8009001F - 0x100000000), /// /// An internal error occurred. /// NTE_FAIL = (int)(0x80090020 - 0x100000000), /// /// A base error occurred. /// NTE_SYS_ERR = (int)(0x80090021 - 0x100000000), /// /// Provider could not perform the action since the context was acquired as silent. /// NTE_SILENT_CONTEXT = (int)(0x80090022 - 0x100000000), /// /// The security token does not have storage space available for an additional container. /// NTE_TOKEN_KEYSET_STORAGE_FULL = (int)(0x80090023 - 0x100000000), /// /// The profile for the user is a temporary profile. /// NTE_TEMPORARY_PROFILE = (int)(0x80090024 - 0x100000000), /// /// The key parameters could not be set because the CSP uses fixed parameters. /// NTE_FIXEDPARAMETER = (int)(0x80090025 - 0x100000000), /// /// Not enough memory is available to complete this request /// SEC_E_INSUFFICIENT_MEMORY = (int)(0x80090300 - 0x100000000), /// /// The handle specified is invalid /// SEC_E_INVALID_HANDLE = (int)(0x80090301 - 0x100000000), /// /// The function requested is not supported /// SEC_E_UNSUPPORTED_FUNCTION = (int)(0x80090302 - 0x100000000), /// /// The specified target is unknown or unreachable /// SEC_E_TARGET_UNKNOWN = (int)(0x80090303 - 0x100000000), /// /// The Local Security Authority cannot be contacted /// SEC_E_INTERNAL_ERROR = (int)(0x80090304 - 0x100000000), /// /// The requested security package does not exist /// SEC_E_SECPKG_NOT_FOUND = (int)(0x80090305 - 0x100000000), /// /// The caller is not the owner of the desired credentials /// SEC_E_NOT_OWNER = (int)(0x80090306 - 0x100000000), /// /// The security package failed to initialize, and cannot be installed /// SEC_E_CANNOT_INSTALL = (int)(0x80090307 - 0x100000000), /// /// The token supplied to the function is invalid /// SEC_E_INVALID_TOKEN = (int)(0x80090308 - 0x100000000), /// /// The security package is not able to marshall the logon buffer, so the logon attempt has failed /// SEC_E_CANNOT_PACK = (int)(0x80090309 - 0x100000000), /// /// The per-message Quality of Protection is not supported by the security package /// SEC_E_QOP_NOT_SUPPORTED = (int)(0x8009030A - 0x100000000), /// /// The security context does not allow impersonation of the client /// SEC_E_NO_IMPERSONATION = (int)(0x8009030B - 0x100000000), /// /// The logon attempt failed /// SEC_E_LOGON_DENIED = (int)(0x8009030C - 0x100000000), /// /// The credentials supplied to the package were not recognized /// SEC_E_UNKNOWN_CREDENTIALS = (int)(0x8009030D - 0x100000000), /// /// No credentials are available in the security package /// SEC_E_NO_CREDENTIALS = (int)(0x8009030E - 0x100000000), /// /// The message or signature supplied for verification has been altered /// SEC_E_MESSAGE_ALTERED = (int)(0x8009030F - 0x100000000), /// /// The message supplied for verification is out of sequence /// SEC_E_OUT_OF_SEQUENCE = (int)(0x80090310 - 0x100000000), /// /// No authority could be contacted for authentication. /// SEC_E_NO_AUTHENTICATING_AUTHORITY = (int)(0x80090311 - 0x100000000), /// /// The function completed successfully, but must be called again to complete the context /// SEC_I_CONTINUE_NEEDED = 0x00090312, /// /// The function completed successfully, but CompleteToken must be called /// SEC_I_COMPLETE_NEEDED = 0x00090313, /// /// The function completed successfully, but both CompleteToken and this function must be called to complete the context /// SEC_I_COMPLETE_AND_CONTINUE = 0x00090314, /// /// The logon was completed, but no network authority was available. The logon was made using locally known information /// SEC_I_LOCAL_LOGON = 0x00090315, /// /// The requested security package does not exist /// SEC_E_BAD_PKGID = (int)(0x80090316 - 0x100000000), /// /// The context has expired and can no longer be used. /// SEC_E_CONTEXT_EXPIRED = (int)(0x80090317 - 0x100000000), /// /// The context has expired and can no longer be used. /// SEC_I_CONTEXT_EXPIRED = 0x00090317, /// /// The supplied message is incomplete. The signature was not verified. /// SEC_E_INCOMPLETE_MESSAGE = (int)(0x80090318 - 0x100000000), /// /// The credentials supplied were not complete, and could not be verified. The context could not be initialized. /// SEC_E_INCOMPLETE_CREDENTIALS = (int)(0x80090320 - 0x100000000), /// /// The buffers supplied to a function was too small. /// SEC_E_BUFFER_TOO_SMALL = (int)(0x80090321 - 0x100000000), /// /// The credentials supplied were not complete, and could not be verified. Additional information can be returned from the context. /// SEC_I_INCOMPLETE_CREDENTIALS = 0x00090320, /// /// The context data must be renegotiated with the peer. /// SEC_I_RENEGOTIATE = 0x00090321, /// /// The target principal name is incorrect. /// SEC_E_WRONG_PRINCIPAL = (int)(0x80090322 - 0x100000000), /// /// There is no LSA mode context associated with this context. /// SEC_I_NO_LSA_CONTEXT = 0x00090323, /// /// The clocks on the client and server machines are skewed. /// SEC_E_TIME_SKEW = (int)(0x80090324 - 0x100000000), /// /// The certificate chain was issued by an authority that is not trusted. /// SEC_E_UNTRUSTED_ROOT = (int)(0x80090325 - 0x100000000), /// /// The message received was unexpected or badly formatted. /// SEC_E_ILLEGAL_MESSAGE = (int)(0x80090326 - 0x100000000), /// /// An unknown error occurred while processing the certificate. /// SEC_E_CERT_UNKNOWN = (int)(0x80090327 - 0x100000000), /// /// The received certificate has expired. /// SEC_E_CERT_EXPIRED = (int)(0x80090328 - 0x100000000), /// /// The specified data could not be encrypted. /// SEC_E_ENCRYPT_FAILURE = (int)(0x80090329 - 0x100000000), /// /// The specified data could not be decrypted. /// SEC_E_DECRYPT_FAILURE = (int)(0x80090330 - 0x100000000), /// /// The client and server cannot communicate, because they do not possess a common algorithm. /// SEC_E_ALGORITHM_MISMATCH = (int)(0x80090331 - 0x100000000), /// /// The security context could not be established due to a failure in the requested quality of service (e.g. mutual authentication or delegation). /// SEC_E_SECURITY_QOS_FAILED = (int)(0x80090332 - 0x100000000), /// /// A security context was deleted before the context was completed. This is considered a logon failure. /// SEC_E_UNFINISHED_CONTEXT_DELETED = (int)(0x80090333 - 0x100000000), /// /// The client is trying to negotiate a context and the server requires user-to-user but didn't send a TGT reply. /// SEC_E_NO_TGT_REPLY = (int)(0x80090334 - 0x100000000), /// /// Unable to accomplish the requested task because the local machine does not have any IP addresses. /// SEC_E_NO_IP_ADDRESSES = (int)(0x80090335 - 0x100000000), /// /// The supplied credential handle does not match the credential associated with the security context. /// SEC_E_WRONG_CREDENTIAL_HANDLE = (int)(0x80090336 - 0x100000000), /// /// The crypto system or checksum function is invalid because a required function is unavailable. /// SEC_E_CRYPTO_SYSTEM_INVALID = (int)(0x80090337 - 0x100000000), /// /// The number of maximum ticket referrals has been exceeded. /// SEC_E_MAX_REFERRALS_EXCEEDED = (int)(0x80090338 - 0x100000000), /// /// The local machine must be a Kerberos KDC (domain controller) and it is not. /// SEC_E_MUST_BE_KDC = (int)(0x80090339 - 0x100000000), /// /// The other end of the security negotiation is requires strong crypto but it is not supported on the local machine. /// SEC_E_STRONG_CRYPTO_NOT_SUPPORTED = (int)(0x8009033A - 0x100000000), /// /// The KDC reply contained more than one principal name. /// SEC_E_TOO_MANY_PRINCIPALS = (int)(0x8009033B - 0x100000000), /// /// Expected to find PA data for a hint of what etype to use, but it was not found. /// SEC_E_NO_PA_DATA = (int)(0x8009033C - 0x100000000), /// /// The client cert name does not matches the user name or the KDC name is incorrect. /// SEC_E_PKINIT_NAME_MISMATCH = (int)(0x8009033D - 0x100000000), /// /// Smartcard logon is required and was not used. /// SEC_E_SMARTCARD_LOGON_REQUIRED = (int)(0x8009033E - 0x100000000), /// /// A system shutdown is in progress. /// SEC_E_SHUTDOWN_IN_PROGRESS = (int)(0x8009033F - 0x100000000), /// /// An invalid request was sent to the KDC. /// SEC_E_KDC_INVALID_REQUEST = (int)(0x80090340 - 0x100000000), /// /// The KDC was unable to generate a referral for the service requested. /// SEC_E_KDC_UNABLE_TO_REFER = (int)(0x80090341 - 0x100000000), /// /// The encryption type requested is not supported by the KDC. /// SEC_E_KDC_UNKNOWN_ETYPE = (int)(0x80090342 - 0x100000000), /// /// An unsupported preauthentication mechanism was presented to the kerberos package. /// SEC_E_UNSUPPORTED_PREAUTH = (int)(0x80090343 - 0x100000000), /// /// The requested operation requires delegation to be enabled on the machine. /// SEC_E_DELEGATION_REQUIRED = (int)(0x80090345 - 0x100000000), /// /// Client's supplied SSPI channel bindings were incorrect. /// SEC_E_BAD_BINDINGS = (int)(0x80090346 - 0x100000000), /// /// The received certificate was mapped to multiple accounts. /// SEC_E_MULTIPLE_ACCOUNTS = (int)(0x80090347 - 0x100000000), /// /// SEC_E_NO_KERB_KEY /// SEC_E_NO_KERB_KEY = (int)(0x80090348 - 0x100000000), /// /// No information avialable. /// SEC_E_CERT_WRONG_USAGE = (int)(0x80090349 - 0x100000000), /// /// No information avialable. /// SEC_E_DOWNGRADE_DETECTED = (int)(0x80090350 - 0x100000000), /// /// No information avialable. /// SEC_E_SMARTCARD_CERT_REVOKED = (int)(0x80090351 - 0x100000000), /// /// No information avialable. /// SEC_E_ISSUING_CA_UNTRUSTED = (int)(0x80090352 - 0x100000000), /// /// No information avialable. /// SEC_E_REVOCATION_OFFLINE_C = (int)(0x80090353 - 0x100000000), /// /// No information avialable. /// SEC_E_PKINIT_CLIENT_FAILURE = (int)(0x80090354 - 0x100000000), /// /// No information avialable. /// SEC_E_SMARTCARD_CERT_EXPIRED = (int)(0x80090355 - 0x100000000), /// /// No information avialable. /// SEC_E_NO_S4U_PROT_SUPPORT = (int)(0x80090356 - 0x100000000), /// /// No information avialable. /// SEC_E_CROSSREALM_DELEGATION_FAILURE = (int)(0x80090357 - 0x100000000), /// /// No information avialable. /// SEC_E_NO_SPM = SEC_E_INTERNAL_ERROR, /// /// No information avialable. /// SEC_E_NOT_SUPPORTED = SEC_E_UNSUPPORTED_FUNCTION, /// /// An error occurred while performing an operation on a cryptographic message. /// CRYPT_E_MSG_ERROR = (int)(0x80091001 - 0x100000000), /// /// Unknown cryptographic algorithm. /// CRYPT_E_UNKNOWN_ALGO = (int)(0x80091002 - 0x100000000), /// /// The object identifier is poorly formatted. /// CRYPT_E_OID_FORMAT = (int)(0x80091003 - 0x100000000), /// /// Invalid cryptographic message type. /// CRYPT_E_INVALID_MSG_TYPE = (int)(0x80091004 - 0x100000000), /// /// Unexpected cryptographic message encoding. /// CRYPT_E_UNEXPECTED_ENCODING = (int)(0x80091005 - 0x100000000), /// /// The cryptographic message does not contain an expected authenticated attribute. /// CRYPT_E_AUTH_ATTR_MISSING = (int)(0x80091006 - 0x100000000), /// /// The hash value is not correct. /// CRYPT_E_HASH_VALUE = (int)(0x80091007 - 0x100000000), /// /// The index value is not valid. /// CRYPT_E_INVALID_INDEX = (int)(0x80091008 - 0x100000000), /// /// The content of the cryptographic message has already been decrypted. /// CRYPT_E_ALREADY_DECRYPTED = (int)(0x80091009 - 0x100000000), /// /// The content of the cryptographic message has not been decrypted yet. /// CRYPT_E_NOT_DECRYPTED = (int)(0x8009100A - 0x100000000), /// /// The enveloped-data message does not contain the specified recipient. /// CRYPT_E_RECIPIENT_NOT_FOUND = (int)(0x8009100B - 0x100000000), /// /// Invalid control type. /// CRYPT_E_CONTROL_TYPE = (int)(0x8009100C - 0x100000000), /// /// Invalid issuer and/or serial number. /// CRYPT_E_ISSUER_SERIALNUMBER = (int)(0x8009100D - 0x100000000), /// /// Cannot find the original signer. /// CRYPT_E_SIGNER_NOT_FOUND = (int)(0x8009100E - 0x100000000), /// /// The cryptographic message does not contain all of the requested attributes. /// CRYPT_E_ATTRIBUTES_MISSING = (int)(0x8009100F - 0x100000000), /// /// The streamed cryptographic message is not ready to return data. /// CRYPT_E_STREAM_MSG_NOT_READY = (int)(0x80091010 - 0x100000000), /// /// The streamed cryptographic message requires more data to complete the decode operation. /// CRYPT_E_STREAM_INSUFFICIENT_DATA = (int)(0x80091011 - 0x100000000), /// /// The protected data needs to be re-protected. /// CRYPT_I_NEW_PROTECTION_REQUIRED = 0x00091012, /// /// The length specified for the output data was insufficient. /// CRYPT_E_BAD_LEN = (int)(0x80092001 - 0x100000000), /// /// An error occurred during encode or decode operation. /// CRYPT_E_BAD_ENCODE = (int)(0x80092002 - 0x100000000), /// /// An error occurred while reading or writing to a file. /// CRYPT_E_FILE_ERROR = (int)(0x80092003 - 0x100000000), /// /// Cannot find object or property. /// CRYPT_E_NOT_FOUND = (int)(0x80092004 - 0x100000000), /// /// The object or property already exists. /// CRYPT_E_EXISTS = (int)(0x80092005 - 0x100000000), /// /// No provider was specified for the store or object. /// CRYPT_E_NO_PROVIDER = (int)(0x80092006 - 0x100000000), /// /// The specified certificate is self signed. /// CRYPT_E_SELF_SIGNED = (int)(0x80092007 - 0x100000000), /// /// The previous certificate or CRL context was deleted. /// CRYPT_E_DELETED_PREV = (int)(0x80092008 - 0x100000000), /// /// Cannot find the requested object. /// CRYPT_E_NO_MATCH = (int)(0x80092009 - 0x100000000), /// /// The certificate does not have a property that references a private key. /// CRYPT_E_UNEXPECTED_MSG_TYPE = (int)(0x8009200A - 0x100000000), /// /// Cannot find the certificate and private key for decryption. /// CRYPT_E_NO_KEY_PROPERTY = (int)(0x8009200B - 0x100000000), /// /// Cannot find the certificate and private key to use for decryption. /// CRYPT_E_NO_DECRYPT_CERT = (int)(0x8009200C - 0x100000000), /// /// Not a cryptographic message or the cryptographic message is not formatted correctly. /// CRYPT_E_BAD_MSG = (int)(0x8009200D - 0x100000000), /// /// The signed cryptographic message does not have a signer for the specified signer index. /// CRYPT_E_NO_SIGNER = (int)(0x8009200E - 0x100000000), /// /// Final closure is pending until additional frees or closes. /// CRYPT_E_PENDING_CLOSE = (int)(0x8009200F - 0x100000000), /// /// The certificate is revoked. /// CRYPT_E_REVOKED = (int)(0x80092010 - 0x100000000), /// /// No Dll or exported function was found to verify revocation. /// CRYPT_E_NO_REVOCATION_DLL = (int)(0x80092011 - 0x100000000), /// /// The revocation function was unable to check revocation for the certificate. /// CRYPT_E_NO_REVOCATION_CHECK = (int)(0x80092012 - 0x100000000), /// /// The revocation function was unable to check revocation because the revocation server was offline. /// CRYPT_E_REVOCATION_OFFLINE = (int)(0x80092013 - 0x100000000), /// /// The certificate is not in the revocation server's database. /// CRYPT_E_NOT_IN_REVOCATION_DATABASE = (int)(0x80092014 - 0x100000000), /// /// The string contains a non-numeric character. /// CRYPT_E_INVALID_NUMERIC_STRING = (int)(0x80092020 - 0x100000000), /// /// The string contains a non-printable character. /// CRYPT_E_INVALID_PRINTABLE_STRING = (int)(0x80092021 - 0x100000000), /// /// The string contains a character not in the 7 bit ASCII character set. /// CRYPT_E_INVALID_IA5_STRING = (int)(0x80092022 - 0x100000000), /// /// The string contains an invalid X500 name attribute key, oid, value or delimiter. /// CRYPT_E_INVALID_X500_STRING = (int)(0x80092023 - 0x100000000), /// /// The dwValueType for the CERT_NAME_VALUE is not one of the character strings. Most likely it is either a CERT_RDN_ENCODED_BLOB or CERT_TDN_OCTED_STRING. /// CRYPT_E_NOT_CHAR_STRING = (int)(0x80092024 - 0x100000000), /// /// The Put operation can not continue. The file needs to be resized. However, there is already a signature present. A complete signing operation must be done. /// CRYPT_E_FILERESIZED = (int)(0x80092025 - 0x100000000), /// /// The cryptographic operation failed due to a local security option setting. /// CRYPT_E_SECURITY_SETTINGS = (int)(0x80092026 - 0x100000000), /// /// No DLL or exported function was found to verify subject usage. /// CRYPT_E_NO_VERIFY_USAGE_DLL = (int)(0x80092027 - 0x100000000), /// /// The called function was unable to do a usage check on the subject. /// CRYPT_E_NO_VERIFY_USAGE_CHECK = (int)(0x80092028 - 0x100000000), /// /// Since the server was offline, the called function was unable to complete the usage check. /// CRYPT_E_VERIFY_USAGE_OFFLINE = (int)(0x80092029 - 0x100000000), /// /// The subject was not found in a Certificate Trust List (CTL). /// CRYPT_E_NOT_IN_CTL = (int)(0x8009202A - 0x100000000), /// /// None of the signers of the cryptographic message or certificate trust list is trusted. /// CRYPT_E_NO_TRUSTED_SIGNER = (int)(0x8009202B - 0x100000000), /// /// The public key's algorithm parameters are missing. /// CRYPT_E_MISSING_PUBKEY_PARA = (int)(0x8009202C - 0x100000000), /// /// OSS Certificate encode/decode error code base /// /// See asn1code.h for a definition of the OSS runtime errors. The OSS /// error values are offset by CRYPT_E_OSS_ERROR. /// CRYPT_E_OSS_ERROR = (int)(0x80093000 - 0x100000000), /// /// OSS ASN.1 Error: Output Buffer is too small. /// OSS_MORE_BUF = (int)(0x80093001 - 0x100000000), /// /// OSS ASN.1 Error: Signed integer is encoded as a unsigned integer. /// OSS_NEGATIVE_UINTEGER = (int)(0x80093002 - 0x100000000), /// /// OSS ASN.1 Error: Unknown ASN.1 data type. /// OSS_PDU_RANGE = (int)(0x80093003 - 0x100000000), /// /// OSS ASN.1 Error: Output buffer is too small, the decoded data has been truncated. /// OSS_MORE_INPUT = (int)(0x80093004 - 0x100000000), /// /// OSS ASN.1 Error: Invalid data. /// OSS_DATA_ERROR = (int)(0x80093005 - 0x100000000), /// /// OSS ASN.1 Error: Invalid argument. /// OSS_BAD_ARG = (int)(0x80093006 - 0x100000000), /// /// OSS ASN.1 Error: Encode/Decode version mismatch. /// OSS_BAD_VERSION = (int)(0x80093007 - 0x100000000), /// /// OSS ASN.1 Error: Out of memory. /// OSS_OUT_MEMORY = (int)(0x80093008 - 0x100000000), /// /// OSS ASN.1 Error: Encode/Decode Error. /// OSS_PDU_MISMATCH = (int)(0x80093009 - 0x100000000), /// /// OSS ASN.1 Error: Internal Error. /// OSS_LIMITED = (int)(0x8009300A - 0x100000000), /// /// OSS ASN.1 Error: Invalid data. /// OSS_BAD_PTR = (int)(0x8009300B - 0x100000000), /// /// OSS ASN.1 Error: Invalid data. /// OSS_BAD_TIME = (int)(0x8009300C - 0x100000000), /// /// OSS ASN.1 Error: Unsupported BER indefinite-length encoding. /// OSS_INDEFINITE_NOT_SUPPORTED = (int)(0x8009300D - 0x100000000), /// /// OSS ASN.1 Error: Access violation. /// OSS_MEM_ERROR = (int)(0x8009300E - 0x100000000), /// /// OSS ASN.1 Error: Invalid data. /// OSS_BAD_TABLE = (int)(0x8009300F - 0x100000000), /// /// OSS ASN.1 Error: Invalid data. /// OSS_TOO_Int32 = (int)(0x80093010 - 0x100000000), /// /// OSS ASN.1 Error: Invalid data. /// OSS_CONSTRAINT_VIOLATED = (int)(0x80093011 - 0x100000000), /// /// OSS ASN.1 Error: Internal Error. /// OSS_FATAL_ERROR = (int)(0x80093012 - 0x100000000), /// /// OSS ASN.1 Error: Multi-threading conflict. /// OSS_ACCESS_SERIALIZATION_ERROR = (int)(0x80093013 - 0x100000000), /// /// OSS ASN.1 Error: Invalid data. /// OSS_NULL_TBL = (int)(0x80093014 - 0x100000000), /// /// OSS ASN.1 Error: Invalid data. /// OSS_NULL_FCN = (int)(0x80093015 - 0x100000000), /// /// OSS ASN.1 Error: Invalid data. /// OSS_BAD_ENCRULES = (int)(0x80093016 - 0x100000000), /// /// OSS ASN.1 Error: Encode/Decode function not implemented. /// OSS_UNAVAIL_ENCRULES = (int)(0x80093017 - 0x100000000), /// /// OSS ASN.1 Error: Trace file error. /// OSS_CANT_OPEN_TRACE_WINDOW = (int)(0x80093018 - 0x100000000), /// /// OSS ASN.1 Error: Function not implemented. /// OSS_UNIMPLEMENTED = (int)(0x80093019 - 0x100000000), /// /// OSS ASN.1 Error: Program link error. /// OSS_OID_DLL_NOT_LINKED = (int)(0x8009301A - 0x100000000), /// /// OSS ASN.1 Error: Trace file error. /// OSS_CANT_OPEN_TRACE_FILE = (int)(0x8009301B - 0x100000000), /// /// OSS ASN.1 Error: Trace file error. /// OSS_TRACE_FILE_ALREADY_OPEN = (int)(0x8009301C - 0x100000000), /// /// OSS ASN.1 Error: Invalid data. /// OSS_TABLE_MISMATCH = (int)(0x8009301D - 0x100000000), /// /// OSS ASN.1 Error: Invalid data. /// OSS_TYPE_NOT_SUPPORTED = (int)(0x8009301E - 0x100000000), /// /// OSS ASN.1 Error: Program link error. /// OSS_REAL_DLL_NOT_LINKED = (int)(0x8009301F - 0x100000000), /// /// OSS ASN.1 Error: Program link error. /// OSS_REAL_CODE_NOT_LINKED = (int)(0x80093020 - 0x100000000), /// /// OSS ASN.1 Error: Program link error. /// OSS_OUT_OF_RANGE = (int)(0x80093021 - 0x100000000), /// /// OSS ASN.1 Error: Program link error. /// OSS_COPIER_DLL_NOT_LINKED = (int)(0x80093022 - 0x100000000), /// /// OSS ASN.1 Error: Program link error. /// OSS_CONSTRAINT_DLL_NOT_LINKED = (int)(0x80093023 - 0x100000000), /// /// OSS ASN.1 Error: Program link error. /// OSS_COMPARATOR_DLL_NOT_LINKED = (int)(0x80093024 - 0x100000000), /// /// OSS ASN.1 Error: Program link error. /// OSS_COMPARATOR_CODE_NOT_LINKED = (int)(0x80093025 - 0x100000000), /// /// OSS ASN.1 Error: Program link error. /// OSS_MEM_MGR_DLL_NOT_LINKED = (int)(0x80093026 - 0x100000000), /// /// OSS ASN.1 Error: Program link error. /// OSS_PDV_DLL_NOT_LINKED = (int)(0x80093027 - 0x100000000), /// /// OSS ASN.1 Error: Program link error. /// OSS_PDV_CODE_NOT_LINKED = (int)(0x80093028 - 0x100000000), /// /// OSS ASN.1 Error: Program link error. /// OSS_API_DLL_NOT_LINKED = (int)(0x80093029 - 0x100000000), /// /// OSS ASN.1 Error: Program link error. /// OSS_BERDER_DLL_NOT_LINKED = (int)(0x8009302A - 0x100000000), /// /// OSS ASN.1 Error: Program link error. /// OSS_PER_DLL_NOT_LINKED = (int)(0x8009302B - 0x100000000), /// /// OSS ASN.1 Error: Program link error. /// OSS_OPEN_TYPE_ERROR = (int)(0x8009302C - 0x100000000), /// /// OSS ASN.1 Error: System resource error. /// OSS_MUTEX_NOT_CREATED = (int)(0x8009302D - 0x100000000), /// /// OSS ASN.1 Error: Trace file error. /// OSS_CANT_CLOSE_TRACE_FILE = (int)(0x8009302E - 0x100000000), /// /// ASN1 Certificate encode/decode error code base. /// /// The ASN1 error values are offset by CRYPT_E_ASN1_ERROR. /// CRYPT_E_ASN1_ERROR = (int)(0x80093100 - 0x100000000), /// /// ASN1 internal encode or decode error. /// CRYPT_E_ASN1_INTERNAL = (int)(0x80093101 - 0x100000000), /// /// ASN1 unexpected end of data. /// CRYPT_E_ASN1_EOD = (int)(0x80093102 - 0x100000000), /// /// ASN1 corrupted data. /// CRYPT_E_ASN1_CORRUPT = (int)(0x80093103 - 0x100000000), /// /// ASN1 value too large. /// CRYPT_E_ASN1_LARGE = (int)(0x80093104 - 0x100000000), /// /// ASN1 constraint violated. /// CRYPT_E_ASN1_CONSTRAINT = (int)(0x80093105 - 0x100000000), /// /// ASN1 out of memory. /// CRYPT_E_ASN1_MEMORY = (int)(0x80093106 - 0x100000000), /// /// ASN1 buffer overflow. /// CRYPT_E_ASN1_OVERFLOW = (int)(0x80093107 - 0x100000000), /// /// ASN1 function not supported for this PDU. /// CRYPT_E_ASN1_BADPDU = (int)(0x80093108 - 0x100000000), /// /// ASN1 bad arguments to function call. /// CRYPT_E_ASN1_BADARGS = (int)(0x80093109 - 0x100000000), /// /// ASN1 bad real value. /// CRYPT_E_ASN1_BADREAL = (int)(0x8009310A - 0x100000000), /// /// ASN1 bad tag value met. /// CRYPT_E_ASN1_BADTAG = (int)(0x8009310B - 0x100000000), /// /// ASN1 bad choice value. /// CRYPT_E_ASN1_CHOICE = (int)(0x8009310C - 0x100000000), /// /// ASN1 bad encoding rule. /// CRYPT_E_ASN1_RULE = (int)(0x8009310D - 0x100000000), /// /// ASN1 bad unicode (UTF8). /// CRYPT_E_ASN1_UTF8 = (int)(0x8009310E - 0x100000000), /// /// ASN1 bad PDU type. /// CRYPT_E_ASN1_PDU_TYPE = (int)(0x80093133 - 0x100000000), /// /// ASN1 not yet implemented. /// CRYPT_E_ASN1_NYI = (int)(0x80093134 - 0x100000000), /// /// ASN1 skipped unknown extension(s). /// CRYPT_E_ASN1_EXTENDED = (int)(0x80093201 - 0x100000000), /// /// ASN1 end of data expected /// CRYPT_E_ASN1_NOEOD = (int)(0x80093202 - 0x100000000), /// /// The request subject name is invalid or too long. /// CERTSRV_E_BAD_REQUESTSUBJECT = (int)(0x80094001 - 0x100000000), /// /// The request does not exist. /// CERTSRV_E_NO_REQUEST = (int)(0x80094002 - 0x100000000), /// /// The request's current status does not allow this operation. /// CERTSRV_E_BAD_REQUESTSTATUS = (int)(0x80094003 - 0x100000000), /// /// The requested property value is empty. /// CERTSRV_E_PROPERTY_EMPTY = (int)(0x80094004 - 0x100000000), /// /// The certification authority's certificate contains invalid data. /// CERTSRV_E_INVALID_CA_CERTIFICATE = (int)(0x80094005 - 0x100000000), /// /// Certificate service has been suspended for a database restore operation. /// CERTSRV_E_SERVER_SUSPENDED = (int)(0x80094006 - 0x100000000), /// /// The certificate contains an encoded length that is potentially incompatible with older enrollment software. /// CERTSRV_E_ENCODING_LENGTH = (int)(0x80094007 - 0x100000000), /// /// The operation is denied. The user has multiple roles assigned and the certification authority is configured to enforce role separation. /// CERTSRV_E_ROLECONFLICT = (int)(0x80094008 - 0x100000000), /// /// The operation is denied. It can only be performed by a certificate manager that is allowed to manage certificates for the current requester. /// CERTSRV_E_RESTRICTEDOFFICER = (int)(0x80094009 - 0x100000000), /// /// Cannot archive private key. The certification authority is not configured for key archival. /// CERTSRV_E_KEY_ARCHIVAL_NOT_CONFIGURED = (int)(0x8009400A - 0x100000000), /// /// Cannot archive private key. The certification authority could not verify one or more key recovery certificates. /// CERTSRV_E_NO_VALID_KRA = (int)(0x8009400B - 0x100000000), /// /// The request is incorrectly formatted. The encrypted private key must be in an unauthenticated attribute in an outermost signature. /// CERTSRV_E_BAD_REQUEST_KEY_ARCHIVAL = (int)(0x8009400C - 0x100000000), /// /// At least one security principal must have the permission to manage this CA. /// CERTSRV_E_NO_CAADMIN_DEFINED = (int)(0x8009400D - 0x100000000), /// /// The request contains an invalid renewal certificate attribute. /// CERTSRV_E_BAD_RENEWAL_CERT_ATTRIBUTE = (int)(0x8009400E - 0x100000000), /// /// An attempt was made to open a Certification Authority database session, but there are already too many active sessions. The server may need to be configured to allow additional sessions. /// CERTSRV_E_NO_DB_SESSIONS = (int)(0x8009400F - 0x100000000), /// /// A memory reference caused a data alignment fault. /// CERTSRV_E_ALIGNMENT_FAULT = (int)(0x80094010 - 0x100000000), /// /// The permissions on this certification authority do not allow the current user to enroll for certificates. /// CERTSRV_E_ENROLL_DENIED = (int)(0x80094011 - 0x100000000), /// /// The permissions on the certificate template do not allow the current user to enroll for this type of certificate. /// CERTSRV_E_TEMPLATE_DENIED = (int)(0x80094012 - 0x100000000), /// /// No information avialable. /// CERTSRV_E_DOWNLEVEL_DC_SSL_OR_UPGRADE = (int)(0x80094013 - 0x100000000), /// /// The requested certificate template is not supported by this CA. /// CERTSRV_E_UNSUPPORTED_CERT_TYPE = (int)(0x80094800 - 0x100000000), /// /// The request contains no certificate template information. /// CERTSRV_E_NO_CERT_TYPE = (int)(0x80094801 - 0x100000000), /// /// The request contains conflicting template information. /// CERTSRV_E_TEMPLATE_CONFLICT = (int)(0x80094802 - 0x100000000), /// /// The request is missing a required Subject Alternate name extension. /// CERTSRV_E_SUBJECT_ALT_NAME_REQUIRED = (int)(0x80094803 - 0x100000000), /// /// The request is missing a required private key for archival by the server. /// CERTSRV_E_ARCHIVED_KEY_REQUIRED = (int)(0x80094804 - 0x100000000), /// /// The request is missing a required SMIME capabilities extension. /// CERTSRV_E_SMIME_REQUIRED = (int)(0x80094805 - 0x100000000), /// /// The request was made on behalf of a subject other than the caller. The certificate template must be configured to require at least one signature to authorize the request. /// CERTSRV_E_BAD_RENEWAL_SUBJECT = (int)(0x80094806 - 0x100000000), /// /// The request template version is newer than the supported template version. /// CERTSRV_E_BAD_TEMPLATE_VERSION = (int)(0x80094807 - 0x100000000), /// /// The template is missing a required signature policy attribute. /// CERTSRV_E_TEMPLATE_POLICY_REQUIRED = (int)(0x80094808 - 0x100000000), /// /// The request is missing required signature policy information. /// CERTSRV_E_SIGNATURE_POLICY_REQUIRED = (int)(0x80094809 - 0x100000000), /// /// The request is missing one or more required signatures. /// CERTSRV_E_SIGNATURE_COUNT = (int)(0x8009480A - 0x100000000), /// /// One or more signatures did not include the required application or issuance policies. The request is missing one or more required valid signatures. /// CERTSRV_E_SIGNATURE_REJECTED = (int)(0x8009480B - 0x100000000), /// /// The request is missing one or more required signature issuance policies. /// CERTSRV_E_ISSUANCE_POLICY_REQUIRED = (int)(0x8009480C - 0x100000000), /// /// The UPN is unavailable and cannot be added to the Subject Alternate name. /// CERTSRV_E_SUBJECT_UPN_REQUIRED = (int)(0x8009480D - 0x100000000), /// /// The Active Directory GUID is unavailable and cannot be added to the Subject Alternate name. /// CERTSRV_E_SUBJECT_DIRECTORY_GUID_REQUIRED = (int)(0x8009480E - 0x100000000), /// /// The DNS name is unavailable and cannot be added to the Subject Alternate name. /// CERTSRV_E_SUBJECT_DNS_REQUIRED = (int)(0x8009480F - 0x100000000), /// /// The request includes a private key for archival by the server, but key archival is not enabled for the specified certificate template. /// CERTSRV_E_ARCHIVED_KEY_UNEXPECTED = (int)(0x80094810 - 0x100000000), /// /// The public key does not meet the minimum size required by the specified certificate template. /// CERTSRV_E_KEY_LENGTH = (int)(0x80094811 - 0x100000000), /// /// No information avialable. /// CERTSRV_E_SUBJECT_EMAIL_REQUIRED = (int)(0x80094812 - 0x100000000), /// /// No information avialable. /// CERTSRV_E_UNKNOWN_CERT_TYPE = (int)(0x80094813 - 0x100000000), /// /// No information avialable. /// CERTSRV_E_CERT_TYPE_OVERLAP = (int)(0x80094814 - 0x100000000), /// /// The key is not exportable. /// XENROLL_E_KEY_NOT_EXPORTABLE = (int)(0x80095000 - 0x100000000), /// /// You cannot add the root CA certificate into your local store. /// XENROLL_E_CANNOT_ADD_ROOT_CERT = (int)(0x80095001 - 0x100000000), /// /// The key archival hash attribute was not found in the response. /// XENROLL_E_RESPONSE_KA_HASH_NOT_FOUND = (int)(0x80095002 - 0x100000000), /// /// An unexpetced key archival hash attribute was found in the response. /// XENROLL_E_RESPONSE_UNEXPECTED_KA_HASH = (int)(0x80095003 - 0x100000000), /// /// There is a key archival hash mismatch between the request and the response. /// XENROLL_E_RESPONSE_KA_HASH_MISMATCH = (int)(0x80095004 - 0x100000000), /// /// Signing certificate cannot include SMIME extension. /// XENROLL_E_KEYSPEC_SMIME_MISMATCH = (int)(0x80095005 - 0x100000000), /// /// A system-level error occurred while verifying trust. /// TRUST_E_SYSTEM_ERROR = (int)(0x80096001 - 0x100000000), /// /// The certificate for the signer of the message is invalid or not found. /// TRUST_E_NO_SIGNER_CERT = (int)(0x80096002 - 0x100000000), /// /// One of the counter signatures was invalid. /// TRUST_E_COUNTER_SIGNER = (int)(0x80096003 - 0x100000000), /// /// The signature of the certificate can not be verified. /// TRUST_E_CERT_SIGNATURE = (int)(0x80096004 - 0x100000000), /// /// The timestamp signature and/or certificate could not be verified or is malformed. /// TRUST_E_TIME_STAMP = (int)(0x80096005 - 0x100000000), /// /// The digital signature of the object did not verify. /// TRUST_E_BAD_DIGEST = (int)(0x80096010 - 0x100000000), /// /// A certificate's basic constraint extension has not been observed. /// TRUST_E_BASIC_CONSTRAINTS = (int)(0x80096019 - 0x100000000), /// /// The certificate does not meet or contain the Authenticode financial extensions. /// TRUST_E_FINANCIAL_CRITERIA = (int)(0x8009601E - 0x100000000), /// /// Tried to reference a part of the file outside the proper range. /// MSSIPOTF_E_OUTOFMEMRANGE = (int)(0x80097001 - 0x100000000), /// /// Could not retrieve an object from the file. /// MSSIPOTF_E_CANTGETOBJECT = (int)(0x80097002 - 0x100000000), /// /// Could not find the head table in the file. /// MSSIPOTF_E_NOHEADTABLE = (int)(0x80097003 - 0x100000000), /// /// The magic number in the head table is incorrect. /// MSSIPOTF_E_BAD_MAGICNUMBER = (int)(0x80097004 - 0x100000000), /// /// The offset table has incorrect values. /// MSSIPOTF_E_BAD_OFFSET_TABLE = (int)(0x80097005 - 0x100000000), /// /// Duplicate table tags or tags out of alphabetical order. /// MSSIPOTF_E_TABLE_TAGORDER = (int)(0x80097006 - 0x100000000), /// /// A table does not start on a long word boundary. /// MSSIPOTF_E_TABLE_Int32UInt16 = (int)(0x80097007 - 0x100000000), /// /// First table does not appear after header information. /// MSSIPOTF_E_BAD_FIRST_TABLE_PLACEMENT = (int)(0x80097008 - 0x100000000), /// /// Two or more tables overlap. /// MSSIPOTF_E_TABLES_OVERLAP = (int)(0x80097009 - 0x100000000), /// /// Too many pad bytes between tables or pad bytes are not 0. /// MSSIPOTF_E_TABLE_PADBYTES = (int)(0x8009700A - 0x100000000), /// /// File is too small to contain the last table. /// MSSIPOTF_E_FILETOOSMALL = (int)(0x8009700B - 0x100000000), /// /// A table checksum is incorrect. /// MSSIPOTF_E_TABLE_CHECKSUM = (int)(0x8009700C - 0x100000000), /// /// The file checksum is incorrect. /// MSSIPOTF_E_FILE_CHECKSUM = (int)(0x8009700D - 0x100000000), /// /// The signature does not have the correct attributes for the policy. /// MSSIPOTF_E_FAILED_POLICY = (int)(0x80097010 - 0x100000000), /// /// The file did not pass the hints check. /// MSSIPOTF_E_FAILED_HINTS_CHECK = (int)(0x80097011 - 0x100000000), /// /// The file is not an OpenType file. /// MSSIPOTF_E_NOT_OPENTYPE = (int)(0x80097012 - 0x100000000), /// /// Failed on a file operation (open, map, read, write). /// MSSIPOTF_E_FILE = (int)(0x80097013 - 0x100000000), /// /// A call to a CryptoAPI function failed. /// MSSIPOTF_E_CRYPT = (int)(0x80097014 - 0x100000000), /// /// There is a bad version number in the file. /// MSSIPOTF_E_BADVERSION = (int)(0x80097015 - 0x100000000), /// /// The structure of the DSIG table is incorrect. /// MSSIPOTF_E_DSIG_STRUCTURE = (int)(0x80097016 - 0x100000000), /// /// A check failed in a partially constant table. /// MSSIPOTF_E_PCONST_CHECK = (int)(0x80097017 - 0x100000000), /// /// Some kind of structural error. /// MSSIPOTF_E_STRUCTURE = (int)(0x80097018 - 0x100000000), /// /// The operation completed successfully. /// NTE_OP_OK = 0, /// /// Unknown trust provider. /// TRUST_E_PROVIDER_UNKNOWN = (int)(0x800B0001 - 0x100000000), /// /// The trust verification action specified is not supported by the specified trust provider. /// TRUST_E_ACTION_UNKNOWN = (int)(0x800B0002 - 0x100000000), /// /// The form specified for the subject is not one supported or known by the specified trust provider. /// TRUST_E_SUBJECT_FORM_UNKNOWN = (int)(0x800B0003 - 0x100000000), /// /// The subject is not trusted for the specified action. /// TRUST_E_SUBJECT_NOT_TRUSTED = (int)(0x800B0004 - 0x100000000), /// /// Error due to problem in ASN.1 encoding process. /// DIGSIG_E_ENCODE = (int)(0x800B0005 - 0x100000000), /// /// Error due to problem in ASN.1 decoding process. /// DIGSIG_E_DECODE = (int)(0x800B0006 - 0x100000000), /// /// Reading / writing Extensions where Attributes are appropriate, and visa versa. /// DIGSIG_E_EXTENSIBILITY = (int)(0x800B0007 - 0x100000000), /// /// Unspecified cryptographic failure. /// DIGSIG_E_CRYPTO = (int)(0x800B0008 - 0x100000000), /// /// The size of the data could not be determined. /// PERSIST_E_SIZEDEFINITE = (int)(0x800B0009 - 0x100000000), /// /// The size of the indefinite-sized data could not be determined. /// PERSIST_E_SIZEINDEFINITE = (int)(0x800B000A - 0x100000000), /// /// This object does not read and write self-sizing data. /// PERSIST_E_NOTSELFSIZING = (int)(0x800B000B - 0x100000000), /// /// No signature was present in the subject. /// TRUST_E_NOSIGNATURE = (int)(0x800B0100 - 0x100000000), /// /// A required certificate is not within its validity period when verifying against the current system clock or the timestamp in the signed file. /// CERT_E_EXPIRED = (int)(0x800B0101 - 0x100000000), /// /// The validity periods of the certification chain do not nest correctly. /// CERT_E_VALIDITYPERIODNESTING = (int)(0x800B0102 - 0x100000000), /// /// A certificate that can only be used as an end-entity is being used as a CA or visa versa. /// CERT_E_ROLE = (int)(0x800B0103 - 0x100000000), /// /// A path length constraint in the certification chain has been violated. /// CERT_E_PATHLENCONST = (int)(0x800B0104 - 0x100000000), /// /// A certificate contains an unknown extension that is marked 'critical'. /// CERT_E_CRITICAL = (int)(0x800B0105 - 0x100000000), /// /// A certificate being used for a purpose other than the ones specified by its CA. /// CERT_E_PURPOSE = (int)(0x800B0106 - 0x100000000), /// /// A parent of a given certificate in fact did not issue that child certificate. /// CERT_E_ISSUERCHAINING = (int)(0x800B0107 - 0x100000000), /// /// A certificate is missing or has an empty value for an important field, such as a subject or issuer name. /// CERT_E_MALFORMED = (int)(0x800B0108 - 0x100000000), /// /// A certificate chain processed, but terminated in a root certificate which is not trusted by the trust provider. /// CERT_E_UNTRUSTEDROOT = (int)(0x800B0109 - 0x100000000), /// /// An internal certificate chaining error has occurred. /// CERT_E_CHAINING = (int)(0x800B010A - 0x100000000), /// /// Generic trust failure. /// TRUST_E_FAIL = (int)(0x800B010B - 0x100000000), /// /// A certificate was explicitly revoked by its issuer. /// CERT_E_REVOKED = (int)(0x800B010C - 0x100000000), /// /// The certification path terminates with the test root which is not trusted with the current policy settings. /// CERT_E_UNTRUSTEDTESTROOT = (int)(0x800B010D - 0x100000000), /// /// The revocation process could not continue - the certificate(s) could not be checked. /// CERT_E_REVOCATION_FAILURE = (int)(0x800B010E - 0x100000000), /// /// The certificate's CN name does not match the passed value. /// CERT_E_CN_NO_MATCH = (int)(0x800B010F - 0x100000000), /// /// The certificate is not valid for the requested usage. /// CERT_E_WRONG_USAGE = (int)(0x800B0110 - 0x100000000), /// /// The certificate was explicitly marked as untrusted by the user. /// TRUST_E_EXPLICIT_DISTRUST = (int)(0x800B0111 - 0x100000000), /// /// A certification chain processed correctly, but one of the CA certificates is not trusted by the policy provider. /// CERT_E_UNTRUSTEDCA = (int)(0x800B0112 - 0x100000000), /// /// The certificate has invalid policy. /// CERT_E_INVALID_POLICY = (int)(0x800B0113 - 0x100000000), /// /// The certificate has an invalid name. The name is not included in the permitted list or is explicitly excluded. /// CERT_E_INVALID_NAME = (int)(0x800B0114 - 0x100000000), /// /// A non-empty line was encountered in the INF before the start of a section. /// SPAPI_E_EXPECTED_SECTION_NAME = (int)(0x800F0000 - 0x100000000), /// /// A section name marker in the INF is not complete, or does not exist on a line by itself. /// SPAPI_E_BAD_SECTION_NAME_LINE = (int)(0x800F0001 - 0x100000000), /// /// An INF section was encountered whose name exceeds the maximum section name length. /// SPAPI_E_SECTION_NAME_TOO_Int32 = (int)(0x800F0002 - 0x100000000), /// /// The syntax of the INF is invalid. /// SPAPI_E_GENERAL_SYNTAX = (int)(0x800F0003 - 0x100000000), /// /// The style of the INF is different than what was requested. /// SPAPI_E_WRONG_INF_STYLE = (int)(0x800F0100 - 0x100000000), /// /// The required section was not found in the INF. /// SPAPI_E_SECTION_NOT_FOUND = (int)(0x800F0101 - 0x100000000), /// /// The required line was not found in the INF. /// SPAPI_E_LINE_NOT_FOUND = (int)(0x800F0102 - 0x100000000), /// /// The files affected by the installation of this file queue have not been backed up for uninstall. /// SPAPI_E_NO_BACKUP = (int)(0x800F0103 - 0x100000000), /// /// The INF or the device information set or element does not have an associated install class. /// SPAPI_E_NO_ASSOCIATED_CLASS = (int)(0x800F0200 - 0x100000000), /// /// The INF or the device information set or element does not match the specified install class. /// SPAPI_E_CLASS_MISMATCH = (int)(0x800F0201 - 0x100000000), /// /// An existing device was found that is a duplicate of the device being manually installed. /// SPAPI_E_DUPLICATE_FOUND = (int)(0x800F0202 - 0x100000000), /// /// There is no driver selected for the device information set or element. /// SPAPI_E_NO_DRIVER_SELECTED = (int)(0x800F0203 - 0x100000000), /// /// The requested device registry key does not exist. /// SPAPI_E_KEY_DOES_NOT_EXIST = (int)(0x800F0204 - 0x100000000), /// /// The device instance name is invalid. /// SPAPI_E_INVALID_DEVINST_NAME = (int)(0x800F0205 - 0x100000000), /// /// The install class is not present or is invalid. /// SPAPI_E_INVALID_CLASS = (int)(0x800F0206 - 0x100000000), /// /// The device instance cannot be created because it already exists. /// SPAPI_E_DEVINST_ALREADY_EXISTS = (int)(0x800F0207 - 0x100000000), /// /// The operation cannot be performed on a device information element that has not been registered. /// SPAPI_E_DEVINFO_NOT_REGISTERED = (int)(0x800F0208 - 0x100000000), /// /// The device property code is invalid. /// SPAPI_E_INVALID_REG_PROPERTY = (int)(0x800F0209 - 0x100000000), /// /// The INF from which a driver list is to be built does not exist. /// SPAPI_E_NO_INF = (int)(0x800F020A - 0x100000000), /// /// The device instance does not exist in the hardware tree. /// SPAPI_E_NO_SUCH_DEVINST = (int)(0x800F020B - 0x100000000), /// /// The icon representing this install class cannot be loaded. /// SPAPI_E_CANT_LOAD_CLASS_ICON = (int)(0x800F020C - 0x100000000), /// /// The class installer registry entry is invalid. /// SPAPI_E_INVALID_CLASS_INSTALLER = (int)(0x800F020D - 0x100000000), /// /// The class installer has indicated that the default action should be performed for this installation request. /// SPAPI_E_DI_DO_DEFAULT = (int)(0x800F020E - 0x100000000), /// /// The operation does not require any files to be copied. /// SPAPI_E_DI_NOFILECOPY = (int)(0x800F020F - 0x100000000), /// /// The specified hardware profile does not exist. /// SPAPI_E_INVALID_HWPROFILE = (int)(0x800F0210 - 0x100000000), /// /// There is no device information element currently selected for this device information set. /// SPAPI_E_NO_DEVICE_SELECTED = (int)(0x800F0211 - 0x100000000), /// /// The operation cannot be performed because the device information set is locked. /// SPAPI_E_DEVINFO_LIST_LOCKED = (int)(0x800F0212 - 0x100000000), /// /// The operation cannot be performed because the device information element is locked. /// SPAPI_E_DEVINFO_DATA_LOCKED = (int)(0x800F0213 - 0x100000000), /// /// The specified path does not contain any applicable device INFs. /// SPAPI_E_DI_BAD_PATH = (int)(0x800F0214 - 0x100000000), /// /// No class installer parameters have been set for the device information set or element. /// SPAPI_E_NO_CLASSINSTALL_PARAMS = (int)(0x800F0215 - 0x100000000), /// /// The operation cannot be performed because the file queue is locked. /// SPAPI_E_FILEQUEUE_LOCKED = (int)(0x800F0216 - 0x100000000), /// /// A service installation section in this INF is invalid. /// SPAPI_E_BAD_SERVICE_INSTALLSECT = (int)(0x800F0217 - 0x100000000), /// /// There is no class driver list for the device information element. /// SPAPI_E_NO_CLASS_DRIVER_LIST = (int)(0x800F0218 - 0x100000000), /// /// The installation failed because a function driver was not specified for this device instance. /// SPAPI_E_NO_ASSOCIATED_SERVICE = (int)(0x800F0219 - 0x100000000), /// /// There is presently no default device interface designated for this interface class. /// SPAPI_E_NO_DEFAULT_DEVICE_INTERFACE = (int)(0x800F021A - 0x100000000), /// /// The operation cannot be performed because the device interface is currently active. /// SPAPI_E_DEVICE_INTERFACE_ACTIVE = (int)(0x800F021B - 0x100000000), /// /// The operation cannot be performed because the device interface has been removed from the system. /// SPAPI_E_DEVICE_INTERFACE_REMOVED = (int)(0x800F021C - 0x100000000), /// /// An interface installation section in this INF is invalid. /// SPAPI_E_BAD_INTERFACE_INSTALLSECT = (int)(0x800F021D - 0x100000000), /// /// This interface class does not exist in the system. /// SPAPI_E_NO_SUCH_INTERFACE_CLASS = (int)(0x800F021E - 0x100000000), /// /// The reference string supplied for this interface device is invalid. /// SPAPI_E_INVALID_REFERENCE_STRING = (int)(0x800F021F - 0x100000000), /// /// The specified machine name does not conform to UNC naming conventions. /// SPAPI_E_INVALID_MACHINENAME = (int)(0x800F0220 - 0x100000000), /// /// A general remote communication error occurred. /// SPAPI_E_REMOTE_COMM_FAILURE = (int)(0x800F0221 - 0x100000000), /// /// The machine selected for remote communication is not available at this time. /// SPAPI_E_MACHINE_UNAVAILABLE = (int)(0x800F0222 - 0x100000000), /// /// The Plug and Play service is not available on the remote machine. /// SPAPI_E_NO_CONFIGMGR_SERVICES = (int)(0x800F0223 - 0x100000000), /// /// The property page provider registry entry is invalid. /// SPAPI_E_INVALID_PROPPAGE_PROVIDER = (int)(0x800F0224 - 0x100000000), /// /// The requested device interface is not present in the system. /// SPAPI_E_NO_SUCH_DEVICE_INTERFACE = (int)(0x800F0225 - 0x100000000), /// /// The device's co-installer has additional work to perform after installation is complete. /// SPAPI_E_DI_POSTPROCESSING_REQUIRED = (int)(0x800F0226 - 0x100000000), /// /// The device's co-installer is invalid. /// SPAPI_E_INVALID_COINSTALLER = (int)(0x800F0227 - 0x100000000), /// /// There are no compatible drivers for this device. /// SPAPI_E_NO_COMPAT_DRIVERS = (int)(0x800F0228 - 0x100000000), /// /// There is no icon that represents this device or device type. /// SPAPI_E_NO_DEVICE_ICON = (int)(0x800F0229 - 0x100000000), /// /// A logical configuration specified in this INF is invalid. /// SPAPI_E_INVALID_INF_LOGCONFIG = (int)(0x800F022A - 0x100000000), /// /// The class installer has denied the request to install or upgrade this device. /// SPAPI_E_DI_DONT_INSTALL = (int)(0x800F022B - 0x100000000), /// /// One of the filter drivers installed for this device is invalid. /// SPAPI_E_INVALID_FILTER_DRIVER = (int)(0x800F022C - 0x100000000), /// /// The driver selected for this device does not support Windows XP. /// SPAPI_E_NON_WINDOWS_NT_DRIVER = (int)(0x800F022D - 0x100000000), /// /// The driver selected for this device does not support Windows. /// SPAPI_E_NON_WINDOWS_DRIVER = (int)(0x800F022E - 0x100000000), /// /// The third-party INF does not contain digital signature information. /// SPAPI_E_NO_CATALOG_FOR_OEM_INF = (int)(0x800F022F - 0x100000000), /// /// An invalid attempt was made to use a device installation file queue for verification of digital signatures relative to other platforms. /// SPAPI_E_DEVINSTALL_QUEUE_NONNATIVE = (int)(0x800F0230 - 0x100000000), /// /// The device cannot be disabled. /// SPAPI_E_NOT_DISABLEABLE = (int)(0x800F0231 - 0x100000000), /// /// The device could not be dynamically removed. /// SPAPI_E_CANT_REMOVE_DEVINST = (int)(0x800F0232 - 0x100000000), /// /// Cannot copy to specified target. /// SPAPI_E_INVALID_TARGET = (int)(0x800F0233 - 0x100000000), /// /// Driver is not intended for this platform. /// SPAPI_E_DRIVER_NONNATIVE = (int)(0x800F0234 - 0x100000000), /// /// Operation not allowed in WOW64. /// SPAPI_E_IN_WOW64 = (int)(0x800F0235 - 0x100000000), /// /// The operation involving unsigned file copying was rolled back, so that a system restore point could be set. /// SPAPI_E_SET_SYSTEM_RESTORE_POINT = (int)(0x800F0236 - 0x100000000), /// /// An INF was copied into the Windows INF directory in an improper manner. /// SPAPI_E_INCORRECTLY_COPIED_INF = (int)(0x800F0237 - 0x100000000), /// /// The Security Configuration Editor (SCE) APIs have been disabled on this Embedded product. /// SPAPI_E_SCE_DISABLED = (int)(0x800F0238 - 0x100000000), /// /// No installed components were detected. /// SPAPI_E_ERROR_NOT_INSTALLED = (int)(0x800F1000 - 0x100000000), /// /// An internal consistency check failed. /// SCARD_F_INTERNAL_ERROR = (int)(0x80100001 - 0x100000000), /// /// The action was cancelled by an SCardCancel request. /// SCARD_E_CANCELLED = (int)(0x80100002 - 0x100000000), /// /// The supplied handle was invalid. /// SCARD_E_INVALID_HANDLE = (int)(0x80100003 - 0x100000000), /// /// One or more of the supplied parameters could not be properly interpreted. /// SCARD_E_INVALID_PARAMETER = (int)(0x80100004 - 0x100000000), /// /// Registry startup information is missing or invalid. /// SCARD_E_INVALID_TARGET = (int)(0x80100005 - 0x100000000), /// /// Not enough memory available to complete this command. /// SCARD_E_NO_MEMORY = (int)(0x80100006 - 0x100000000), /// /// An internal consistency timer has expired. /// SCARD_F_WAITED_TOO_Int32 = (int)(0x80100007 - 0x100000000), /// /// The data buffer to receive returned data is too small for the returned data. /// SCARD_E_INSUFFICIENT_BUFFER = (int)(0x80100008 - 0x100000000), /// /// The specified reader name is not recognized. /// SCARD_E_UNKNOWN_READER = (int)(0x80100009 - 0x100000000), /// /// The user-specified timeout value has expired. /// SCARD_E_TIMEOUT = (int)(0x8010000A - 0x100000000), /// /// The smart card cannot be accessed because of other connections outstanding. /// SCARD_E_SHARING_VIOLATION = (int)(0x8010000B - 0x100000000), /// /// The operation requires a Smart Card, but no Smart Card is currently in the device. /// SCARD_E_NO_SMARTCARD = (int)(0x8010000C - 0x100000000), /// /// The specified smart card name is not recognized. /// SCARD_E_UNKNOWN_CARD = (int)(0x8010000D - 0x100000000), /// /// The system could not dispose of the media in the requested manner. /// SCARD_E_CANT_DISPOSE = (int)(0x8010000E - 0x100000000), /// /// The requested protocols are incompatible with the protocol currently in use with the smart card. /// SCARD_E_PROTO_MISMATCH = (int)(0x8010000F - 0x100000000), /// /// The reader or smart card is not ready to accept commands. /// SCARD_E_NOT_READY = (int)(0x80100010 - 0x100000000), /// /// One or more of the supplied parameters values could not be properly interpreted. /// SCARD_E_INVALID_VALUE = (int)(0x80100011 - 0x100000000), /// /// The action was cancelled by the system, presumably to log off or shut down. /// SCARD_E_SYSTEM_CANCELLED = (int)(0x80100012 - 0x100000000), /// /// An internal communications error has been detected. /// SCARD_F_COMM_ERROR = (int)(0x80100013 - 0x100000000), /// /// An internal error has been detected, but the source is unknown. /// SCARD_F_UNKNOWN_ERROR = (int)(0x80100014 - 0x100000000), /// /// An ATR obtained from the registry is not a valid ATR string. /// SCARD_E_INVALID_ATR = (int)(0x80100015 - 0x100000000), /// /// An attempt was made to end a non-existent transaction. /// SCARD_E_NOT_TRANSACTED = (int)(0x80100016 - 0x100000000), /// /// The specified reader is not currently available for use. /// SCARD_E_READER_UNAVAILABLE = (int)(0x80100017 - 0x100000000), /// /// The operation has been aborted to allow the server application to exit. /// SCARD_P_SHUTDOWN = (int)(0x80100018 - 0x100000000), /// /// The PCI Receive buffer was too small. /// SCARD_E_PCI_TOO_SMALL = (int)(0x80100019 - 0x100000000), /// /// The reader driver does not meet minimal requirements for support. /// SCARD_E_READER_UNSUPPORTED = (int)(0x8010001A - 0x100000000), /// /// The reader driver did not produce a unique reader name. /// SCARD_E_DUPLICATE_READER = (int)(0x8010001B - 0x100000000), /// /// The smart card does not meet minimal requirements for support. /// SCARD_E_CARD_UNSUPPORTED = (int)(0x8010001C - 0x100000000), /// /// The Smart card resource manager is not running. /// SCARD_E_NO_SERVICE = (int)(0x8010001D - 0x100000000), /// /// The Smart card resource manager has shut down. /// SCARD_E_SERVICE_STOPPED = (int)(0x8010001E - 0x100000000), /// /// An unexpected card error has occurred. /// SCARD_E_UNEXPECTED = (int)(0x8010001F - 0x100000000), /// /// No Primary Provider can be found for the smart card. /// SCARD_E_ICC_INSTALLATION = (int)(0x80100020 - 0x100000000), /// /// The requested order of object creation is not supported. /// SCARD_E_ICC_CREATEORDER = (int)(0x80100021 - 0x100000000), /// /// This smart card does not support the requested feature. /// SCARD_E_UNSUPPORTED_FEATURE = (int)(0x80100022 - 0x100000000), /// /// The identified directory does not exist in the smart card. /// SCARD_E_DIR_NOT_FOUND = (int)(0x80100023 - 0x100000000), /// /// The identified file does not exist in the smart card. /// SCARD_E_FILE_NOT_FOUND = (int)(0x80100024 - 0x100000000), /// /// The supplied path does not represent a smart card directory. /// SCARD_E_NO_DIR = (int)(0x80100025 - 0x100000000), /// /// The supplied path does not represent a smart card file. /// SCARD_E_NO_FILE = (int)(0x80100026 - 0x100000000), /// /// Access is denied to this file. /// SCARD_E_NO_ACCESS = (int)(0x80100027 - 0x100000000), /// /// The smartcard does not have enough memory to store the information. /// SCARD_E_WRITE_TOO_MANY = (int)(0x80100028 - 0x100000000), /// /// There was an error trying to set the smart card file object pointer. /// SCARD_E_BAD_SEEK = (int)(0x80100029 - 0x100000000), /// /// The supplied PIN is incorrect. /// SCARD_E_INVALID_CHV = (int)(0x8010002A - 0x100000000), /// /// An unrecognized error code was returned from a layered component. /// SCARD_E_UNKNOWN_RES_MNG = (int)(0x8010002B - 0x100000000), /// /// The requested certificate does not exist. /// SCARD_E_NO_SUCH_CERTIFICATE = (int)(0x8010002C - 0x100000000), /// /// The requested certificate could not be obtained. /// SCARD_E_CERTIFICATE_UNAVAILABLE = (int)(0x8010002D - 0x100000000), /// /// Cannot find a smart card reader. /// SCARD_E_NO_READERS_AVAILABLE = (int)(0x8010002E - 0x100000000), /// /// A communications error with the smart card has been detected. Retry the operation. /// SCARD_E_COMM_DATA_LOST = (int)(0x8010002F - 0x100000000), /// /// The requested key container does not exist on the smart card. /// SCARD_E_NO_KEY_CONTAINER = (int)(0x80100030 - 0x100000000), /// /// No information avialable. /// SCARD_E_SERVER_TOO_BUSY = (int)(0x80100031 - 0x100000000), /// /// The reader cannot communicate with the smart card, due to ATR configuration conflicts. /// SCARD_W_UNSUPPORTED_CARD = (int)(0x80100065 - 0x100000000), /// /// The smart card is not responding to a reset. /// SCARD_W_UNRESPONSIVE_CARD = (int)(0x80100066 - 0x100000000), /// /// Power has been removed from the smart card, so that further communication is not possible. /// SCARD_W_UNPOWERED_CARD = (int)(0x80100067 - 0x100000000), /// /// The smart card has been reset, so any shared state information is invalid. /// SCARD_W_RESET_CARD = (int)(0x80100068 - 0x100000000), /// /// The smart card has been removed, so that further communication is not possible. /// SCARD_W_REMOVED_CARD = (int)(0x80100069 - 0x100000000), /// /// Access was denied because of a security violation. /// SCARD_W_SECURITY_VIOLATION = (int)(0x8010006A - 0x100000000), /// /// The card cannot be accessed because the wrong PIN was presented. /// SCARD_W_WRONG_CHV = (int)(0x8010006B - 0x100000000), /// /// The card cannot be accessed because the maximum number of PIN entry attempts has been reached. /// SCARD_W_CHV_BLOCKED = (int)(0x8010006C - 0x100000000), /// /// The end of the smart card file has been reached. /// SCARD_W_EOF = (int)(0x8010006D - 0x100000000), /// /// The action was cancelled by the user. /// SCARD_W_CANCELLED_BY_USER = (int)(0x8010006E - 0x100000000), /// /// No PIN was presented to the smart card. /// SCARD_W_CARD_NOT_AUTHENTICATED = (int)(0x8010006F - 0x100000000), /// /// Errors occurred accessing one or more objects - the ErrorInfo collection may have more detail /// COMADMIN_E_OBJECTERRORS = (int)(0x80110401 - 0x100000000), /// /// One or more of the object's properties are missing or invalid /// COMADMIN_E_OBJECTINVALID = (int)(0x80110402 - 0x100000000), /// /// The object was not found in the catalog /// COMADMIN_E_KEYMISSING = (int)(0x80110403 - 0x100000000), /// /// The object is already registered /// COMADMIN_E_ALREADYINSTALLED = (int)(0x80110404 - 0x100000000), /// /// Error occurred writing to the application file /// COMADMIN_E_APP_FILE_WRITEFAIL = (int)(0x80110407 - 0x100000000), /// /// Error occurred reading the application file /// COMADMIN_E_APP_FILE_READFAIL = (int)(0x80110408 - 0x100000000), /// /// Invalid version number in application file /// COMADMIN_E_APP_FILE_VERSION = (int)(0x80110409 - 0x100000000), /// /// The file path is invalid /// COMADMIN_E_BADPATH = (int)(0x8011040A - 0x100000000), /// /// The application is already installed /// COMADMIN_E_APPLICATIONEXISTS = (int)(0x8011040B - 0x100000000), /// /// The role already exists /// COMADMIN_E_ROLEEXISTS = (int)(0x8011040C - 0x100000000), /// /// An error occurred copying the file /// COMADMIN_E_CANTCOPYFILE = (int)(0x8011040D - 0x100000000), /// /// One or more users are not valid /// COMADMIN_E_NOUSER = (int)(0x8011040F - 0x100000000), /// /// One or more users in the application file are not valid /// COMADMIN_E_INVALIDUSERIDS = (int)(0x80110410 - 0x100000000), /// /// The component's CLSID is missing or corrupt /// COMADMIN_E_NOREGISTRYCLSID = (int)(0x80110411 - 0x100000000), /// /// The component's progID is missing or corrupt /// COMADMIN_E_BADREGISTRYPROGID = (int)(0x80110412 - 0x100000000), /// /// Unable to set required authentication level for update request /// COMADMIN_E_AUTHENTICATIONLEVEL = (int)(0x80110413 - 0x100000000), /// /// The identity or password set on the application is not valid /// COMADMIN_E_USERPASSWDNOTVALID = (int)(0x80110414 - 0x100000000), /// /// Application file CLSIDs or IIDs do not match corresponding DLLs /// COMADMIN_E_CLSIDORIIDMISMATCH = (int)(0x80110418 - 0x100000000), /// /// Interface information is either missing or changed /// COMADMIN_E_REMOTEINTERFACE = (int)(0x80110419 - 0x100000000), /// /// DllRegisterServer failed on component install /// COMADMIN_E_DLLREGISTERSERVER = (int)(0x8011041A - 0x100000000), /// /// No server file share available /// COMADMIN_E_NOSERVERSHARE = (int)(0x8011041B - 0x100000000), /// /// DLL could not be loaded /// COMADMIN_E_DLLLOADFAILED = (int)(0x8011041D - 0x100000000), /// /// The registered TypeLib ID is not valid /// COMADMIN_E_BADREGISTRYLIBID = (int)(0x8011041E - 0x100000000), /// /// Application install directory not found /// COMADMIN_E_APPDIRNOTFOUND = (int)(0x8011041F - 0x100000000), /// /// Errors occurred while in the component registrar /// COMADMIN_E_REGISTRARFAILED = (int)(0x80110423 - 0x100000000), /// /// The file does not exist /// COMADMIN_E_COMPFILE_DOESNOTEXIST = (int)(0x80110424 - 0x100000000), /// /// The DLL could not be loaded /// COMADMIN_E_COMPFILE_LOADDLLFAIL = (int)(0x80110425 - 0x100000000), /// /// GetClassObject failed in the DLL /// COMADMIN_E_COMPFILE_GETCLASSOBJ = (int)(0x80110426 - 0x100000000), /// /// The DLL does not support the components listed in the TypeLib /// COMADMIN_E_COMPFILE_CLASSNOTAVAIL = (int)(0x80110427 - 0x100000000), /// /// The TypeLib could not be loaded /// COMADMIN_E_COMPFILE_BADTLB = (int)(0x80110428 - 0x100000000), /// /// The file does not contain components or component information /// COMADMIN_E_COMPFILE_NOTINSTALLABLE = (int)(0x80110429 - 0x100000000), /// /// Changes to this object and its sub-objects have been disabled /// COMADMIN_E_NOTCHANGEABLE = (int)(0x8011042A - 0x100000000), /// /// The delete function has been disabled for this object /// COMADMIN_E_NOTDELETEABLE = (int)(0x8011042B - 0x100000000), /// /// The server catalog version is not supported /// COMADMIN_E_SESSION = (int)(0x8011042C - 0x100000000), /// /// The component move was disallowed, because the source or destination application is either a system application or currently locked against changes /// COMADMIN_E_COMP_MOVE_LOCKED = (int)(0x8011042D - 0x100000000), /// /// The component move failed because the destination application no longer exists /// COMADMIN_E_COMP_MOVE_BAD_DEST = (int)(0x8011042E - 0x100000000), /// /// The system was unable to register the TypeLib /// COMADMIN_E_REGISTERTLB = (int)(0x80110430 - 0x100000000), /// /// This operation can not be performed on the system application /// COMADMIN_E_SYSTEMAPP = (int)(0x80110433 - 0x100000000), /// /// The component registrar referenced in this file is not available /// COMADMIN_E_COMPFILE_NOREGISTRAR = (int)(0x80110434 - 0x100000000), /// /// A component in the same DLL is already installed /// COMADMIN_E_COREQCOMPINSTALLED = (int)(0x80110435 - 0x100000000), /// /// The service is not installed /// COMADMIN_E_SERVICENOTINSTALLED = (int)(0x80110436 - 0x100000000), /// /// One or more property settings are either invalid or in conflict with each other /// COMADMIN_E_PROPERTYSAVEFAILED = (int)(0x80110437 - 0x100000000), /// /// The object you are attempting to add or rename already exists /// COMADMIN_E_OBJECTEXISTS = (int)(0x80110438 - 0x100000000), /// /// The component already exists /// COMADMIN_E_COMPONENTEXISTS = (int)(0x80110439 - 0x100000000), /// /// The registration file is corrupt /// COMADMIN_E_REGFILE_CORRUPT = (int)(0x8011043B - 0x100000000), /// /// The property value is too large /// COMADMIN_E_PROPERTY_OVERFLOW = (int)(0x8011043C - 0x100000000), /// /// Object was not found in registry /// COMADMIN_E_NOTINREGISTRY = (int)(0x8011043E - 0x100000000), /// /// This object is not poolable /// COMADMIN_E_OBJECTNOTPOOLABLE = (int)(0x8011043F - 0x100000000), /// /// A CLSID with the same GUID as the new application ID is already installed on this machine /// COMADMIN_E_APPLID_MATCHES_CLSID = (int)(0x80110446 - 0x100000000), /// /// A role assigned to a component, interface, or method did not exist in the application /// COMADMIN_E_ROLE_DOES_NOT_EXIST = (int)(0x80110447 - 0x100000000), /// /// You must have components in an application in order to start the application /// COMADMIN_E_START_APP_NEEDS_COMPONENTS = (int)(0x80110448 - 0x100000000), /// /// This operation is not enabled on this platform /// COMADMIN_E_REQUIRES_DIFFERENT_PLATFORM = (int)(0x80110449 - 0x100000000), /// /// Application Proxy is not exportable /// COMADMIN_E_CAN_NOT_EXPORT_APP_PROXY = (int)(0x8011044A - 0x100000000), /// /// Failed to start application because it is either a library application or an application proxy /// COMADMIN_E_CAN_NOT_START_APP = (int)(0x8011044B - 0x100000000), /// /// System application is not exportable /// COMADMIN_E_CAN_NOT_EXPORT_SYS_APP = (int)(0x8011044C - 0x100000000), /// /// Can not subscribe to this component (the component may have been imported) /// COMADMIN_E_CANT_SUBSCRIBE_TO_COMPONENT = (int)(0x8011044D - 0x100000000), /// /// An event class cannot also be a subscriber component /// COMADMIN_E_EVENTCLASS_CANT_BE_SUBSCRIBER = (int)(0x8011044E - 0x100000000), /// /// Library applications and application proxies are incompatible /// COMADMIN_E_LIB_APP_PROXY_INCOMPATIBLE = (int)(0x8011044F - 0x100000000), /// /// This function is valid for the base partition only /// COMADMIN_E_BASE_PARTITION_ONLY = (int)(0x80110450 - 0x100000000), /// /// You cannot start an application that has been disabled /// COMADMIN_E_START_APP_DISABLED = (int)(0x80110451 - 0x100000000), /// /// The specified partition name is already in use on this computer /// COMADMIN_E_CAT_DUPLICATE_PARTITION_NAME = (int)(0x80110457 - 0x100000000), /// /// The specified partition name is invalid. Check that the name contains at least one visible character /// COMADMIN_E_CAT_INVALID_PARTITION_NAME = (int)(0x80110458 - 0x100000000), /// /// The partition cannot be deleted because it is the default partition for one or more users /// COMADMIN_E_CAT_PARTITION_IN_USE = (int)(0x80110459 - 0x100000000), /// /// The partition cannot be exported, because one or more components in the partition have the same file name /// COMADMIN_E_FILE_PARTITION_DUPLICATE_FILES = (int)(0x8011045A - 0x100000000), /// /// Applications that contain one or more imported components cannot be installed into a non-base partition /// COMADMIN_E_CAT_IMPORTED_COMPONENTS_NOT_ALLOWED = (int)(0x8011045B - 0x100000000), /// /// The application name is not unique and cannot be resolved to an application id /// COMADMIN_E_AMBIGUOUS_APPLICATION_NAME = (int)(0x8011045C - 0x100000000), /// /// The partition name is not unique and cannot be resolved to a partition id /// COMADMIN_E_AMBIGUOUS_PARTITION_NAME = (int)(0x8011045D - 0x100000000), /// /// The COM+ registry database has not been initialized /// COMADMIN_E_REGDB_NOTINITIALIZED = (int)(0x80110472 - 0x100000000), /// /// The COM+ registry database is not open /// COMADMIN_E_REGDB_NOTOPEN = (int)(0x80110473 - 0x100000000), /// /// The COM+ registry database detected a system error /// COMADMIN_E_REGDB_SYSTEMERR = (int)(0x80110474 - 0x100000000), /// /// The COM+ registry database is already running /// COMADMIN_E_REGDB_ALREADYRUNNING = (int)(0x80110475 - 0x100000000), /// /// This version of the COM+ registry database cannot be migrated /// COMADMIN_E_MIG_VERSIONNOTSUPPORTED = (int)(0x80110480 - 0x100000000), /// /// The schema version to be migrated could not be found in the COM+ registry database /// COMADMIN_E_MIG_SCHEMANOTFOUND = (int)(0x80110481 - 0x100000000), /// /// There was a type mismatch between binaries /// COMADMIN_E_CAT_BITNESSMISMATCH = (int)(0x80110482 - 0x100000000), /// /// A binary of unknown or invalid type was provided /// COMADMIN_E_CAT_UNACCEPTABLEBITNESS = (int)(0x80110483 - 0x100000000), /// /// There was a type mismatch between a binary and an application /// COMADMIN_E_CAT_WRONGAPPBITNESS = (int)(0x80110484 - 0x100000000), /// /// The application cannot be paused or resumed /// COMADMIN_E_CAT_PAUSE_RESUME_NOT_SUPPORTED = (int)(0x80110485 - 0x100000000), /// /// The COM+ Catalog Server threw an exception during execution /// COMADMIN_E_CAT_SERVERFAULT = (int)(0x80110486 - 0x100000000), /// /// Only COM+ Applications marked "queued" can be invoked using the "queue" moniker /// COMQC_E_APPLICATION_NOT_QUEUED = (int)(0x80110600 - 0x100000000), /// /// At least one interface must be marked "queued" in order to create a queued component instance with the "queue" moniker /// COMQC_E_NO_QUEUEABLE_INTERFACES = (int)(0x80110601 - 0x100000000), /// /// MSMQ is required for the requested operation and is not installed /// COMQC_E_QUEUING_SERVICE_NOT_AVAILABLE = (int)(0x80110602 - 0x100000000), /// /// Unable to marshal an interface that does not support IPersistStream /// COMQC_E_NO_IPERSISTSTREAM = (int)(0x80110603 - 0x100000000), /// /// The message is improperly formatted or was damaged in transit /// COMQC_E_BAD_MESSAGE = (int)(0x80110604 - 0x100000000), /// /// An unauthenticated message was received by an application that accepts only authenticated messages /// COMQC_E_UNAUTHENTICATED = (int)(0x80110605 - 0x100000000), /// /// The message was requeued or moved by a user not in the "QC Trusted User" role /// COMQC_E_UNTRUSTED_ENQUEUER = (int)(0x80110606 - 0x100000000), /// /// Cannot create a duplicate resource of type Distributed Transaction Coordinator /// MSDTC_E_DUPLICATE_RESOURCE = (int)(0x80110701 - 0x100000000), /// /// One of the objects being inserted or updated does not belong to a valid parent collection /// COMADMIN_E_OBJECT_PARENT_MISSING = (int)(0x80110808 - 0x100000000), /// /// One of the specified objects cannot be found /// COMADMIN_E_OBJECT_DOES_NOT_EXIST = (int)(0x80110809 - 0x100000000), /// /// The specified application is not currently running /// COMADMIN_E_APP_NOT_RUNNING = (int)(0x8011080A - 0x100000000), /// /// The partition(s) specified are not valid. /// COMADMIN_E_INVALID_PARTITION = (int)(0x8011080B - 0x100000000), /// /// COM+ applications that run as NT service may not be pooled or recycled /// COMADMIN_E_SVCAPP_NOT_POOLABLE_OR_RECYCLABLE = (int)(0x8011080D - 0x100000000), /// /// One or more users are already assigned to a local partition set. /// COMADMIN_E_USER_IN_SET = (int)(0x8011080E - 0x100000000), /// /// Library applications may not be recycled. /// COMADMIN_E_CANTRECYCLELIBRARYAPPS = (int)(0x8011080F - 0x100000000), /// /// Applications running as NT services may not be recycled. /// COMADMIN_E_CANTRECYCLESERVICEAPPS = (int)(0x80110811 - 0x100000000), /// /// The process has already been recycled. /// COMADMIN_E_PROCESSALREADYRECYCLED = (int)(0x80110812 - 0x100000000), /// /// A paused process may not be recycled. /// COMADMIN_E_PAUSEDPROCESSMAYNOTBERECYCLED = (int)(0x80110813 - 0x100000000), /// /// Library applications may not be NT services. /// COMADMIN_E_CANTMAKEINPROCSERVICE = (int)(0x80110814 - 0x100000000), /// /// The ProgID provided to the copy operation is invalid. The ProgID is in use by another registered CLSID. /// COMADMIN_E_PROGIDINUSEBYCLSID = (int)(0x80110815 - 0x100000000), /// /// The partition specified as default is not a member of the partition set. /// COMADMIN_E_DEFAULT_PARTITION_NOT_IN_SET = (int)(0x80110816 - 0x100000000), /// /// A recycled process may not be paused. /// COMADMIN_E_RECYCLEDPROCESSMAYNOTBEPAUSED = (int)(0x80110817 - 0x100000000), /// /// Access to the specified partition is denied. /// COMADMIN_E_PARTITION_ACCESSDENIED = (int)(0x80110818 - 0x100000000), /// /// Only Application Files (*.MSI files) can be installed into partitions. /// COMADMIN_E_PARTITION_MSI_ONLY = (int)(0x80110819 - 0x100000000), /// /// Applications containing one or more legacy components may not be exported to 1.0 format. /// COMADMIN_E_LEGACYCOMPS_NOT_ALLOWED_IN_1_0_FORMAT = (int)(0x8011081A - 0x100000000), /// /// Legacy components may not exist in non-base partitions. /// COMADMIN_E_LEGACYCOMPS_NOT_ALLOWED_IN_NONBASE_PARTITIONS = (int)(0x8011081B - 0x100000000), /// /// A component cannot be moved (or copied) from the System Application, an application proxy or a non-changeable application /// COMADMIN_E_COMP_MOVE_SOURCE = (int)(0x8011081C - 0x100000000), /// /// A component cannot be moved (or copied) to the System Application, an application proxy or a non-changeable application /// COMADMIN_E_COMP_MOVE_DEST = (int)(0x8011081D - 0x100000000), /// /// A private component cannot be moved (or copied) to a library application or to the base partition /// COMADMIN_E_COMP_MOVE_PRIVATE = (int)(0x8011081E - 0x100000000), /// /// The Base Application Partition exists in all partition sets and cannot be removed. /// COMADMIN_E_BASEPARTITION_REQUIRED_IN_SET = (int)(0x8011081F - 0x100000000), /// /// Alas, Event Class components cannot be aliased. /// COMADMIN_E_CANNOT_ALIAS_EVENTCLASS = (int)(0x80110820 - 0x100000000), /// /// Access is denied because the component is private. /// COMADMIN_E_PRIVATE_ACCESSDENIED = (int)(0x80110821 - 0x100000000), /// /// The specified SAFER level is invalid. /// COMADMIN_E_SAFERINVALID = (int)(0x80110822 - 0x100000000), /// /// The specified user cannot write to the system registry /// COMADMIN_E_REGISTRY_ACCESSDENIED = (int)(0x80110823 - 0x100000000), /// /// No information avialable. /// COMADMIN_E_PARTITIONS_DISABLED = (int)(0x80110824 - 0x100000000), /// /// Failed to open a file. /// NS_E_FILE_OPEN_FAILED = (int)(0xC00D001DL - 0x100000000), } } /******************************************************************************/ /* END OF FILE */ /******************************************************************************/ ================================================ FILE: source/HelperTools/ResultWin32Extensions.cs ================================================ using System; using System.IO; using System.Runtime.InteropServices; using System.Text; namespace Microsoft.Win32.Interop { internal static class ResultWin32Extensions { /// /// Converts a ResultWin32 error code to an appropriate .Net Exception. /// /// The ResultWin32 error code to convert. /// An optional message to append to the exception message. /// Whether to include the system message for the error code, if any. /// An Exception corresponding to the specified error code. public static Exception ToException(this ResultWin32 errorCode, string additionalMessage = null, bool getSystemMessage = true) { var message = errorCode.ToString(); if (getSystemMessage) { var systemMessage = GetSystemMessage(errorCode); if (!string.IsNullOrWhiteSpace(systemMessage)) message += " | " + systemMessage; } if (!string.IsNullOrWhiteSpace(additionalMessage)) message += " | " + additionalMessage; switch (errorCode) { case ResultWin32.ERROR_BAD_ENVIRONMENT: case ResultWin32.ERROR_INVALID_FUNCTION: return new InvalidOperationException(message); case ResultWin32.ERROR_INVALID_DATA: return new InvalidDataException(message); case ResultWin32.ERROR_ACCESS_DENIED: case ResultWin32.ERROR_NETWORK_ACCESS_DENIED: return new UnauthorizedAccessException(); case ResultWin32.ERROR_FILE_NOT_FOUND: case ResultWin32.ERROR_PATH_NOT_FOUND: return new FileNotFoundException(message); case ResultWin32.ERROR_NOT_ENOUGH_MEMORY: case ResultWin32.ERROR_NOT_ENOUGH_SERVER_MEMORY: return new InsufficientMemoryException(message); case ResultWin32.ERROR_INVALID_PARAMETER: case ResultWin32.ERROR_DIRECTORY: case ResultWin32.ERROR_UNKNOWN_PROPERTY: case ResultWin32.ERROR_UNKNOWN_PRODUCT: case ResultWin32.ERROR_UNKNOWN_FEATURE: case ResultWin32.ERROR_UNKNOWN_COMPONENT: return new ArgumentException(message); case ResultWin32.ERROR_INSTALL_USEREXIT: return new OperationCanceledException(message); case ResultWin32.ERROR_CALL_NOT_IMPLEMENTED: return new NotImplementedException(message); case ResultWin32.WAIT_TIMEOUT: case ResultWin32.ERROR_SEM_TIMEOUT: return new TimeoutException(message); default: return new IOException(message, (int)errorCode); } } [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "FormatMessageW")] private static extern uint FormatMessage(uint dwFlags, IntPtr lpSource, uint dwMessageId, uint dwLanguageId, StringBuilder lpBuffer, uint nSize, IntPtr arguments); /// /// Retrieves the system error message associated with the specified Win32 error code, if any. /// /// The Win32 error code for which to obtain the system message. /// The corresponding system error message, or null if no message is found. public static string GetSystemMessage(this ResultWin32 errorCode) { const uint FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200; const uint FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000; var buf = new StringBuilder(1024); var formatCount = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, IntPtr.Zero, (uint)errorCode, 0, buf, (uint)buf.Capacity, IntPtr.Zero); return formatCount != 0 ? buf.ToString().Trim() : null; } /// /// Determines whether the specified ResultCom value represents an error code. /// /// The ResultCom value to evaluate. /// true if the value represents an error; otherwise, false. public static bool IsError(this ResultCom comCode) => (int)comCode < 0; /// /// Determines whether the specified ResultCom value represents a success code. /// /// The ResultCom value to evaluate. /// true if the value is greater than or equal to zero; otherwise, false. public static bool IsSuccess(this ResultCom comCode) => (int)comCode >= 0; } } ================================================ FILE: source/KlocTools/Collections/ObservedList.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections; using System.Collections.Generic; using System.Linq; namespace Klocman.Collections { /// /// Generic list with an ListChanged event that fires whenever items get added or removed (not modified). /// //[Serializable] public class ObservedList : IList { private readonly List _itemList = new(); public virtual int Count => _itemList.Count; public virtual bool IsReadOnly => false; public virtual T this[int index] { get { return _itemList[index]; } set { _itemList[index] = value; } } public virtual void Add(T item) { OnListChangedEvent(); _itemList.Add(item); } public virtual void Clear() { OnListChangedEvent(); _itemList.Clear(); } public virtual bool Contains(T item) { return _itemList.Contains(item); } public virtual void CopyTo(T[] array, int arrayIndex) { _itemList.CopyTo(array, arrayIndex); } public virtual IEnumerator GetEnumerator() { return _itemList.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public virtual int IndexOf(T item) { return _itemList.IndexOf(item); } public virtual void Insert(int index, T item) { OnListChangedEvent(); _itemList.Insert(index, item); } public virtual bool Remove(T item) { OnListChangedEvent(); return _itemList.Remove(item); } public virtual void RemoveAt(int index) { OnListChangedEvent(); _itemList.RemoveAt(index); } public event Action ListChanged; public void AddRange(IEnumerable items) { var enumerable = items as IList ?? items.ToList(); if (!enumerable.Any()) return; foreach (var item in enumerable) _itemList.Add(item); try { OnListChangedEvent(); } catch (Exception) { // ignored } } /// A delegate callback throws an exception. public void OnListChangedEvent() { var handler = ListChanged; handler?.Invoke(); } } } ================================================ FILE: source/KlocTools/Controls/CommandLink.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.ComponentModel; using System.Drawing; using System.Runtime.InteropServices; using System.Text; using System.Windows.Forms; namespace Klocman.Controls { public sealed class CommandLink : Button { private const uint BCM_GETNOTE = 0x0000160A; private const uint BCM_GETNOTELENGTH = 0x0000160B; private const uint BCM_SETNOTE = 0x00001609; private const uint BCM_SETSHIELD = 0x0000160C; private const int BS_COMMANDLINK = 0x0000000E; private bool _shield; public CommandLink() { base.FlatStyle = FlatStyle.System; } // Prevent FlatStyle from changing public new FlatStyle FlatStyle => base.FlatStyle; protected override Size DefaultSize => new(180, 60); [Category("Command Link"), Description("Gets or sets the note text of the command link."), DefaultValue("")] public string Note { get { return GetNoteText(); } set { SetNoteText(value); } } [Category("Command Link"), Description("Gets or sets the shield icon visibility of the command link."), DefaultValue(false)] public bool Shield { get { return _shield; } set { _shield = value; SendMessage(new HandleRef(this, Handle), BCM_SETSHIELD, IntPtr.Zero, _shield); } } protected override CreateParams CreateParams { get { var cParams = base.CreateParams; cParams.Style |= BS_COMMANDLINK; return cParams; } } [DllImport("user32.dll", CharSet = CharSet.Unicode)] private static extern int SendMessage(HandleRef hWnd, uint Msg, ref int wParam, StringBuilder lParam); [DllImport("user32.dll", CharSet = CharSet.Unicode)] private static extern int SendMessage(HandleRef hWnd, uint Msg, IntPtr wParam, string lParam); [DllImport("user32.dll", CharSet = CharSet.Unicode)] private static extern int SendMessage(HandleRef hWnd, uint Msg, IntPtr wParam, bool lParam); [DllImport("user32.dll", CharSet = CharSet.Unicode)] private static extern int SendMessage(HandleRef hWnd, uint Msg, IntPtr wParam, IntPtr lParam); private string GetNoteText() { var length = SendMessage(new HandleRef(this, Handle), BCM_GETNOTELENGTH, IntPtr.Zero, IntPtr.Zero) + 1; var sb = new StringBuilder(length); SendMessage(new HandleRef(this, Handle), BCM_GETNOTE, ref length, sb); return sb.ToString(); } private void SetNoteText(string value) { SendMessage(new HandleRef(this, Handle), BCM_SETNOTE, IntPtr.Zero, value); } } } ================================================ FILE: source/KlocTools/Controls/ContentAlignmentBox.Designer.cs ================================================ namespace Klocman.Controls { partial class ContentAlignmentBox { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Component Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel(); this.checkBox9 = new System.Windows.Forms.CheckBox(); this.checkBox8 = new System.Windows.Forms.CheckBox(); this.checkBox7 = new System.Windows.Forms.CheckBox(); this.checkBox6 = new System.Windows.Forms.CheckBox(); this.checkBox5 = new System.Windows.Forms.CheckBox(); this.checkBox4 = new System.Windows.Forms.CheckBox(); this.checkBox3 = new System.Windows.Forms.CheckBox(); this.checkBox2 = new System.Windows.Forms.CheckBox(); this.checkBox1 = new System.Windows.Forms.CheckBox(); this.tableLayoutPanel2.SuspendLayout(); this.SuspendLayout(); // // tableLayoutPanel2 // this.tableLayoutPanel2.ColumnCount = 3; this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333F)); this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333F)); this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333F)); this.tableLayoutPanel2.Controls.Add(this.checkBox9, 2, 2); this.tableLayoutPanel2.Controls.Add(this.checkBox8, 1, 2); this.tableLayoutPanel2.Controls.Add(this.checkBox7, 0, 2); this.tableLayoutPanel2.Controls.Add(this.checkBox6, 2, 1); this.tableLayoutPanel2.Controls.Add(this.checkBox5, 1, 1); this.tableLayoutPanel2.Controls.Add(this.checkBox4, 0, 1); this.tableLayoutPanel2.Controls.Add(this.checkBox3, 2, 0); this.tableLayoutPanel2.Controls.Add(this.checkBox2, 1, 0); this.tableLayoutPanel2.Controls.Add(this.checkBox1, 0, 0); this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill; this.tableLayoutPanel2.Location = new System.Drawing.Point(0, 0); this.tableLayoutPanel2.Name = "tableLayoutPanel2"; this.tableLayoutPanel2.RowCount = 3; this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 33.33333F)); this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 33.33333F)); this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 33.33333F)); this.tableLayoutPanel2.Size = new System.Drawing.Size(78, 78); this.tableLayoutPanel2.TabIndex = 0; // // checkBox9 // this.checkBox9.AutoSize = true; this.checkBox9.Dock = System.Windows.Forms.DockStyle.Fill; this.checkBox9.Location = new System.Drawing.Point(55, 55); this.checkBox9.Name = "checkBox9"; this.checkBox9.Padding = new System.Windows.Forms.Padding(4); this.checkBox9.Size = new System.Drawing.Size(20, 20); this.checkBox9.TabIndex = 8; this.checkBox9.UseVisualStyleBackColor = true; this.checkBox9.CheckedChanged += new System.EventHandler(this.CheckedChanged); // // checkBox8 // this.checkBox8.AutoSize = true; this.checkBox8.Dock = System.Windows.Forms.DockStyle.Fill; this.checkBox8.Location = new System.Drawing.Point(29, 55); this.checkBox8.Name = "checkBox8"; this.checkBox8.Padding = new System.Windows.Forms.Padding(4); this.checkBox8.Size = new System.Drawing.Size(20, 20); this.checkBox8.TabIndex = 7; this.checkBox8.UseVisualStyleBackColor = true; this.checkBox8.CheckedChanged += new System.EventHandler(this.CheckedChanged); // // checkBox7 // this.checkBox7.AutoSize = true; this.checkBox7.Dock = System.Windows.Forms.DockStyle.Fill; this.checkBox7.Location = new System.Drawing.Point(3, 55); this.checkBox7.Name = "checkBox7"; this.checkBox7.Padding = new System.Windows.Forms.Padding(4); this.checkBox7.Size = new System.Drawing.Size(20, 20); this.checkBox7.TabIndex = 6; this.checkBox7.UseVisualStyleBackColor = true; this.checkBox7.CheckedChanged += new System.EventHandler(this.CheckedChanged); // // checkBox6 // this.checkBox6.AutoSize = true; this.checkBox6.Dock = System.Windows.Forms.DockStyle.Fill; this.checkBox6.Location = new System.Drawing.Point(55, 29); this.checkBox6.Name = "checkBox6"; this.checkBox6.Padding = new System.Windows.Forms.Padding(4); this.checkBox6.Size = new System.Drawing.Size(20, 20); this.checkBox6.TabIndex = 5; this.checkBox6.UseVisualStyleBackColor = true; this.checkBox6.CheckedChanged += new System.EventHandler(this.CheckedChanged); // // checkBox5 // this.checkBox5.AutoSize = true; this.checkBox5.Checked = true; this.checkBox5.CheckState = System.Windows.Forms.CheckState.Checked; this.checkBox5.Dock = System.Windows.Forms.DockStyle.Fill; this.checkBox5.Location = new System.Drawing.Point(29, 29); this.checkBox5.Name = "checkBox5"; this.checkBox5.Padding = new System.Windows.Forms.Padding(4); this.checkBox5.Size = new System.Drawing.Size(20, 20); this.checkBox5.TabIndex = 4; this.checkBox5.UseVisualStyleBackColor = true; this.checkBox5.CheckedChanged += new System.EventHandler(this.CheckedChanged); // // checkBox4 // this.checkBox4.AutoSize = true; this.checkBox4.Dock = System.Windows.Forms.DockStyle.Fill; this.checkBox4.Location = new System.Drawing.Point(3, 29); this.checkBox4.Name = "checkBox4"; this.checkBox4.Padding = new System.Windows.Forms.Padding(4); this.checkBox4.Size = new System.Drawing.Size(20, 20); this.checkBox4.TabIndex = 3; this.checkBox4.UseVisualStyleBackColor = true; this.checkBox4.CheckedChanged += new System.EventHandler(this.CheckedChanged); // // checkBox3 // this.checkBox3.AutoSize = true; this.checkBox3.Dock = System.Windows.Forms.DockStyle.Fill; this.checkBox3.Location = new System.Drawing.Point(55, 3); this.checkBox3.Name = "checkBox3"; this.checkBox3.Padding = new System.Windows.Forms.Padding(4); this.checkBox3.Size = new System.Drawing.Size(20, 20); this.checkBox3.TabIndex = 2; this.checkBox3.UseVisualStyleBackColor = true; this.checkBox3.CheckedChanged += new System.EventHandler(this.CheckedChanged); // // checkBox2 // this.checkBox2.AutoSize = true; this.checkBox2.Dock = System.Windows.Forms.DockStyle.Fill; this.checkBox2.Location = new System.Drawing.Point(29, 3); this.checkBox2.Name = "checkBox2"; this.checkBox2.Padding = new System.Windows.Forms.Padding(4); this.checkBox2.Size = new System.Drawing.Size(20, 20); this.checkBox2.TabIndex = 1; this.checkBox2.UseVisualStyleBackColor = true; this.checkBox2.CheckedChanged += new System.EventHandler(this.CheckedChanged); // // checkBox1 // this.checkBox1.AutoSize = true; this.checkBox1.Dock = System.Windows.Forms.DockStyle.Fill; this.checkBox1.Location = new System.Drawing.Point(3, 3); this.checkBox1.Name = "checkBox1"; this.checkBox1.Padding = new System.Windows.Forms.Padding(4); this.checkBox1.Size = new System.Drawing.Size(20, 20); this.checkBox1.TabIndex = 0; this.checkBox1.UseVisualStyleBackColor = true; this.checkBox1.CheckedChanged += new System.EventHandler(this.CheckedChanged); // // ContentAlignmentBox // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.Controls.Add(this.tableLayoutPanel2); this.MaximumSize = new System.Drawing.Size(78, 78); this.MinimumSize = new System.Drawing.Size(78, 78); this.Name = "ContentAlignmentBox"; this.Size = new System.Drawing.Size(78, 78); this.tableLayoutPanel2.ResumeLayout(false); this.tableLayoutPanel2.PerformLayout(); this.ResumeLayout(false); } #endregion private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2; private System.Windows.Forms.CheckBox checkBox9; private System.Windows.Forms.CheckBox checkBox8; private System.Windows.Forms.CheckBox checkBox7; private System.Windows.Forms.CheckBox checkBox6; private System.Windows.Forms.CheckBox checkBox5; private System.Windows.Forms.CheckBox checkBox4; private System.Windows.Forms.CheckBox checkBox3; private System.Windows.Forms.CheckBox checkBox2; private System.Windows.Forms.CheckBox checkBox1; } } ================================================ FILE: source/KlocTools/Controls/ContentAlignmentBox.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Linq; using System.Windows.Forms; namespace Klocman.Controls { public partial class ContentAlignmentBox : UserControl { private readonly IEnumerable _checkBoxes; private readonly object _lock = new(); private bool _suppress; public ContentAlignmentBox() { InitializeComponent(); _checkBoxes = tableLayoutPanel2.Controls.Cast().OfType(); } [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public ContentAlignment SelectedContentAlignment { get { lock (_lock) { var box = _checkBoxes.Single(x => x.Checked); if (box == checkBox1) return ContentAlignment.TopLeft; if (box == checkBox2) return ContentAlignment.TopCenter; if (box == checkBox3) return ContentAlignment.TopRight; if (box == checkBox4) return ContentAlignment.MiddleLeft; if (box == checkBox5) return ContentAlignment.MiddleCenter; if (box == checkBox6) return ContentAlignment.MiddleRight; if (box == checkBox7) return ContentAlignment.BottomLeft; if (box == checkBox8) return ContentAlignment.BottomCenter; if (box == checkBox9) return ContentAlignment.BottomRight; throw new InvalidOperationException(); } } set { lock (_lock) { switch (value) { case ContentAlignment.TopLeft: checkBox1.Checked = true; break; case ContentAlignment.TopCenter: checkBox2.Checked = true; break; case ContentAlignment.TopRight: checkBox3.Checked = true; break; case ContentAlignment.MiddleLeft: checkBox4.Checked = true; break; case ContentAlignment.MiddleCenter: checkBox5.Checked = true; break; case ContentAlignment.MiddleRight: checkBox6.Checked = true; break; case ContentAlignment.BottomLeft: checkBox7.Checked = true; break; case ContentAlignment.BottomCenter: checkBox8.Checked = true; break; case ContentAlignment.BottomRight: checkBox9.Checked = true; break; default: throw new InvalidEnumArgumentException(); } } } } public event EventHandler SelectedContentAlignmentChanged; private void CheckedChanged(object sender, EventArgs e) { lock (_lock) { if (_suppress) return; _suppress = true; var box = (CheckBox) sender; var changed = true; if (box.Checked) { foreach (var checkedBox in _checkBoxes.Where(x => x != box)) { checkedBox.Checked = false; } } else if (_checkBoxes.All(x => !x.Checked)) { box.Checked = true; changed = false; } _suppress = false; if (changed) SelectedContentAlignmentChanged?.Invoke(sender, e); } } } } ================================================ FILE: source/KlocTools/Controls/ContentAlignmentBox.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ================================================ FILE: source/KlocTools/Controls/DirectorySelectBox.Designer.cs ================================================ using System.ComponentModel; using System.Windows.Forms; namespace Klocman.Controls { partial class DirectorySelectBox { /// /// Required designer variable. /// private IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Component Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { ComponentResourceManager resources = new ComponentResourceManager(typeof(DirectorySelectBox)); textBox1 = new TextBox(); button1 = new Button(); folderBrowserDialog = new FolderBrowserDialog(); panel1 = new Panel(); panel1.SuspendLayout(); SuspendLayout(); // // textBox1 // textBox1.AllowDrop = true; resources.ApplyResources(textBox1, "textBox1"); textBox1.Name = "textBox1"; textBox1.DragDrop += OnDragDrop; textBox1.DragEnter += OnDragEnter; textBox1.Validating += textBox1_Validating; // // button1 // button1.AllowDrop = true; resources.ApplyResources(button1, "button1"); button1.Name = "button1"; button1.UseVisualStyleBackColor = true; button1.Click += button1_Click; button1.DragDrop += OnDragDrop; button1.DragEnter += OnDragEnter; // // panel1 // panel1.Controls.Add(textBox1); resources.ApplyResources(panel1, "panel1"); panel1.Name = "panel1"; // // DirectorySelectBox // resources.ApplyResources(this, "$this"); AutoScaleMode = AutoScaleMode.Font; Controls.Add(panel1); Controls.Add(button1); Name = "DirectorySelectBox"; panel1.ResumeLayout(false); panel1.PerformLayout(); ResumeLayout(false); PerformLayout(); } #endregion private TextBox textBox1; private Button button1; private FolderBrowserDialog folderBrowserDialog; private Panel panel1; } } ================================================ FILE: source/KlocTools/Controls/DirectorySelectBox.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.ComponentModel; using System.IO; using System.Linq; using System.Text.RegularExpressions; using System.Windows.Forms; namespace Klocman.Controls { /// /// Path selection box with validation and filtering of the supplied path. /// Browsing to find desired file is possible with a dedicated button. /// public sealed partial class DirectorySelectBox : UserControl { #region Fields private readonly Regex _r; #endregion Fields #region Constructors public DirectorySelectBox() { InitializeComponent(); var regexSearch = new string(Path.GetInvalidPathChars()); _r = new Regex(string.Format("[{0}]", Regex.Escape(regexSearch))); } #endregion Constructors #region Properties [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public string DirectoryPath { get { return textBox1.Text; } set { if (textBox1.Text != value) { textBox1.Text = value; OnDirectoryPathChanged(); } } } #endregion Properties #region Events public event EventHandler DirectoryPathChanged; #endregion Events #region Methods private void button1_Click(object sender, EventArgs e) { folderBrowserDialog.ShowDialog(); DirectoryPath = folderBrowserDialog.SelectedPath; } private void OnDirectoryPathChanged() { DirectoryPathChanged?.Invoke(this, EventArgs.Empty); } private void textBox1_Validating(object sender, CancelEventArgs e) { DirectoryPath = _r.Replace(DirectoryPath, string.Empty); OnDirectoryPathChanged(); } #endregion Methods private void OnDragDrop(object sender, DragEventArgs e) { if (e.Data.GetDataPresent(DataFormats.FileDrop)) e.Effect = DragDropEffects.Link; } private void OnDragEnter(object sender, DragEventArgs e) { string[] files = (string[])e.Data.GetData(DataFormats.FileDrop); var dir = files.FirstOrDefault(Directory.Exists); if (!string.IsNullOrEmpty(dir)) DirectoryPath = dir; } } } ================================================ FILE: source/KlocTools/Controls/DirectorySelectBox.cs.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Procházet ... ================================================ FILE: source/KlocTools/Controls/DirectorySelectBox.de.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 blättern ================================================ FILE: source/KlocTools/Controls/DirectorySelectBox.es.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Explorar... ================================================ FILE: source/KlocTools/Controls/DirectorySelectBox.fr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Parcourir... ================================================ FILE: source/KlocTools/Controls/DirectorySelectBox.hu.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Böngészés... ================================================ FILE: source/KlocTools/Controls/DirectorySelectBox.it.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Sfoglia... ================================================ FILE: source/KlocTools/Controls/DirectorySelectBox.ja.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 参照... ================================================ FILE: source/KlocTools/Controls/DirectorySelectBox.nl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Bladeren... ================================================ FILE: source/KlocTools/Controls/DirectorySelectBox.pl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Przeglądaj... ================================================ FILE: source/KlocTools/Controls/DirectorySelectBox.pt-BR.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Procurar... ================================================ FILE: source/KlocTools/Controls/DirectorySelectBox.pt.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Procurar... ================================================ FILE: source/KlocTools/Controls/DirectorySelectBox.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Fill 1, 1 4, 3, 4, 3 257, 23 0 textBox1 System.Windows.Forms.TextBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel1 0 True Right 267, 0 4, 3, 4, 3 88, 25 1 Browse... button1 System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 1 17, 17 Fill 0, 0 4, 3, 4, 3 1, 1, 9, 1 267, 25 2 panel1 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 0 True 7, 15 4, 3, 4, 3 116667, 25 12, 25 355, 25 folderBrowserDialog System.Windows.Forms.FolderBrowserDialog, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 DirectorySelectBox System.Windows.Forms.UserControl, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 ================================================ FILE: source/KlocTools/Controls/DirectorySelectBox.ru.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Обзор... ================================================ FILE: source/KlocTools/Controls/DirectorySelectBox.sl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Prebrskaj... ================================================ FILE: source/KlocTools/Controls/DirectorySelectBox.sv.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Bläddra... ================================================ FILE: source/KlocTools/Controls/DirectorySelectBox.tr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Göz at... ================================================ FILE: source/KlocTools/Controls/DirectorySelectBox.vi.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Duyệt qua... ================================================ FILE: source/KlocTools/Controls/DirectorySelectBox.zh-Hans.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 浏览... ================================================ FILE: source/KlocTools/Controls/DirectorySelectBox.zh-Hant.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 瀏覽... ================================================ FILE: source/KlocTools/Controls/EditableCheckedListView.Designer.cs ================================================ using System.ComponentModel; using System.Windows.Forms; namespace Klocman.Controls { partial class EditableCheckedListView { /// /// Required designer variable. /// private IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Component Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.groupBox1 = new System.Windows.Forms.GroupBox(); this.checkedListBox1 = new System.Windows.Forms.CheckedListBox(); this.buttonUpdate = new System.Windows.Forms.Button(); this.buttonRemove = new System.Windows.Forms.Button(); this.buttonAdd = new System.Windows.Forms.Button(); this.groupBox1.SuspendLayout(); this.SuspendLayout(); // // groupBox1 // this.groupBox1.Controls.Add(this.checkedListBox1); this.groupBox1.Controls.Add(this.buttonUpdate); this.groupBox1.Controls.Add(this.buttonRemove); this.groupBox1.Controls.Add(this.buttonAdd); this.groupBox1.Dock = System.Windows.Forms.DockStyle.Fill; this.groupBox1.Location = new System.Drawing.Point(0, 0); this.groupBox1.Name = "groupBox1"; this.groupBox1.Size = new System.Drawing.Size(330, 277); this.groupBox1.TabIndex = 0; this.groupBox1.TabStop = false; // // checkedListBox1 // this.checkedListBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.checkedListBox1.CheckOnClick = true; this.checkedListBox1.FormattingEnabled = true; this.checkedListBox1.IntegralHeight = false; this.checkedListBox1.Location = new System.Drawing.Point(7, 49); this.checkedListBox1.Name = "checkedListBox1"; this.checkedListBox1.Size = new System.Drawing.Size(317, 222); this.checkedListBox1.Sorted = true; this.checkedListBox1.TabIndex = 3; this.checkedListBox1.ItemCheck += new System.Windows.Forms.ItemCheckEventHandler(this.checkedListBox1_ItemCheck); // // buttonUpdate // this.buttonUpdate.Location = new System.Drawing.Point(72, 19); this.buttonUpdate.Name = "buttonUpdate"; this.buttonUpdate.Size = new System.Drawing.Size(60, 23); this.buttonUpdate.TabIndex = 1; this.buttonUpdate.Text = "Update"; this.buttonUpdate.UseVisualStyleBackColor = true; this.buttonUpdate.Click += new System.EventHandler(this.buttonUpdate_Click); // // buttonRemove // this.buttonRemove.Location = new System.Drawing.Point(138, 19); this.buttonRemove.Name = "buttonRemove"; this.buttonRemove.Size = new System.Drawing.Size(60, 23); this.buttonRemove.TabIndex = 2; this.buttonRemove.Text = "Remove"; this.buttonRemove.UseVisualStyleBackColor = true; this.buttonRemove.Click += new System.EventHandler(this.buttonRemove_Click); // // buttonAdd // this.buttonAdd.Location = new System.Drawing.Point(6, 19); this.buttonAdd.Name = "buttonAdd"; this.buttonAdd.Size = new System.Drawing.Size(60, 23); this.buttonAdd.TabIndex = 0; this.buttonAdd.Text = "Add"; this.buttonAdd.UseVisualStyleBackColor = true; this.buttonAdd.Click += new System.EventHandler(this.buttonAdd_Click); // // EditableCheckedListView // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.Controls.Add(this.groupBox1); this.Name = "EditableCheckedListView"; this.Size = new System.Drawing.Size(330, 277); this.groupBox1.ResumeLayout(false); this.ResumeLayout(false); } #endregion private GroupBox groupBox1; private Button buttonUpdate; private Button buttonRemove; private Button buttonAdd; private CheckedListBox checkedListBox1; } } ================================================ FILE: source/KlocTools/Controls/EditableCheckedListView.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Windows.Forms; namespace Klocman.Controls { public partial class EditableCheckedListView : UserControl { #region Delegates public delegate string GetStringDelegate(string previous); #endregion Delegates #region Constructors public EditableCheckedListView() { InitializeComponent(); } #endregion Constructors #region Events public event Action ListViewChanged; #endregion Events #region Properties public IEnumerable CheckedItems { get { return checkedListBox1.CheckedItems.Cast(); } } public IEnumerable Items { get { return checkedListBox1.Items.Cast(); } } [Description("Sorting of the list box enabled/disabled"), Category("Behavior")] [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public bool ListBoxSorted { get { return checkedListBox1.Sorted; } set { checkedListBox1.Sorted = value; } } [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public GetStringDelegate StringGetter { get; set; } [Description("Text shown in the title of this control"), Category("Appearance")] [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public string Title { get { return groupBox1.Text; } set { groupBox1.Text = value; } } #endregion Properties #region Methods public void AddRange(object[] items, object[] checkedItems) { foreach (var item in items) { checkedListBox1.Items.Add(item, checkedItems.Contains(item)); } FireListViewChanged(); } private void buttonAdd_Click(object sender, EventArgs e) { var output = GetString(null); if (string.IsNullOrEmpty(output) || Items.Contains(output)) return; checkedListBox1.Items.Add(output, true); FireListViewChanged(); } private void buttonRemove_Click(object sender, EventArgs e) { if (checkedListBox1.SelectedItem != null) { checkedListBox1.Items.Remove(checkedListBox1.SelectedItem); FireListViewChanged(); } } private void buttonUpdate_Click(object sender, EventArgs e) { var output = GetString(checkedListBox1.SelectedItem as string); if (string.IsNullOrEmpty(output) || Items.Contains(output)) return; checkedListBox1.Items.Remove(checkedListBox1.SelectedItem); checkedListBox1.Items.Add(output); FireListViewChanged(); } private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e) { FireListViewChanged(); //TODO fires before change happens } private void FireListViewChanged() { if (ListViewChanged != null) ListViewChanged(this); } private string GetString(string previous) { if (StringGetter != null) return StringGetter(previous); return null; } #endregion Methods } } ================================================ FILE: source/KlocTools/Controls/EditableCheckedListView.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ================================================ FILE: source/KlocTools/Controls/EditableListView.Designer.cs ================================================ using System.ComponentModel; using System.Windows.Forms; namespace Klocman.Controls { partial class EditableListView { /// /// Required designer variable. /// private IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Component Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.groupBox1 = new System.Windows.Forms.GroupBox(); this.listBox = new System.Windows.Forms.ListBox(); this.buttonUpdate = new System.Windows.Forms.Button(); this.buttonRemove = new System.Windows.Forms.Button(); this.buttonAdd = new System.Windows.Forms.Button(); this.groupBox1.SuspendLayout(); this.SuspendLayout(); // // groupBox1 // this.groupBox1.Controls.Add(this.listBox); this.groupBox1.Controls.Add(this.buttonUpdate); this.groupBox1.Controls.Add(this.buttonRemove); this.groupBox1.Controls.Add(this.buttonAdd); this.groupBox1.Dock = System.Windows.Forms.DockStyle.Fill; this.groupBox1.Location = new System.Drawing.Point(0, 0); this.groupBox1.Name = "groupBox1"; this.groupBox1.Size = new System.Drawing.Size(330, 277); this.groupBox1.TabIndex = 9; this.groupBox1.TabStop = false; // // listBox // this.listBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.listBox.FormattingEnabled = true; this.listBox.HorizontalScrollbar = true; this.listBox.IntegralHeight = false; this.listBox.Location = new System.Drawing.Point(6, 48); this.listBox.Name = "listBox"; this.listBox.Size = new System.Drawing.Size(318, 223); this.listBox.TabIndex = 3; // // buttonUpdate // this.buttonUpdate.Location = new System.Drawing.Point(72, 19); this.buttonUpdate.Name = "buttonUpdate"; this.buttonUpdate.Size = new System.Drawing.Size(60, 23); this.buttonUpdate.TabIndex = 2; this.buttonUpdate.Text = "Update"; this.buttonUpdate.UseVisualStyleBackColor = true; this.buttonUpdate.Click += new System.EventHandler(this.buttonUpdate_Click); // // buttonRemove // this.buttonRemove.Location = new System.Drawing.Point(138, 19); this.buttonRemove.Name = "buttonRemove"; this.buttonRemove.Size = new System.Drawing.Size(60, 23); this.buttonRemove.TabIndex = 1; this.buttonRemove.Text = "Remove"; this.buttonRemove.UseVisualStyleBackColor = true; this.buttonRemove.Click += new System.EventHandler(this.buttonRemove_Click); // // buttonAdd // this.buttonAdd.Location = new System.Drawing.Point(6, 19); this.buttonAdd.Name = "buttonAdd"; this.buttonAdd.Size = new System.Drawing.Size(60, 23); this.buttonAdd.TabIndex = 0; this.buttonAdd.Text = "Add"; this.buttonAdd.UseVisualStyleBackColor = true; this.buttonAdd.Click += new System.EventHandler(this.buttonAdd_Click); // // EditableListView // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.Controls.Add(this.groupBox1); this.Name = "EditableListView"; this.Size = new System.Drawing.Size(330, 277); this.groupBox1.ResumeLayout(false); this.ResumeLayout(false); } #endregion private GroupBox groupBox1; private ListBox listBox; private Button buttonUpdate; private Button buttonRemove; private Button buttonAdd; } } ================================================ FILE: source/KlocTools/Controls/EditableListView.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Windows.Forms; namespace Klocman.Controls { public partial class EditableListView : UserControl { #region Delegates public delegate string GetStringDelegate(string previous); #endregion Delegates #region Constructors public EditableListView() { InitializeComponent(); } #endregion Constructors #region Events public event Action ListViewChanged; #endregion Events #region Properties public IEnumerable Items { get { return listBox.Items.Cast(); } } [Description("Sorting of the list box enabled/disabled"), Category("Behavior")] [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public bool ListBoxSorted { get { return listBox.Sorted; } set { listBox.Sorted = value; } } [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public GetStringDelegate StringGetter { get; set; } [Description("Text shown in the title of this control"), Category("Appearance")] [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public string Title { get { return groupBox1.Text; } set { groupBox1.Text = value; } } #endregion Properties #region Methods public void AddRange(object[] items) { listBox.Items.AddRange(items); FireListViewChanged(); } private void buttonAdd_Click(object sender, EventArgs e) { var output = GetString(null); if (string.IsNullOrEmpty(output) || Items.Contains(output)) return; listBox.Items.Add(output); FireListViewChanged(); } private void buttonRemove_Click(object sender, EventArgs e) { if (listBox.SelectedItem != null) { listBox.Items.Remove(listBox.SelectedItem); FireListViewChanged(); } } private void buttonUpdate_Click(object sender, EventArgs e) { var output = GetString(listBox.SelectedItem as string); if (string.IsNullOrEmpty(output) || Items.Contains(output)) return; listBox.Items.Remove(listBox.SelectedItem); listBox.Items.Add(output); FireListViewChanged(); } private void FireListViewChanged() { if (ListViewChanged != null) ListViewChanged(this); } private string GetString(string previous) { if (StringGetter != null) return StringGetter(previous); return null; } #endregion Methods } } ================================================ FILE: source/KlocTools/Controls/EditableListView.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ================================================ FILE: source/KlocTools/Controls/FacebookButton.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using Klocman.Forms.Tools; using System; using System.ComponentModel; using System.Drawing; using System.Windows.Forms; namespace Klocman.Controls { public sealed class FacebookButton : Button { public FacebookButton() { Text = string.Empty; BackgroundImage = Properties.Resources.facebookButton; BackgroundImageLayout = ImageLayout.Stretch; Size = new Size(23, 23); base.FlatStyle = FlatStyle.Standard; TabStop = false; Click += FacebookButton_Click; } public new FlatStyle FlatStyle => base.FlatStyle; [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public string TargetSite { get; set; } private void FacebookButton_Click(object sender, EventArgs e) { if (!string.IsNullOrEmpty(TargetSite)) { PremadeDialogs.StartProcessSafely(@"https://www.facebook.com/sharer/sharer.php?u=" + TargetSite); } else { throw new InvalidOperationException("TargetSite is null or empty"); } } } } ================================================ FILE: source/KlocTools/Controls/FacebookStatusButton.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.ComponentModel; using System.Windows.Forms; using Klocman.Forms.Tools; namespace Klocman.Controls { public sealed class FacebookStatusButton : ToolStripStatusLabel { public FacebookStatusButton() { Image = Properties.Resources.facebookButton; DisplayStyle = ToolStripItemDisplayStyle.Image; Click += FacebookStatusButton_Click; IsLink = true; Padding = new Padding(2, 0, 2, 0); } [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public string TargetSite { get; set; } private void FacebookStatusButton_Click(object sender, EventArgs e) { if (!string.IsNullOrEmpty(TargetSite)) { PremadeDialogs.StartProcessSafely(@"https://www.facebook.com/sharer/sharer.php?u=" + TargetSite); } else { throw new InvalidOperationException("TargetSite is null or empty"); } } } } ================================================ FILE: source/KlocTools/Controls/FixedFlowLayoutPanel.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System.Linq; using System.Windows.Forms; namespace Klocman.Controls { public sealed class FixedFlowLayoutPanel : FlowLayoutPanel { protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); if (AutoSize && Dock != DockStyle.None) { var newHeight = Controls.Cast().Sum(c => c.Height) + Padding.Top + Padding.Bottom; if (Height != newHeight) { Height = newHeight; } } } protected override void OnLayout(LayoutEventArgs levent) { base.OnLayout(levent); if (AutoSize && Dock != DockStyle.None) { var newHeight = Controls.Cast().Sum(c => c.Height) + Padding.Top + Padding.Bottom; if (Height != newHeight) { Height = newHeight; } } } private bool _autoSize; public override bool AutoSize { get { return _autoSize; } set { _autoSize = value; } } } } ================================================ FILE: source/KlocTools/Controls/LineSeparator.Designer.cs ================================================ using System.ComponentModel; namespace Klocman.Controls { sealed partial class LineSeparator { /// /// Required designer variable. /// private IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Component Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { components = new System.ComponentModel.Container(); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; } #endregion } } ================================================ FILE: source/KlocTools/Controls/LineSeparator.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System.Drawing; using System.Windows.Forms; namespace Klocman.Controls { public sealed partial class LineSeparator : UserControl { #region Constructors public LineSeparator() { InitializeComponent(); Paint += LineSeparator_Paint; MaximumSize = new Size(2000, 2); MinimumSize = new Size(0, 2); Width = 350; } #endregion Constructors #region Methods private void LineSeparator_Paint(object sender, PaintEventArgs e) { var g = e.Graphics; g.DrawLine(Pens.DarkGray, new Point(0, 0), new Point(Width, 0)); g.DrawLine(Pens.White, new Point(0, 1), new Point(Width, 1)); } #endregion Methods } } ================================================ FILE: source/KlocTools/Controls/LineSeparator.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ================================================ FILE: source/KlocTools/Controls/PassThroughLabel.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Windows.Forms; namespace Klocman.Controls { /// /// Label that doesn't capture any mouse events /// public sealed class PassThroughLabel : Label { #region Methods //Pass through mouse events protected override void WndProc(ref Message m) { const int WM_NCHITTEST = 0x0084; const int HTTRANSPARENT = (-1); if (m.Msg == WM_NCHITTEST) { m.Result = (IntPtr) HTTRANSPARENT; } else { base.WndProc(ref m); } } #endregion Methods } } ================================================ FILE: source/KlocTools/Controls/PathSelectBox.Designer.cs ================================================ using System.ComponentModel; using System.Windows.Forms; namespace Klocman.Controls { partial class PathSelectBox { /// /// Required designer variable. /// private IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Component Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { ComponentResourceManager resources = new ComponentResourceManager(typeof(PathSelectBox)); textBox1 = new TextBox(); button1 = new Button(); openFileDialog = new OpenFileDialog(); panel1 = new Panel(); panel1.SuspendLayout(); SuspendLayout(); // // textBox1 // textBox1.AllowDrop = true; resources.ApplyResources(textBox1, "textBox1"); textBox1.Name = "textBox1"; textBox1.TextChanged += textBox1_Changed; textBox1.DragDrop += OnDragDrop; textBox1.DragEnter += OnDragEnter; // // button1 // button1.AllowDrop = true; resources.ApplyResources(button1, "button1"); button1.Name = "button1"; button1.UseVisualStyleBackColor = true; button1.Click += button1_Click; button1.DragDrop += OnDragDrop; button1.DragEnter += OnDragEnter; // // openFileDialog // openFileDialog.FileOk += openFileDialog_FileOk; // // panel1 // panel1.Controls.Add(textBox1); resources.ApplyResources(panel1, "panel1"); panel1.Name = "panel1"; // // PathSelectBox // resources.ApplyResources(this, "$this"); AutoScaleMode = AutoScaleMode.Font; Controls.Add(panel1); Controls.Add(button1); Name = "PathSelectBox"; panel1.ResumeLayout(false); panel1.PerformLayout(); ResumeLayout(false); PerformLayout(); } #endregion private TextBox textBox1; private Button button1; private OpenFileDialog openFileDialog; private Panel panel1; } } ================================================ FILE: source/KlocTools/Controls/PathSelectBox.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.ComponentModel; using System.IO; using System.Linq; using System.Text.RegularExpressions; using System.Windows.Forms; namespace Klocman.Controls { /// /// Path selection box with validation and filtering of the supplied path. /// Browsing to find desired file is possible with a dedicated button. /// public sealed partial class PathSelectBox : UserControl { private readonly Regex _r; public PathSelectBox() { InitializeComponent(); var regexSearch = new string(Path.GetInvalidPathChars()); _r = new Regex($"[{Regex.Escape(regexSearch)}]"); } public event EventHandler FileNameChanged; [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public string FileName { get { return textBox1.Text; } set { if (textBox1.Text != value) { textBox1.Text = value; OnFileNameChanged(); } } } [Category("Behavior")] [DefaultValue("")] public string Filter { get { return openFileDialog.Filter; } set { openFileDialog.Filter = value; } } private void button1_Click(object sender, EventArgs e) { openFileDialog.ShowDialog(); } private void OnFileNameChanged() { FileNameChanged?.Invoke(this, EventArgs.Empty); } private void openFileDialog_FileOk(object sender, CancelEventArgs e) { textBox1.Text = openFileDialog.FileName; } private void textBox1_Changed(object sender, EventArgs e) { FileName = _r.Replace(FileName, string.Empty); OnFileNameChanged(); } private void OnDragDrop(object sender, DragEventArgs e) { if (e.Data.GetDataPresent(DataFormats.FileDrop)) e.Effect = DragDropEffects.Link; } private void OnDragEnter(object sender, DragEventArgs e) { string[] files = (string[])e.Data.GetData(DataFormats.FileDrop); var dir = files.FirstOrDefault(File.Exists); if (!string.IsNullOrEmpty(dir)) FileName = dir; } } } ================================================ FILE: source/KlocTools/Controls/PathSelectBox.cs.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Procházet ... ================================================ FILE: source/KlocTools/Controls/PathSelectBox.de.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 blättern ================================================ FILE: source/KlocTools/Controls/PathSelectBox.es.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Explorar... ================================================ FILE: source/KlocTools/Controls/PathSelectBox.fr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Parcourir... ================================================ FILE: source/KlocTools/Controls/PathSelectBox.hu.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Tallózás... ================================================ FILE: source/KlocTools/Controls/PathSelectBox.it.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Sfoglia... ================================================ FILE: source/KlocTools/Controls/PathSelectBox.ja.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 参照... ================================================ FILE: source/KlocTools/Controls/PathSelectBox.nl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Bladeren... ================================================ FILE: source/KlocTools/Controls/PathSelectBox.pl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Przeglądaj... ================================================ FILE: source/KlocTools/Controls/PathSelectBox.pt-BR.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Procurar... ================================================ FILE: source/KlocTools/Controls/PathSelectBox.pt.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Procurar... ================================================ FILE: source/KlocTools/Controls/PathSelectBox.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Fill 1, 1 4, 3, 4, 3 266, 23 0 textBox1 System.Windows.Forms.TextBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel1 0 True Right 276, 0 4, 3, 4, 3 88, 25 1 Browse... button1 System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 1 17, 17 Fill 0, 0 4, 3, 4, 3 1, 1, 9, 1 276, 25 2 panel1 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 0 True 7, 15 4, 3, 4, 3 116667, 25 12, 25 364, 25 openFileDialog System.Windows.Forms.OpenFileDialog, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 PathSelectBox System.Windows.Forms.UserControl, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 ================================================ FILE: source/KlocTools/Controls/PathSelectBox.ru.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Обзор... ================================================ FILE: source/KlocTools/Controls/PathSelectBox.sl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Prebrskaj... ================================================ FILE: source/KlocTools/Controls/PathSelectBox.sv.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Bläddra... ================================================ FILE: source/KlocTools/Controls/PathSelectBox.tr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Göz at... ================================================ FILE: source/KlocTools/Controls/PathSelectBox.vi.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Duyệt qua... ================================================ FILE: source/KlocTools/Controls/PathSelectBox.zh-Hans.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 浏览... ================================================ FILE: source/KlocTools/Controls/PathSelectBox.zh-Hant.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 瀏覽... ================================================ FILE: source/KlocTools/Controls/SearchBox.Designer.cs ================================================ using System.ComponentModel; using System.Windows.Forms; namespace Klocman.Controls { partial class SearchBox { /// /// Required designer variable. /// private IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Component Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { ComponentResourceManager resources = new ComponentResourceManager(typeof(SearchBox)); filteringTextBox = new TextBox(); SuspendLayout(); // // filteringTextBox // resources.ApplyResources(filteringTextBox, "filteringTextBox"); filteringTextBox.AutoCompleteMode = AutoCompleteMode.SuggestAppend; filteringTextBox.AutoCompleteSource = AutoCompleteSource.CustomSource; filteringTextBox.BackColor = System.Drawing.SystemColors.Window; filteringTextBox.ForeColor = System.Drawing.SystemColors.GrayText; filteringTextBox.Name = "filteringTextBox"; filteringTextBox.TextChanged += filteringTextBox_TextChanged; filteringTextBox.Enter += filteringTextBox_Enter; filteringTextBox.KeyDown += filteringTextBox_KeyDown; filteringTextBox.KeyUp += filteringTextBox_KeyUp; filteringTextBox.Leave += filteringTextBox_Leave; // // SearchBox // AutoScaleMode = AutoScaleMode.None; resources.ApplyResources(this, "$this"); Controls.Add(filteringTextBox); Name = "SearchBox"; ResumeLayout(false); PerformLayout(); } #endregion private TextBox filteringTextBox; } } ================================================ FILE: source/KlocTools/Controls/SearchBox.ar.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 بحث... ================================================ FILE: source/KlocTools/Controls/SearchBox.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.ComponentModel; using System.Drawing; using System.Windows.Forms; namespace Klocman.Controls { public partial class SearchBox : UserControl { [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public Color InactiveSearchColor { get { return _inactiveSearchColor; } set { _inactiveSearchColor = value; UpdateFieldColor(); } } private void UpdateFieldColor() { if (filteringTextBox == null) return; filteringTextBox.ForeColor = string.IsNullOrEmpty(SearchString) ? _inactiveSearchColor : _normalSearchColor; filteringTextBox.BackColor = base.BackColor; } [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public BorderStyle SearchBoxBorderStyle { get { return filteringTextBox.BorderStyle; } set { filteringTextBox.BorderStyle = value; } } [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public Color NormalSearchColor { get { return _normalSearchColor; } set { _normalSearchColor = value; UpdateFieldColor(); } } public override Color BackColor { get { return base.BackColor; } set { base.BackColor = value; UpdateFieldColor(); } } private static string _inactiveSearchText; private Color _inactiveSearchColor; private Color _normalSearchColor; public SearchBox() { InactiveSearchColor = SystemColors.GrayText; NormalSearchColor = SystemColors.WindowText; InitializeComponent(); _inactiveSearchText = filteringTextBox.Text; } [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public AutoCompleteStringCollection AutoCompleteCustomSource { get { return filteringTextBox.AutoCompleteCustomSource; } set { filteringTextBox.AutoCompleteCustomSource = value; } } [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [Browsable(false)] public string[] SearchParts { get { if (string.IsNullOrEmpty(filteringTextBox.Text) || filteringTextBox.Text.Equals(_inactiveSearchText)) return new string[] { }; return filteringTextBox.Text.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); } } [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [Browsable(false)] public string SearchString { get; private set; } = string.Empty; public event EventHandler FocusSearchTarget; public event EventHandler SearchTextChanged; public void ClearSearchBox() { filteringTextBox.Text = _inactiveSearchText; filteringTextBox.ForeColor = InactiveSearchColor; } private void filteringTextBox_Enter(object sender, EventArgs e) { FocusSearchBox(); } private void filteringTextBox_KeyDown(object sender, KeyEventArgs e) { // Stop the Ding noise switch (e.KeyCode) { case Keys.Escape: e.Handled = true; e.SuppressKeyPress = true; break; default: break; } } private void filteringTextBox_KeyUp(object sender, KeyEventArgs e) { e.Handled = true; e.SuppressKeyPress = true; switch (e.KeyCode) { case Keys.Escape: ClearSearchBox(); OnFocusSearchTarget(); break; default: e.Handled = false; e.SuppressKeyPress = false; break; } } private void filteringTextBox_Leave(object sender, EventArgs e) { if (string.IsNullOrEmpty(filteringTextBox.Text)) ClearSearchBox(); } private void filteringTextBox_TextChanged(object sender, EventArgs e) { var text = filteringTextBox.Text; if (_inactiveSearchText.Equals(text)) text = string.Empty; if (!text.Equals(SearchString)) { SearchString = text; OnSearchTextChanged(); } } public void FocusSearchBox() { filteringTextBox.Focus(); filteringTextBox.ForeColor = NormalSearchColor; if (_inactiveSearchText.Equals(filteringTextBox.Text)) filteringTextBox.Text = string.Empty; filteringTextBox.SelectAll(); } protected virtual void OnFocusSearchTarget() { if (FocusSearchTarget != null) FocusSearchTarget(this, EventArgs.Empty); else Parent.Focus(); } protected virtual void OnSearchTextChanged() { SearchTextChanged?.Invoke(this, new SearchEventArgs(this, SearchString)); } public void Search(string searchString) { if (string.IsNullOrEmpty(searchString) || searchString.Equals(_inactiveSearchText)) ClearSearchBox(); else { filteringTextBox.Text = searchString; filteringTextBox.ForeColor = NormalSearchColor; } } public sealed class SearchEventArgs : EventArgs { public SearchEventArgs(SearchBox origin, string searchText) { Origin = origin; SearchText = searchText; } public SearchBox Origin { get; } public string SearchText { get; } } } } ================================================ FILE: source/KlocTools/Controls/SearchBox.cs.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Hledat... True fr ================================================ FILE: source/KlocTools/Controls/SearchBox.de.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Suche... Suchfeld Suchfeld True fr ================================================ FILE: source/KlocTools/Controls/SearchBox.es.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Buscar... Cuadro de búsqueda Cuadro de búsqueda ================================================ FILE: source/KlocTools/Controls/SearchBox.fr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Chercher... Boîte de recherche Boîte de recherche ================================================ FILE: source/KlocTools/Controls/SearchBox.hu.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Keresés... Keresőmező Keresőmező ================================================ FILE: source/KlocTools/Controls/SearchBox.it.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Cerca... Box di ricerca Box di ricerca ================================================ FILE: source/KlocTools/Controls/SearchBox.ja.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 検索... 検索ボックス 検索ボックス ================================================ FILE: source/KlocTools/Controls/SearchBox.nl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Zoeken... Zoekvenster Zoekvenster ================================================ FILE: source/KlocTools/Controls/SearchBox.pl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Wyszukiwarka Wyszukiwarka Szukaj... ================================================ FILE: source/KlocTools/Controls/SearchBox.pt-BR.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Pesquisa... Caixa de pesquisa Caixa de pesquisa ================================================ FILE: source/KlocTools/Controls/SearchBox.pt.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Pesquisa... ================================================ FILE: source/KlocTools/Controls/SearchBox.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Search box Search box Top 0, 0 50, 23 3 Search... filteringTextBox System.Windows.Forms.TextBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 0 True True GrowAndShrink 50, 0 50, 23 SearchBox System.Windows.Forms.UserControl, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 ================================================ FILE: source/KlocTools/Controls/SearchBox.ru.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Поиск... Строка поиска Строка поиска True fr ================================================ FILE: source/KlocTools/Controls/SearchBox.sl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Poišči... True fr ================================================ FILE: source/KlocTools/Controls/SearchBox.sv.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Sök... Sökruta Sökruta ================================================ FILE: source/KlocTools/Controls/SearchBox.tr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Ara... Arama kutusu Arama kutusu ================================================ FILE: source/KlocTools/Controls/SearchBox.vi.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Tìm kiếm... Hộp tìm kiếm Hộp tìm kiếm ================================================ FILE: source/KlocTools/Controls/SearchBox.zh-Hans.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 搜索... 搜索框 搜索框 ================================================ FILE: source/KlocTools/Controls/SearchBox.zh-Hant.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 尋找... 搜尋欄 搜尋欄 ================================================ FILE: source/KlocTools/Controls/ToolStripNumberControl.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System.Windows.Forms; using System.Windows.Forms.Design; namespace Klocman.Controls { [ToolStripItemDesignerAvailability(ToolStripItemDesignerAvailability.ToolStrip)] public sealed class ToolStripNumberControl : ToolStripControlHost { #region Constructors public ToolStripNumberControl() : base(new NumericUpDown()) { } #endregion Constructors #region Properties public NumericUpDown NumericUpDownControl { get { return Control as NumericUpDown; } } #endregion Properties } } ================================================ FILE: source/KlocTools/Controls/TwitterButton.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.ComponentModel; using System.Drawing; using System.Windows.Forms; using Klocman.Forms.Tools; namespace Klocman.Controls { public sealed class TwitterButton : Button { public TwitterButton() { Text = string.Empty; BackgroundImage = Properties.Resources.twitterButton; BackgroundImageLayout = ImageLayout.Stretch; Size = new Size(23, 23); base.FlatStyle = FlatStyle.Standard; TabStop = false; Click += TwitterButton_Click; } public new FlatStyle FlatStyle => base.FlatStyle; /// /// Overwrite default message text. If set ignores TargetSite. /// [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public string MessageText { get; set; } [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public string TargetSite { get; set; } private void TwitterButton_Click(object sender, EventArgs e) { if (!string.IsNullOrEmpty(MessageText)) { PremadeDialogs.StartProcessSafely(@"https://twitter.com/intent/tweet?text=" + MessageText.Replace(' ', '+')); } else if (!string.IsNullOrEmpty(TargetSite)) { PremadeDialogs.StartProcessSafely(@"https://twitter.com/intent/tweet?text=" + "Check+out+this+cool+app+I+found!+" + TargetSite); } else { throw new InvalidOperationException("TargetSite and MessageText are both null or empty"); } } } } ================================================ FILE: source/KlocTools/Controls/TwitterStatusButton.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.ComponentModel; using System.Windows.Forms; using Klocman.Forms.Tools; namespace Klocman.Controls { public sealed class TwitterStatusButton : ToolStripStatusLabel { public TwitterStatusButton() { Image = Properties.Resources.twitterButton; DisplayStyle = ToolStripItemDisplayStyle.Image; Click += FacebookStatusButton_Click; IsLink = true; Padding = new Padding(2, 0, 2, 0); } /// /// Overwrite default message text. If set ignores TargetSite. /// [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public string MessageText { get; set; } [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public string TargetSite { get; set; } private void FacebookStatusButton_Click(object sender, EventArgs e) { if (!string.IsNullOrEmpty(MessageText)) { PremadeDialogs.StartProcessSafely(@"https://twitter.com/intent/tweet?text=" + MessageText.Replace(' ', '+')); } else if (!string.IsNullOrEmpty(TargetSite)) { PremadeDialogs.StartProcessSafely(@"https://twitter.com/intent/tweet?text=" + "Check+out+this+cool+app+I+found!+" + TargetSite); } else { throw new InvalidOperationException("TargetSite and MessageText are both null or empty"); } } } } ================================================ FILE: source/KlocTools/Controls/WindowTargeter.Designer.cs ================================================ namespace Klocman.Controls { partial class WindowTargeter { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Component Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(WindowTargeter)); label1 = new System.Windows.Forms.Label(); label2 = new System.Windows.Forms.Label(); label3 = new System.Windows.Forms.Label(); pictureBox1 = new System.Windows.Forms.PictureBox(); ((System.ComponentModel.ISupportInitialize)pictureBox1).BeginInit(); SuspendLayout(); // // label1 // label1.AutoEllipsis = true; resources.ApplyResources(label1, "label1"); label1.Name = "label1"; // // label2 // label2.AutoEllipsis = true; resources.ApplyResources(label2, "label2"); label2.Name = "label2"; // // label3 // label3.AutoEllipsis = true; resources.ApplyResources(label3, "label3"); label3.Name = "label3"; // // pictureBox1 // resources.ApplyResources(pictureBox1, "pictureBox1"); pictureBox1.Image = Properties.Resources.centerline; pictureBox1.Name = "pictureBox1"; pictureBox1.TabStop = false; // // WindowTargeter // resources.ApplyResources(this, "$this"); AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; Controls.Add(label3); Controls.Add(label2); Controls.Add(label1); Controls.Add(pictureBox1); Name = "WindowTargeter"; ((System.ComponentModel.ISupportInitialize)pictureBox1).EndInit(); ResumeLayout(false); } #endregion private System.Windows.Forms.PictureBox pictureBox1; private System.Windows.Forms.Label label1; private System.Windows.Forms.Label label2; private System.Windows.Forms.Label label3; } } ================================================ FILE: source/KlocTools/Controls/WindowTargeter.ar.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 انقر واسحب فوق نافذة لتحديدها ================================================ FILE: source/KlocTools/Controls/WindowTargeter.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.ComponentModel; using System.Windows.Forms; using Klocman.Subsystems; namespace Klocman.Controls { public partial class WindowTargeter : UserControl { private readonly string _helpText; private readonly WindowHoverSearcher _searcher; public WindowTargeter() { InitializeComponent(); _helpText = label2.Text; _searcher = new WindowHoverSearcher(pictureBox1); _searcher.HoveredWindowChanged += SearcherOnHoveredWindowChanged; _searcher.WindowSelected += SearcherOnWindowSelected; } public event EventHandler PickingStarted { add => _searcher.PickingStarted += value; remove => _searcher.PickingStarted -= value; } public event EventHandler HoveredWindowChanged { add { _searcher.HoveredWindowChanged += value; } remove { _searcher.HoveredWindowChanged -= value; } } public event EventHandler WindowSelected { add { _searcher.WindowSelected += value; } remove { _searcher.WindowSelected -= value; } } private void SearcherOnWindowSelected(object sender, WindowHoverEventArgs windowHoverEventArgs) { label1.Text = string.Empty; label2.Text = _helpText; label3.Text = string.Empty; } private void SearcherOnHoveredWindowChanged(object sender, WindowHoverEventArgs windowHoverEventArgs) { label1.Text = windowHoverEventArgs.TargetWindow.WindowText; label2.Text = windowHoverEventArgs.TargetWindow.WindowRect.ToString(); try { label3.Text = windowHoverEventArgs.TargetWindow.GetRunningProcess().MainModule?.FileName ?? "---"; } catch (SystemException ex) { // Getting MainModule on a 64 bit process throws if BCU is running as 32 bit label3.Text = ex.Message; } } } } ================================================ FILE: source/KlocTools/Controls/WindowTargeter.cs.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Klepněte a přetáhněte přes okno pro výběr ================================================ FILE: source/KlocTools/Controls/WindowTargeter.de.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Klicken und ziehen Sie über ein Fenster, um auszuwählen ================================================ FILE: source/KlocTools/Controls/WindowTargeter.es.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Pulse y arrastre sobre una ventana para selec. ================================================ FILE: source/KlocTools/Controls/WindowTargeter.fr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Cliquer et faire glisser sur une fenêtre pour sélectionner True ================================================ FILE: source/KlocTools/Controls/WindowTargeter.hu.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Kattintson rá, és húzza át az ablakba a kiválasztottat ================================================ FILE: source/KlocTools/Controls/WindowTargeter.it.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Clicca e trascina su una finestra per selezionare ================================================ FILE: source/KlocTools/Controls/WindowTargeter.ja.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ウィンドウをクリック&ドラッグして選択 ================================================ FILE: source/KlocTools/Controls/WindowTargeter.nl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Klik en sleep over een venster om te selecteren ================================================ FILE: source/KlocTools/Controls/WindowTargeter.pl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Naciśnij i przeciągnij nad wybrane okno ================================================ FILE: source/KlocTools/Controls/WindowTargeter.pt-BR.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Clique e arraste sobre uma janela para selecionar ================================================ FILE: source/KlocTools/Controls/WindowTargeter.pt.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Clicar e arrastar para uma janela para seleccionar True ================================================ FILE: source/KlocTools/Controls/WindowTargeter.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Top 74, 0 4, 0, 4, 0 0, 7, 0, 0 263, 29 4 label1 System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 2 Top 74, 29 4, 0, 4, 0 18, 0 0, 0, 0, 3 263, 22 5 Click and drag over a window to select label2 System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 1 Top 74, 51 4, 0, 4, 0 18, 0 263, 20 6 label3 System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 0 Left 0, 0 4, 3, 4, 3 74, 74 CenterImage 0 pictureBox1 System.Windows.Forms.PictureBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 3 True 7, 15 4, 3, 4, 3 11666666, 74 0, 74 337, 74 WindowTargeter System.Windows.Forms.UserControl, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 ================================================ FILE: source/KlocTools/Controls/WindowTargeter.ru.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Нажмите и перетащите на нужное окно True ================================================ FILE: source/KlocTools/Controls/WindowTargeter.sl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Za izbor, kliknite in povlecite nad okno True ================================================ FILE: source/KlocTools/Controls/WindowTargeter.sv.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Klicka och dra över ett fönster för att välja ================================================ FILE: source/KlocTools/Controls/WindowTargeter.tr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Seçmek için bir pencerenin üzerine tıklayın ve sürükleyin ================================================ FILE: source/KlocTools/Controls/WindowTargeter.vi.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Nhấp và kéo trên cửa sổ để chọn ================================================ FILE: source/KlocTools/Controls/WindowTargeter.zh-Hans.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 在窗口上单击并拖动以选择 ================================================ FILE: source/KlocTools/Controls/WindowTargeter.zh-Hant.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 在視窗上點擊並移動來選擇 ================================================ FILE: source/KlocTools/DisplayMode.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ namespace Klocman { public enum DisplayMode { Closed, Simple, Advanced } } ================================================ FILE: source/KlocTools/Events/CountingUpdateEventArgs.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; namespace Klocman.Events { public class CountingUpdateEventArgs : EventArgs { public CountingUpdateEventArgs(int minimum, int maximum, int value) { if (minimum < 0 || maximum < 0) throw new ArgumentException("min and max values can't be negative"); Minimum = minimum; Maximum = maximum; Value = value; IsValid = (value >= minimum) && (value <= maximum); Finished = value == maximum; } /// /// Same as comparing value to the maximum (Value == Maximum) /// public bool Finished { get; private set; } /// /// Returns false if the value is out of bounds ((value >= minimum) && (maximum >= value)) /// public bool IsValid { get; } public int Maximum { get; } public int Minimum { get; private set; } public object Tag { get; set; } public int Value { get; } /// /// Get the percentage of this task. 100% is only returned when Finished is true. /// If the values are invalid returns 0 /// /// public int GetPercentage() { if (IsValid) return (100*Value)/Maximum; return 0; } } } ================================================ FILE: source/KlocTools/Events/PropertyChangedEventArgs.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System.ComponentModel; namespace Klocman.Events { /// /// Generic version of the System.ComponentModel.PropertyChangedEventArgs. /// It might not contain a valid propertyName /// public class PropertyChangedEventArgs : PropertyChangedEventArgs { public PropertyChangedEventArgs(T newValue) : this(newValue, string.Empty) { } public PropertyChangedEventArgs(T newValue, string propertyName) : base(propertyName) { NewValue = newValue; } public T NewValue { get; private set; } } } ================================================ FILE: source/KlocTools/Extensions/BooleanTools.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System.Windows.Forms; using Klocman.Properties; using Klocman.Resources; namespace Klocman.Extensions { public static class BooleanTools { /// /// Convert CheckState value to bool. /// CheckState.Checked returns true, everything else returns false. /// public static bool ToBool(this CheckState value) { return value == CheckState.Checked; } /// /// Convert boolean value to CheckState.Checked or CheckState.Unchecked. /// public static CheckState ToCheckState(this bool value) { return value ? CheckState.Checked : CheckState.Unchecked; } /// /// Convert nullable bool to CheckState, null being CheckState.Indeterminate. /// public static CheckState ToCheckState(this bool? value) { if (!value.HasValue) return CheckState.Indeterminate; return value.Value ? CheckState.Checked : CheckState.Unchecked; } /// /// Convert CheckState to nullable bool, CheckState.Indeterminate being null. /// public static bool? ToNullBool(this CheckState value) { if (value == CheckState.Indeterminate) return null; return value == CheckState.Checked; } /// /// Convert boolean value to string contained in Localisation.Yes and Localisation.No resources. Can be localised. /// public static string ToYesNo(this bool value) { return value ? Localisation.Yes : Localisation.No; } /// /// Convert nullable boolean value to string contained in /// Localisation.Yes, Localisation.No and CommonStrings.Unknown resources. Can be localised. /// public static string ToYesNo(this bool? value) { return value.HasValue ? value.Value.ToYesNo() : CommonStrings.Unknown; } } } ================================================ FILE: source/KlocTools/Extensions/CheckBoxExtension.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System.Reflection; using System.Windows.Forms; namespace Klocman.Extensions { public static class CheckBoxExtension { private static readonly FieldInfo CheckStateInfo = typeof (CheckBox).GetField("checkState", BindingFlags.NonPublic | BindingFlags.Instance); /// /// Set the CheckState value, optionally not raising the CheckStateChanged event. /// /// New state /// If true the CheckStateChanged event will not be raised. The control will still be invalidated. /// Checkbox to access public static void SetCheckState(this CheckBox chBox, CheckState check, bool raiseEvent) { if (raiseEvent) { chBox.CheckState = check; } else { CheckStateInfo.SetValue(chBox, check); chBox.Invalidate(); } } } } ================================================ FILE: source/KlocTools/Extensions/CollectionExtensions.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Linq; namespace Klocman.Extensions { public static class CollectionExtensions { private static readonly Random R = new(); /// /// Wrap this object in an enumerable that returns this object once and finishes. /// public static IEnumerable ToEnumerable(this T obj) { return Enumerable.Repeat(obj, 1); } /// /// Recursively select all subitems based on the selector. /// public static IEnumerable SelectManyResursively(this IEnumerable enumerable, Func> subitemSelector) { return enumerable.SelectMany( x => Enumerable.Repeat(x, 1) .Concat(subitemSelector(x).SelectManyResursively(subitemSelector))); } /// /// Move item at specified index to a new index /// public static void Move(this IList list, int oldIndex, int newIndex) { var item = list[oldIndex]; list.RemoveAt(oldIndex); list.Insert(newIndex, item); } /// /// Move item at specified index to index + 1. Does nothing if item is already last. /// public static void MoveUp(this IList list, int oldIndex) { if (list.Count - 1 > oldIndex) list.Move(oldIndex, oldIndex + 1); } /// /// Move item at specified index to index - 1. Does nothing if item is already first. /// public static void MoveDown(this IList list, int oldIndex) { if (oldIndex > 0) list.Move(oldIndex, oldIndex - 1); } /// /// Returns a read-only wrapper of this dictionary. /// Attempts to modify this collection will throw InvalidOperationException. /// public static IDictionary AsReadOnly(this IDictionary obj) { return new ReadOnlyDictionaryWrapper(obj); } /// /// Usually faster than calling Count() and comparing, at worst it's about the same. /// It enumerates at most (count + 1) elements from the collection. /// /// Collection to count against /// Count to compare to. public static bool CountEquals(this IEnumerable collection, int count) { if (collection is ICollection col) return col.Count == count; using (var enumerator = collection.GetEnumerator()) { var i = 0; while (enumerator.MoveNext()) { i++; if (i > count) return false; } return i == count; } } /// /// Run distinct using the specified equality comparator /// public static IEnumerable Distinct(this IEnumerable source, Func equalityComparator) { var seenItems = new List(); foreach (var item in source) { if (seenItems.Any(x => equalityComparator(item, x))) continue; seenItems.Add(item); yield return item; } } /// /// Run the specified action on all members of the collection as they are enumerated. /// Action will be executed for each enumeration over the element (lazy evaluation). /// /// Type that is being iterated over /// Base enumerable /// Action to run on all of the enumerated members /// Enumerator public static IEnumerable DoForEach(this IEnumerable collection, Action action) { foreach (var item in collection) { action(item); yield return item; } } /// /// Run the specified action on all members of the collection. The collection is enumerated in process. /// /// Type that is being iterated over /// Base enumerable /// Action to run on all of the members public static void ForEach(this IEnumerable collection, Action action) { foreach (var item in collection) action(item); } /// /// Get ID of the element. If the element is not in the array, returns -1 (indexof is not available) /// public static int GetPositionOfElement(this T[] array, T element) { for (var i = 0; i < array.Length; i++) { if (EqualityComparer.Default.Equals(array[i], element)) return i; } return -1; } /// /// Returns random element from this sequence. If it is empty, returns default value of the type. /// public static T GetRandomElement(this IEnumerable items) { var list = items.ToList(); switch (list.Count) { case 0: return default(T); case 1: return list[0]; default: return list[R.Next(0, list.Count)]; } } /// /// Remove all items that are contained in the supplied collection. /// /// Collection to remove items from /// Collection with items to remove. public static void RemoveAll(this IList collection, IEnumerable items) { foreach (var item in items) { if (collection.Contains(item)) collection.Remove(item); } } /// /// Remove all items for which the predicate returns true. /// /// Collection to remove items from /// Predicate used to choose items to remove. public static void RemoveAll(this IList collection, Func predicate) { foreach (var item in collection.Where(predicate).ToArray()) collection.Remove(item); } /// /// Create a new sub array starting at specified index and spanning a number of positions. /// /// Source array /// Starting index. /// How many items to take after the index (including the item at index). public static T[] SubArray(this T[] data, int index, int length) { var result = new T[length]; Array.Copy(data, index, result, 0, length); return result; } /// /// Check if any element of the collection equals to the supplied string value. /// public static bool Contains(this IEnumerable data, string value, StringComparison options) { return data.Any(x => x.Equals(value, options)); } /// /// Rotate the collection to the left so that the item at startIndex becomes index 0. /// Elements rotated to the left wrap around, so the number of elements stays the same. /// public static IEnumerable Rotate(this ICollection targets, int startIndex) { return targets.Skip(startIndex).Concat(targets.Take(startIndex)); } } } ================================================ FILE: source/KlocTools/Extensions/DictionaryExtensions.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Linq; using System.Xml.Serialization; using System.Collections; using System.IO; namespace Klocman.Extensions { public static class DictionaryExtensions { public static void Serialize(this IDictionary dictionary, TextWriter writer) { var entries = new List(from object key in dictionary.Keys select new Entry(key, dictionary[key])); var serializer = new XmlSerializer(typeof(List)); serializer.Serialize(writer, entries); } public static void Deserialize(this IDictionary dictionary, TextReader reader) { dictionary.Clear(); var serializer = new XmlSerializer(typeof(List)); var list = (List)serializer.Deserialize(reader); if (list == null) throw new ArgumentException(@"Reader didn't contain valid data", nameof(reader)); foreach (var entry in list) { dictionary[entry.Key] = entry.Value; } } private class Entry { public object Key; public object Value; public Entry() { } public Entry(object key, object value) { Key = key; Value = value; } } } } ================================================ FILE: source/KlocTools/Extensions/EnumerableExtensions.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; namespace Klocman.Extensions { public static class EnumerableExtensions { /// /// Wraps the specified disposable in an using statement. /// Dispose is called on the current item when the next item is enumerated, /// at the end of the enumeration, and when an uncaught exception is thrown. /// /// Type of the base enumerable /// Type of the disposable class /// Base enumerable /// Lambda for getting the disposable public static IEnumerable Using(this IEnumerable baseEnumerable, Func disposableGetter) where TDisp : class, IDisposable { TDisp disposable = null; try { foreach (var item in baseEnumerable) { disposable?.Dispose(); disposable = disposableGetter(item); yield return disposable; } } finally { disposable?.Dispose(); } } /// /// Executes a lambda on each item as it is enumerated. Doesn't enumerate. /// WARNING: Will only run for the items that are enumerated. Enumerating twice will /// run the action twice. /// /// /// Base enumerable /// Action to execute on each of the enumerated items. public static IEnumerable Do(this IEnumerable baseEnumerable, Action action) { foreach (var item in baseEnumerable) { action(item); yield return item; } } /// /// Select using the given action, but ignore exceptions and skip offending items. /// public static IEnumerable Attempt(this IEnumerable baseEnumerable, Func action) { foreach (var item in baseEnumerable) { TOut output; try { output = action(item); } catch (Exception e) { Console.Error.WriteLine("Attempt failed, skipping. Error: " + e); continue; } yield return output; } } } } ================================================ FILE: source/KlocTools/Extensions/EventExtensions.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.ComponentModel; using System.Linq; namespace Klocman.Extensions { public static class EventExtensions { public static bool CancellableInvoke(this EventHandler handler, object sender, T eventArgs) where T : CancelEventArgs { var cancel = false; foreach (var tmp in handler.GetInvocationList().Cast>()) { tmp(sender, eventArgs); if (eventArgs.Cancel) { cancel = true; break; } } return !cancel; } } } ================================================ FILE: source/KlocTools/Extensions/FormsExtensions.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Linq; using System.Reflection; using System.Runtime.InteropServices; using System.Windows.Forms; namespace Klocman.Extensions { public static class FormsExtensions { /// /// An application sends the WM_SETREDRAW message to a window to allow changes in that /// window to be redrawn or to prevent changes in that window from being redrawn. /// private const int WM_SETREDRAW = 11; /// /// Suspends painting for the target control. Do NOT forget to call EndControlUpdate!!! /// /// visual control public static void BeginControlUpdate(this Control control) { var msgSuspendUpdate = Message.Create(control.Handle, WM_SETREDRAW, IntPtr.Zero, IntPtr.Zero); var window = NativeWindow.FromHandle(control.Handle); window.DefWndProc(ref msgSuspendUpdate); } /// /// Show the form and make sure that it is at the top of the screen /// public static void ShowAndMoveToTop(this Form targetForm) { targetForm.WindowState = FormWindowState.Minimized; targetForm.Show(); targetForm.WindowState = FormWindowState.Normal; } /// /// Move this form to be centered to the other. Same effect as setting FormStartPosition.CenterParent and using /// ShowDialog. /// /// Form that will be moved /// Form to be centered to. public static void CenterToForm(this Form thisForm, Form targetForm) { thisForm.StartPosition = FormStartPosition.Manual; thisForm.Location = new Point(targetForm.Location.X + (targetForm.Width - thisForm.Width) / 2, targetForm.Location.Y + (targetForm.Height - thisForm.Height) / 2); } /// /// Resumes painting for the target control. Intended to be called following a call to BeginControlUpdate() /// /// visual control public static void EndControlUpdate(this Control control) { // Create a C "true" boolean as an IntPtr var wparam = new IntPtr(1); var msgResumeUpdate = Message.Create(control.Handle, WM_SETREDRAW, wparam, IntPtr.Zero); var window = NativeWindow.FromHandle(control.Handle); window.DefWndProc(ref msgResumeUpdate); control.Invalidate(); control.Refresh(); } /// /// Get an enumerator that will get all child controls recursively. It will return contents of custom controls as well. /// /// Control to get children of public static IEnumerable GetAllChildren(this Control control) { var controls = control.Controls.Cast().ToList(); return controls.SelectMany(GetAllChildren).Concat(controls); } /// /// Get an enumerator that will get all child controls recursively. It will return contents of custom controls as well. /// /// Control to get children of /// /// Predicate to filter the controls by. If a control is filtered its children will be filtered as /// well. /// public static IEnumerable GetAllChildren(this Control control, Func predicate) { var controls = control.Controls.Cast().Where(predicate).ToList(); return controls.SelectMany(ctrl => GetAllChildren(ctrl, predicate)).Concat(controls); } public static IEnumerable GetComponents(this Form form) { return from field in form.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) where typeof(Component).IsAssignableFrom(field.FieldType) let component = (Component)field.GetValue(form) where component != null select component; } /// /// Recursively check if this form is a child of specified control. /// Will deadlock if you have a ring of parented controls (don't do that). /// /// Child control /// Control to check against public static bool IsChildOf(this Control c, Control parent) { if (c == null) throw new NullReferenceException(); if (parent == null) throw new ArgumentNullException(nameof(parent)); while (true) { if (c.Parent == null) return false; if (c.Parent == parent) return true; c = c.Parent; } } /// /// Safely invoke supplied action on this object. If this object is disposed, do nothing. /// If invoke is not required, supplied action is launched directly. /// /// /// Action to invoke /// The value of 'action' and 'obj' cannot be null. /// A delegate callback throws an exception. public static void SafeInvoke(this Control obj, Action action) { if (action == null) throw new ArgumentNullException(nameof(action)); if (obj == null) throw new ArgumentNullException(nameof(obj)); if (!obj.IsDisposed && !obj.Disposing) { if (obj.InvokeRequired) { try { obj.Invoke(action); } catch (ObjectDisposedException) { } catch (InvalidOperationException) { } catch (InvalidAsynchronousStateException) { } } else { action(); } } } /// /// Extend aero frame into the client area of the form by specified amounts. /// /// Form to extend into /// Amount of pixels to extend inwards /// True if operation succeeded, otherwise false. public static bool ExtendAeroFrameInwards(this Form f, Padding insetMargins) { var margins = new NativeMethods.MARGINS { cxLeftWidth = insetMargins.Left, cxRightWidth = insetMargins.Right, cyTopHeight = insetMargins.Top, cyBottomHeight = insetMargins.Bottom }; var result = NativeMethods.DwmExtendFrameIntoClientArea(f.Handle, ref margins); return result == 0; } /// /// Enable/disable hidden double buffered attribute using reflection. /// http://blogs.msdn.com/oldnewthing/archive/2006/01/03/508694.aspx /// public static void SetDoubleBuffered(this Control c, bool enabled) { if (SystemInformation.TerminalServerSession) return; var aProp = typeof(Control).GetProperty("DoubleBuffered", BindingFlags.NonPublic | BindingFlags.Instance); if (aProp != null) aProp.SetValue(c, enabled, null); } /// /// Convert keycode to a string with a single letter/digit. Returns null if key is not between A and Z or is not a /// number. /// /// /// public static string ToLetterOrNumberString(this Keys keyVal) { string keyName = null; if (keyVal >= Keys.A && keyVal <= Keys.Z) { keyName = keyVal.ToString(); } else { var temp = keyVal.ToNumber(); if (temp >= 0) keyName = temp.ToString(); } return keyName; } /// /// Convert keycode of a pressed number key to the actual number. Returns -1 if key is not a number. /// public static int ToNumber(this Keys keyVal) { var value = -1; if (keyVal >= Keys.D0 && keyVal <= Keys.D9) { value = keyVal - Keys.D0; } else if (keyVal >= Keys.NumPad0 && keyVal <= Keys.NumPad9) { value = keyVal - Keys.NumPad0; } return value; } /// /// Get height of the form's titlebar. /// public static int GetBorderHeight(this Form f) { var screenRectangle = f.RectangleToScreen(f.ClientRectangle); return screenRectangle.Top - f.Top; } /// /// Get width of the form's left border. /// public static int GetBorderWidth(this Form f) { var screenRectangle = f.RectangleToScreen(f.ClientRectangle); return screenRectangle.Left - f.Left; } /// /// Move the form as close to the cursor as possible without going past the edges of current screen's working area. /// public static void MoveCloseToCursor(this Form form) { var screen = Screen.FromPoint(Control.MousePosition).WorkingArea; var x = Math.Max(Math.Min(Control.MousePosition.X - form.Width / 2, screen.X + screen.Width - form.Width), screen.X); var y = Math.Max(Math.Min(Control.MousePosition.Y - form.Height / 2, screen.Y + screen.Height - form.Height), screen.Y); form.Location = new Point(x, y); } private static class NativeMethods { [DllImport("dwmapi.dll")] public static extern int DwmExtendFrameIntoClientArea( IntPtr hWnd, ref MARGINS pMarInset ); [StructLayout(LayoutKind.Sequential)] public struct MARGINS { public int cxLeftWidth; public int cxRightWidth; public int cyTopHeight; public int cyBottomHeight; } } } } ================================================ FILE: source/KlocTools/Extensions/IconExtensions.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System.Drawing; using System.Media; namespace Klocman.Extensions { public static class IconExtensions { /// /// Useful only with icons from the SystemIcons class. Plays sounds from the SystemSounds class. /// /// public static void PlayCorrespondingSystemSound(this Icon iconSet) { if (iconSet.Equals(SystemIcons.Error) || iconSet.Equals(SystemIcons.Hand)) { SystemSounds.Hand.Play(); } else if (iconSet.Equals(SystemIcons.Warning) || iconSet.Equals(SystemIcons.Exclamation)) { SystemSounds.Exclamation.Play(); } else if (iconSet.Equals(SystemIcons.Asterisk) || iconSet.Equals(SystemIcons.Application)) { SystemSounds.Asterisk.Play(); } else if (iconSet.Equals(SystemIcons.Question)) { SystemSounds.Question.Play(); } else if (iconSet.Equals(SystemIcons.Shield)) { SystemSounds.Beep.Play(); } } } } ================================================ FILE: source/KlocTools/Extensions/IoExtensions.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.IO; using System.Linq; namespace Klocman.Extensions { public static class IoExtensions { /// /// Get basic attributes of this file in a Name/Value format. /// /// Base file /// Extended attributes of this file public static IEnumerable> GetAttributes(this FileInfo file) { if (file == null) throw new ArgumentNullException(nameof(file)); if (!file.Exists) throw new ArgumentException(@"Requested file doesn't exist", nameof(file)); var lq = from property in typeof (FileInfo).GetProperties() select new KeyValuePair(property.Name, property.GetValue(file, new object[] {})); return lq; } /// /// Attempt to get DriveInfo of this directory's root partition. /// /// /// First drive matching the root name, null if no matches were found. public static DriveInfo GetDriveInfo(this DirectoryInfo obj) { if (obj == null) throw new ArgumentNullException(nameof(obj)); return DriveInfo.GetDrives().FirstOrDefault(x => obj.RootEquals(x.RootDirectory)); } public static bool IsFileLocked(this FileInfo file) { FileStream stream = null; try { stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None); } catch (IOException) { // File is locked return true; } finally { stream?.Close(); } // File is not locked return false; } /// /// Check if this drive is formatted with NTFS file system /// /// /// public static bool IsNtfs(this DriveInfo obj) { if (obj == null) throw new ArgumentNullException(nameof(obj)); return obj.DriveFormat.Contains("NTFS"); } /// /// Compare roots of the selected directory paths. /// If any path is null, false is returned (even if both are null). /// /// /// Path to compare root with /// True if roots are equal public static bool RootEquals(this DirectoryInfo obj, DirectoryInfo target) { if (obj == null || target == null) return false; if (ReferenceEquals(obj, target)) return true; return obj.Root.Name.Equals(target.Root.Name, StringComparison.CurrentCultureIgnoreCase); } /// /// Compare roots of the selected file paths. /// If any path is null, false is returned (even if both are null). /// /// /// Path to compare root with /// True if roots are equal public static bool RootEquals(this FileInfo obj, FileInfo target) { if (obj == null || target == null) return false; if (ReferenceEquals(obj, target)) return true; return obj.Directory.RootEquals(target.Directory); } public static string GetNameWithoutExtension(this FileSystemInfo obj) { return Path.GetFileNameWithoutExtension(obj.Name); } } } ================================================ FILE: source/KlocTools/Extensions/MiscExtensions.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; namespace Klocman.Extensions { public static class MiscExtensions { // Buggy with signed enums /*public static bool Contains(this Enum keys, Enum flag) { var keysVal = Convert.ToUInt64(keys); var flagVal = Convert.ToUInt64(flag); return (keysVal & flagVal) == flagVal; }*/ /// /// Check if this struct is equal to the default value for this type. /// /// /// public static bool IsDefault(this T value) where T : struct { var isDefault = value.Equals(default(T)); return isDefault; } public static bool IsEmpty(this Guid obj) { return Guid.Empty.Equals(obj); } public static bool IsZeroOrNull(this Version obj) { return obj == null || obj.Equals(new Version(0, 0, 0, 0)) || obj.Equals(new Version(0, 0, 0)) || obj.Equals(new Version(0, 0)); } } } ================================================ FILE: source/KlocTools/Extensions/ParentProcessUtilities.cs ================================================ using System; using System.ComponentModel; using System.Diagnostics; using System.Runtime.InteropServices; namespace Klocman.Extensions { /// /// A utility class to determine a process parent. /// By Simon Mourier https://stackoverflow.com/a/3346055/4309247 /// [StructLayout(LayoutKind.Sequential)] public struct ParentProcessUtilities { // These members must match PROCESS_BASIC_INFORMATION internal IntPtr Reserved1; internal IntPtr PebBaseAddress; internal IntPtr Reserved2_0; internal IntPtr Reserved2_1; internal IntPtr UniqueProcessId; internal IntPtr InheritedFromUniqueProcessId; [DllImport("ntdll.dll")] private static extern int NtQueryInformationProcess(IntPtr processHandle, int processInformationClass, ref ParentProcessUtilities processInformation, int processInformationLength, out int returnLength); /// /// Gets the parent process of the current process. /// /// An instance of the Process class. public static Process GetParentProcess() { return GetParentProcess(Process.GetCurrentProcess().Handle); } /// /// Gets the parent process of specified process. /// /// The process id. /// An instance of the Process class. public static Process GetParentProcess(int id) { Process process = Process.GetProcessById(id); return GetParentProcess(process.Handle); } /// /// Gets the parent process of a specified process. /// /// The process handle. /// An instance of the Process class. public static Process GetParentProcess(IntPtr handle) { ParentProcessUtilities pbi = new ParentProcessUtilities(); int status = NtQueryInformationProcess(handle, 0, ref pbi, Marshal.SizeOf(pbi), out _); if (status != 0) throw new Win32Exception(status); try { return Process.GetProcessById(pbi.InheritedFromUniqueProcessId.ToInt32()); } catch (ArgumentException) { // not found return null; } } } } ================================================ FILE: source/KlocTools/Extensions/ProcessExtensions.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Management; using System.Text; namespace Klocman.Extensions { public static class ProcessExtensions { public static IEnumerable GetChildProcesses(this Process process) { if (process == null) throw new ArgumentNullException(nameof(process)); var results = new List(); try { var searchString = $"Select * From Win32_Process Where ParentProcessID={process.Id}"; using (var mos = new ManagementObjectSearcher(searchString)) { foreach (var mo in mos.Get()) { //var mo = (ManagementObject) o; Process resultProcess = null; try { resultProcess = Process.GetProcessById(Convert.ToInt32(mo["ProcessID"])); } catch (ArgumentException) { // Process exited by now } if (resultProcess != null) results.Add(resultProcess); } } } catch (Exception e1) { Console.WriteLine(@"Failed to GetChildProcesses using ManagementObjectSearcher: " + e1.Message); try { var allProcesses = Process.GetProcesses() .Attempt(proc => new { proc, parent = ParentProcessUtilities.GetParentProcess(proc.Handle) }) .Where(x => x.parent != null) .ToList(); var newChildren = allProcesses.Where(p => p.parent == process).Select(x => x.proc).ToList(); while (newChildren.Any()) { results.AddRange(newChildren); newChildren = allProcesses.Where(p => newChildren.Contains(p.parent)).Select(x => x.proc).ToList(); } } catch (Exception e2) { Console.WriteLine(@"Failed to GetChildProcesses using ParentProcessUtilities: " + e2); } } return results.Distinct(); } public static string GetCommandLine(this Process process) { if (process == null) throw new ArgumentNullException(nameof(process)); if (process.MainModule?.FileName == null) throw new ArgumentException("null MainModule"); var commandLine = new StringBuilder(process.MainModule.FileName); commandLine.Append(' '); using (var searcher = new ManagementObjectSearcher("SELECT CommandLine FROM Win32_Process WHERE ProcessId = " + process.Id)) { foreach (var @object in searcher.Get()) { commandLine.Append(@object["CommandLine"]); commandLine.Append(' '); } } return commandLine.ToString(); } /// /// Stop the proces and optionally all of its child processes immidiately. Only the main process can throw exceptions. /// public static void Kill(this Process pr, bool killChildren) { if (killChildren) { foreach (var cp in pr.GetChildProcesses()) { try { cp.Kill(); } catch { // Ignore failures, the process probably ended } } } pr.Kill(); } public static Process Start(this ProcessStartInfo startInfo) { return Process.Start(startInfo); } /// /// Start a new process using Process.Start, /// but don't return until this process and all of its child processes end. /// /// Exit code returned by the main process public static int StartAndWait(this ProcessStartInfo startInfo) { var uninstaller = Process.Start(startInfo); if (uninstaller == null) return -1; uninstaller.WaitForExit(); while (true) { var children = uninstaller.GetChildProcesses(); var processes = children as IList ?? children.ToList(); if (processes.Any()) processes.First().WaitForExit(1000); else break; } return uninstaller.ExitCode; } } } ================================================ FILE: source/KlocTools/Extensions/ReadOnlyDictionaryWrapper.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections; using System.Collections.Generic; namespace Klocman.Extensions { public sealed class ReadOnlyDictionaryWrapper : IDictionary { private readonly IDictionary _baseDictionary; public ReadOnlyDictionaryWrapper(IDictionary baseDictionary) { _baseDictionary = baseDictionary; } public IEnumerator> GetEnumerator() { return _baseDictionary.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public void Add(KeyValuePair item) { throw new InvalidOperationException(); } public void Clear() { throw new InvalidOperationException(); } public bool Contains(KeyValuePair item) { return _baseDictionary.Contains(item); } public void CopyTo(KeyValuePair[] array, int arrayIndex) { _baseDictionary.CopyTo(array, arrayIndex); } public bool Remove(KeyValuePair item) { throw new InvalidOperationException(); } public int Count => _baseDictionary.Count; public bool IsReadOnly => true; public bool ContainsKey(TKey key) { return _baseDictionary.ContainsKey(key); } public void Add(TKey key, TValue value) { throw new InvalidOperationException(); } public bool Remove(TKey key) { throw new InvalidOperationException(); } public bool TryGetValue(TKey key, out TValue value) { return _baseDictionary.TryGetValue(key, out value); } public TValue this[TKey key] { get { return _baseDictionary[key]; } set { throw new InvalidOperationException(); } } public ICollection Keys => _baseDictionary.Keys; public ICollection Values => _baseDictionary.Values; } } ================================================ FILE: source/KlocTools/Extensions/RegistryKeyExtensions.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.IO; using System.Linq; using Microsoft.Win32; namespace Klocman.Extensions { public static class RegistryKeyExtensions { /// /// Get only the name of this key, instead of the whole path /// public static string GetKeyName(this RegistryKey obj) { return obj.Name.Substring(obj.Name.LastIndexOf('\\') + 1); } /// /// Lazily open and return all subkeys. /// public static IEnumerable GetSubKeys(this RegistryKey obj, bool writable) { if (obj == null) throw new NullReferenceException(); return obj.GetSubKeyNames().Select(x => obj.OpenSubKey(x, writable)); } public static IEnumerable TryGetValueNames(this RegistryKey key) { try { return key.GetValueNames(); } catch (IOException) { return Enumerable.Empty(); } } /// /// Get the specified value as a string. If the value is a string, then it is trimmed up until the /// first null character to avoid buggy GetValue returning data after the end of string. /// public static string GetStringSafe(this RegistryKey key, string valueName) { var v = key.GetValue(valueName, null, RegistryValueOptions.None)?.ToString(); if (string.IsNullOrEmpty(v)) return v; // Handle strings written with invalid (too large) lengths // https://blogs.msdn.microsoft.com/oldnewthing/20040824-00/?p=38063/ var ni = v.IndexOf('\0'); if (ni >= 0) v = v.Substring(0, ni); // Strip any other invalid data return v.SafeNormalize(); } } } ================================================ FILE: source/KlocTools/Extensions/RichTextBoxExtensions.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System.Drawing; using System.Windows.Forms; namespace Klocman.Extensions { public static class RichTextBoxExtensions { /// /// Append text in specified color to the end of the document without interrupting the user. /// /// Box to append text to /// Text to append. /// Color of the appended text. public static void AppendText(this RichTextBox box, string text, Color color) { box.SuspendLayout(); // Backup current state var start = box.SelectionStart; var length = box.SelectionLength; var prevColor = box.SelectionColor; // Append the text box.SelectionStart = box.TextLength; box.SelectionLength = 0; box.SelectionColor = color; box.AppendText(text); // Restore state box.SelectionStart = start; box.SelectionLength = length; box.SelectionColor = prevColor; box.ResumeLayout(); } } } ================================================ FILE: source/KlocTools/Extensions/StreamExtensions.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System.IO; namespace Klocman.Extensions { public static class StreamExtensions { /// /// Alternative to Net4 CopyTo /// /// /// /// public static long CopyTo(this Stream source, Stream destination) { var buffer = new byte[2048]; int bytesRead; long totalBytes = 0; while ((bytesRead = source.Read(buffer, 0, buffer.Length)) > 0) { destination.Write(buffer, 0, bytesRead); totalBytes += bytesRead; } return totalBytes; } } } ================================================ FILE: source/KlocTools/Extensions/StringExtensions.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Drawing; using System.Globalization; using System.IO; using System.Linq; using System.Text; using System.Text.RegularExpressions; using Klocman.Tools; namespace Klocman.Extensions { public static class StringExtensions { /// /// Reverse the string using the specified pattern. The string is split into parts corresponding /// to the pattern's values, then each of the parts is reversed and finally they are joined back. /// Example: String("Tester") Pattern(1,3,2) -> T est er -> T tse re -> Result("Ttsere") /// /// String to reverse /// /// Pattern used to reverse the string. /// Warning: The pattern has to have identical total length to the length of the string. /// public static string Reverse(this string value, int[] pattern) { if (value == null) throw new NullReferenceException(); if (pattern == null) throw new ArgumentNullException(nameof(pattern)); if (value.Length != pattern.Sum()) throw new ArgumentException( "Pattern doesn't match the string. Sum of the pattern's parts has to have length equal to the length the string."); var returnString = new StringBuilder(); var index = 0; // Iterate over the reversal pattern foreach (var length in pattern) { // Reverse the sub-string and append it returnString.Append(value.Substring(index, length).Reverse().ToArray()); // Increment our posistion in the string index += length; } return returnString.ToString(); } public static string ToHexString(this byte[] ba) { var hex = BitConverter.ToString(ba); return hex.Replace("-", ""); } #region Methods /// /// Split string on newlines /// public static string[] SplitNewlines(this string value, StringSplitOptions options) { return value.Split(new[] { "\r\n", "\n" }, options); } /// /// Append supplied string to this string and return the result. /// public static string Append(this string value, string append) { return String.Concat(value, append); // value + append; } /// /// Append supplied strings to this string and return the result. /// public static string Append(this string value, params string[] append) { return String.Concat(value, String.Concat(append)); // value + append; } /// /// Append supplied string to the base string if expression is true and return the result. /// /// /// Appension will happen only if expression is equal to true /// Strings to append, if more than one is supplied they will be concetrated using string.Concat /// Base string with or without the appended extra string public static string AppendIf(this string value, bool expression, params string[] append) { return expression ? String.Concat(value, String.Concat(append)) : value; } public static StringBuilder AppendIf(this StringBuilder value, bool expression, string append) { if (expression) value.Append(append); return value; } public static StringBuilder AppendIfFormat(this StringBuilder value, bool expression, string format, params object[] args) { if (expression) value.AppendFormat(format, args); return value; } /// /// is not a valid /// value. /// /// The value of 'value' cannot be null. public static bool Contains(this string value, string str, StringComparison comparisonType) { if (value == null) throw new ArgumentNullException(nameof(value)); return value.Contains(str, comparisonType); } /// /// Check if base string contains all of the supplied strings. /// /// /// Items to be compared to the base string /// Rules of the comparison /// True if any of the items were found in the base string, else false public static bool ContainsAll(this string s, IEnumerable items, StringComparison comparisonType) { return items.All(item => s.Contains(item, comparisonType)); } /// /// Check if base char array contains any of the supplied chars. /// /// /// Chars to be compared to the base array /// True if any of the items were found in the base string, else false public static bool ContainsAny(this IEnumerable s, IEnumerable items) { return items.Any(s.Contains); } /// /// Check if base string contains any of the supplied strings. /// /// /// Items to be compared to the base string /// Rules of the comparison /// True if any of the items were found in the base string, else false public static bool ContainsAny(this string s, IEnumerable items, StringComparison comparisonType) { return items.Any(item => s.Contains(item, comparisonType)); } /// /// Check if base string starts with any of the supplied strings. /// /// /// Items to be compared to the base string /// Rules of the comparison /// True if any of the items were found in the base string, else false public static bool StartsWithAny(this string s, IEnumerable items, StringComparison comparisonType) { return items.Any(item => s.StartsWith(item, comparisonType)); } /// /// Remove any non-ascii characters and replace them with their ascii counterparts. /// Will remove most accents (for example ć -> c). IF no valid ASCII counterpart is found the char is replaced by "?" /// /// ASCII compliant string public static string DownconvertToAscii(this string input) { var tempContentsUnicode = Encoding.GetEncoding(1251).GetBytes(input); return Encoding.ASCII.GetString(tempContentsUnicode); } /// /// Trim this string from all whitespaces and ending pronounciations (eg. '.' ','), /// then remove any of the supplied items from the end of the resulting string. /// This method is greedy, it will remove the same item multiple times if possible. /// After every successful removal whitespaces and ending pronounciations are trimmed again. /// /// /// Items to be trimmed from base string /// How the items are compared to the base string /// Trimmed version of the base string public static string ExtendedTrimEndAny(this string s, IEnumerable trimmers, StringComparison comparisonType) { if (String.IsNullOrEmpty(s)) return String.Empty; var trimmerList = trimmers as IList ?? trimmers.ToList(); var resultStr = s.Trim().Trim(',', '.', ' '); var rerun = true; while (rerun) { rerun = false; foreach (var trimmer in trimmerList) { if (!resultStr.EndsWith(trimmer, comparisonType)) continue; var cutNum = resultStr.Length - trimmer.Length; // Exit the loop quickly if resultStr contains only the trimmer. Also checks for negative lenght. if (cutNum <= 0) return String.Empty; resultStr = resultStr.Substring(0, cutNum); resultStr = resultStr.Trim().Trim(',', '.', ' '); rerun = true; break; } } return resultStr; } /// /// Trim all whitespace and specified strings from start and end of this string. /// public static string ExtendedTrim(this string s, IEnumerable trimmers, StringComparison comparisonType) { if (String.IsNullOrEmpty(s)) return String.Empty; var trimmerList = trimmers as IList ?? trimmers.ToList(); var resultStr = s.Trim(); bool rerun; do { rerun = false; foreach (var trimmer in trimmerList) { if (resultStr.EndsWith(trimmer, comparisonType)) { var cutNum = resultStr.Length - trimmer.Length; if (cutNum <= 0) return String.Empty; resultStr = resultStr.Substring(0, cutNum).Trim(); rerun = true; } if (resultStr.StartsWith(trimmer, comparisonType)) { var cutNum = resultStr.Length - trimmer.Length; if (cutNum <= 0) return String.Empty; resultStr = resultStr.Substring(trimmer.Length).Trim(); rerun = true; } if (rerun) break; } } while (rerun); return resultStr; } /// /// Return index of first element found in this string. /// /// Target string /// Chars to look for /// Index to start the search at /// Index of first found element or -1 if none were found public static int IndexOfAny(this string str, IEnumerable chars, int startIndex) { var result = -1; foreach (var c in chars) { var i = str.IndexOf(c, startIndex); if (i >= 0 && (i < result || result < 0)) result = i; } return result; } /// /// Same as inverted string.IsNullOrEmpty /// /// /// public static bool IsNotEmpty(this string input) { return !String.IsNullOrEmpty(input); } public static string RemoveInvalidPathChars(this string value) { if (value == null) return String.Empty; return StringTools.InvalidPathChars.Aggregate(value, (current, str) => current.Replace(str.ToString(), String.Empty)); } /// /// Remove all possible newline characters in a greedy way. /// public static string RemoveNewLines(this string value) { if (value == null) return String.Empty; return StringTools.NewLineChars.Aggregate(value, (current, str) => current.Replace(str, String.Empty)); } /// /// Removes all non-word characters using Regex (^\w). /// /// Stripped string public static string RemoveSpecialCharacters(this string value) { if (value == null) return String.Empty; return Regex.Replace(value, @"[^\w ]", String.Empty); //Path.GetInvalidFileNameChars() } /// /// Remove diacritics (accents) from a string (for example ć -> c) /// /// ASCII compliant string public static string StripAccents(this string input) { var text = input.SafeNormalize(NormalizationForm.FormD); var chars = text.Where(c => CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark).ToArray(); return new string(chars).SafeNormalize(NormalizationForm.FormC); } /// /// Convert to - camelCase. /// public static string ToCamelCase(this string baseStr) { if (String.IsNullOrEmpty(baseStr)) return String.Empty; baseStr = baseStr.ToPascalCase(); return baseStr.Substring(0, 1).ToLowerInvariant() + baseStr.Substring(1); } /// /// Convert to - Normal case /// public static string ToNormalCase(this string baseStr) { if (String.IsNullOrEmpty(baseStr)) return String.Empty; baseStr = baseStr.ToTitleCase().ToLowerInvariant(); return baseStr.Substring(0, 1).ToUpperInvariant() + baseStr.Substring(1); } /// /// Convert to - PascalCase. /// public static string ToPascalCase(this string baseStr) { baseStr = baseStr?.Trim(); if (String.IsNullOrEmpty(baseStr)) return String.Empty; if (!baseStr.Contains(" ")) return baseStr; baseStr = CultureInfo.GetCultureInfo("en-US").TextInfo.ToTitleCase(baseStr); return String.Join(String.Empty, baseStr.Split(new char[] { }, StringSplitOptions.RemoveEmptyEntries)); } /// /// Calculate a StringFormat object from supplied ContentAlignment. /// public static StringFormat ToStringFormat(this ContentAlignment a) { var cFormat = new StringFormat(); var lNum = (int)Math.Log((double)a, 2); cFormat.LineAlignment = (StringAlignment)(lNum / 4); cFormat.Alignment = (StringAlignment)(lNum % 4); cFormat.Trimming = StringTrimming.None; return cFormat; } /// /// Convert to - Title Case /// Capitalize the first character and add a space before each capitalized letter (except the first character). /// public static string ToTitleCase(this string baseStr) { if (String.IsNullOrEmpty(baseStr)) return String.Empty; const string pattern = @"(?<=\w)(?=[A-Z])"; baseStr = Regex.Replace(baseStr.ToPascalCase(), pattern, " ", RegexOptions.None); return baseStr.Substring(0, 1).ToUpperInvariant() + baseStr.Substring(1); } /// /// Safe version of normalize that doesn't crash on invalid code points in string. /// Instead the points are replaced with question marks. /// public static string SafeNormalize(this string input, NormalizationForm normalizationForm = NormalizationForm.FormC) { try { return StringTools.ReplaceNonCharacters(input, '?').Normalize(normalizationForm); } catch (ArgumentException e) { throw new InvalidDataException("String contains invalid characters. Data: " + Encoding.UTF32.GetBytes(input).ToHexString(), e); } } #endregion Methods } } ================================================ FILE: source/KlocTools/Extensions/TimeExtensions.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using Klocman.Properties; namespace Klocman.Extensions { public static class TimeExtensions { /// /// Get fuzzy time string as spoken at present moment when referring to this DateTime. /// For example 6 years ago, 3 months ago, Just now. /// public static string ToFuzzyTimeSinceString(this DateTime source) { return ToFuzzyTimeSinceString(source, DateTime.Now); } /// /// Get fuzzy time string as spoken at supplied time (now) when referring to this DateTime. /// For example 6 years ago, 3 months ago, Just now. /// /// Point in time that happened in the past /// From which point to speak about this DateTime public static string ToFuzzyTimeSinceString(this DateTime past, DateTime now) { var difference = now.Subtract(past); var years = difference.Days/365; //no leap year accounting if (years > 0) { if (years == 1) return Localisation.ToFuzzyTimeSinceString_Years_Single; return string.Format(Localisation.ToFuzzyTimeSinceString_Years_Since, years); } var months = (difference.Days%365)/30; //naive guess at month size if (months > 0) { if (months == 1) return Localisation.ToFuzzyTimeSinceString_Months_Single; return string.Format(Localisation.ToFuzzyTimeSinceString_Months_Since, months); } if (difference.Days > 0) { if (difference.Days == 1) return Localisation.ToFuzzyTimeSinceString_Days_Single; return string.Format(Localisation.ToFuzzyTimeSinceString_Days_Since, difference.Days); } if (difference.Hours > 0) { if (difference.Hours == 1) return Localisation.ToFuzzyTimeSinceString_Hours_Single; return string.Format(Localisation.ToFuzzyTimeSinceString_Hours_Since, difference.Hours); } if (difference.Minutes > 0) { if (difference.Minutes == 1) return Localisation.ToFuzzyTimeSinceString_Minutes_Single; return string.Format(Localisation.ToFuzzyTimeSinceString_Minutes_Since, difference.Minutes); } return Localisation.ToFuzzyTimeSinceString_JustNow; } } } ================================================ FILE: source/KlocTools/Extensions/WebExtensions.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Specialized; using System.Linq; using System.Net; using System.Text; namespace Klocman.Extensions { public static class WebExtensions { /// /// http://stackoverflow.com/a/30049848/4309247 /// public static Encoding GetEncodingFrom(NameValueCollection responseHeaders, Encoding defaultEncoding = null) { if (responseHeaders == null) throw new ArgumentNullException("responseHeaders"); //Note that key lookup is case-insensitive var contentType = responseHeaders["Content-Type"]; if (contentType == null) return defaultEncoding; var contentTypeParts = contentType.Split(';'); if (contentTypeParts.Length <= 1) return defaultEncoding; var charsetPart = contentTypeParts.Skip(1).FirstOrDefault( p => p.TrimStart().StartsWith("charset", StringComparison.InvariantCultureIgnoreCase)); if (charsetPart == null) return defaultEncoding; var charsetPartParts = charsetPart.Split('='); if (charsetPartParts.Length != 2) return defaultEncoding; var charsetName = charsetPartParts[1].Trim(); if (charsetName == "") return defaultEncoding; try { return Encoding.GetEncoding(charsetName); } catch (ArgumentException ex) { throw new InvalidOperationException("The server returned data in an unknown encoding: " + charsetName, ex); } } public static string DownloadStringAwareOfEncoding(this WebClient webClient, Uri uri) { var rawData = webClient.DownloadData(uri); var encoding = GetEncodingFrom(webClient.ResponseHeaders, Encoding.UTF8); return encoding.GetString(rawData); } } } ================================================ FILE: source/KlocTools/Extensions/XmlExtensions.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System.IO; using System.Text; using System.Xml; using System.Xml.Linq; using System.Xml.Serialization; namespace Klocman.Extensions { public static class XmlExtensions { /// /// Get element with supplied name. If the element doesn't exist crate it. /// public static XElement GetOrCreateElement(this XElement baseElement, XName name) { var element = baseElement.Element(name); if (element == null) { element = new XElement(name); baseElement.Add(element); } return element; } public static string Serialize(this XmlSerializer serializer, object value, bool indent = false) { if (value == null) return null; var settings = new XmlWriterSettings { // no BOM in a .NET string Encoding = new UnicodeEncoding(false, false), Indent = indent, OmitXmlDeclaration = true }; using (var textWriter = new StringWriter()) { using (var xmlWriter = XmlWriter.Create(textWriter, settings)) { serializer.Serialize(xmlWriter, value); } return textWriter.ToString(); } } public static object Deserialize(this XmlSerializer serializer, string xml) { if (string.IsNullOrEmpty(xml)) return null; var settings = new XmlReaderSettings(); using (var textReader = new StringReader(xml)) { using (var xmlReader = XmlReader.Create(textReader, settings)) { return serializer.Deserialize(xmlReader); } } } } } ================================================ FILE: source/KlocTools/Forms/CmbBasicSettings.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System.Drawing; using System.Windows.Forms; namespace Klocman.Forms { public sealed class CmbBasicSettings { public CmbBasicSettings(string title, string largeHeading, string smallExplanation, Icon iconSet, string rightButton) : this(title, largeHeading, smallExplanation, iconSet, null, null, rightButton) { } public CmbBasicSettings(string title, string largeHeading, string smallExplanation, Icon iconSet, string middleButton, string rightButton) : this(title, largeHeading, smallExplanation, iconSet, null, middleButton, rightButton) { } /* public CustomMessageBoxBasicSettings(string title, string largeHeading, string smallExplanation, Icon iconSet, string leftButton, string middleButton, string rightButton):this(title, largeHeading, smallExplanation, iconSet, leftButton, middleButton, rightButton){} public CustomMessageBoxBasicSettings(string title, string largeHeading, string smallExplanation, Image iconSet, string rightButton):this(title, largeHeading, smallExplanation, iconSet, null, null, rightButton) { } public CustomMessageBoxBasicSettings(string title, string largeHeading, string smallExplanation, Image iconSet, string middleButton, string rightButton):this(title, largeHeading, smallExplanation, iconSet, null, middleButton, rightButton) { } */ /// /// Create a special dialog in the style of Windows XP or Vista. A dialog has a custom icon, an optional large /// title in the form, body text, window text, and one or two custom-labeled buttons. /// /// This string will be displayed in the system window frame. /// This is the first string to appear in the dialog. It will be most prominent. /// /// This string appears either under the big string, or is null, which means it is /// not displayed at all. /// /// /// This is the left button, typically the "accept" button--label it with an /// action verb (or "OK"). /// /// /// The right button--typically "Cancel", but could be "No". /// An image to be displayed on the left side of the dialog. Should be 32 x 32 pixels. public CmbBasicSettings(string title, string largeHeading, string smallExplanation, Icon iconSet, string leftButton, string middleButton, string rightButton) { Title = title; LargeHeading = largeHeading; SmallExplanation = smallExplanation; LeftButton = leftButton; MiddleButton = middleButton; RightButton = rightButton; IconSet = iconSet; StartPosition = FormStartPosition.CenterParent; AlwaysOnTop = false; } public bool AlwaysOnTop { get; set; } //public Image IconSet { get; private set; } public Icon IconSet { get; } public string LargeHeading { get; } public string LeftButton { get; } public string MiddleButton { get; } public string RightButton { get; } public string SmallExplanation { get; } //public Form Parent { get; set; } public FormStartPosition StartPosition { get; set; } public string Title { get; } public Icon WindowIcon { get; set; } } } ================================================ FILE: source/KlocTools/Forms/CmbCheckboxSettings.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ namespace Klocman.Forms { public sealed class CmbCheckboxSettings { public CmbCheckboxSettings(string text) : this(text, false) { } public CmbCheckboxSettings(string text, bool initialState) { Text = text; InitialState = initialState; Result = null; } public bool DisableLeftButton { get; set; } public bool DisableMiddleButton { get; set; } public bool DisableRightButton { get; set; } public bool InitialState { get; } /// /// Resulting value of the checkbox. Null if not yet set. /// public bool? Result { get; internal set; } public string Text { get; } } } ================================================ FILE: source/KlocTools/Forms/CmbHyperlinkSettings.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; namespace Klocman.Forms { public sealed class CmbHyperlinkSettings { public CmbHyperlinkSettings(string text, Action clickAction) { Text = text; ClickAction = clickAction; } public Action ClickAction { get; private set; } public string Text { get; private set; } } } ================================================ FILE: source/KlocTools/Forms/CustomMessageBox.cs ================================================ using System; using System.Drawing; using System.Linq; using System.Windows.Forms; using Klocman.Extensions; using Klocman.Tools; namespace Klocman.Forms { public sealed partial class CustomMessageBox : Form { public enum PressedButton { None, Right, Middle, Left } private readonly CmbCheckboxSettings _checkboxSettings; private readonly Icon _overrideIcon; private int _topWidth, _topHeigth; private CustomMessageBox(CmbBasicSettings settings, CmbCheckboxSettings checkboxSettings) { Opacity = 0; Result = PressedButton.None; if (SystemFonts.MessageBoxFont != null) Font = SystemFonts.MessageBoxFont; ForeColor = SystemColors.WindowText; InitializeComponent(); StartPosition = settings.StartPosition; if (checkboxSettings != null) { _checkboxSettings = checkboxSettings; if (checkboxSettings.Text.IsNotEmpty()) checkBox1.Text = checkboxSettings.Text; checkBox1.Checked = checkboxSettings.InitialState; checkBox1.Visible = true; } else { checkBox1.Visible = false; } if (!string.IsNullOrEmpty(settings.SmallExplanation) && SystemFonts.MessageBoxFont != null) { if (SystemFonts.MessageBoxFont.FontFamily.Name == "Segoe UI" && SystemFonts.MessageBoxFont.FontFamily.IsStyleAvailable(FontStyle.Regular)) { // use the special, windows-vista font style if we are running vista (using Segoe UI). label1.ForeColor = Color.FromArgb(0, 51, 153); // [ColorTranslator.FromHtml("#003399")] label1.Font = new Font("Segoe UI", 12.0f, FontStyle.Regular, GraphicsUnit.Point); } else { // might want to special case the old, MS Sans Serif font. // use the regular font but bold it for XP, etc. label1.Font = new Font(SystemFonts.MessageBoxFont.FontFamily.Name, 8.0f, FontStyle.Bold, GraphicsUnit.Point); } } Text = settings.Title; label1.Text = settings.LargeHeading; label2.Text = string.IsNullOrEmpty(settings.SmallExplanation) ? string.Empty : settings.SmallExplanation; if (!string.IsNullOrEmpty(settings.LeftButton)) { // if we have the button, we are fine buttonLeft.Text = settings.LeftButton; } else { // move settings to right button if we don't have the left button AcceptButton = buttonMiddle; buttonLeft.Visible = false; panelLeft.Visible = false; } if (!string.IsNullOrEmpty(settings.MiddleButton)) { // if we have the button, we are fine buttonMiddle.Text = settings.MiddleButton; } else { // move settings to right button if we don't have the left button AcceptButton = buttonRight; buttonMiddle.Visible = false; panelMiddle.Visible = false; } // this button must always be present buttonRight.Text = settings.RightButton; if (settings.IconSet != null) { try { pictureBox1.Image = settings.IconSet.ToBitmap(); settings.IconSet.PlayCorrespondingSystemSound(); } catch (SystemException e) { Console.WriteLine(e); } } TopMost = settings.AlwaysOnTop; _overrideIcon = settings.WindowIcon; } internal bool Checked => checkBox1.Checked; public PressedButton Result { get; private set; } private void buttonLeft_Click(object sender, EventArgs e) { Result = PressedButton.Left; Close(); } private void buttonMiddle_Click(object sender, EventArgs e) { Result = PressedButton.Middle; Close(); } private void buttonRight_Click(object sender, EventArgs e) { Result = PressedButton.Right; Close(); } private void checkBox1_CheckedChanged(object sender, EventArgs e) { if (_checkboxSettings != null) { var enable = !checkBox1.Checked; if (_checkboxSettings.DisableRightButton) buttonRight.Enabled = enable; if (_checkboxSettings.DisableMiddleButton) buttonMiddle.Enabled = enable; if (_checkboxSettings.DisableLeftButton) buttonLeft.Enabled = enable; } } private void CustomMessageBox_SizeChanged(object sender, EventArgs e) { // Needed to prevent the size from shrinking by itself Width = _topWidth; Height = _topHeigth; } private void flowLayoutPanel1_SizeChanged(object sender, EventArgs e) { SetHeight(); SetWidth(); } protected override void OnShown(EventArgs e) { base.OnShown(e); if (_overrideIcon != null) Icon = _overrideIcon; else if (ParentForm?.Icon != null) Icon = ParentForm.Icon; else { try { Icon = ProcessTools.GetIconFromEntryExe(); } catch { /* Fall back to the default icon */ } } SetHeight(); SetWidth(); if (StartPosition == FormStartPosition.CenterParent && Owner != null && Owner.Visible) this.CenterToForm(Owner); Opacity = 1; } private void SetHeight() { var border = Height - ClientSize.Height; _topHeigth = Math.Max(panelButtons.Location.Y + panelButtons.Height + border, _topHeigth); Height = _topHeigth; } private void SetWidth() { var border = Width - ClientSize.Width; var buttonWidth = panelButtons.Controls.Cast().Where(x => x.Visible).Sum(x => x.Width) + panelButtons.Padding.Left + panelButtons.Padding.Right + border; _topWidth = Math.Max(buttonWidth, _topWidth); Width = _topWidth; } public static CustomMessageBox Show(Form owner, CmbBasicSettings settings) { return Show(owner, settings, null); } public static CustomMessageBox Show(Form owner, CmbBasicSettings settings, CmbCheckboxSettings checkboxSettings) { if (owner.IsDisposed || owner.Disposing || !owner.Visible) owner = null; var dialog = new CustomMessageBox(settings, checkboxSettings) { Owner = owner }; //, hyperlinkSettings)) dialog.Show(owner); if (dialog.Result != PressedButton.None && checkboxSettings != null) checkboxSettings.Result = dialog.Checked; return dialog; } public static PressedButton ShowDialog(Form owner, CmbBasicSettings settings, CmbCheckboxSettings checkboxSettings) { return ShowDialog(owner, settings, checkboxSettings, null); } public static PressedButton ShowDialog(Form owner, CmbBasicSettings settings, CmbHyperlinkSettings hyperlinkSettings) { return ShowDialog(owner, settings, null, hyperlinkSettings); } public static PressedButton ShowDialog(Form owner, CmbBasicSettings settings) { var result = PressedButton.None; void ShowDialogLocal() { result = ShowDialog(owner, settings, null, null); } if (owner != null) owner.SafeInvoke(ShowDialogLocal); else ShowDialogLocal(); return result; } public static PressedButton ShowDialog(Form owner, CmbBasicSettings settings, CmbCheckboxSettings checkboxSettings, CmbHyperlinkSettings hyperlinkSettings) { using (var dialog = new CustomMessageBox(settings, checkboxSettings)) //, hyperlinkSettings)) { if (owner != null && !owner.IsDisposed && !owner.Disposing) { if (owner.Visible) { dialog.Owner = owner; owner.Select(); dialog.ShowDialog(owner); } else { dialog.CenterToForm(owner); dialog.ShowDialog(); } } else { dialog.StartPosition = FormStartPosition.CenterScreen; dialog.ShowDialog(); } if (dialog.Result != PressedButton.None && checkboxSettings != null) checkboxSettings.Result = dialog.Checked; return dialog.Result; } } } } ================================================ FILE: source/KlocTools/Forms/CustomMessageBox.designer.cs ================================================ namespace Klocman.Forms { using System.ComponentModel; using System.Windows.Forms; sealed partial class CustomMessageBox { #region Fields private Button buttonLeft; private Button buttonMiddle; private Button buttonRight; private CheckBox checkBox1; /// /// Required designer variable. /// private IContainer components = null; private Label label1; private Label label2; private PictureBox pictureBox1; #endregion Fields #region Methods /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.pictureBox1 = new System.Windows.Forms.PictureBox(); this.label1 = new System.Windows.Forms.Label(); this.buttonRight = new System.Windows.Forms.Button(); this.buttonLeft = new System.Windows.Forms.Button(); this.label2 = new System.Windows.Forms.Label(); this.buttonMiddle = new System.Windows.Forms.Button(); this.checkBox1 = new System.Windows.Forms.CheckBox(); this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); this.panelButtons = new System.Windows.Forms.Panel(); this.panel1 = new System.Windows.Forms.Panel(); this.panelLeft = new System.Windows.Forms.Panel(); this.panelMiddle = new System.Windows.Forms.Panel(); ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); this.flowLayoutPanel1.SuspendLayout(); this.panelButtons.SuspendLayout(); this.SuspendLayout(); // // pictureBox1 // this.pictureBox1.BackColor = System.Drawing.SystemColors.Window; this.pictureBox1.Location = new System.Drawing.Point(25, 18); this.pictureBox1.Margin = new System.Windows.Forms.Padding(3, 11, 8, 3); this.pictureBox1.Name = "pictureBox1"; this.pictureBox1.Size = new System.Drawing.Size(32, 32); this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; this.pictureBox1.TabIndex = 0; this.pictureBox1.TabStop = false; // // label1 // this.label1.AutoSize = true; this.flowLayoutPanel1.SetFlowBreak(this.label1, true); this.label1.Location = new System.Drawing.Point(68, 0); this.label1.Name = "label1"; this.label1.Padding = new System.Windows.Forms.Padding(0, 12, 0, 12); this.label1.Size = new System.Drawing.Size(85, 37); this.label1.TabIndex = 2; this.label1.Text = "Dialog message."; // // buttonRight // this.buttonRight.AutoSize = true; this.buttonRight.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; this.buttonRight.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.buttonRight.Dock = System.Windows.Forms.DockStyle.Right; this.buttonRight.Location = new System.Drawing.Point(338, 11); this.buttonRight.MinimumSize = new System.Drawing.Size(75, 0); this.buttonRight.Name = "buttonRight"; this.buttonRight.Size = new System.Drawing.Size(75, 24); this.buttonRight.TabIndex = 2; this.buttonRight.Text = "Right"; this.buttonRight.UseVisualStyleBackColor = true; this.buttonRight.Click += new System.EventHandler(this.buttonRight_Click); // // buttonLeft // this.buttonLeft.AutoSize = true; this.buttonLeft.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; this.buttonLeft.DialogResult = System.Windows.Forms.DialogResult.OK; this.buttonLeft.Dock = System.Windows.Forms.DockStyle.Right; this.buttonLeft.Location = new System.Drawing.Point(168, 11); this.buttonLeft.MinimumSize = new System.Drawing.Size(75, 0); this.buttonLeft.Name = "buttonLeft"; this.buttonLeft.Size = new System.Drawing.Size(75, 24); this.buttonLeft.TabIndex = 0; this.buttonLeft.Text = "Left"; this.buttonLeft.UseVisualStyleBackColor = true; this.buttonLeft.Click += new System.EventHandler(this.buttonLeft_Click); // // label2 // this.label2.AutoSize = true; this.flowLayoutPanel1.SetFlowBreak(this.label2, true); this.label2.Location = new System.Drawing.Point(68, 37); this.label2.Name = "label2"; this.label2.Padding = new System.Windows.Forms.Padding(5, 5, 5, 14); this.label2.Size = new System.Drawing.Size(53, 32); this.label2.TabIndex = 0; this.label2.Text = "Caption"; // // buttonMiddle // this.buttonMiddle.AutoSize = true; this.buttonMiddle.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; this.buttonMiddle.DialogResult = System.Windows.Forms.DialogResult.OK; this.buttonMiddle.Dock = System.Windows.Forms.DockStyle.Right; this.buttonMiddle.Location = new System.Drawing.Point(253, 11); this.buttonMiddle.MinimumSize = new System.Drawing.Size(75, 0); this.buttonMiddle.Name = "buttonMiddle"; this.buttonMiddle.Size = new System.Drawing.Size(75, 24); this.buttonMiddle.TabIndex = 1; this.buttonMiddle.Text = "Middle"; this.buttonMiddle.UseVisualStyleBackColor = true; this.buttonMiddle.Click += new System.EventHandler(this.buttonMiddle_Click); // // checkBox1 // this.checkBox1.AutoSize = true; this.checkBox1.Dock = System.Windows.Forms.DockStyle.Left; this.checkBox1.Location = new System.Drawing.Point(11, 11); this.checkBox1.Name = "checkBox1"; this.checkBox1.Size = new System.Drawing.Size(112, 24); this.checkBox1.TabIndex = 3; this.checkBox1.Text = "Remember choice"; this.checkBox1.UseVisualStyleBackColor = true; this.checkBox1.CheckedChanged += new System.EventHandler(this.checkBox1_CheckedChanged); // // flowLayoutPanel1 // this.flowLayoutPanel1.AutoSize = true; this.flowLayoutPanel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; this.flowLayoutPanel1.BackColor = System.Drawing.SystemColors.Window; this.flowLayoutPanel1.Controls.Add(this.label1); this.flowLayoutPanel1.Controls.Add(this.label2); this.flowLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Top; this.flowLayoutPanel1.Location = new System.Drawing.Point(0, 0); this.flowLayoutPanel1.MinimumSize = new System.Drawing.Size(0, 65); this.flowLayoutPanel1.Name = "flowLayoutPanel1"; this.flowLayoutPanel1.Padding = new System.Windows.Forms.Padding(65, 0, 0, 0); this.flowLayoutPanel1.Size = new System.Drawing.Size(424, 69); this.flowLayoutPanel1.TabIndex = 3; this.flowLayoutPanel1.SizeChanged += new System.EventHandler(this.flowLayoutPanel1_SizeChanged); // // panelButtons // this.panelButtons.Controls.Add(this.panel1); this.panelButtons.Controls.Add(this.buttonLeft); this.panelButtons.Controls.Add(this.panelLeft); this.panelButtons.Controls.Add(this.buttonMiddle); this.panelButtons.Controls.Add(this.panelMiddle); this.panelButtons.Controls.Add(this.buttonRight); this.panelButtons.Controls.Add(this.checkBox1); this.panelButtons.Dock = System.Windows.Forms.DockStyle.Top; this.panelButtons.Location = new System.Drawing.Point(0, 69); this.panelButtons.Name = "panelButtons"; this.panelButtons.Padding = new System.Windows.Forms.Padding(11); this.panelButtons.Size = new System.Drawing.Size(424, 46); this.panelButtons.TabIndex = 5; // // panel1 // this.panel1.Dock = System.Windows.Forms.DockStyle.Right; this.panel1.Location = new System.Drawing.Point(158, 11); this.panel1.MaximumSize = new System.Drawing.Size(10, 11111111); this.panel1.MinimumSize = new System.Drawing.Size(10, 0); this.panel1.Name = "panel1"; this.panel1.Size = new System.Drawing.Size(10, 24); this.panel1.TabIndex = 6; // // panelLeft // this.panelLeft.Dock = System.Windows.Forms.DockStyle.Right; this.panelLeft.Location = new System.Drawing.Point(243, 11); this.panelLeft.MaximumSize = new System.Drawing.Size(10, 11111111); this.panelLeft.MinimumSize = new System.Drawing.Size(10, 0); this.panelLeft.Name = "panelLeft"; this.panelLeft.Size = new System.Drawing.Size(10, 24); this.panelLeft.TabIndex = 4; // // panelMiddle // this.panelMiddle.Dock = System.Windows.Forms.DockStyle.Right; this.panelMiddle.Location = new System.Drawing.Point(328, 11); this.panelMiddle.MaximumSize = new System.Drawing.Size(10, 11111111); this.panelMiddle.MinimumSize = new System.Drawing.Size(10, 0); this.panelMiddle.Name = "panelMiddle"; this.panelMiddle.Size = new System.Drawing.Size(10, 24); this.panelMiddle.TabIndex = 5; // // CustomMessageBox // this.AcceptButton = this.buttonLeft; this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.CancelButton = this.buttonRight; this.ClientSize = new System.Drawing.Size(424, 347); this.Controls.Add(this.pictureBox1); this.Controls.Add(this.panelButtons); this.Controls.Add(this.flowLayoutPanel1); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; this.KeyPreview = true; this.MaximizeBox = false; this.MinimizeBox = false; this.MinimumSize = new System.Drawing.Size(375, 171); this.Name = "CustomMessageBox"; this.ShowIcon = false; this.ShowInTaskbar = false; this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "Special Dialog"; this.SizeChanged += new System.EventHandler(this.CustomMessageBox_SizeChanged); ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); this.flowLayoutPanel1.ResumeLayout(false); this.flowLayoutPanel1.PerformLayout(); this.panelButtons.ResumeLayout(false); this.panelButtons.PerformLayout(); this.ResumeLayout(false); this.PerformLayout(); } #endregion Methods private FlowLayoutPanel flowLayoutPanel1; private Panel panelButtons; private Panel panelLeft; private Panel panelMiddle; private Panel panel1; } } ================================================ FILE: source/KlocTools/Forms/CustomMessageBox.resx ================================================ text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ================================================ FILE: source/KlocTools/Forms/LoadingDialog.Designer.cs ================================================ using System.ComponentModel; using System.Windows.Forms; namespace Klocman.Forms { sealed partial class LoadingDialog { /// /// Required designer variable. /// private IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { progressBar = new ProgressBar(); label1 = new Label(); panel1 = new Panel(); progressBar2 = new ProgressBar(); label2 = new Label(); panel1.SuspendLayout(); SuspendLayout(); // // progressBar // progressBar.Dock = DockStyle.Top; progressBar.Location = new System.Drawing.Point(7, 28); progressBar.Margin = new Padding(4, 3, 4, 3); progressBar.Name = "progressBar"; progressBar.Size = new System.Drawing.Size(392, 24); progressBar.Style = ProgressBarStyle.Marquee; progressBar.TabIndex = 0; progressBar.Value = 100; // // label1 // label1.AutoEllipsis = true; label1.AutoSize = true; label1.Dock = DockStyle.Top; label1.Location = new System.Drawing.Point(7, 7); label1.Margin = new Padding(4, 0, 4, 0); label1.Name = "label1"; label1.Padding = new Padding(0, 0, 0, 6); label1.Size = new System.Drawing.Size(59, 21); label1.TabIndex = 1; label1.Text = "Loading..."; // // panel1 // panel1.AutoSize = true; panel1.AutoSizeMode = AutoSizeMode.GrowAndShrink; panel1.BorderStyle = BorderStyle.FixedSingle; panel1.Controls.Add(progressBar2); panel1.Controls.Add(label2); panel1.Controls.Add(progressBar); panel1.Controls.Add(label1); panel1.Location = new System.Drawing.Point(0, 0); panel1.Margin = new Padding(0); panel1.MinimumSize = new System.Drawing.Size(408, 12); panel1.Name = "panel1"; panel1.Padding = new Padding(7, 7, 7, 7); panel1.Size = new System.Drawing.Size(408, 113); panel1.TabIndex = 2; panel1.Resize += panel1_Resize; // // progressBar2 // progressBar2.Dock = DockStyle.Top; progressBar2.Location = new System.Drawing.Point(7, 80); progressBar2.Margin = new Padding(4, 3, 4, 3); progressBar2.Name = "progressBar2"; progressBar2.Size = new System.Drawing.Size(392, 24); progressBar2.Style = ProgressBarStyle.Marquee; progressBar2.TabIndex = 2; progressBar2.Value = 100; progressBar2.Visible = false; // // label2 // label2.AutoEllipsis = true; label2.AutoSize = true; label2.Dock = DockStyle.Top; label2.Location = new System.Drawing.Point(7, 52); label2.Margin = new Padding(4, 0, 4, 0); label2.Name = "label2"; label2.Padding = new Padding(0, 7, 0, 6); label2.Size = new System.Drawing.Size(59, 28); label2.TabIndex = 3; label2.Text = "Loading..."; label2.Visible = false; // // LoadingDialog // AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); AutoScaleMode = AutoScaleMode.Font; AutoSizeMode = AutoSizeMode.GrowAndShrink; BackColor = System.Drawing.SystemColors.Control; ClientSize = new System.Drawing.Size(464, 290); ControlBox = false; Controls.Add(panel1); FormBorderStyle = FormBorderStyle.None; Margin = new Padding(4, 3, 4, 3); MaximizeBox = false; MinimizeBox = false; Name = "LoadingDialog"; ShowIcon = false; ShowInTaskbar = false; SizeGripStyle = SizeGripStyle.Hide; StartPosition = FormStartPosition.CenterParent; panel1.ResumeLayout(false); panel1.PerformLayout(); ResumeLayout(false); PerformLayout(); } #endregion private Label label1; private Panel panel1; private ProgressBar progressBar; private ProgressBar progressBar2; private Label label2; } } ================================================ FILE: source/KlocTools/Forms/LoadingDialog.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.ComponentModel; using System.Drawing; using System.Threading; using System.Windows.Forms; using Klocman.Tools; namespace Klocman.Forms { public sealed partial class LoadingDialog : Form { private readonly Thread _workThread; private readonly LoadingDialogInterface _controller; private Point _offset; private ContentAlignment _ownerAlignment; private bool _startAutomatically; internal LoadingDialog(string title, Action action) { InitializeComponent(); Text = title; label1.Text = title; UseWaitCursor = true; _controller = new LoadingDialogInterface(this); _workThread = new Thread(() => { _controller.WaitTillDialogIsReady(); try { action(_controller); } catch (Exception ex) { Error = ex; } _controller.CloseDialog(); }) { Name = "LoadingDialogThread - " + title }; } protected override CreateParams CreateParams { get { const int csDropshadow = 0x20000; var cp = base.CreateParams; cp.ClassStyle |= csDropshadow; return cp; } } public static Form DefaultOwner { get; set; } public Exception Error { get; private set; } internal ProgressBar ProgressBar => progressBar; internal ProgressBar SubProgressBar => progressBar2; /*public string StatusText { get { return label1.Text; } set { label1.Text = value; } } internal string SubStatusText { get { return label2.Text; } set { label2.Text = value; } }*/ [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] internal bool SubProgressVisible { get { return progressBar2.Visible; } set { progressBar2.Visible = value; label2.Visible = value; } } internal Label StatusLabel => label1; internal Label SubStatusLabel => label2; protected override void OnLoad(EventArgs e) { base.OnLoad(e); if (Owner?.Icon != null) Icon = Owner.Icon; else { try { Icon = ProcessTools.GetIconFromEntryExe(); } catch { /* Fall back to the default icon */ } } } protected override void OnShown(EventArgs e) { base.OnShown(e); if (Owner != null) { Owner.Move += OwnerOnMove; Owner.Resize += OwnerOnMove; OwnerOnMove(this, e); } if (_startAutomatically) StartWork(); } protected override void OnClosing(CancelEventArgs e) { if (Owner != null) { Owner.Move -= OwnerOnMove; Owner.Resize -= OwnerOnMove; } base.OnClosing(e); } protected override void OnFormClosed(FormClosedEventArgs e) { _controller.Abort = true; base.OnFormClosed(e); } protected override void OnResize(EventArgs e) { base.OnResize(e); OwnerOnMove(this, e); } private void OwnerOnMove(object sender, EventArgs eventArgs) { if (Owner == null) return; var newPos = new Point(); switch (_ownerAlignment) { case ContentAlignment.MiddleLeft: case ContentAlignment.MiddleCenter: case ContentAlignment.MiddleRight: newPos.Y = Owner.Location.Y + Owner.Size.Height / 2 - Size.Height / 2; break; case ContentAlignment.BottomLeft: case ContentAlignment.BottomCenter: case ContentAlignment.BottomRight: newPos.Y = Owner.Location.Y + Owner.Size.Height - Size.Height; break; default: break; } switch (_ownerAlignment) { case ContentAlignment.TopCenter: case ContentAlignment.MiddleCenter: case ContentAlignment.BottomCenter: newPos.X = Owner.Location.X + Owner.Size.Width / 2 - Size.Width / 2; break; case ContentAlignment.TopRight: case ContentAlignment.MiddleRight: case ContentAlignment.BottomRight: newPos.X = Owner.Location.X + Owner.Size.Width - Size.Width; break; default: break; } newPos.X += _offset.X; newPos.Y += _offset.Y; Location = newPos; } /// /// Start the action on a separate thread and show a progress bar. When action completes the dialog is closed. /// /// Parent form /// Title of the window /// Action to perform while displaying the dialog /// Offset from the alignment point /// Alignment point to the parent public static LoadingDialog Show(Form owner, string title, Action action, Point offset = default(Point), ContentAlignment ownerAlignment = ContentAlignment.MiddleCenter) { if (owner == null) owner = DefaultOwner; // Find the topmost form so clicking on forms above owner doesn't bring the loading form under the others while (owner != null && owner.OwnedForms.Length > 0) owner = owner.OwnedForms[0]; var loadBar = new LoadingDialog(title, action) { _offset = offset, _ownerAlignment = ownerAlignment, Owner = owner, StartPosition = FormStartPosition.Manual, _startAutomatically = false, }; loadBar.Show(loadBar.Owner); return loadBar; } /// /// Start the action on a separate thread and show a progress bar. /// /// Parent form /// Title of the window /// Action to perform while displaying the dialog /// Offset from the alignment point /// Alignment point to the parent public static Exception ShowDialog(Form owner, string title, Action action, Point offset = default(Point), ContentAlignment ownerAlignment = ContentAlignment.MiddleCenter) { using (var loadBar = new LoadingDialog(title, action) { _offset = offset, _ownerAlignment = ownerAlignment, Owner = owner ?? DefaultOwner, StartPosition = FormStartPosition.Manual, _startAutomatically = true }) { loadBar.ShowDialog(loadBar.Owner); return loadBar.Error; } } public void StartWork() { _workThread.Start(); } private void panel1_Resize(object sender, EventArgs e) { Size = panel1.Size; } } } ================================================ FILE: source/KlocTools/Forms/LoadingDialog.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ================================================ FILE: source/KlocTools/Forms/LoadingDialogInterface.cs ================================================ using System; using System.Threading; using System.Timers; using System.Windows.Forms; using Klocman.Extensions; using Timer = System.Timers.Timer; namespace Klocman.Forms { [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1001:Types that own disposable fields should be disposable", Justification = "")] public sealed class LoadingDialogInterface { private readonly Timer _updateTimer; private Action _lastProgressUpdate; private Action _lastSubProgressUpdate; internal LoadingDialogInterface(LoadingDialog dialog) { Dialog = dialog; _updateTimer = new Timer { AutoReset = true, Interval = 35, SynchronizingObject = Dialog }; _updateTimer.Elapsed += UpdateTimerOnElapsed; _updateTimer.Start(); dialog.Disposed += (sender, args) => _updateTimer.Dispose(); } private void UpdateTimerOnElapsed(object sender, ElapsedEventArgs elapsedEventArgs) { var p = Interlocked.Exchange(ref _lastProgressUpdate, null); p?.Invoke(); p = Interlocked.Exchange(ref _lastSubProgressUpdate, null); p?.Invoke(); } public bool Abort { get; internal set; } private LoadingDialog Dialog { get; } public void CloseDialog() { _updateTimer.Dispose(); Dialog.SafeInvoke(() => { if (!Dialog.IsDisposed) Dialog.Close(); }); } public void SetMaximum(int value) { SetMaximumInt(value, Dialog.ProgressBar); } private void SetMaximumInt(int value, ProgressBar targetBar) { Dialog.SafeInvoke(() => { if (targetBar.Maximum == value) return; if (value < targetBar.Minimum) targetBar.Style = ProgressBarStyle.Marquee; else { try { targetBar.Maximum = value; } catch { targetBar.Style = ProgressBarStyle.Marquee; } } }); } public void SetMinimum(int value) { SetMinimumInt(value, Dialog.ProgressBar); } private void SetMinimumInt(int value, ProgressBar targetBar) { Dialog.SafeInvoke(() => { try { targetBar.Minimum = value; } catch { targetBar.Style = ProgressBarStyle.Marquee; } }); } /// /// Setting progress automatically changes the style from "Unknown time" (Marquee) to a normal progressbar. /// If the value is invalid the style goes back to Marquee /// public void SetProgress(int value, string description = null, bool forceNoAnimation = false) { _lastProgressUpdate = () => SetProgressInt(value, description, Dialog.ProgressBar, Dialog.StatusLabel, forceNoAnimation); } private void SetProgressInt(int value, string description, ProgressBar targetBar, Label targetLabel, bool forceNoAnimation) { if (description != null && targetLabel.Text != description) targetLabel.Text = description; try { if (targetBar.Value == value) return; var min = targetBar.Minimum; var max = targetBar.Maximum; if (min >= max || min > value || value > max) { targetBar.Style = ProgressBarStyle.Marquee; } else { targetBar.Style = ProgressBarStyle.Blocks; if (value < min) value = min; else if (value > max) value = max; if (forceNoAnimation) { // Moving progress forward then back skips the animation if (value == max) { targetBar.Maximum = value + 1; targetBar.Value = value + 1; targetBar.Maximum = value; } else { targetBar.Value = value + 1; } } targetBar.Value = value; } } catch { targetBar.Style = ProgressBarStyle.Marquee; } } public void SetSubMaximum(int value) { SetMaximumInt(value, Dialog.SubProgressBar); } public void SetSubMinimum(int value) { SetMinimumInt(value, Dialog.SubProgressBar); } public void SetSubProgress(int value, string description, bool forceNoAnimation = false) { _lastSubProgressUpdate = () => SetProgressInt(value, description, Dialog.SubProgressBar, Dialog.SubStatusLabel, forceNoAnimation); } public void SetSubProgressVisible(bool visible) { Dialog.SafeInvoke(() => { Dialog.SubProgressVisible = visible; }); } public void SetTitle(string newTitle) { Dialog.SafeInvoke(() => { Dialog.Text = newTitle; }); } /// /// Block current thread until dialog is visible /// internal void WaitTillDialogIsReady() { var notReady = true; while (notReady) { Dialog.SafeInvoke(() => notReady = !Dialog.Visible); Thread.Sleep(10); } } } } ================================================ FILE: source/KlocTools/Forms/OverlaySplashScreen.Designer.cs ================================================ namespace Klocman.Forms { partial class OverlaySplashScreen { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.components = new System.ComponentModel.Container(); this.startupSplashPictureBox = new System.Windows.Forms.PictureBox(); this.timerFadeout = new System.Windows.Forms.Timer(this.components); ((System.ComponentModel.ISupportInitialize)(this.startupSplashPictureBox)).BeginInit(); this.SuspendLayout(); // // startupSplashPictureBox // this.startupSplashPictureBox.BackColor = System.Drawing.SystemColors.Window; this.startupSplashPictureBox.Dock = System.Windows.Forms.DockStyle.Fill; this.startupSplashPictureBox.Image = global::Klocman.Properties.Resources.centerline; this.startupSplashPictureBox.ImeMode = System.Windows.Forms.ImeMode.NoControl; this.startupSplashPictureBox.Location = new System.Drawing.Point(0, 0); this.startupSplashPictureBox.Name = "startupSplashPictureBox"; this.startupSplashPictureBox.Size = new System.Drawing.Size(284, 261); this.startupSplashPictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage; this.startupSplashPictureBox.TabIndex = 0; this.startupSplashPictureBox.TabStop = false; // // timerFadeout // this.timerFadeout.Interval = 25; this.timerFadeout.Tick += new System.EventHandler(this.timerFadeout_Tick); // // OverlaySplashScreen // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.BackColor = System.Drawing.SystemColors.Window; this.ClientSize = new System.Drawing.Size(284, 261); this.ControlBox = false; this.Controls.Add(this.startupSplashPictureBox); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "OverlaySplashScreen"; this.ShowIcon = false; this.ShowInTaskbar = false; this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; this.StartPosition = System.Windows.Forms.FormStartPosition.Manual; ((System.ComponentModel.ISupportInitialize)(this.startupSplashPictureBox)).EndInit(); this.ResumeLayout(false); } #endregion private System.Windows.Forms.PictureBox startupSplashPictureBox; private System.Windows.Forms.Timer timerFadeout; } } ================================================ FILE: source/KlocTools/Forms/OverlaySplashScreen.cs ================================================ using System; using System.Drawing; using System.Windows.Forms; namespace Klocman.Forms { internal partial class OverlaySplashScreen : Form { private readonly Form _owner; private bool _faded; /// /// Create a new splash screen. /// /// Form over which the splas screen will be drawn /// Image that the splash is showing public OverlaySplashScreen(Form owner, Image shownImage) : this() { _owner = owner; startupSplashPictureBox.Image = shownImage; Icon = _owner.Icon; Location = _owner.PointToScreen(Point.Empty); Size = _owner.ClientSize; _owner.Move += OnOwnerMove; _owner.Resize += OnOwnerResize; _owner.FormClosed += OnOwnerClosed; } private OverlaySplashScreen() { InitializeComponent(); } /// /// Fade out the splash screen /// public void FadeOut() { if (_faded || IsDisposed) return; _faded = true; timerFadeout.Start(); } protected override void OnClosed(EventArgs e) { _owner.Move -= OnOwnerMove; _owner.Resize -= OnOwnerResize; _owner.FormClosed -= OnOwnerClosed; } protected override void OnGotFocus(EventArgs e) { _owner.Focus(); } private void OnOwnerClosed(object sender, FormClosedEventArgs args) { Close(); } private void OnOwnerMove(object sender, EventArgs args) { Location = _owner.PointToScreen(Point.Empty); } private void OnOwnerResize(object sender, EventArgs e) { Size = _owner.ClientSize; } private void timerFadeout_Tick(object sender, EventArgs e) { var op = Math.Max(0, Opacity - 0.14); if (Math.Abs(op) < 0.01) { timerFadeout.Stop(); Close(); Dispose(); } else { Opacity = op; } } } } ================================================ FILE: source/KlocTools/Forms/OverlaySplashScreen.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 17, 17 ================================================ FILE: source/KlocTools/Forms/ProcessWaiter.Designer.cs ================================================ namespace Klocman.Forms { partial class ProcessWaiter { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ProcessWaiter)); processWaiterControl1 = new ProcessWaiterControl(); SuspendLayout(); // // processWaiterControl1 // resources.ApplyResources(processWaiterControl1, "processWaiterControl1"); processWaiterControl1.Name = "processWaiterControl1"; processWaiterControl1.ShowIgnoreAndCancel = true; // // ProcessWaiter // resources.ApplyResources(this, "$this"); AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; ControlBox = false; Controls.Add(processWaiterControl1); MaximizeBox = false; MinimizeBox = false; Name = "ProcessWaiter"; ShowIcon = false; ShowInTaskbar = false; SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; Shown += ProcessWaiter_Shown; ResumeLayout(false); } #endregion private ProcessWaiterControl processWaiterControl1; } } ================================================ FILE: source/KlocTools/Forms/ProcessWaiter.ar.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 انظار حتى انتهاء العمليات... ================================================ FILE: source/KlocTools/Forms/ProcessWaiter.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Windows.Forms; namespace Klocman.Forms { public partial class ProcessWaiter : Form { private ProcessWaiter() { InitializeComponent(); processWaiterControl1.AllProcessesClosed += ProcessWaiterControl1_AllProcessesClosed; processWaiterControl1.CancelClicked += ProcessWaiterControl1_CancelClicked; } private void ProcessWaiterControl1_CancelClicked(object sender, EventArgs e) { DialogResult = DialogResult.Cancel; Close(); } private void ProcessWaiterControl1_AllProcessesClosed(object sender, EventArgs e) { DialogResult = DialogResult.OK; Close(); } /// /// Returns flase if user cancels the operation. /// /// /// IDs of processes to check /// Check child processes as well /// public static bool ShowDialog(Form owner, int[] processIDs, bool processChildren) { using (var pw = new ProcessWaiter()) { pw.Icon = owner.Icon; pw.processWaiterControl1.Initialize(processIDs,processChildren); return pw.ShowDialog(owner) == DialogResult.OK; } } private void ProcessWaiter_Shown(object sender, EventArgs e) { processWaiterControl1.StartUpdating(); } } } ================================================ FILE: source/KlocTools/Forms/ProcessWaiter.cs.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Čekání na ukončení procesu ... ================================================ FILE: source/KlocTools/Forms/ProcessWaiter.de.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Warte auf das Beenden der Prozesse... ================================================ FILE: source/KlocTools/Forms/ProcessWaiter.es.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Esperando procesos para salir... ================================================ FILE: source/KlocTools/Forms/ProcessWaiter.fr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 En attente de la sortie des processus... ================================================ FILE: source/KlocTools/Forms/ProcessWaiter.hu.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Várakozás a folyamatok leállítására... ================================================ FILE: source/KlocTools/Forms/ProcessWaiter.it.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 In attesa che il processo sia concluso... ================================================ FILE: source/KlocTools/Forms/ProcessWaiter.ja.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 プロセスの終了を待っています... ================================================ FILE: source/KlocTools/Forms/ProcessWaiter.nl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Wachten op het beëindigen van de processen... ================================================ FILE: source/KlocTools/Forms/ProcessWaiter.pl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Oczekiwanie na zamknięcie procesów... ================================================ FILE: source/KlocTools/Forms/ProcessWaiter.pt-BR.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Esperando processos para sair... ================================================ FILE: source/KlocTools/Forms/ProcessWaiter.pt.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 À espera do término dos processos... ================================================ FILE: source/KlocTools/Forms/ProcessWaiter.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Fill 7, 7 5, 3, 5, 3 7, 7, 7, 7 502, 323 0 processWaiterControl1 Klocman.Forms.ProcessWaiterControl, KlocTools, Culture=neutral, PublicKeyToken=null $this 0 True 7, 15 516, 337 4, 3, 4, 3 7, 7, 7, 7 CenterParent Waiting for processes to exit... ProcessWaiter System.Windows.Forms.Form, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 ================================================ FILE: source/KlocTools/Forms/ProcessWaiter.ru.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Дождитесь остановки процессов... ================================================ FILE: source/KlocTools/Forms/ProcessWaiter.sl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Čakanje na procese, za izhod... ================================================ FILE: source/KlocTools/Forms/ProcessWaiter.sv.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Väntar på att processer ska avslutas... ================================================ FILE: source/KlocTools/Forms/ProcessWaiter.tr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Çıkmak için işlemler bekleniyor... ================================================ FILE: source/KlocTools/Forms/ProcessWaiter.vi.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Chờ cho quá trình kết thúc... ================================================ FILE: source/KlocTools/Forms/ProcessWaiter.zh-Hans.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 正在等待进程退出... ================================================ FILE: source/KlocTools/Forms/ProcessWaiter.zh-Hant.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 正在等待程序退出... ================================================ FILE: source/KlocTools/Forms/ProcessWaiterControl.Designer.cs ================================================ namespace Klocman.Forms { partial class ProcessWaiterControl { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } _timer?.Dispose(); base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ProcessWaiterControl)); treeView1 = new System.Windows.Forms.TreeView(); label1 = new System.Windows.Forms.Label(); buttonCancel = new System.Windows.Forms.Button(); buttonIgnore = new System.Windows.Forms.Button(); buttonKillAll = new System.Windows.Forms.Button(); flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); panel1 = new System.Windows.Forms.Panel(); buttonKill = new System.Windows.Forms.Button(); panel3 = new System.Windows.Forms.Panel(); panel2c = new System.Windows.Forms.Panel(); panel4c = new System.Windows.Forms.Panel(); flowLayoutPanel1.SuspendLayout(); panel1.SuspendLayout(); SuspendLayout(); // // treeView1 // resources.ApplyResources(treeView1, "treeView1"); treeView1.Name = "treeView1"; treeView1.ShowNodeToolTips = true; treeView1.AfterSelect += treeView1_AfterSelect; // // label1 // resources.ApplyResources(label1, "label1"); label1.Name = "label1"; // // buttonCancel // resources.ApplyResources(buttonCancel, "buttonCancel"); buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; buttonCancel.Name = "buttonCancel"; buttonCancel.UseVisualStyleBackColor = true; buttonCancel.Click += buttonCancel_Click; // // buttonIgnore // resources.ApplyResources(buttonIgnore, "buttonIgnore"); buttonIgnore.Name = "buttonIgnore"; buttonIgnore.UseVisualStyleBackColor = true; buttonIgnore.Click += buttonIgnore_Click; // // buttonKillAll // resources.ApplyResources(buttonKillAll, "buttonKillAll"); buttonKillAll.Name = "buttonKillAll"; buttonKillAll.UseVisualStyleBackColor = true; buttonKillAll.Click += buttonKillAll_Click; // // flowLayoutPanel1 // resources.ApplyResources(flowLayoutPanel1, "flowLayoutPanel1"); flowLayoutPanel1.Controls.Add(label1); flowLayoutPanel1.Name = "flowLayoutPanel1"; // // panel1 // panel1.Controls.Add(buttonKill); panel1.Controls.Add(panel3); panel1.Controls.Add(buttonKillAll); panel1.Controls.Add(panel2c); panel1.Controls.Add(buttonIgnore); panel1.Controls.Add(panel4c); panel1.Controls.Add(buttonCancel); resources.ApplyResources(panel1, "panel1"); panel1.Name = "panel1"; // // buttonKill // resources.ApplyResources(buttonKill, "buttonKill"); buttonKill.Name = "buttonKill"; buttonKill.UseVisualStyleBackColor = true; buttonKill.Click += buttonKill_Click; // // panel3 // resources.ApplyResources(panel3, "panel3"); panel3.Name = "panel3"; // // panel2c // resources.ApplyResources(panel2c, "panel2c"); panel2c.Name = "panel2c"; // // panel4c // resources.ApplyResources(panel4c, "panel4c"); panel4c.Name = "panel4c"; // // ProcessWaiterControl // resources.ApplyResources(this, "$this"); AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; Controls.Add(treeView1); Controls.Add(panel1); Controls.Add(flowLayoutPanel1); Name = "ProcessWaiterControl"; flowLayoutPanel1.ResumeLayout(false); flowLayoutPanel1.PerformLayout(); panel1.ResumeLayout(false); panel1.PerformLayout(); ResumeLayout(false); PerformLayout(); } #endregion private System.Windows.Forms.TreeView treeView1; private System.Windows.Forms.Label label1; private System.Windows.Forms.Button buttonCancel; private System.Windows.Forms.Button buttonIgnore; private System.Windows.Forms.Button buttonKillAll; private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1; private System.Windows.Forms.Panel panel1; private System.Windows.Forms.Button buttonKill; private System.Windows.Forms.Panel panel3; private System.Windows.Forms.Panel panel2c; private System.Windows.Forms.Panel panel4c; } } ================================================ FILE: source/KlocTools/Forms/ProcessWaiterControl.ar.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 قتل قتل الكل تجاهل الغاء الامر قد تستخدم العمليات التالية الملفات التي سيتم الغاء تثبيتها الان ، الرجاء اغلاقها قبل المتابعة. اذا قررت عدم اغلاقها ، فقد يفشل الغاء تثبيت بعض المواد او تسبب مشاكل. قد تفقد ايضا ايه بيانات غير محفوظه تم فتحها في تلك التطبيقات. ================================================ FILE: source/KlocTools/Forms/ProcessWaiterControl.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Linq; using System.Windows.Forms; using Klocman.Forms.Tools; using Klocman.Tools; using Timer = System.Timers.Timer; namespace Klocman.Forms { public partial class ProcessWaiterControl : UserControl { private readonly Timer _timer = new(600); private static readonly string DefaultImageKey = "Default"; public void Initialize(int[] processIDs, bool processChildren) { treeView1.ShowRootLines = processChildren; SetNodes(processIDs, processChildren); } public bool ProcessesStillRunning => treeView1.Nodes.Count > 0; public void StartUpdating() { _timer.Start(); } public ProcessWaiterControl() { InitializeComponent(); _timer.Elapsed += updateTimer_Tick; _timer.AutoReset = false; _timer.SynchronizingObject = this; } private IEnumerable MainMonitoredProcesses { get { return treeView1.Nodes.Cast().Select(x => x.Tag as Process); } } private void SetNodes(int[] processIDs, bool processChildren) { var results = new List(); var il = new ImageList(); il.Images.Add(DefaultImageKey, SystemIcons.Application); treeView1.ImageKey = DefaultImageKey; foreach (var id in processIDs) { try { var p = Process.GetProcessById(id); if (p.HasExited) continue; var mainPrName = string.IsNullOrEmpty(p.MainWindowTitle) ? p.ProcessName : p.MainWindowTitle; var node = new TreeNode(mainPrName) { SelectedImageKey = mainPrName, ImageKey = mainPrName, Tag = p }; results.Add(node); try { var ico = DrawingTools.ExtractAssociatedIcon(p.MainModule!.FileName); if (ico != null) il.Images.Add(mainPrName, ico); } catch (Exception ex) { Console.WriteLine(ex); } if (!processChildren) continue; try { var children = ProcessTools.GetChildProcesses(id); node.Nodes.AddRange(children.Select(x => { var pr = Process.GetProcessById(x); var name = string.IsNullOrEmpty(pr.MainWindowTitle) ? pr.ProcessName : pr.MainWindowTitle; return new TreeNode(name) { SelectedImageKey = mainPrName, ImageKey = mainPrName, Tag = pr }; }).ToArray()); } catch (Exception ex) { // Ignore, probably the process exited by now. The child nodes are not important Console.WriteLine(ex); } } catch (Exception ex) { // Probably the main process exited, remove it from the task Console.WriteLine(ex); } } treeView1.Nodes.Clear(); var prev = treeView1.ImageList; treeView1.ImageList = il; prev?.Dispose(); treeView1.Nodes.AddRange(results.ToArray()); } [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public bool ShowIgnoreAndCancel { get { return buttonCancel.Enabled; } set { buttonIgnore.Enabled = value; buttonIgnore.Visible = value; buttonCancel.Enabled = value; buttonCancel.Visible = value; panel2c.Visible = value; panel4c.Visible = value; } } public event EventHandler AllProcessesClosed; public event EventHandler CancelClicked; private void buttonIgnore_Click(object sender, EventArgs e) { AllProcessesClosed?.Invoke(sender, e); } private void buttonKillAll_Click(object sender, EventArgs e) { // ask if sure and kill if (!PremadeDialogs.KillRunningProcessesQuestion()) return; foreach (var id in MainMonitoredProcesses) { try { id.Kill(false); } catch (Exception ex) { // Ignore, probably the process exited by now Console.WriteLine(ex); } } } private void updateTimer_Tick(object sender, EventArgs e) { foreach (var node in treeView1.Nodes.Cast().ToArray()) { try { if (node.Tag is not Process pr || pr.HasExited) { treeView1.Nodes.Remove(node); } else { foreach (var subNode in node.Nodes.Cast().ToArray()) { try { if (subNode.Tag is not Process spr || spr.HasExited) node.Nodes.Remove(subNode); } catch (Exception ex) { Console.WriteLine(ex); node.Nodes.Remove(subNode); } } } } catch (Exception ex) { Console.WriteLine(ex); treeView1.Nodes.Remove(node); } } if (treeView1.Nodes.Count <= 0) AllProcessesClosed?.Invoke(sender, e); else _timer.Start(); } private void buttonKill_Click(object sender, EventArgs e) { if (treeView1.SelectedNode?.Tag is not Process process) return; try { process.Kill(); } catch (Exception ex) { Console.WriteLine(ex); } } private void treeView1_AfterSelect(object sender, TreeViewEventArgs e) { buttonKill.Enabled = treeView1.SelectedNode != null; } private void buttonCancel_Click(object sender, EventArgs e) { CancelClicked?.Invoke(sender, e); } public void StopUpdating() { _timer.Stop(); } } } ================================================ FILE: source/KlocTools/Forms/ProcessWaiterControl.cs.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Ukončit Ukončit vše Ignorovat Zrušit Následující procesy by mohly používat soubory, které bude nyní možné odinstalovat, zavřete je prosím před pokračováním. Pokud se rozhodnete k neuzavření, odinstalování některých položek může dojít k selhání nebo způsobit problémy. Můžete také přijít o neuložená data otevřené v těchto aplikacích. ================================================ FILE: source/KlocTools/Forms/ProcessWaiterControl.de.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Beenden Alle beenden Ignorieren Abbrechen Die folgenden Prozesse verwenden möglicherweise Dateien, die jetzt deinstalliert werden sollen. Schließen Sie sie bitte bevor Sie fortfahren. Wenn Sie sich entscheiden, sie nicht zu schließen, könnte die Deinstallation fehlschlagen oder Probleme verursachen. Sie verlieren auch alle nicht gespeicherten Daten, die von diesen Anwendungen geöffnet sind. ================================================ FILE: source/KlocTools/Forms/ProcessWaiterControl.es.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Terminar Terminar todo Ignorar Cancelar Los siguientes procesos podrían estar utilizando archivos que ahora se desinstalarán, por favor, ciérrelos antes de continuar. Si decide no cerrarlos, la desinstalación de algunos elementos podría fallar o causar problemas. También puede perder todos los datos no guardados abiertos en esas aplicaciones. ================================================ FILE: source/KlocTools/Forms/ProcessWaiterControl.fr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Tuer Tuer tout Ignorer Annuler Les processus suivants pourraient utiliser des fichiers qui vont maintenant être désinstallés ; veuillez les fermer avant de continuer. Si vous décidez de ne pas les fermer, la désinstallation de quelques éléments pourrait échouer ou causer des problèmes. Vous pourriez aussi perdre toute donnée non sauvegardée ouverte dans ces applications. ================================================ FILE: source/KlocTools/Forms/ProcessWaiterControl.hu.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Leállítás Mindet leállít Kihagyás Mégse A következő folyamatok lehet, hogy olyan fájlokat használnak, amelyek nem távolíthatók el addig, amíg ezeket nem zárja be. Ha úgy dönt, hogy mégsem zárja be ezeket, egyes elemek eltávolítása sikertelen lesz, vagy problémákat okozhat. Illetve a megnyitott alkalmazásokban adatvesztéssel járhat. ================================================ FILE: source/KlocTools/Forms/ProcessWaiterControl.it.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Termina Termina tutto Ignora Cancella I seguenti processi potrebbero utilizzare file che saranno disinstallati, ti invitiamo a chiuderli prima di continuare. Se decidessi di non farlo la disinstallazione di alcuni elementi potrebbe fallire o causare problemi. Potresti perdere delle informazioni non salvate in uso in quelle applicazioni. ================================================ FILE: source/KlocTools/Forms/ProcessWaiterControl.ja.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 終了 すべて終了 無視 キャンセル 以下のプロセスが現在アンインストールされるファイルを使用している可能性があります。続行する前に閉じてください。閉じない場合、一部のアイテムのアンインストールが失敗するか、問題を引き起こす可能性があります。また、これらのアプリケーションで開いている未保存のデータが失われることがあります。 ================================================ FILE: source/KlocTools/Forms/ProcessWaiterControl.nl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Beëindigen Alle beëindigen Negeren Annuleren De volgende processen gebruiken mogelijk bestanden, die nu gede-installeerd moeten worden. Sluit deze eerst voordat u verder gaat. Als u ervoor kiest deze niet te sluiten, kan de de-installatie mislukken of problemen veroorzaken. Daardoor verliest u ook alle niet opgeslagen gegevens, die door deze toepasssing(en) geopend zijn. ================================================ FILE: source/KlocTools/Forms/ProcessWaiterControl.pl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Zakończ Zakończ wszystkie Ignoruj Anuluj Następujące procesy mogą używać niektórych plików które zostaną teraz odinstalowane, i powinny zostać zamknięte przed kontynuacją. Jeżeli nie zostaną zamknięte, dezinstalacja niektórych elementów może się nie powieść lub może sprawić problemy. Mogą także zostać utracone niezapisane dane otwarte w tych aplikacjach. ================================================ FILE: source/KlocTools/Forms/ProcessWaiterControl.pt-BR.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Terminar Finalizar tudo Ignorar Cancelar Os seguintes processos podem estar usando arquivos que agora serão desinstalados, feche-os antes de continuar. Se você decidir não fechá-los, a desinstalação de alguns itens pode falhar ou causar problemas. Você também pode perder todos os dados não salvos abertos nesses aplicativos. ================================================ FILE: source/KlocTools/Forms/ProcessWaiterControl.pt.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Terminar Acabar com tudo Ignorar Cancelar Os seguintes processos podem estar a usar arquivos que não serão desinstalados; feche-os antes de continuar. Se decidir não os fechar, a desinstalação de alguns itens poderá falhar ou causar problemas. Também pode perder dados que não foram guardados, abertos nessas aplicações. ================================================ FILE: source/KlocTools/Forms/ProcessWaiterControl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Fill 0, 54 4, 3, 4, 3 617, 287 1 treeView1 System.Windows.Forms.TreeView, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 0 True 4, 0 4, 0, 4, 0 605, 45 0 The following processes might be using files that will now be uninstalled, please close them before continuing. If you decide not to close them, uninstallation of some items might fail or cause problems. You might also lose any unsaved data opened in those applications. label1 System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 flowLayoutPanel1 0 True Right 527, 9 4, 3, 4, 3 88, 31 3 Cancel buttonCancel System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel1 6 True Right 427, 9 4, 3, 4, 3 88, 31 2 Ignore buttonIgnore System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel1 4 True Right 296, 9 4, 3, 4, 3 119, 31 1 Kill all buttonKillAll System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel1 2 True Top 0, 0 4, 3, 4, 3 0, 0, 0, 9 617, 54 0 flowLayoutPanel1 System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 2 True Right False NoControl 196, 9 4, 3, 4, 3 88, 31 0 Kill buttonKill System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel1 0 Right 284, 9 4, 3, 4, 3 12, 31 5 panel3 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel1 1 Right 415, 9 4, 3, 4, 3 12, 31 4 panel2c System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel1 3 Right 515, 9 4, 3, 4, 3 12, 31 6 panel4c System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel1 5 Bottom 0, 341 4, 3, 4, 3 2, 9, 2, 2 617, 42 2 panel1 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 1 True 7, 15 4, 3, 4, 3 617, 383 ProcessWaiterControl System.Windows.Forms.UserControl, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 ================================================ FILE: source/KlocTools/Forms/ProcessWaiterControl.ru.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Убить Убить все Игнор Отмена Следующие процессы могут использовать файлы, которые будут сейчас удалены, пожалуйста, закройте их перед продолжением. Если Вы решили не закрывать их, то удаление некоторых элементов может не произойти или вызвать проблемы. Также Вы можете потерять все несохранённые данные в этих приложениях. ================================================ FILE: source/KlocTools/Forms/ProcessWaiterControl.sl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Uniči Uniči vse Prezri Prekliči Naslednji procesi morda uporabljajo datoteke, ki bodo zdaj odstranjene. Prosimo, da jih zaprete preden nadaljujete. Če ste se odločili, da jih ne boste zaprli, odstranitev nekaterih vnosov lahko spodleti ali povzroči težave. Morda boste izgubili tudi vse neshranjene podatke, ki so odprti v teh aplikacijah. ================================================ FILE: source/KlocTools/Forms/ProcessWaiterControl.sv.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Avsluta Avsluta alla Ignorera Avbryt Följande processer kan använda filer som nu kommer att avinstalleras, vänligen stäng dem innan du fortsätter. Om du bestämmer dig för att inte stänga dem, kan avinstallationen av vissa objekt misslyckas eller orsaka problem. Du kan också förlora eventuella osparade data som är öppna i dessa appar. ================================================ FILE: source/KlocTools/Forms/ProcessWaiterControl.tr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Zorla kapat Hepsini zorla kapat Yoksay İptal Aşağıdaki işlemler şimdi kaldırılacak hala bazı dosyalar kullanıyor olabilir, lütfen devam etmeden önce bunları kapatın. Bunları kapatmamaya karar verirseniz, bazı öğelerin kaldırılması başarısız olabilir veya sorunlara neden olabilir. Ayrıca bu uygulamalarda açılan kaydedilmemiş verileri de kaybedebilirsiniz. ================================================ FILE: source/KlocTools/Forms/ProcessWaiterControl.vi.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Buộc dừng Buộc dừng tất cả Phớt lờ Huỷ Các quy trình sau đây có thể đang sử dụng các tệp sẽ được gỡ cài đặt, vui lòng đóng chúng trước khi tiếp tục. Nếu bạn quyết định không đóng chúng, việc gỡ cài đặt một số mục có thể không thành công hoặc gây ra sự cố. Bạn cũng có thể mất mọi dữ liệu chưa lưu được mở trong các ứng dụng đó. ================================================ FILE: source/KlocTools/Forms/ProcessWaiterControl.zh-Hans.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 终止 全部终止 忽略 取消 以下进程可能正在使用将要卸载的文件,请在继续之前关闭这些文件。如果你决定不关闭它们,则卸载某些项可能会失败或导致问题。你还可能丢失在这些应用程序中打开的任何未保存的数据。 ================================================ FILE: source/KlocTools/Forms/ProcessWaiterControl.zh-Hant.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 結束 全部結束 忽略 取消 以下程序可能正在使用將要移除的檔案,請在繼續之前關閉這些檔案。如果你決定不關閉它們,則移除某些項目可能會失敗或導致問題。你還可能遺失這些應用程式中開啟的未儲存資料。 ================================================ FILE: source/KlocTools/Forms/SplashScreen.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.ComponentModel; using System.Drawing; using System.Windows.Forms; using Klocman.Forms.Tools; namespace Klocman.Forms { /// /// A Windows 10 Store App styled splash screen. It will draw over form's client area and fade out when needed. /// public class SplashScreen : ReferencedComponent { private OverlaySplashScreen _splash; [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public Image SplashScreenImage { get; set; } [DefaultValue(true)] public bool AutomaticallyClose { get; set; } = true; [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2213:Disposable fields should be disposed", Justification = "")] private Form _ownerForm; protected override void OnContainerControlChanged(object orig, EventArgs args) { _ownerForm = ContainerControl.FindForm(); if (_ownerForm != null) { _ownerForm.Load += OnLoad; _ownerForm.Shown += OnShown; } } public void CloseSplashScreen() { if (_splash == null || _splash.IsDisposed) return; _splash.FadeOut(); SetOwnerEnabled(true); } private void SetOwnerEnabled(bool enabled) { // Don't disable the entire main form to avoid it being unmovable foreach (Control control in ContainerControl.Controls) control.Enabled = enabled; } protected override void Dispose(bool disposing) { _splash?.Dispose(); base.Dispose(disposing); } private void OnLoad(object orig, EventArgs e) { _ownerForm.Opacity = 0; _splash = new OverlaySplashScreen(_ownerForm, SplashScreenImage); _splash.Disposed += (sender, args) => _splash = null; } private void OnShown(object orig, EventArgs e) { var canSplash = _splash != null && !_splash.IsDisposed; if (canSplash) { SetOwnerEnabled(false); _splash.Opacity = 0; _splash.Show(ContainerControl); _splash.Refresh(); _splash.Opacity = 1; } _ownerForm.Opacity = 1; if(canSplash && AutomaticallyClose) CloseSplashScreen(); } } } ================================================ FILE: source/KlocTools/Forms/StringEditBox.Designer.cs ================================================ using System.ComponentModel; using System.Windows.Forms; namespace Klocman.Forms { partial class StringEditBox { /// /// Required designer variable. /// private IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.button1 = new System.Windows.Forms.Button(); this.button2 = new System.Windows.Forms.Button(); this.label1 = new System.Windows.Forms.Label(); this.textBox1 = new System.Windows.Forms.TextBox(); this.SuspendLayout(); // // button1 // this.button1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.button1.DialogResult = System.Windows.Forms.DialogResult.OK; this.button1.Location = new System.Drawing.Point(67, 57); this.button1.Name = "button1"; this.button1.Size = new System.Drawing.Size(75, 23); this.button1.TabIndex = 2; this.button1.Text = "Apply"; this.button1.UseVisualStyleBackColor = true; // // button2 // this.button2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.button2.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.button2.Location = new System.Drawing.Point(148, 57); this.button2.Name = "button2"; this.button2.Size = new System.Drawing.Size(75, 23); this.button2.TabIndex = 3; this.button2.Text = "Cancel"; this.button2.UseVisualStyleBackColor = true; // // label1 // this.label1.AutoSize = true; this.label1.Location = new System.Drawing.Point(12, 9); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(60, 13); this.label1.TabIndex = 0; this.label1.Text = "Description"; // // textBox1 // this.textBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.textBox1.Location = new System.Drawing.Point(12, 28); this.textBox1.Name = "textBox1"; this.textBox1.Size = new System.Drawing.Size(211, 20); this.textBox1.TabIndex = 1; // // StringEditBox // this.AcceptButton = this.button1; this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.CancelButton = this.button2; this.ClientSize = new System.Drawing.Size(236, 92); this.Controls.Add(this.textBox1); this.Controls.Add(this.label1); this.Controls.Add(this.button2); this.Controls.Add(this.button1); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; this.Name = "StringEditBox"; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "StringEditBox"; this.Shown += new System.EventHandler(this.StringEditBox_Shown); this.ResumeLayout(false); this.PerformLayout(); } #endregion private Button button1; private Button button2; private Label label1; private TextBox textBox1; } } ================================================ FILE: source/KlocTools/Forms/StringEditBox.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Windows.Forms; using Klocman.Tools; namespace Klocman.Forms { public partial class StringEditBox : Form { public StringEditBox() { InitializeComponent(); } public static bool ShowDialog(string description, string title, string defaultText, string acceptButton, string cancelButton, out string result) { using (var instance = new StringEditBox()) { instance.button1.Text = acceptButton; instance.button2.Text = cancelButton; instance.label1.Text = description; instance.Text = title; instance.textBox1.Text = defaultText; instance.textBox1.Focus(); var outVar = instance.ShowDialog(); result = instance.textBox1.Text; return outVar != DialogResult.Cancel; } } private void StringEditBox_Shown(object sender, EventArgs e) { if (ParentForm != null && ParentForm.Icon != null) Icon = ParentForm.Icon; else { try { Icon = ProcessTools.GetIconFromEntryExe(); } catch { /* Fall back to the default icon */ } } } } } ================================================ FILE: source/KlocTools/Forms/StringEditBox.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ================================================ FILE: source/KlocTools/Forms/Tools/Buttons.Designer.cs ================================================ //------------------------------------------------------------------------------ // // This code was generated by a tool. // Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ namespace Klocman.Forms.Tools { using System; /// /// A strongly-typed resource class, for looking up localized strings, etc. /// // This class was auto-generated by the StronglyTypedResourceBuilder // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] public class Buttons { private static global::System.Resources.ResourceManager resourceMan; private static global::System.Globalization.CultureInfo resourceCulture; [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] internal Buttons() { } /// /// Returns the cached ResourceManager instance used by this class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] public static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Klocman.Forms.Tools.Buttons", typeof(Buttons).Assembly); resourceMan = temp; } return resourceMan; } } /// /// Overrides the current thread's CurrentUICulture property for all /// resource lookups using this strongly typed resource class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] public static global::System.Globalization.CultureInfo Culture { get { return resourceCulture; } set { resourceCulture = value; } } /// /// Looks up a localized string similar to Add. /// public static string ButtonAdd { get { return ResourceManager.GetString("ButtonAdd", resourceCulture); } } /// /// Looks up a localized string similar to Cancel. /// public static string ButtonCancel { get { return ResourceManager.GetString("ButtonCancel", resourceCulture); } } /// /// Looks up a localized string similar to Clear. /// public static string ButtonClear { get { return ResourceManager.GetString("ButtonClear", resourceCulture); } } /// /// Looks up a localized string similar to Close. /// public static string ButtonClose { get { return ResourceManager.GetString("ButtonClose", resourceCulture); } } /// /// Looks up a localized string similar to Continue. /// public static string ButtonContinue { get { return ResourceManager.GetString("ButtonContinue", resourceCulture); } } /// /// Looks up a localized string similar to Copy. /// public static string ButtonCopy { get { return ResourceManager.GetString("ButtonCopy", resourceCulture); } } /// /// Looks up a localized string similar to Create. /// public static string ButtonCreate { get { return ResourceManager.GetString("ButtonCreate", resourceCulture); } } /// /// Looks up a localized string similar to Details. /// public static string ButtonDetails { get { return ResourceManager.GetString("ButtonDetails", resourceCulture); } } /// /// Looks up a localized string similar to Don't create. /// public static string ButtonDontCreate { get { return ResourceManager.GetString("ButtonDontCreate", resourceCulture); } } /// /// Looks up a localized string similar to Keep. /// public static string ButtonKeep { get { return ResourceManager.GetString("ButtonKeep", resourceCulture); } } /// /// Looks up a localized string similar to No. /// public static string ButtonNo { get { return ResourceManager.GetString("ButtonNo", resourceCulture); } } /// /// Looks up a localized string similar to OK. /// public static string ButtonOk { get { return ResourceManager.GetString("ButtonOk", resourceCulture); } } /// /// Looks up a localized string similar to Overwrite. /// public static string ButtonOverwrite { get { return ResourceManager.GetString("ButtonOverwrite", resourceCulture); } } /// /// Looks up a localized string similar to Rate. /// public static string ButtonRate { get { return ResourceManager.GetString("ButtonRate", resourceCulture); } } /// /// Looks up a localized string similar to Remove. /// public static string ButtonRemove { get { return ResourceManager.GetString("ButtonRemove", resourceCulture); } } /// /// Looks up a localized string similar to Reset. /// public static string ButtonReset { get { return ResourceManager.GetString("ButtonReset", resourceCulture); } } /// /// Looks up a localized string similar to Skip. /// public static string ButtonSkip { get { return ResourceManager.GetString("ButtonSkip", resourceCulture); } } /// /// Looks up a localized string similar to Stop. /// public static string ButtonStop { get { return ResourceManager.GetString("ButtonStop", resourceCulture); } } /// /// Looks up a localized string similar to Submit. /// public static string ButtonSubmit { get { return ResourceManager.GetString("ButtonSubmit", resourceCulture); } } /// /// Looks up a localized string similar to Terminate. /// public static string ButtonTerminate { get { return ResourceManager.GetString("ButtonTerminate", resourceCulture); } } /// /// Looks up a localized string similar to Uninstall. /// public static string ButtonUninstall { get { return ResourceManager.GetString("ButtonUninstall", resourceCulture); } } /// /// Looks up a localized string similar to Use loud. /// public static string ButtonUseLoud { get { return ResourceManager.GetString("ButtonUseLoud", resourceCulture); } } /// /// Looks up a localized string similar to Yes. /// public static string ButtonYes { get { return ResourceManager.GetString("ButtonYes", resourceCulture); } } } } ================================================ FILE: source/KlocTools/Forms/Tools/Buttons.ar.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 اضافه الغاء الامر واضح اغلاق مواصله نسخ انشاء لا تخلق احتفظ لا موافق كتابه معدل ازاله اعاده تخطي Used as "Skip waiting for process" توقف ارسال انهاء Used as "Terminate process" الغاء التثبيت استخدام بصوت عال نعم تفاصيل ================================================ FILE: source/KlocTools/Forms/Tools/Buttons.cs.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Přidat Zrušit Vymazat Zavřít Pokračovat Kopírovat Vytvořit Nevytvářet Zachovat Ne OK Přepsat Odstranit Obnovit Přeskočit Used as "Skip waiting for process" Stop Odeslat Dokončit Used as "Terminate process" Odinstalovat Použít výchozí Ano Hodnotit Details ================================================ FILE: source/KlocTools/Forms/Tools/Buttons.de.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Hinzufügen Abbrechen Löschen Schließen Weiter Erstellen Nicht erstellen Behalten Nein OK Überschreiben Entfernen Zurücksetzen Überspringen Used as "Skip waiting for process" Stopp Senden Beenden Used as "Terminate process" Deinstallation Standard verwenden Ja Copy Bewerten Einzelheiten ================================================ FILE: source/KlocTools/Forms/Tools/Buttons.es.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Agregar Cancelar Limpiar Cerrar Continuar Copiar Crear No crear Conservar No Ok Sobreescribir Puntuar Eliminar Reiniciar Omitir Used as "Skip waiting for process" Detener Enviar Terminar Used as "Terminate process" Desinstalar Uso fuerte Si Detalles ================================================ FILE: source/KlocTools/Forms/Tools/Buttons.fr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Ajouter Annuler Effacer Fermer Continuer Créer Ne pas créer Garder Non OK Écraser Supprimer Réinitialiser Passer Used as "Skip waiting for process" Arrêter Soumettre Terminer Used as "Terminate process" Désinstaller Utiliser causant Oui Copier Noter Détails ================================================ FILE: source/KlocTools/Forms/Tools/Buttons.hu.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Hozzáad Mégse Kiürítés Bezárás Tovább Másolás Létrehozás Ne hozza létre Megtartás Nem OK Felülírás Értékelés Törlés Visszaállítás Kihagyás Used as "Skip waiting for process" Leállítás Elküldés Befejezés Used as "Terminate process" Eltávolítás Normál Igen Részletek ================================================ FILE: source/KlocTools/Forms/Tools/Buttons.it.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Aggiungi Cancella Pulisci Chiudi Continua Copia Crea Non creare Mantieni No Ok Sovrascrivi Valuta Rimuovi Resetta Salta Used as "Skip waiting for process" Arresta Invia Termina Used as "Terminate process" Disinstalla Uso guidato Dettagli ================================================ FILE: source/KlocTools/Forms/Tools/Buttons.ja.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 評価する 追加 キャンセル クリア 閉じる 続ける コピー 作成 作成しない 保持 いいえ はい 上書き 削除 リセット スキップ Used as "Skip waiting for process" 停止 送信 終了する Used as "Terminate process" アンインストール 騒音アンインストーラーを使う はい 詳細 ================================================ FILE: source/KlocTools/Forms/Tools/Buttons.nl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Toevoegen Annuleren Verwijderen Sluiten Doorgaan Kopieer Creëer Niet creëren Behouden Nee OK Overschrijven Waarderen Verwijderen Terug zetten Overslaan Used as "Skip waiting for process" Stop Indienen Afbreken Used as "Terminate process" De-installeren Standaard gebruiken Ja Details ================================================ FILE: source/KlocTools/Forms/Tools/Buttons.pl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Dodaj Anuluj Wyczyść Zamknij Kontynuuj Utwórz Nie twórz Zatrzymaj Nie OK Nadpisz Usuń Resetuj Pomiń Used as "Skip waiting for process" Zatrzymaj Wyślij Zakończ Used as "Terminate process" Odinstaluj Pozostaw Tak Kopiuj Oceń Szczegóły ================================================ FILE: source/KlocTools/Forms/Tools/Buttons.pt-BR.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Adicionar Cancelar Limpar Fechar Continuar Copiar Criar Não criar Manter Não OK Sobrescrever Classificar Remover Redefinir Pular Used as "Skip waiting for process" Parar Enviar Finalizar Used as "Terminate process" Desinstalar Usar Primeiro Plano Sim Detalhes ================================================ FILE: source/KlocTools/Forms/Tools/Buttons.pt.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Adicionar Cancelar Limpar Fechar Continuar Copiar Criar Não criar Guardar Não Está bem Sobrescrever Classificar Remover Reiniciar Pular Used as "Skip waiting for process" Parar Enviar Terminar Used as "Terminate process" Desinstalar Actuar Sim Pormenores ================================================ FILE: source/KlocTools/Forms/Tools/Buttons.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Add Cancel Clear Close Continue Copy Create Don't create Keep No OK Overwrite Rate Remove Reset Skip Used as "Skip waiting for process" Stop Submit Terminate Used as "Terminate process" Uninstall Use loud Yes Details ================================================ FILE: source/KlocTools/Forms/Tools/Buttons.ru.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Добавить Отмена Очистить Закрыть Продолжить Копировать Создать Не создавать Сохранить Нет OK Переписать Оценить Удалить Сброс Пропустить Used as "Skip waiting for process" Стоп Отправить Завершить Used as "Terminate process" Удалить "Громко" Да Детали ================================================ FILE: source/KlocTools/Forms/Tools/Buttons.sl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Dodaj Prekliči Počisti Zapri Nadaljuj Kopiraj Ustvari Ne ustvari Obdrži Ne Vredu Prepiši Oceni Odstrani Ponastavi Preskoči Used as "Skip waiting for process" Ustavi Pošlji Prekini Used as "Terminate process" Odstrani Uporabi glasno Da Podrobno ================================================ FILE: source/KlocTools/Forms/Tools/Buttons.sv.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Lägg till Avbryta Rensa Stäng Fortsätt Kopiera Skapa Skapa inte Behåll Nej OK Skriv över Betygsätt Ta bort Återställ Hoppa över Used as "Skip waiting for process" Stop Skicka in Avsluta Used as "Terminate process" Avinstallera Använd synlig Ja Detaljer ================================================ FILE: source/KlocTools/Forms/Tools/Buttons.tr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Ekle İptal Temizle Kapat Devam et Yapıştır Oluştur Oluşturma Sakla Hayır Tamam Üzerine yaz Puanla Kaldır Sıfırla Süreci beklemeyi atla Used as "Skip waiting for process" Dur Gönder İşlemi sonlandır Used as "Terminate process" Kaldır Yüksek sesle kullan Evet Detaylar ================================================ FILE: source/KlocTools/Forms/Tools/Buttons.vi.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Thêm Huỷ Dọn dẹp Đóng Tiếp tục Sao chép Tạo Không tạo Giữ lại Không OK Ghi đè Đánh giá Loại bỏ Cài lại Bỏ qua Used as "Skip waiting for process" Dừng Gửi Chấm dứt Used as "Terminate process" Gỡ cài đặt Dùng chế độ ồn ào Đúng Chi tiết ================================================ FILE: source/KlocTools/Forms/Tools/Buttons.zh-Hans.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 添加 取消 清除 关闭 继续 复制 创建 不要创建 保留 覆盖 评分 删除 重置 跳过 Used as "Skip waiting for process" 停止 提交 终止 Used as "Terminate process" 卸载 使用交互 详细信息 ================================================ FILE: source/KlocTools/Forms/Tools/Buttons.zh-Hant.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 新增 取消 清除 關閉 繼續 複製 建立 不要建立 保留 覆寫 評分 刪除 重設 跳過 Used as "Skip waiting for process" 停止 上傳 中止 Used as "Terminate process" 移除 使用交互 詳細訊息 ================================================ FILE: source/KlocTools/Forms/Tools/ComboBoxWrapper.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; namespace Klocman.Forms.Tools { public class ComboBoxWrapper { public ComboBoxWrapper() { } public ComboBoxWrapper(T wrappedObject) { WrappedObject = wrappedObject; } public ComboBoxWrapper(T wrappedObject, Func toStringConverter) : this(wrappedObject) { ToStringConverter = toStringConverter; } public T WrappedObject { get; set; } public Func ToStringConverter { get; set; } public override string ToString() { return ToStringConverter == null ? WrappedObject.ToString() : ToStringConverter(WrappedObject); } } } ================================================ FILE: source/KlocTools/Forms/Tools/GlobalMouseMove.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Windows.Forms; namespace Klocman.Forms.Tools { public class GlobalMouseMove : IMessageFilter { private const int WM_MOUSEMOVE = 0x0200; public bool PreFilterMessage(ref Message m) { if (m.Msg == WM_MOUSEMOVE) { MouseMove?.Invoke(this, EventArgs.Empty); } // Always allow message to continue to the next filter control return false; } public event MouseMovedEvent MouseMove; public void RegisterHandler() { Application.AddMessageFilter(this); } public void UnregisterEvent() { Application.RemoveMessageFilter(this); } } } ================================================ FILE: source/KlocTools/Forms/Tools/MouseMovedEvent.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; namespace Klocman.Forms.Tools { public delegate void MouseMovedEvent(object source, EventArgs args); } ================================================ FILE: source/KlocTools/Forms/Tools/PremadeDialogs.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Reflection; using System.Runtime.InteropServices; using System.Text; using System.Windows.Forms; using Klocman.Extensions; using Klocman.Properties; using Klocman.Tools; namespace Klocman.Forms.Tools { public static class PremadeDialogs { public static Form DefaultOwner { get; set; } public static Action SendErrorAction { get; set; } /// /// Attempt to run the specified command then catch and display any exceptions in a message box. /// True is returned if there were no exceptions thrown. /// public static bool StartProcessSafely(string command) { try { Process.Start(new ProcessStartInfo(command) { UseShellExecute = true }); return true; } catch (Win32Exception) { // Thrown then user cancels the unverified file execute dialog } catch (Exception ex) { GenericError(ex); } return false; } /// /// Attempt to run the specified command then catch and display any exceptions in a message box. /// True is returned if there were no exceptions thrown. /// public static bool StartProcessSafely(string command, string arguments) { try { Process.Start(new ProcessStartInfo(command, arguments) { UseShellExecute = true }); return true; } catch (Win32Exception) { // Thrown then user cancels the unverified file execute dialog } catch (Exception ex) { GenericError(ex); } return false; } /// /// Show a generic error message with supplied exception info. Shows all inner exceptions and stack traces as well as a /// copy button. /// public static void GenericError(Exception ex) { if (ex == null) return; Console.WriteLine(@"Showing error message: " + ex); if (SendErrorAction != null) SendErrorQuestion(ex); else GenericError(ex.Message, GetExceptionDetailString(ex)); } private static string GetExceptionDetailString(Exception ex) { if (ex == null) return string.Empty; var sb = new StringBuilder(); do { sb.Append(ex.GetType().FullName); sb.AppendLine(); sb.Append(ex.Message); sb.AppendLine(); sb.Append(ex.StackTrace); if (ex.InnerException != null) { sb.AppendLine(); sb.AppendLine(); sb.Append(Localisation.PremadeDialogs_GenericError_InnerExceptionTitle); sb.AppendLine(); ex = ex.InnerException; } else { ex = null; } } while (ex != null); var details = sb.ToString(); return details; } public static bool KillRunningProcessesQuestion() { var result = false; if (DefaultOwner != null) DefaultOwner.SafeInvoke(() => result = KillRunningProcessesQuestionSafe()); else result = KillRunningProcessesQuestionSafe(); return result; } /// /// Show a generic error message. /// public static void GenericError(string errorType, string additionalInfo = null) { if (string.IsNullOrEmpty(errorType)) return; if (string.IsNullOrEmpty(additionalInfo)) additionalInfo = errorType; var entryAsy = Assembly.GetEntryAssembly(); if (entryAsy != null) { entryAsy.ManifestModule.GetPEKind(out var peKind, out var machine); var bits = ProcessTools.Is64BitProcess ? "64bit" : "32bit"; additionalInfo = $"{entryAsy.FullName} | {peKind} | {machine} | {Environment.OSVersion} | {bits}\n{additionalInfo}"; } if (DefaultOwner != null) DefaultOwner.SafeInvoke(() => GenericErrorSafe(errorType, additionalInfo)); else GenericErrorSafe(errorType, additionalInfo); } private static bool KillRunningProcessesQuestionSafe() { return CustomMessageBox.ShowDialog(DefaultOwner, new CmbBasicSettings(Localisation.PremadeDialogs_KillRunningProcessesQuestion_Title, Localisation.PremadeDialogs_KillRunningProcessesQuestion_Message, Localisation.PremadeDialogs_KillRunningProcessesQuestion_Details , SystemIcons.Question, Buttons.ButtonOk, Buttons.ButtonCancel)) == CustomMessageBox.PressedButton.Middle; } /// /// If user choses to send error information, SendErrorAction is called. /// private static void SendErrorQuestion(Exception ex) { switch (CustomMessageBox.ShowDialog(DefaultOwner, new CmbBasicSettings(Localisation.PremadeDialogs_GenericError_Title, Localisation.PremadeDialogs_GenericError_Heading, string.Format(Localisation.PremadeDialogs_GenericError_Details, ex.Message), SystemIcons.Error, Buttons.ButtonSubmit, Buttons.ButtonCopy, Buttons.ButtonClose))) { case CustomMessageBox.PressedButton.Left: SendErrorAction.Invoke(ex); break; case CustomMessageBox.PressedButton.Middle: var fullInfo = GetExceptionDetailString(ex); try { if (DefaultOwner != null) DefaultOwner.SafeInvoke(() => Clipboard.SetText(fullInfo)); else Clipboard.SetText(fullInfo); } catch (ExternalException) { } break; } } private static void GenericErrorSafe(string errorType, string fullInfo) { switch (CustomMessageBox.ShowDialog(DefaultOwner, new CmbBasicSettings(Localisation.PremadeDialogs_GenericError_Title, Localisation.PremadeDialogs_GenericError_Heading, string.Format(Localisation.PremadeDialogs_GenericError_Details, errorType), SystemIcons.Error, Buttons.ButtonCopy, Buttons.ButtonDetails, Buttons.ButtonClose))) { case CustomMessageBox.PressedButton.Middle: GenericErrorExtendedSafe(fullInfo); break; case CustomMessageBox.PressedButton.Left: try { if (DefaultOwner != null) DefaultOwner.SafeInvoke(() => Clipboard.SetText(fullInfo)); else Clipboard.SetText(fullInfo); } catch (ExternalException) { } break; } } private static void GenericErrorExtendedSafe(string fullInfo) { var trimmed = fullInfo.Length > 1000 ? fullInfo.Substring(0, 997) + "..." : fullInfo; if (CustomMessageBox.ShowDialog(DefaultOwner, new CmbBasicSettings(Localisation.PremadeDialogs_GenericError_Title, Localisation.PremadeDialogs_GenericErrorExtendedSafe_Heading, trimmed, SystemIcons.Error, Buttons.ButtonCopy, Buttons.ButtonClose)) == CustomMessageBox.PressedButton.Middle) { try { if (DefaultOwner != null) DefaultOwner.SafeInvoke(() => Clipboard.SetText(fullInfo)); else Clipboard.SetText(fullInfo); } catch (ExternalException) { } } } } } ================================================ FILE: source/KlocTools/Forms/Tools/ReferencedComponent.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.ComponentModel; using System.ComponentModel.Design; using System.Windows.Forms; namespace Klocman.Forms.Tools { public abstract class ReferencedComponent : Component { private ContainerControl _containerControl; [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public ContainerControl ContainerControl { get { return _containerControl; } set { if (!DesignMode) { if (_containerControl != null) throw new InvalidOperationException("ContainerControl can be set only once"); _containerControl = value; if (_containerControl.Visible) ContainerVisibleChanged(this, EventArgs.Empty); else _containerControl.VisibleChanged += ContainerVisibleChanged; } else { _containerControl = value; } OnContainerControlChanged(this, EventArgs.Empty); } } /// /// Automatically populate ContainerForm when added using designer /// public override ISite Site { get { return base.Site; } set { base.Site = value; if (value == null) return; var host = value.GetService(typeof (IDesignerHost)) as IDesignerHost; if (host?.RootComponent is ContainerControl control) ContainerControl = control; } } private void ContainerVisibleChanged(object obj, EventArgs args) { if (!_containerControl.Visible) return; _containerControl.VisibleChanged -= ContainerVisibleChanged; OnContainerInitialized(obj, args); } protected virtual void OnContainerControlChanged(object obj, EventArgs args) { } protected virtual void OnContainerInitialized(object obj, EventArgs args) { } } } ================================================ FILE: source/KlocTools/Forms/Tools/SingleColorTable.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System.Drawing; using System.Windows.Forms; namespace Klocman.Forms.Tools { public class SingleColorTable : ProfessionalColorTable { public SingleColorTable(Color color) { SelectedColor = color; } public Color SelectedColor { get; set; } public override Color ToolStripGradientBegin => SelectedColor; public override Color ToolStripGradientMiddle => SelectedColor; public override Color ToolStripGradientEnd => SelectedColor; public override Color MenuStripGradientBegin => SelectedColor; public override Color MenuStripGradientEnd => SelectedColor; public override Color StatusStripGradientBegin => SelectedColor; public override Color StatusStripGradientEnd => SelectedColor; } } ================================================ FILE: source/KlocTools/Forms/Tools/StandardSystemColorTable.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System.Drawing; using System.Windows.Forms; namespace Klocman.Forms.Tools { //Add this to the bottom of your form. (After your class ends) public class StandardSystemColorTable : ProfessionalColorTable { public override Color ToolStripGradientBegin => SystemColors.Control; public override Color ToolStripGradientMiddle => SystemColors.Control; public override Color ToolStripGradientEnd => SystemColors.Control; public override Color MenuStripGradientBegin => SystemColors.MenuBar; public override Color MenuStripGradientEnd => SystemColors.MenuBar; public override Color StatusStripGradientBegin => SystemColors.MenuBar; public override Color StatusStripGradientEnd => SystemColors.MenuBar; } //Add this to the bottom of your form. (After your class ends) } ================================================ FILE: source/KlocTools/Forms/Tools/WindowStyleController.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Windows.Forms; using Klocman.Extensions; namespace Klocman.Forms.Tools { /// /// Allows easy acces to FlatStyle and ToolStripRenderMode properties of all child controls. /// It is possible to switch between System and Standard/ManagerRenderMode with one method call. /// public class WindowStyleController { private readonly Form _reference; private readonly List> _targets = new(); public WindowStyleController(Form parentForm) { _reference = parentForm; var children = parentForm.GetAllChildren(CanBeChanged).Concat(parentForm.GetComponents().Where(CanBeChanged)); foreach (var item in children) { var type = item.GetType(); var property = type.GetProperty("FlatStyle"); if (property != null) { _targets.Add(x => property.SetValue(item, x ? FlatStyle.System : FlatStyle.Standard, null)); } else { property = type.GetProperty("RenderMode"); if (property != null) { _targets.Add( x => property.SetValue(item, x ? ToolStripRenderMode.System : ToolStripRenderMode.ManagerRenderMode, null)); } } } } /// /// Switch between System (if true) and Standard/ManagerRenderMode (if false); /// /// Use system style for all child controls. public void SetStyles(bool useSystemStyle) { _reference.SuspendLayout(); foreach (var child in _targets) { child(useSystemStyle); } _reference.ResumeLayout(); } private static bool CanBeChanged(Component x) { var attrib = x.GetType() .GetCustomAttributes(typeof (ControlStyleAttribute), true) .Cast() .FirstOrDefault(); return attrib == null || attrib.AllowStyleChange; } public class ControlStyleAttribute : Attribute { public ControlStyleAttribute(bool allowStyleChange) { AllowStyleChange = allowStyleChange; } public bool AllowStyleChange { get; } } } } ================================================ FILE: source/KlocTools/Forms/WindowTargeterDialog.Designer.cs ================================================ namespace Klocman.Forms { partial class WindowTargeterDialog { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(WindowTargeterDialog)); windowTargeter1 = new Klocman.Controls.WindowTargeter(); SuspendLayout(); // // windowTargeter1 // resources.ApplyResources(windowTargeter1, "windowTargeter1"); windowTargeter1.Name = "windowTargeter1"; // // WindowTargeterDialog // resources.ApplyResources(this, "$this"); AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; Controls.Add(windowTargeter1); FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; Name = "WindowTargeterDialog"; ResumeLayout(false); } #endregion private Controls.WindowTargeter windowTargeter1; } } ================================================ FILE: source/KlocTools/Forms/WindowTargeterDialog.ar.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ابحث عن نافذه... ================================================ FILE: source/KlocTools/Forms/WindowTargeterDialog.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System.Drawing; using System.Windows.Forms; using Klocman.Subsystems; namespace Klocman.Forms { public partial class WindowTargeterDialog : Form { private WindowHoverSearcher.WindowInfo _result; private WindowTargeterDialog() { InitializeComponent(); windowTargeter1.WindowSelected += OnWindowSelected; } public static WindowHoverSearcher.WindowInfo ShowDialog(IWin32Window owner, bool useCursorPos) { using (var window = new WindowTargeterDialog()) { if (useCursorPos) { window.StartPosition = FormStartPosition.Manual; var targeterHalf = window.windowTargeter1.Height / 2; var offsetx = targeterHalf + 10; var offsety = targeterHalf + 30; window.Location = new Point(Cursor.Position.X - offsetx, Cursor.Position.Y - offsety); } else { window.StartPosition = FormStartPosition.CenterParent; } return window.ShowDialog(owner) != DialogResult.OK ? null : window._result; } } private void OnWindowSelected(object sender, WindowHoverEventArgs windowHoverEventArgs) { _result = windowHoverEventArgs.TargetWindow; DialogResult = DialogResult.OK; Close(); } } } ================================================ FILE: source/KlocTools/Forms/WindowTargeterDialog.cs.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Podívejte se na okno ... ================================================ FILE: source/KlocTools/Forms/WindowTargeterDialog.de.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Suche nach einem Fenster ... ================================================ FILE: source/KlocTools/Forms/WindowTargeterDialog.es.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Buscar una ventana... ================================================ FILE: source/KlocTools/Forms/WindowTargeterDialog.fr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Chercher une fenêtre... ================================================ FILE: source/KlocTools/Forms/WindowTargeterDialog.hu.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Egy ablak megkeresése... ================================================ FILE: source/KlocTools/Forms/WindowTargeterDialog.it.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Cerca una finestra... ================================================ FILE: source/KlocTools/Forms/WindowTargeterDialog.ja.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ウィンドウを探す... ================================================ FILE: source/KlocTools/Forms/WindowTargeterDialog.nl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Zoeken met venster... ================================================ FILE: source/KlocTools/Forms/WindowTargeterDialog.pl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Szukaj okna... ================================================ FILE: source/KlocTools/Forms/WindowTargeterDialog.pt-BR.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Procure uma janela... ================================================ FILE: source/KlocTools/Forms/WindowTargeterDialog.pt.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Procutrar uma janela... True ================================================ FILE: source/KlocTools/Forms/WindowTargeterDialog.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Top 5, 5 5, 3, 5, 3 11666666, 74 0, 74 345, 74 0 windowTargeter1 Klocman.Controls.WindowTargeter, KlocTools, Culture=neutral, PublicKeyToken=null $this 0 True 7, 15 True GrowAndShrink 355, 118 4, 3, 4, 3 371, 1153846055 371, 86 5, 5, 5, 5 Look for a window... WindowTargeterDialog System.Windows.Forms.Form, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 ================================================ FILE: source/KlocTools/Forms/WindowTargeterDialog.ru.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Выберите окно... True ================================================ FILE: source/KlocTools/Forms/WindowTargeterDialog.sl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Poglej za okno... True ================================================ FILE: source/KlocTools/Forms/WindowTargeterDialog.sv.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Leta efter ett fönster... ================================================ FILE: source/KlocTools/Forms/WindowTargeterDialog.tr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Bir pencere ara... ================================================ FILE: source/KlocTools/Forms/WindowTargeterDialog.vi.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Tìm kiếm cửa sổ... ================================================ FILE: source/KlocTools/Forms/WindowTargeterDialog.zh-Hans.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 查找窗口... ================================================ FILE: source/KlocTools/Forms/WindowTargeterDialog.zh-Hant.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 尋找視窗... ================================================ FILE: source/KlocTools/IO/AdvancedFileInfo.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Diagnostics; using System.IO; using Klocman.Localising; using Klocman.Properties; namespace Klocman.IO { /// /// Advanced file information /// public class AdvancedFileInfo { private readonly FileInfo _fileInfo; private readonly FileVersionInfo _versionInfo; private AdvancedFileInfo(FileInfo fileInfo, FileVersionInfo versionInfo) { _fileInfo = fileInfo; _versionInfo = versionInfo; } [LocalisedName(typeof (Localisation), nameof(Localisation.FileInfo_CreationTime))] public DateTime CreationTime { get { return _fileInfo.CreationTime; } set { _fileInfo.CreationTime = value; } } [LocalisedName(typeof (Localisation), nameof(Localisation.FileInfo_LastAccessTime))] public DateTime LastAccessTime { get { return _fileInfo.LastAccessTime; } set { _fileInfo.LastAccessTime = value; } } [LocalisedName(typeof (Localisation), nameof(Localisation.FileInfo_LastWriteTime))] public DateTime LastWriteTime { get { return _fileInfo.LastWriteTime; } set { _fileInfo.LastWriteTime = value; } } [LocalisedName(typeof (Localisation), nameof(Localisation.FileInfo_Attributes))] public FileAttributes Attributes { get { return _fileInfo.Attributes; } set { _fileInfo.Attributes = value; } } [LocalisedName(typeof (Localisation), nameof(Localisation.FileInfo_IsReadOnly))] public bool IsReadOnly { get { return _fileInfo.IsReadOnly; } set { _fileInfo.IsReadOnly = value; } } [LocalisedName(typeof (Localisation), nameof(Localisation.FileInfo_FullName))] public string FullName => _fileInfo.FullName; [LocalisedName(typeof (Localisation), nameof(Localisation.FileInfo_FileName))] public string FileName => _fileInfo.Name; [LocalisedName(typeof (Localisation), nameof(Localisation.FileInfo_Size))] public FileSize Size => FileSize.FromBytes(_fileInfo.Length); [LocalisedName(typeof (Localisation), nameof(Localisation.FileInfo_Directory))] public DirectoryInfo Directory => _fileInfo.Directory; [LocalisedName(typeof (Localisation), nameof(Localisation.FileInfo_Exists))] public bool Exists => _fileInfo.Exists; [LocalisedName(typeof (Localisation), nameof(Localisation.FileInfo_Comments))] public string Comments => _versionInfo?.Comments; [LocalisedName(typeof (Localisation), nameof(Localisation.FileInfo_CompanyName))] public string CompanyName => _versionInfo?.CompanyName; [LocalisedName(typeof (Localisation), nameof(Localisation.FileInfo_FileDescription))] public string FileDescription => _versionInfo?.FileDescription; [LocalisedName(typeof (Localisation), nameof(Localisation.FileInfo_FileVersion))] public Version FileVersion => _versionInfo == null ? null : new Version(_versionInfo.FileMajorPart, _versionInfo.FileMinorPart, _versionInfo.FileBuildPart, _versionInfo.FilePrivatePart); [LocalisedName(typeof (Localisation), nameof(Localisation.FileInfo_InternalName))] public string InternalName => _versionInfo?.InternalName; [LocalisedName(typeof (Localisation), nameof(Localisation.FileInfo_Language))] public string Language => _versionInfo?.Language; [LocalisedName(typeof (Localisation), nameof(Localisation.FileInfo_LegalCopyright))] public string LegalCopyright => _versionInfo?.LegalCopyright; [LocalisedName(typeof (Localisation), nameof(Localisation.FileInfo_LegalTrademarks))] public string LegalTrademarks => _versionInfo?.LegalTrademarks; [LocalisedName(typeof (Localisation), nameof(Localisation.FileInfo_OriginalFilename))] public string OriginalFilename => _versionInfo?.OriginalFilename; [LocalisedName(typeof (Localisation), nameof(Localisation.FileInfo_ProductName))] public string ProductName => _versionInfo?.ProductName; [LocalisedName(typeof (Localisation), nameof(Localisation.FileInfo_ProductVersion))] public Version ProductVersion => _versionInfo == null ? null : new Version(_versionInfo.ProductMajorPart, _versionInfo.ProductMinorPart, _versionInfo.ProductBuildPart, _versionInfo.ProductPrivatePart); public static AdvancedFileInfo FromPath(string filePath) { FileVersionInfo fileVersionInfo; try { fileVersionInfo = FileVersionInfo.GetVersionInfo(filePath); } catch { fileVersionInfo = null; } return new AdvancedFileInfo(new FileInfo(filePath), fileVersionInfo); } } } ================================================ FILE: source/KlocTools/IO/Arguments.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Text; using System.Text.RegularExpressions; namespace Klocman.IO { /// /// Command Line Argument Parser /// http://jake.ginnivan.net/c-sharp-argument-parser/ /// public class Arguments { /// /// Splits the command line. When main(string[] args) is used escaped quotes (ie a path "c:\folder\") /// Will consume all the following command line arguments as the one argument. /// This function ignores escaped quotes making handling paths much easier. /// /// The command line. /// If false, leave the quotes /// public static string[] SplitCommandLine(string commandLine, bool removeMatchingQuotes = true) { var translatedArguments = new StringBuilder(commandLine); var escaped = false; for (var i = 0; i < translatedArguments.Length; i++) { if (translatedArguments[i] == '"') { escaped = !escaped; } if (translatedArguments[i] == ' ' && !escaped) { translatedArguments[i] = '\n'; } } var toReturn = translatedArguments.ToString().Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries); if (removeMatchingQuotes) { for (var i = 0; i < toReturn.Length; i++) { toReturn[i] = RemoveMatchingQuotes(toReturn[i]); } } return toReturn; } public static string RemoveMatchingQuotes(string stringToTrim) { var firstQuoteIndex = stringToTrim.IndexOf('"'); var lastQuoteIndex = stringToTrim.LastIndexOf('"'); while (firstQuoteIndex != lastQuoteIndex) { stringToTrim = stringToTrim.Remove(firstQuoteIndex, 1); stringToTrim = stringToTrim.Remove(lastQuoteIndex - 1, 1); //-1 because we've shifted the indicies left by one firstQuoteIndex = stringToTrim.IndexOf('"'); lastQuoteIndex = stringToTrim.LastIndexOf('"'); } return stringToTrim; } private readonly Dictionary> _parameters; private string _waitingParameter; public Arguments(IEnumerable arguments) { _parameters = new Dictionary>(); //Splits on beginning of arguments ( - and -- and / ) //And on assignment operators ( = and : ) var argumentSplitter = new Regex(@"^-{1,2}|^/|=|:", RegexOptions.IgnoreCase | RegexOptions.Compiled); foreach (var argument in arguments) { var parts = argumentSplitter.Split(argument, 3); switch (parts.Length) { case 1: AddValueToWaitingArgument(parts[0]); break; case 2: AddWaitingArgumentAsFlag(); //Because of the split index 0 will be a empty string _waitingParameter = parts[1]; break; case 3: AddWaitingArgumentAsFlag(); //Because of the split index 0 will be a empty string string valuesWithoutQuotes = RemoveMatchingQuotes(parts[2]); AddListValues(parts[1], valuesWithoutQuotes.Split(',')); break; } } AddWaitingArgumentAsFlag(); } private void AddListValues(string argument, IEnumerable values) { foreach (var listValue in values) { Add(argument, listValue); } } private void AddWaitingArgumentAsFlag() { if (_waitingParameter == null) return; AddSingle(_waitingParameter, "true"); _waitingParameter = null; } private void AddValueToWaitingArgument(string value) { if (_waitingParameter == null) return; value = RemoveMatchingQuotes(value); Add(_waitingParameter, value); _waitingParameter = null; } /// /// Gets the count. /// /// The count. public int Count => _parameters.Count; /// /// Adds the specified argument. /// /// The argument. /// The value. public void Add(string argument, string value) { if (!_parameters.ContainsKey(argument)) _parameters.Add(argument, new Collection()); _parameters[argument].Add(value); } public void AddSingle(string argument, string value) { if (!_parameters.ContainsKey(argument)) _parameters.Add(argument, new Collection()); else throw new ArgumentException($"Argument {argument} has already been defined"); _parameters[argument].Add(value); } public void Remove(string argument) { if (_parameters.ContainsKey(argument)) _parameters.Remove(argument); } /// /// Determines whether the specified argument is true. /// /// The argument. /// /// true if the specified argument is true; otherwise, false. /// public bool IsTrue(string argument) { AssertSingle(argument); var arg = this[argument]; return arg != null && arg[0].Equals("true", StringComparison.OrdinalIgnoreCase); } private void AssertSingle(string argument) { if (this[argument] != null && this[argument].Count > 1) throw new ArgumentException($"{argument} has been specified more than once, expecting single value"); } public string Single(string argument) { AssertSingle(argument); //only return value if its NOT true, there is only a single item for that argument //and the argument is defined if (this[argument] != null && !IsTrue(argument)) return this[argument][0]; return null; } public bool Exists(string argument) { return (this[argument] != null && this[argument].Count > 0); } /// /// Gets the with the specified parameter. /// /// public Collection this[string parameter] => _parameters.ContainsKey(parameter) ? _parameters[parameter] : null; } } ================================================ FILE: source/KlocTools/IO/DismTools.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Text; using Klocman.Native; using Klocman.Tools; namespace Klocman.IO { public static class DismTools { public static readonly string DismFullPath = Path.Combine(WindowsTools.GetEnvironmentPath(CSIDL.CSIDL_SYSTEM), "Dism.exe"); private static bool? _dismIsAvailable; public static bool DismIsAvailable { get { if (!_dismIsAvailable.HasValue) { _dismIsAvailable = File.Exists(DismFullPath); } return _dismIsAvailable.Value; } } /// /// Get a list of feature names and their status (true for enabled) /// public static IEnumerable> GetWindowsFeatures() { var output = RunDismCommand("/english /format:list /online /get-features"); var results = new List>(); string storedFeatureName = null; foreach (var line in output.Split(StringTools.NewLineChars.ToArray(), StringSplitOptions.RemoveEmptyEntries)) { if (line.StartsWith("Feature Name", StringComparison.Ordinal)) { storedFeatureName = line.Substring(line.IndexOf(':') + 2); } else if (line.StartsWith("State", StringComparison.Ordinal)) { if (storedFeatureName == null) throw new InvalidDataException("Dism output has invalid format"); var isEnabled = line.Substring(line.IndexOf(':') + 1) .TrimStart() .Equals("Enabled", StringComparison.InvariantCultureIgnoreCase); results.Add(new KeyValuePair(storedFeatureName, isEnabled)); storedFeatureName = null; } } return results; } private static string RunDismCommand(string command) { var psi = new ProcessStartInfo(DismFullPath, command) { UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = false, CreateNoWindow = true, StandardOutputEncoding = Encoding.GetEncoding(850) }; var process = Process.Start(psi); Debug.Assert(process != null); var output = process.StandardOutput.ReadToEnd(); process.WaitForExit(); if (process.ExitCode != 0) { var code = process.ExitCode.ToString(); var index = output.IndexOf(code, StringComparison.InvariantCulture); throw new IOException("Dism returned error code " + code, new Exception(index > 0 ? output.Substring(index + code.Length).Trim() : output)); } return output; } public static WindowsFeatureInfo GetFeatureInfo(string featureName) { var output = RunDismCommand("/english /format:list /online /get-featureinfo /featurename=" + '\"' + featureName + '\"'); return FromDismOutput(output); } public static string GetDismUninstallString(string featureName, bool silent) { return string.Format("Dism.exe /norestart {1}/online /disable-feature /featurename=\"{0}\"", featureName, silent ? "/quiet " : string.Empty); } private static WindowsFeatureInfo FromDismOutput(string output) { var result = new WindowsFeatureInfo(); foreach (var line in output .Split(StringTools.NewLineChars.ToArray(), StringSplitOptions.RemoveEmptyEntries)) { if (!line.Contains(':')) continue; var data = line.Substring(line.IndexOf(':') + 1).TrimStart(); if (line.StartsWith("Feature Name", StringComparison.Ordinal)) result.FeatureName = data; else if (line.StartsWith("State", StringComparison.Ordinal)) result.Enabled = data.Equals("Enabled", StringComparison.InvariantCultureIgnoreCase); else if (line.StartsWith("Display Name", StringComparison.Ordinal)) result.DisplayName = data; else if (line.StartsWith("Restart Required", StringComparison.Ordinal)) result.RestartRequired = data; else if (line.StartsWith("Description", StringComparison.Ordinal)) result.Description = data; } return string.IsNullOrEmpty(result.FeatureName) ? null : result; } } } ================================================ FILE: source/KlocTools/IO/FileSize.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Linq; using System.Xml; using System.Xml.Schema; using System.Xml.Serialization; using Klocman.Properties; namespace Klocman.IO { public struct FileSize : IXmlSerializable, IComparable, IEquatable, IComparable { public enum SizeRange { None = 0, Kb, Mb, Gb, Tb } public static FileSize SumFileSizes(IEnumerable sizes) { return FromKilobytes(sizes.Sum(x => x.GetKbSize())); } public static readonly FileSize Empty = new(0); private long _sizeInKb; public FileSize(long kiloBytes) { _sizeInKb = kiloBytes; } public static bool operator !=(FileSize a, FileSize b) { return !a.Equals(b); } public static FileSize operator +(FileSize a, FileSize b) { return new FileSize(a._sizeInKb + b._sizeInKb); } public static FileSize operator -(FileSize a, FileSize b) { return new FileSize(a._sizeInKb - b._sizeInKb); } public static bool operator ==(FileSize a, FileSize b) { return a.Equals(b); } public static FileSize FromBytes(long bytes) { if (bytes < 0) bytes = 0; return new FileSize(bytes / 1024); } public static FileSize FromKilobytes(long kiloBytes) { if (kiloBytes < 0) kiloBytes = 0; return new FileSize(kiloBytes); } public int CompareTo(object obj) { return obj is FileSize other ? CompareTo(other) : 0; } public override bool Equals(object obj) { return obj is FileSize other && Equals(other); } public override int GetHashCode() { return _sizeInKb.GetHashCode(); } public int CompareTo(FileSize other) { return _sizeInKb.CompareTo(other._sizeInKb); } public bool Equals(FileSize other) { return _sizeInKb == other._sizeInKb; } /// /// Empty items return long.MaxValue. For use in sorting /// public long GetKbSize(bool treatEmptyAsLargest = false) { if (treatEmptyAsLargest && _sizeInKb <= 0) return long.MaxValue; return _sizeInKb; } /// /// Returns string representation of the unif of this FileSize. /// (eg. Megabytes, Kilobytes) /// public string GetUnitName() { return GetUnitName(_sizeInKb); } /// public static string GetUnitName(long sizeInKb) { var tempSize = sizeInKb; if (tempSize <= 0) return string.Empty; if (tempSize < 1000) return Localisation.FileSize_KB_Long; tempSize /= 1024; if (tempSize < 1000) return Localisation.FileSize_MB_Long; tempSize /= 1024; if (tempSize < 1000) return Localisation.FileSize_GB_Long; return Localisation.FileSize_TB_Long; } public float GetCompactSize(out SizeRange sizeRange) { sizeRange = SizeRange.None; if (_sizeInKb <= 0) return 0; sizeRange = SizeRange.Kb; var tempSize = (double)_sizeInKb; if (tempSize < 1024) return (float)tempSize; sizeRange = SizeRange.Mb; tempSize /= 1024; if (tempSize < 1024) return (float)tempSize; sizeRange = SizeRange.Gb; tempSize /= 1024; if (tempSize < 1024) return (float)tempSize; sizeRange = SizeRange.Tb; tempSize /= 1024; return (float)tempSize; } /// /// Returns string representation of the filesize in format "Number.Decimal ShortName" /// (eg. 32,51 MB, 1021 KB) /// public override string ToString() { return ToString(false); } /// /// Returns string representation of the filesize in format "Number.Decimal LongName" /// (eg. 32,51 Megabytes, 1021 Kilobytes) /// public string ToString(bool longFormat) { var value = GetCompactSize(out var range); if (range == SizeRange.None || value <= 0) return string.Empty; return string.Format("{0} {1}", Math.Round(value, 2), GetRangeString(range, longFormat)); } private static string GetRangeString(SizeRange range, bool longString) { if (range == SizeRange.None) return string.Empty; string rangeName; switch (range) { case SizeRange.Tb: rangeName = longString ? Localisation.FileSize_TB_Long : Localisation.FileSize_TB_Short; break; case SizeRange.Gb: rangeName = longString ? Localisation.FileSize_GB_Long : Localisation.FileSize_GB_Short; break; case SizeRange.Mb: rangeName = longString ? Localisation.FileSize_MB_Long : Localisation.FileSize_MB_Short; break; case SizeRange.Kb: rangeName = longString ? Localisation.FileSize_KB_Long : Localisation.FileSize_KB_Short; break; default: throw new ArgumentOutOfRangeException(nameof(range), range, @"Unknown range"); } return rangeName; } public XmlSchema GetSchema() { return null; } public void ReadXml(XmlReader reader) { if (reader.MoveToContent() == XmlNodeType.Element) { reader.Read(); if (reader.HasValue) { _sizeInKb = long.Parse(reader.Value); reader.Read(); } reader.ReadEndElement(); } } public void WriteXml(XmlWriter writer) { writer.WriteValue(_sizeInKb); } public long GetRoundedKbSize() { var size = _sizeInKb; if (size <= 0) return 0; var result = 1; while(size >= 1024) { size /= 1024; result *= 1024; } return result; } } } ================================================ FILE: source/KlocTools/IO/MsiTools.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Security.Cryptography.X509Certificates; using System.Text; using Klocman.Extensions; using Klocman.Native; using Klocman.Tools; using Microsoft.Win32.Interop; namespace Klocman.IO { public static class MsiTools { private static readonly int[] GuidRegistryFormatPattern = { 8, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2 }; public static IEnumerable MsiEnumProducts() { var sbProductCode = new StringBuilder(39); var iIdx = 0; while (MsiWrapper.MsiEnumProducts(iIdx++, sbProductCode) == 0) { var guidString = sbProductCode.ToString(); if (GuidTools.GuidTryParse(guidString, out var guid)) yield return guid; else Console.WriteLine($@"Invalid MSI guid in MsiEnumProducts: {guidString}"); } } public static string MsiGetProductInfo(Guid productCode, MsiWrapper.INSTALLPROPERTY property) { var propertyLen = 512; var sbProperty = new StringBuilder(propertyLen); var code = MsiWrapper.MsiGetProductInfo(productCode.ToString("B"), property.PropertyName, sbProperty, ref propertyLen); //if (code != 0) // throw new System.IO.IOException("MsiGetProductInfo returned error code " + code); //If code is 0 prevent returning junk return code != 0 ? null : sbProperty.ToString(); } public static Guid ConvertBetweenUpgradeAndProductCode(Guid from) { return new Guid(from.ToString("N").Reverse(GuidRegistryFormatPattern)); } public static X509Certificate2 GetCertificate(Guid productCode) { var localPackage = MsiGetProductInfo(productCode, MsiWrapper.INSTALLPROPERTY.LOCALPACKAGE); if (localPackage == null || !Path.IsPathRooted(localPackage) || !File.Exists(localPackage)) return null; IntPtr certData; uint pcb = 0; var result = MsiWrapper.MsiGetFileSignatureInformation(localPackage, 0, out certData, null, ref pcb); if (result == 0) return new X509Certificate2(certData); return null; } public static IEnumerable GetAllComponents() { var lpComponentBuf = new StringBuilder(40); for (var i = 0; ; i++) { var ret = (ResultWin32)MsiWrapper.MsiEnumComponents(i, lpComponentBuf); if (ret == ResultWin32.ERROR_NO_MORE_ITEMS) break; if (ret != 0) throw ret.ToException(); yield return lpComponentBuf.ToString(); } } /// /// A list of files, folders, registry keys, and registry values associated with an MSI product. /// /// A list of full paths of files and folders. /// A list of full paths of registry keys. /// A list of full paths of registry keys together with value names. public record MsiComponentPaths(IReadOnlyCollection Filenames, IReadOnlyCollection RegistryKeys, IReadOnlyCollection> RegistryValues); /// /// Retrieves the raw installation path of a specified component, if available. /// /// /// The path can be either a file path or a registry path. If it's a reg path it starts with a number: /// HKEY_CLASSES_ROOT 00 /// HKEY_CURRENT_USER 01 /// HKEY_LOCAL_MACHINE 02 /// HKEY_USERS 03 /// On 64-bit operating systems, a value of 20 is added to distinguish native 64bit keys from 32-bit keys that are placed in the Wow6432Node (02 -> 22). /// If a registry path ends with \ it is a registry key, otherwise it's a registry value. /// The component identifier to look up. /// The installation path of the component if found; otherwise, null. public static string GetInstalledComponentPathRaw(string component) { if (ComponentPathLookup.TryGetValue(component, out var value)) return value; InitLookups(); _reverseComponentLookup.TryGetValue(component, out var product); if (!string.IsNullOrEmpty(product)) { var lpPathBuf = new StringBuilder(512); var pcchPathBuf = lpPathBuf.Capacity; var state = MsiWrapper.MsiGetComponentPath(product, component, lpPathBuf, ref pcchPathBuf); if (state == MsiWrapper.INSTALLSTATE.INSTALLSTATE_LOCAL) // TODO also include source? { value = lpPathBuf.ToString(); ComponentPathLookup[component] = value; return value; } } ComponentPathLookup[component] = null; return null; } public static MsiComponentPaths GetInstalledComponentPaths(Guid productCodeGuid) { InitLookups(); var productCode = productCodeGuid.ToString("B"); if (!_componentLookup.Contains(productCode)) return null; var filePaths = new HashSet(StringComparer.OrdinalIgnoreCase); var regKeyPaths = new HashSet(StringComparer.OrdinalIgnoreCase); var regValPaths = new HashSet(StringComparer.OrdinalIgnoreCase); var components = _componentLookup[productCode]; foreach (var component in components) { var path = GetInstalledComponentPathRaw(component); if (!string.IsNullOrEmpty(path) && path.Length > 3) // Length of at least 4 will also exclude disk roots whenever they are included for some reason { if (char.IsDigit(path[0]) && char.IsDigit(path[1]) && path[2] == ':') { // Convert to a valid registry path var hiveId = path[1] - '0'; var hiveName = hiveId switch { 0 => "HKEY_CLASSES_ROOT", 1 => "HKEY_CURRENT_USER", 2 => "HKEY_LOCAL_MACHINE", 3 => "HKEY_USERS", #if RELEASE _ => hiveId.ToString() #else _ => throw new ArgumentOutOfRangeException(nameof(hiveId), hiveId, @"Invalid hive") #endif }; path = hiveName + path[3..]; // Deal with Wow6432Node redirection var isWow64 = ProcessTools.Is64BitProcess && path[0] == '0'; if (isWow64 && !path.Contains(@"\Wow6432Node\", StringComparison.OrdinalIgnoreCase)) { path = path.Replace(@"HKEY_LOCAL_MACHINE\Software\", @"HKEY_LOCAL_MACHINE\Software\Wow6432Node\", StringComparison.OrdinalIgnoreCase) // TODO: Might not be required? HKCR is virtualized and shows both 64 and 32 keys. Some 32bit apps might manage to put their keys in root too? .Replace(@"HKEY_CLASSES_ROOT\", @"HKEY_CLASSES_ROOT\Wow6432Node\", StringComparison.OrdinalIgnoreCase); } if (path.EndsWith('\\')) regKeyPaths.Add(path.TrimEnd('\\')); else regValPaths.Add(path); } else { filePaths.Add(path); } } } var splitKeyValueNames = regValPaths.Select(x => new KeyValuePair(Path.GetDirectoryName(x), Path.GetFileName(x))).ToArray(); return new MsiComponentPaths(filePaths, regKeyPaths, splitKeyValueNames); } private static ILookup _componentLookup; private static Dictionary _reverseComponentLookup; private static readonly ConcurrentDictionary ComponentPathLookup = new(); public static void InitLookups() { lock (GuidRegistryFormatPattern) { if (_componentLookup != null) return; var sw = Stopwatch.StartNew(); // TODO This is slow, on the order of ~8 seconds (4 with AsParallel) on an SSD. It could use caching of GetProductCode and _componentPathLookup // 20% of time is spent in GetAllComponents, 80% in GetProductCode _componentLookup = GetAllComponents() .ToList().AsParallel() // Cuts total time by about 45%, ToList is critical .ToLookup(GetProductCode, StringComparer.OrdinalIgnoreCase); _reverseComponentLookup = _componentLookup .Where(x => !string.IsNullOrEmpty(x.Key)) .SelectMany(x => x.Select(y => new { product = x.Key, component = y, })) .ToDictionary(x => x.component, x => x.product); Trace.WriteLine($"[Performance] Built MSI component lookup in {sw.Elapsed.TotalSeconds:F2} seconds"); } return; static string GetProductCode(string component) { var lpBuf39 = new StringBuilder(40); var ret = MsiWrapper.MsiGetProductCode(component, lpBuf39); return ret != 0 ? null : lpBuf39.ToString(); } } // TODO Use the lookups instead? Some products don't have any components though. public static bool IsInstalled(Guid productCodeGuid) { var productCode = productCodeGuid.ToString("B"); var state = MsiWrapper.MsiQueryProductState(productCode); // https://learn.microsoft.com/en-us/windows/win32/api/msi/nf-msi-msiqueryproductstatea // Default - installed for current user, Absent - installed for another user return state is MsiWrapper.INSTALLSTATE.INSTALLSTATE_DEFAULT or MsiWrapper.INSTALLSTATE.INSTALLSTATE_ABSENT; } } } ================================================ FILE: source/KlocTools/IO/NetFrameworkTools.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Linq; using Klocman.Extensions; using Microsoft.Win32; namespace Klocman.IO { public static class NetFrameworkTools { public static string[] GetInstalledFrameworkVersions() { var results = new List(); using (var ndpKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\")) { if (ndpKey != null) { foreach (var netKeyName in ndpKey.GetSubKeyNames()) { if (!netKeyName.StartsWith("v", StringComparison.Ordinal)) continue; results.AddRange(GetNetFromKey(ndpKey, netKeyName)); } } } return results.ToArray(); } private static IEnumerable GetNetFromKey(RegistryKey ndpKey, string netKeyName) { using (var netKey = ndpKey.OpenSubKey(netKeyName, false)) { if (netKey == null) yield break; var valueNames = netKey.GetValueNames(); if (valueNames.Length == 0 || !valueNames.Contains("Install")) { var subKeyNames = netKey.GetSubKeyNames(); if (subKeyNames.Contains("Full")) { foreach (var result in GetNetFromKey(netKey, "Full")) yield return result + " Full"; } if (subKeyNames.Contains("Client")) { foreach (var result in GetNetFromKey(netKey, "Client")) yield return result + " Client"; } } else if (netKey.GetValue("Install", "")?.ToString() == "1") { var versionStr = netKey.GetValue("Version", "")?.ToString(); if (string.IsNullOrEmpty(versionStr)) versionStr = netKey.GetKeyName(); yield return versionStr; } } } } } ================================================ FILE: source/KlocTools/IO/SysRestore.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Management; using System.Runtime.InteropServices; using Microsoft.Win32; namespace Klocman.IO { /// /// Based on http://www.codeproject.com/Articles/38205/Creating-System-Restore-Points-using-PInvoke /// Updated for new Windows versions /// public static class SysRestore { // Type of restorations public enum RestoreType { ApplicationInstall = 0, // Installing a new application ApplicationUninstall = 1, // An application has been uninstalled ModifySettings = 12, // An application has had features added or removed CancelledOperation = 13, // An application needs to delete the restore point it created Restore = 6, // System Restore Checkpoint = 7, // Checkpoint DeviceDriverInstall = 10, // Device driver has been installed FirstRun = 11, // Program used for 1st time BackupRecovery = 14 // Restoring a backup } private const short AccessibilitySetting = 3; /* not implemented */ private const short ApplicationRun = 5; /* not implemented */ // Windows XP only - used to prevent the restore points intertwined private const short BeginNestedSystemChange = 102; // Constants private const short BeginSystemChange = 100; // Start of operation private const short DesktopSetting = 2; /* not implemented */ private const short EndNestedSystemChange = 103; private const short EndSystemChange = 101; // End of operation private const short MaxDesc = 64; private const short MaxDescW = 256; private const short OeSetting = 4; /* not implemented */ private const short WindowsBoot = 9; /* not implemented */ private const short WindowsShutdown = 8; /* not implemented */ /// /// Attempts to cancel the creation of a restore point. /// Note: Due to Windows API limitations, the restore point will still appear in the restore point list, /// but will be marked as canceled for the application. It is not deleted. /// /// The restore sequence number /// The status of the call public static int CancelRestore(long lSeqNum) { return EndOrCancelRestore(lSeqNum, RestoreType.CancelledOperation); } /// /// Ends system restore call /// public static int EndRestore(long lSeqNum) { return EndOrCancelRestore(lSeqNum, RestoreType.ApplicationUninstall); } private static int EndOrCancelRestore(long lSeqNum, RestoreType cancelType) { var rpInfo = new RestorePointInfo { dwEventType = EndSystemChange, dwRestorePtType = (int)cancelType, llSequenceNumber = lSeqNum }; STATEMGRSTATUS rpStatus; if (!SysRestoreAvailable()) return -1; try { var result = SRSetRestorePointW(ref rpInfo, out rpStatus); if (!result) { var error = Marshal.GetLastWin32Error(); throw new Exception($"SRSetRestorePointW failed with error code: {error}"); } } catch (Exception ex) { LogError("EndOrCancelRestore failed", ex); return -1; } return rpStatus.nStatus; } /// /// Starts system restore /// /// The description of the restore /// Returns the sequence number /// /// Under Win 8 or newer - Minimal amount of minutes since last restore point for this point to be created. /// 0 to always create, number for amount of minutes, -1 for default behaviour (24 hours). /// /// The status of call /// /// Use EndRestore() or CancelRestore() to end the system restore /// public static int StartRestore(string strDescription, out long lSeqNum, int creationFrequency = -1) { if (strDescription == null) throw new ArgumentNullException(nameof(strDescription)); lSeqNum = 0; if (!SysRestoreAvailable()) return -1; if (creationFrequency >= 0) { try { using var key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion\SystemRestore", true); if (key == null) throw new InvalidOperationException("SystemRestore registry key not found."); key.SetValue("SystemRestorePointCreationFrequency", creationFrequency, RegistryValueKind.DWord); } catch (Exception ex) { LogError("Failed to set SystemRestorePointCreationFrequency", ex); } } // Ensure description is under the max character limit if (strDescription.Length > MaxDescW) strDescription = strDescription.Substring(0, MaxDescW); var rpInfo = new RestorePointInfo { dwEventType = BeginSystemChange, dwRestorePtType = (int)RestoreType.ApplicationUninstall, llSequenceNumber = 0, szDescription = strDescription }; STATEMGRSTATUS rpStatus; try { bool result = SRSetRestorePointW(ref rpInfo, out rpStatus); if (!result) { var error = Marshal.GetLastWin32Error(); throw new Exception($"SRSetRestorePointW failed with error code: {error}"); } } catch (Exception ex) { LogError("StartRestore failed", ex); return -1; } lSeqNum = rpStatus.llSequenceNumber; return rpStatus.nStatus; } /// /// Check if system restore is supported and enabled /// public static bool SysRestoreAvailable() { try { // Check if System Protection is enabled for the system drive (usually C:) using var searcher = new ManagementObjectSearcher("root\\default", "SELECT * FROM SystemRestore"); using var results = searcher.Get(); foreach (ManagementObject _ in results) { // If we can enumerate, System Restore is available return true; } } catch (Exception ex) { LogError("System Restore check failed", ex); } return false; } private static void LogError(string message, Exception ex = null) { Console.WriteLine($@"{message}{(ex != null ? ": " + ex : string.Empty)}"); } [DllImport("srclient.dll")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool SRSetRestorePointW(ref RestorePointInfo pRestorePtSpec, out STATEMGRSTATUS pSMgrStatus); /// /// Contains information used by the SRSetRestorePoint function /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] private struct RestorePointInfo { public int dwEventType; // The type of event public int dwRestorePtType; // The type of restore point public long llSequenceNumber; // The sequence number of the restore point [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MaxDescW + 1)] public string szDescription; // The description to be displayed so the user can easily identify a restore point } /// /// Contains status information used by the SRSetRestorePoint function /// [StructLayout(LayoutKind.Sequential)] private struct STATEMGRSTATUS { public int nStatus; // The status code public long llSequenceNumber; // The sequence number of the restore point } } } ================================================ FILE: source/KlocTools/IO/WindowsFeatureInfo.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System.Collections.Generic; namespace Klocman.IO { public class WindowsFeatureInfo { public WindowsFeatureInfo() { CustomProperties = new List>(); } public string FeatureName { get; set; } public string DisplayName { get; set; } public string Description { get; set; } public string RestartRequired { get; set; } public bool Enabled { get; set; } public IList> CustomProperties { get; private set; } } } ================================================ FILE: source/KlocTools/IO/WmiQueries.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Linq; using System.Management; namespace Klocman.IO { public static class WmiQueries { /// /// Get information about enabled and disabled windows features. Works on Windows 7 and newer. /// public static ICollection GetWindowsFeatures() { var features = new List(); var searcher = new ManagementObjectSearcher(new ManagementScope(), new ObjectQuery("select * from Win32_OptionalFeature"), new EnumerationOptions(null, TimeSpan.FromSeconds(35), 100, false, false, false, false, false, false, false)); using (var moc = searcher.Get()) { var items = moc.Cast().ToList(); foreach (var managementObject in items) { var featureInfo = new WindowsFeatureInfo(); foreach (var property in managementObject.Properties) { if (property.Name == "Caption") { featureInfo.DisplayName = property.Value.ToString(); } else if (property.Name == "InstallState") { var status = (uint)property.Value; if (status == 2) featureInfo.Enabled = false; else if (status == 1) featureInfo.Enabled = true; else { featureInfo.FeatureName = null; break; } } else if (property.Name == "Name") { featureInfo.FeatureName = property.Value.ToString(); } } if (string.IsNullOrEmpty(featureInfo.FeatureName)) continue; features.Add(featureInfo); } } return features; } } } ================================================ FILE: source/KlocTools/KlocTools.csproj ================================================  Library Klocman Common utility methods True True Localisation.resx True True Resources.resx PublicResXFileCodeGenerator Localisation.Designer.cs PublicResXFileCodeGenerator Resources.Designer.cs ================================================ FILE: source/KlocTools/Licence.licenseheader ================================================ extensions: designer.cs generated.cs extensions: .cs .cpp .h /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ extensions: .aspx .ascx <%-- Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 --%> extensions: .xml .config .xsd ================================================ FILE: source/KlocTools/Limited.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Globalization; namespace Klocman { /// /// Wrapper for value types that forces them to be constrained within a specified range of values. /// /// Type of the wrapped value public struct Limited : IComparable, IFormattable, IConvertible, IComparable, IEquatable where T : struct, IComparable, IFormattable, IConvertible, IComparable, IEquatable { T _value, _minimum, _maximum; /// /// Wrapped value, always equal to any of or in between Minimum and Maximum. /// If ThrowOutOfRange if false and the value is assigned out of this range, it is trimmed. /// Otherwise an exception is thrown. /// public T Value { get { return _value; } set { _value = GetLimitedValue(value, Minimum, Maximum, ThrowOutOfRange); } } private static Tvalue GetLimitedValue(Tvalue value, Tvalue min, Tvalue max, bool throwOutOfRange) where Tvalue : IComparable { if (value.CompareTo(max) > 0) { if (throwOutOfRange) throw new ArgumentOutOfRangeException(nameof(value), @"New value must be equal to or in between the minimum and maximum values"); return max; } else if (value.CompareTo(min) < 0) { if (throwOutOfRange) throw new ArgumentOutOfRangeException(nameof(value), @"New value must be equal to or in between the minimum and maximum values"); return min; } return value; } /// /// Minimal value of this variable. If set higher than the current value, the current value is trimmed up. /// Must be lower than or equal to the maximal value. /// public T Minimum { get { return _minimum; } set { if (value.CompareTo(_maximum) > 0) throw new ArgumentOutOfRangeException(nameof(value), @"Minimum value must be lower than or equal to the maximum value"); _minimum = value; if (value.CompareTo(_value) > 0) _value = value; } } /// /// Maximal value of this variable. If set lower than the current value, the current value is trimmed down. /// Must be higher than or equal to the minimal value. /// public T Maximum { get { return _maximum; } set { if (value.CompareTo(_minimum) < 0) throw new ArgumentOutOfRangeException(nameof(value), @"Minimum value must be lower than or equal to the maximum value"); _maximum = value; if (value.CompareTo(_value) < 0) _value = value; } } /// /// Indicates whether an exception should be thrown or not when assigning an out-of-range value. /// If set to false the value is trimmed quietly. False by default. /// public bool ThrowOutOfRange { get; set; } /// /// Create new limited value of type T. /// /// Initial value of this variable /// Minimal value of this variable /// Maximal value of this variable /// Indicates whether an exception should be thrown or not when assigning an out-of-range value. public Limited(T value, T min, T max, bool throwOutOfRange) { ThrowOutOfRange = throwOutOfRange; if (min.CompareTo(max) > 0) throw new ArgumentException("Minimum value must be lower than or equal to the maximum value"); _minimum = min; _maximum = max; _value = GetLimitedValue(value, min, max, throwOutOfRange); } /// /// Create new limited value of type T. It automatically truncates out-of-range values. /// /// Initial value of this variable /// Minimal value of this variable /// Maximal value of this variable public Limited(T value, T min, T max) : this(value, min, max, false) { } /// /// Create new limited value of type T. The default and minimal values are set using default(T). /// /// Maximal value of this variable public Limited(T max) : this(default(T), default(T), max) { } public int CompareTo(T other) { return _value.CompareTo(other); } public int CompareTo(object obj) { return _value.CompareTo(obj); } public bool Equals(T other) { return _value.Equals(other); } public override bool Equals(object obj) { return _value.Equals(obj); } public static bool operator ==(Limited a, Limited b) { return a.Equals(b); } public static bool operator !=(Limited a, Limited b) { return !(a == b); } public string ToString(string format, IFormatProvider formatProvider) { return _value.ToString(format, formatProvider); } public override string ToString() { return _value.ToString(CultureInfo.CurrentCulture); } public override int GetHashCode() { return _value.GetHashCode(); } TypeCode IConvertible.GetTypeCode() { return _value.GetTypeCode(); } bool IConvertible.ToBoolean(IFormatProvider provider) { return _value.ToBoolean(provider); } byte IConvertible.ToByte(IFormatProvider provider) { return _value.ToByte(provider); } char IConvertible.ToChar(IFormatProvider provider) { return _value.ToChar(provider); } DateTime IConvertible.ToDateTime(IFormatProvider provider) { return _value.ToDateTime(provider); } decimal IConvertible.ToDecimal(IFormatProvider provider) { return _value.ToDecimal(provider); } double IConvertible.ToDouble(IFormatProvider provider) { return _value.ToDouble(provider); } short IConvertible.ToInt16(IFormatProvider provider) { return _value.ToInt16(provider); } int IConvertible.ToInt32(IFormatProvider provider) { return _value.ToInt32(provider); } long IConvertible.ToInt64(IFormatProvider provider) { return _value.ToInt64(provider); } sbyte IConvertible.ToSByte(IFormatProvider provider) { return _value.ToSByte(provider); } float IConvertible.ToSingle(IFormatProvider provider) { return _value.ToSingle(provider); } public string ToString(IFormatProvider provider) { return _value.ToString(provider); } object IConvertible.ToType(Type conversionType, IFormatProvider provider) { return _value.ToType(conversionType, provider); } ushort IConvertible.ToUInt16(IFormatProvider provider) { return _value.ToUInt16(provider); } uint IConvertible.ToUInt32(IFormatProvider provider) { return _value.ToUInt32(provider); } ulong IConvertible.ToUInt64(IFormatProvider provider) { return _value.ToUInt64(provider); } } } ================================================ FILE: source/KlocTools/Localising/LocalisationExtensions.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Reflection; namespace Klocman.Localising { public static class LocalisationExtensions { private static readonly Dictionary LocalisedEnumNameCache = new(); /// /// Get a fancy name of selected property or field /// public static string GetLocalisedMemberName(this TContainer instance, Expression> selector) where TContainer : class { if (selector.Body is not MemberExpression expression) throw new ArgumentException("Selector is invalid, it has to be in format x => x.Property"); var member = expression.Member; return GetLocalisedMemberName(member); } /// /// Get a fancy name of selected property or field /// public static string GetLocalisedMemberName(Expression> selector) where TContainer : class { if (selector.Body is not MemberExpression expression) throw new ArgumentException("Selector is invalid, it has to be in format x => x.Property"); var member = expression.Member; return GetLocalisedMemberName(member); } /// /// Get a fancy name of selected property or field /// public static string GetLocalisedMemberName(MemberInfo member) { return member.GetCustomAttributes(typeof (LocalisedNameAttribute), false) .FirstOrDefault() is not LocalisedNameAttribute attrib ? member.Name : attrib.GetName(); } /// /// Get a fancy name of this enum /// public static string GetLocalisedName(this Enum enumValue) { string output; if (LocalisedEnumNameCache.TryGetValue(enumValue, out output)) return output; var getName = new Func(f => { return f.GetCustomAttributes(typeof(LocalisedNameAttribute), false) .FirstOrDefault() is not LocalisedNameAttribute attribute ? f.Name : attribute.GetName(); }); var type = enumValue.GetType(); var isFlags = type.GetCustomAttributes(typeof(FlagsAttribute), true).Any(); if (isFlags) { var fields = from object value in Enum.GetValues(type) let flag = Convert.ToInt64(value) where (Convert.ToInt64(enumValue) & flag) == flag select type.GetField(value.ToString()!); var names = fields.Select(f => getName(f)).OrderBy(x => x).ToArray(); return names.Length > 0 ? string.Join(", ", names) : enumValue.ToString(); } var field = type.GetField(enumValue.ToString()); output = field == null ? enumValue.ToString() : getName(field); LocalisedEnumNameCache.Add(enumValue, output); return output; } /// /// Get a fancy name using propertyinfo /// public static string GetLocalisedName(this PropertyInfo propertyInfo) { return propertyInfo.GetCustomAttributes(typeof (LocalisedNameAttribute), false) .FirstOrDefault() is not LocalisedNameAttribute attribute ? propertyInfo.Name : attribute.GetName(); } } } ================================================ FILE: source/KlocTools/Localising/LocalisedEnumWrapper.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; namespace Klocman.Localising { public class LocalisedEnumWrapper { public LocalisedEnumWrapper(Enum targetEnum) { TargetEnum = targetEnum ?? throw new ArgumentNullException(nameof(targetEnum)); } public Enum TargetEnum { get; } public override string ToString() { return TargetEnum.GetLocalisedName(); } } } ================================================ FILE: source/KlocTools/Localising/LocalisedNameAttribute.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Reflection; namespace Klocman.Localising { /// /// Used alongside GetFancyName method to give custom names to properties, fields and enums /// public class LocalisedNameAttribute : Attribute { public LocalisedNameAttribute(string name) { NameOverride = name; } public LocalisedNameAttribute(Type resourceType, string resourceName) { ResourceName = resourceName; ResourceType = resourceType; } private string NameOverride { get; } private string ResourceName { get; } private Type ResourceType { get; } public string GetName() { if (NameOverride != null) return NameOverride; if ((ResourceType != null) && (ResourceName != null)) { var property = ResourceType.GetProperty(ResourceName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); if (property == null) { throw new InvalidOperationException("Resource of this type doesn\'t contain specified property"); } if (property.PropertyType != typeof (string)) { throw new InvalidOperationException("Specified property is not of string type"); } return (string) property.GetValue(null, null); } return string.Empty; } } } ================================================ FILE: source/KlocTools/Native/CSIDL.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ namespace Klocman.Native { public enum CSIDL { //Application Data //C:\Documents and Settings\Administrator\Application Data CSIDL_APPDATA = 0x1a, //CD Burning //C:\Documents and Settings\Administrator\Local Settings\Application Data\Microsoft\CD Burning CSIDL_CDBURN_AREA = 0x3b, //Common Administrative Tools //C:\Documents and Settings\All Users\Start Menu\Programs\Administrative Tools CSIDL_COMMON_ADMINTOOLS = 0x2f, //Common Application Data //C:\Documents and Settings\All Users\Application Data CSIDL_COMMON_APPDATA = 0x23, //Common Desktop //C:\Documents and Settings\All Users\Desktop CSIDL_COMMON_DESKTOPDIRECTORY = 0x19, //Common Documents //C:\Documents and Settings\All Users\Documents CSIDL_COMMON_DOCUMENTS = 0x2e, //Common Favorites //C:\Documents and Settings\All Users\Favorites CSIDL_COMMON_FAVORITES = 0x1f, //Common Music //C:\Documents and Settings\All Users\Documents\My Music CSIDL_COMMON_MUSIC = 0x35, //Common Pictures //C:\Documents and Settings\All Users\Documents\My Pictures CSIDL_COMMON_PICTURES = 0x36, //Common Start Menu //C:\Documents and Settings\All Users\Start Menu CSIDL_COMMON_STARTMENU = 0x16, //Common Start Menu Programs //C:\Documents and Settings\All Users\Start Menu\Programs CSIDL_COMMON_PROGRAMS = 0x17, //Common Startup //C:\Documents and Settings\All Users\Start Menu\Programs\Startup CSIDL_COMMON_STARTUP = 0x18, //Common Templates //C:\Documents and Settings\All Users\Templates CSIDL_COMMON_TEMPLATES = 0x2d, //Common Video //C:\Documents and Settings\All Users\Documents\My Videos CSIDL_COMMON_VIDEO = 0x37, //Cookies //C:\Documents and Settings\Administrator\Cookies CSIDL_COOKIES = 0x21, //Desktop //C:\Documents and Settings\Administrator\Desktop CSIDL_DESKTOPDIRECTORY = 0x10, //Favorites //C:\Documents and Settings\Administrator\Favorites CSIDL_FAVORITES = 0x06, //Fonts //C:\WINDOWS\Fonts CSIDL_FONTS = 0x14, //History //C:\Documents and Settings\Administrator\Local Settings\History CSIDL_HISTORY = 0x22, //Local Application Data //C:\Documents and Settings\Administrator\Local Settings\Application Data CSIDL_LOCAL_APPDATA = 0x1c, //My Documents //C:\Documents and Settings\Administrator\My Documents CSIDL_PERSONAL = 0x05, //My Music //C:\Documents and Settings\Administrator\My Documents\My Music CSIDL_MYMUSIC = 0x0d, //My Pictures //C:\Documents and Settings\Administrator\My Documents\My Pictures CSIDL_MYPICTURES = 0x27, //NetHood //C:\Documents and Settings\Administrator\NetHood CSIDL_NETHOOD = 0x13, //PrintHood //C:\Documents and Settings\Administrator\PrintHood CSIDL_PRINTHOOD = 0x1b, //Profile Folder //C:\Documents and Settings\Administrator CSIDL_PROFILE = 0x28, //Program Files //C:\Program Files CSIDL_PROGRAM_FILES = 0x26, //Program Files - Common //C:\Program Files\Common Files CSIDL_PROGRAM_FILES_COMMON = 0x2b, //Recent //C:\Documents and Settings\Administrator\Recent CSIDL_RECENT = 0x08, //Send To //C:\Documents and Settings\Administrator\SendTo CSIDL_SENDTO = 0x09, //Start Menu //C:\Documents and Settings\Administrator\Start Menu CSIDL_STARTMENU = 0x0b, //Start Menu Programs //C:\Documents and Settings\Administrator\Start Menu\Programs CSIDL_PROGRAMS = 0x02, //Startup //C:\Documents and Settings\Administrator\Start Menu\Programs\Startup CSIDL_STARTUP = 0x07, //System Directory //C:\WINDOWS\system32 CSIDL_SYSTEM = 0x25, //Templates //C:\Documents and Settings\Administrator\Templates CSIDL_TEMPLATES = 0x15, //Temporary Folder //C:\Documents and Settings\Administrator\Local Settings\Temp\ // was empty at the listing, probably 0? //Temporary Internet Files //C:\Documents and Settings\Administrator\Local Settings\Temporary Internet Files CSIDL_INTERNET_CACHE = 0x20, //Windows Directory //C:\WINDOWS CSIDL_WINDOWS = 0x24 } } ================================================ FILE: source/KlocTools/Native/ControlPanelCanonicalNames.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ namespace Klocman.Native { /// /// Canonical names of control panel applets. Add "Microsoft." before them to get full canonical names. /// For example: ActionCenter -> Microsoft.ActionCenter /// DO NOT CHANGE THE ENUM NAMES, THEY ARE CONVERTED TO STRING /// public enum ControlPanelCanonicalNames { ActionCenter, AdministrativeTools, AutoPlay, BiometricDevices, BitLockerDriveEncryption, ColorManagement, CredentialManager, DateAndTime, DefaultPrograms, DeviceManager, DevicesAndPrinters, Display, EaseOfAccessCenter, ParentalControls, FileHistory, FolderOptions, Fonts, HomeGroup, IndexingOptions, Infrared, InternetOptions, iSCSIInitiator, iSNSServer, Keyboard, Language, LocationSettings, Mouse, MPIOConfiguration, NetworkAndSharingCenter, NotificationAreaIcons, PenAndTouch, Personalization, PhoneAndModem, PowerOptions, ProgramsAndFeatures, Recovery, RegionAndLanguage, RemoteAppAndDesktopConnections, Sound, SpeechRecognition, StorageSpaces, SyncCenter, System, TabletPCSettings, Taskbar, Troubleshooting, TSAppInstall, UserAccounts, WindowsAnytimeUpgrade, WindowsDefender, WindowsFirewall, MobilityCenter, PortableWorkspaceCreator, WindowsUpdate, WorkFolders } } ================================================ FILE: source/KlocTools/Native/MsiWrapper.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Runtime.InteropServices; using System.Text; namespace Klocman.Native { public static class MsiWrapper { public enum INSTALLFEATUREATTRIBUTE // bit flags { INSTALLFEATUREATTRIBUTE_FAVORLOCAL = 1 << 0, INSTALLFEATUREATTRIBUTE_FAVORSOURCE = 1 << 1, INSTALLFEATUREATTRIBUTE_FOLLOWPARENT = 1 << 2, INSTALLFEATUREATTRIBUTE_FAVORADVERTISE = 1 << 3, INSTALLFEATUREATTRIBUTE_DISALLOWADVERTISE = 1 << 4, INSTALLFEATUREATTRIBUTE_NOUNSUPPORTEDADVERTISE = 1 << 5 } public enum INSTALLLEVEL { INSTALLLEVEL_DEFAULT = 0, // install authored default INSTALLLEVEL_MINIMUM = 1, // install only required features INSTALLLEVEL_MAXIMUM = 0xFFFF // install all features } // intermediate levels dependent on authoring public enum INSTALLLOGATTRIBUTES // flag attributes for MsiEnableLog { INSTALLLOGATTRIBUTES_APPEND = (1 << 0), INSTALLLOGATTRIBUTES_FLUSHEACHLINE = (1 << 1) } public enum INSTALLLOGMODE // bit flags for use with MsiEnableLog and MsiSetExternalUI { INSTALLLOGMODE_FATALEXIT = (1 << (0x00 >> 24)), INSTALLLOGMODE_ERROR = (1 << (0x01 >> 24)), INSTALLLOGMODE_WARNING = (1 << (0x02 >> 24)), INSTALLLOGMODE_USER = (1 << (0x03 >> 24)), INSTALLLOGMODE_INFO = (1 << (0x04 >> 24)), INSTALLLOGMODE_RESOLVESOURCE = (1 << (0x06 >> 24)), INSTALLLOGMODE_OUTOFDISKSPACE = (1 << (0x07 >> 24)), INSTALLLOGMODE_ACTIONSTART = (1 << (0x08 >> 24)), INSTALLLOGMODE_ACTIONDATA = (1 << (0x09 >> 24)), INSTALLLOGMODE_COMMONDATA = (1 << (0x0B >> 24)), INSTALLLOGMODE_PROPERTYDUMP = (1 << (0x0A >> 24)), // log only INSTALLLOGMODE_VERBOSE = (1 << (0x0C >> 24)), // log only INSTALLLOGMODE_PROGRESS = (1 << (0x0A >> 24)), // external handler only INSTALLLOGMODE_INITIALIZE = (1 << (0x0C >> 24)), // external handler only INSTALLLOGMODE_TERMINATE = (1 << (0x0D >> 24)), // external handler only INSTALLLOGMODE_SHOWDIALOG = (1 << (0x0E >> 24)) // external handler only } // Install message type for callback is a combination of the following: // A message box style: MB_*, where MB_OK is the default // A message box icon type: MB_ICON*, where no icon is the default // A default button: MB_DEFBUTTON?, where MB_DEFBUTTON1 is the default // One of the following install message types, no default public enum INSTALLMESSAGE : long { INSTALLMESSAGE_FATALEXIT = 0x00000000L, // premature termination, possibly fatal OOM INSTALLMESSAGE_ERROR = 0x01000000L, // formatted error message INSTALLMESSAGE_WARNING = 0x02000000L, // formatted warning message INSTALLMESSAGE_USER = 0x03000000L, // user request message INSTALLMESSAGE_INFO = 0x04000000L, // informative message for log INSTALLMESSAGE_FILESINUSE = 0x05000000L, // list of files in use that need to be replaced INSTALLMESSAGE_RESOLVESOURCE = 0x06000000L, // request to determine a valid source location INSTALLMESSAGE_OUTOFDISKSPACE = 0x07000000L, // insufficient disk space message INSTALLMESSAGE_ACTIONSTART = 0x08000000L, // start of action: action name & description INSTALLMESSAGE_ACTIONDATA = 0x09000000L, // formatted data associated with individual action item INSTALLMESSAGE_PROGRESS = 0x0A000000L, // progress gauge info: units so far, total INSTALLMESSAGE_COMMONDATA = 0x0B000000L, // product info for dialog: language Id, dialog caption INSTALLMESSAGE_INITIALIZE = 0x0C000000L, // sent prior to UI initialization, no string data INSTALLMESSAGE_TERMINATE = 0x0D000000L, // sent after UI termination, no string data INSTALLMESSAGE_SHOWDIALOG = 0x0E000000L // sent prior to display or authored dialog or wizard } public enum INSTALLMODE { INSTALLMODE_NOSOURCERESOLUTION = -3, // skip source resolution INSTALLMODE_NODETECTION = -2, // skip detection INSTALLMODE_EXISTING = -1, // provide, if available INSTALLMODE_DEFAULT = 0 // install, if absent } public enum INSTALLSTATE { INSTALLSTATE_NOTUSED = -7, // component disabled INSTALLSTATE_BADCONFIG = -6, // configuration data corrupt INSTALLSTATE_INCOMPLETE = -5, // installation suspended or in progress INSTALLSTATE_SOURCEABSENT = -4, // run from source, source is unavailable INSTALLSTATE_MOREDATA = -3, // return buffer overflow INSTALLSTATE_INVALIDARG = -2, // invalid function argument INSTALLSTATE_UNKNOWN = -1, // unrecognized product or feature INSTALLSTATE_BROKEN = 0, // broken INSTALLSTATE_ADVERTISED = 1, // advertised feature INSTALLSTATE_REMOVED = 1, // component being removed (action state, not settable) INSTALLSTATE_ABSENT = 2, // uninstalled (or action state absent but clients remain) INSTALLSTATE_LOCAL = 3, // installed on local drive INSTALLSTATE_SOURCE = 4, // run from source, CD or net INSTALLSTATE_DEFAULT = 5 // use default, local or source } public enum INSTALLTYPE { INSTALLTYPE_DEFAULT = 0, // set to indicate default behavior INSTALLTYPE_NETWORK_IMAGE = 1 // set to indicate network install } public enum INSTALLUILEVEL { INSTALLUILEVEL_NOCHANGE = 0, // UI level is unchanged INSTALLUILEVEL_DEFAULT = 1, // default UI is used INSTALLUILEVEL_NONE = 2, // completely silent installation INSTALLUILEVEL_BASIC = 3, // simple progress and error handling INSTALLUILEVEL_REDUCED = 4, // authored UI, wizard dialogs suppressed INSTALLUILEVEL_FULL = 5, // authored UI with wizards, progress, errors INSTALLUILEVEL_ENDDIALOG = 0x80, // display success/failure dialog at end of install INSTALLUILEVEL_PROGRESSONLY = 0x40 // display only progress dialog } public enum MSICOLINFO { MSICOLINFO_NAMES = 0, // return column names MSICOLINFO_TYPES = 1 // return column definitions, datatype code followed by width } public enum MSICONDITION { MSICONDITION_FALSE = 0, // expression evaluates to False MSICONDITION_TRUE = 1, // expression evaluates to True MSICONDITION_NONE = 2, // no expression present MSICONDITION_ERROR = 3 // syntax error in expression } public enum MSICOSTTREE { MSICOSTTREE_SELFONLY = 0, MSICOSTTREE_CHILDREN = 1, MSICOSTTREE_PARENTS = 2, MSICOSTTREE_RESERVED = 3 // Reserved for future use } // ------------------------------------------------------------------------- // Functions to query and configure a product as a whole. // ------------------------------------------------------------------------- public enum MSIDBSTATE { MSIDBSTATE_ERROR = -1, // invalid database handle MSIDBSTATE_READ = 0, // database open read-only, no persistent changes MSIDBSTATE_WRITE = 1 // database readable and updatable } public enum MSIMODIFY { MSIMODIFY_SEEK = -1, // reposition to current record primary key MSIMODIFY_REFRESH = 0, // refetch current record data MSIMODIFY_INSERT = 1, // insert new record, fails if matching key exists MSIMODIFY_UPDATE = 2, // update existing non-key data of fetched record MSIMODIFY_ASSIGN = 3, // insert record, replacing any existing record MSIMODIFY_REPLACE = 4, // update record, delete old if primary key edit MSIMODIFY_MERGE = 5, // fails if record with duplicate key not identical MSIMODIFY_DELETE = 6, // remove row referenced by this record from table MSIMODIFY_INSERT_TEMPORARY = 7, // insert a temporary record MSIMODIFY_VALIDATE = 8, // validate a fetched record MSIMODIFY_VALIDATE_NEW = 9, // validate a new record MSIMODIFY_VALIDATE_FIELD = 10, // validate field(s) of an incomplete record MSIMODIFY_VALIDATE_DELETE = 11 // validate before deleting record } public enum REINSTALLMODE // bit flags { REINSTALLMODE_REPAIR = 0x00000001, // Reserved bit - currently ignored REINSTALLMODE_FILEMISSING = 0x00000002, // Reinstall only if file is missing REINSTALLMODE_FILEOLDERVERSION = 0x00000004, // Reinstall if file is missing, or older version REINSTALLMODE_FILEEQUALVERSION = 0x00000008, // Reinstall if file is missing, or equal or older version REINSTALLMODE_FILEEXACT = 0x00000010, // Reinstall if file is missing, or not exact version REINSTALLMODE_FILEVERIFY = 0x00000020, // checksum executables, reinstall if missing or corrupt REINSTALLMODE_FILEREPLACE = 0x00000040, // Reinstall all files, regardless of version REINSTALLMODE_MACHINEDATA = 0x00000080, // insure required machine reg entries REINSTALLMODE_USERDATA = 0x00000100, // insure required user reg entries REINSTALLMODE_SHORTCUT = 0x00000200, // validate shortcuts items REINSTALLMODE_PACKAGE = 0x00000400 // use re-cache source install package } public enum USERINFOSTATE { USERINFOSTATE_MOREDATA = -3, // return buffer overflow USERINFOSTATE_INVALIDARG = -2, // invalid function argument USERINFOSTATE_UNKNOWN = -1, // unrecognized product USERINFOSTATE_ABSENT = 0, // user info and PID not initialized USERINFOSTATE_PRESENT = 1 // user info and PID initialized } /// /// Flags that may be passed into the dwContext parameter of the method. /// https://github.com/dotnet/pinvoke/blob/d974353ca67c4b8e6009096bd3ab7e6f284ed11d/src/Msi/Msi%2BMSIINSTALLCONTEXT.cs /// [Flags] public enum MSIINSTALLCONTEXT : uint { /// /// Product visible to the current user. /// MSIINSTALLCONTEXT_FIRSTVISIBLE = 0, /// /// Invalid context for a product /// MSIINSTALLCONTEXT_NONE = 0, /// /// Enumeration extended to all per–user–managed installations for the users specified by szUserSid. An invalid SID returns no items. /// MSIINSTALLCONTEXT_USERMANAGED = 0x1, /// /// Enumeration extended to all per–user–unmanaged installations for the users specified by szUserSid. An invalid SID returns no items. /// MSIINSTALLCONTEXT_USERUNMANAGED = 0x2, /// /// Enumeration extended to all per-machine installations. When dwInstallContext is set to MSIINSTALLCONTEXT_MACHINE only, the szUserSID parameter must be NULL. /// MSIINSTALLCONTEXT_MACHINE = 0x4, /// /// All contexts. OR of all valid values /// MSIINSTALLCONTEXT_ALL = MSIINSTALLCONTEXT_USERMANAGED | MSIINSTALLCONTEXT_USERUNMANAGED | MSIINSTALLCONTEXT_MACHINE, /// /// All user-managed contexts. /// MSIINSTALLCONTEXT_ALLUSERMANAGED = 0x8, } public const int MAX_FEATURE_CHARS = 38; // maximum chars in feature name (same as string GUID) // MsiOpenDatabase persist predefine values, otherwise output database path is used public const string MSIDBOPEN_READONLY = "0"; // database open read-only, no persistent changes public const string MSIDBOPEN_TRANSACT = "1"; // database read/write in transaction mode public const string MSIDBOPEN_DIRECT = "2"; // database direct read/write without transaction public const string MSIDBOPEN_CREATE = "3"; // create new database, transact mode read/write public const string MSIDBOPEN_CREATEDIRECT = "4"; // create new database, direct mode read/write // ------------------------------------------------------------------------- // Functions to set the UI handling and logging. The UI will be used for error, // progress, and log messages for all subsequent calls to Installer Service // API functions that require UI. // ------------------------------------------------------------------------- // Enable internal UI [DllImport("msi", CharSet = CharSet.Auto)] // UI level // handle of owner window public static extern INSTALLUILEVEL MsiSetInternalUI(INSTALLUILEVEL dwUILevel, ref IntPtr winhandle); // Enable logging to a file for all install sessions for the client process, // with control over which log messages are passed to the specified log file. // Messages are designated with a combination of bits from INSTALLLOGMODE enum. [DllImport("msi", CharSet = CharSet.Auto)] public static extern int MsiEnableLog( int dwLogMode, // bit flags designating operations to report string szLogFile, // log file, or NULL to disable logging int dwLogAttributes); // Return the installed state for a product [DllImport("msi", CharSet = CharSet.Auto)] public static extern INSTALLSTATE MsiQueryProductState( string szProduct); // Return product info [DllImport("msi", CharSet = CharSet.Auto)] public static extern int MsiGetProductInfo( string szProduct, // product code string szAttribute, // attribute name, case-sensitive string lpValueBuf, // returned value, NULL if not desired ref? ref int len); // in/out buffer character count // Install a new product. // Either may be NULL, but the DATABASE property must be specfied [DllImport("msi", CharSet = CharSet.Auto)] public static extern int MsiInstallProduct( string szPackagePath, // location of package to install string szCommandLine); // command line // Install/uninstall an advertised or installed product // No action if installed and INSTALLSTATE_DEFAULT specified [DllImport("msi", CharSet = CharSet.Auto)] public static extern int MsiConfigureProduct( string szProduct, // product code int iInstallLevel, // how much of the product to install INSTALLSTATE eInstallState); // local/source/default/absent/lock/uncache // Reinstall product, used to validate or correct problems [DllImport("msi", CharSet = CharSet.Auto)] public static extern int MsiReinstallProduct( string szProduct, // product code int szReinstallMode); // one or more REINSTALLMODE modes // Return the product code for a registered component, called once by apps [DllImport("msi", CharSet = CharSet.Auto)] public static extern int MsiGetProductCode( string szComponent, // component Id registered for this product [Out] StringBuilder lpBuf39); // returned string GUID, sized for 39 characters // Return the registered user information for an installed product [DllImport("msi", CharSet = CharSet.Auto)] public static extern USERINFOSTATE MsiGetUserInfo( string szProduct, // product code, string GUID string UserNameBuf, // return user name ref int UserNameBufLen, // in/out buffer character count string OrgNameBuf, // return company name ref int OrgNameBufLen, // in/out buffer character count string SerialBuf, // return product serial number ref int SerialBufLen); // in/out buffer character count // Obtain and store user info and PID from installation wizard (first run) [DllImport("msi", CharSet = CharSet.Auto)] public static extern int MsiCollectUserInfo( string szProduct); // product code, string GUID //msiQuery.h // ------------------------------------------------------------------------- // Installer database management functions - not used by custom actions // ------------------------------------------------------------------------- // Open an installer database, specifying the persistance mode, which is a pointer. // Predefined persist values are reserved pointer values, requiring pointer arithmetic. // Execution of this function sets the error record, accessible via MsiGetLastErrorRecord [DllImport("msi", CharSet = CharSet.Auto)] public static extern int MsiOpenDatabase(string dbpath, string persist, ref IntPtr msihandle); // Import an MSI text archive table into an open database // Execution of this function sets the error record, accessible via MsiGetLastErrorRecord [DllImport("msi", CharSet = CharSet.Auto)] public static extern int MsiDatabaseImport(IntPtr msihandle, string FolderPath, // folder containing archive files string FileName); // table archive file to be imported // Export an MSI table from an open database to a text archive file // Execution of this function sets the error record, accessible via MsiGetLastErrorRecord [DllImport("msi", CharSet = CharSet.Auto)] public static extern int MsiDatabaseExport(IntPtr msihandle, string TableName, // name of table in database string FolderPath, // folder containing archive files string FileName); // name of exported table archive file // Merge two database together, allowing duplicate rows // Execution of this function sets the error record, accessible via MsiGetLastErrorRecord [DllImport("msi", CharSet = CharSet.Auto)] public static extern int MsiDatabaseMerge(IntPtr msihandle, IntPtr msihandle2, // database to be merged into hDatabase string TableName); // name of non-persistent table to receive errors // Write out all persistent table data, ignored if database opened read-only // Execution of this function sets the error record, accessible via MsiGetLastErrorRecord [DllImport("msi")] public static extern int MsiDatabaseCommit(IntPtr msihandle); // Return the update state of a database [DllImport("msi")] public static extern MSIDBSTATE MsiGetDatabaseState(IntPtr msihandle); // ------------------------------------------------------------------------- // Installer database access functions // ------------------------------------------------------------------------- // Prepare a database query, creating a view object // Returns ERROR_SUCCESS if successful, and the view handle is returned, // else ERROR_INVALID_HANDLE, ERROR_INVALID_HANDLE_STATE, ERROR_BAD_QUERY_SYNTAX, ERROR_GEN_FAILURE // Execution of this function sets the error record, accessible via MsiGetLastErrorRecord [DllImport("msi")] public static extern int MsiDatabaseOpenView(IntPtr handle, string query, ref IntPtr viewhandle); // Exectute the view query, supplying parameters as required // Returns ERROR_SUCCESS, ERROR_INVALID_HANDLE, ERROR_INVALID_HANDLE_STATE, ERROR_GEN_FAILURE // Execution of this function sets the error record, accessible via MsiGetLastErrorRecord [DllImport("msi")] public static extern int MsiViewExecute(IntPtr viewhandle, IntPtr recordhandle); // Fetch the next sequential record from the view // Result is ERROR_SUCCESS if a row is found, and its handle is returned // else ERROR_NO_MORE_ITEMS if no records remain, and a null handle is returned // else result is error: ERROR_INVALID_HANDLE_STATE, ERROR_INVALID_HANDLE, ERROR_GEN_FAILURE [DllImport("msi")] public static extern int MsiViewFetch(IntPtr viewhandle, ref IntPtr recordhandle); // Modify a database record, parameters must match types in query columns // Returns ERROR_SUCCESS, ERROR_INVALID_HANDLE, ERROR_INVALID_HANDLE_STATE, ERROR_GEN_FAILURE, ERROR_ACCESS_DENIED // Execution of this function sets the error record, accessible via MsiGetLastErrorRecord [DllImport("msi")] public static extern int MsiViewModify(IntPtr viewhandle, MSIMODIFY eModifyMode, // modify action to perform IntPtr recordhandle); // record obtained from fetch, or new record // Return the column names or specifications for the current view // Returns ERROR_SUCCESS, ERROR_INVALID_HANDLE, ERROR_INVALID_PARAMETER, or ERROR_INVALID_HANDLE_STATE [DllImport("msi")] public static extern int MsiViewGetColumnInfo(IntPtr viewhandle, MSICOLINFO eColumnInfo, // retrieve columns names or definitions ref IntPtr recordhandle); // returned data record containing all names or definitions [DllImport("msi")] public static extern int MsiCloseHandle(IntPtr handle); // Release the result set for an executed view, to allow re-execution // Only needs to be called if not all records have been fetched // Returns ERROR_SUCCESS, ERROR_INVALID_HANDLE, ERROR_INVALID_HANDLE_STATE [DllImport("msi")] public static extern int MsiViewClose(IntPtr viewhandle); // Return a record containing the names of all primary key columns for a given table // Returns an MSIHANDLE for a record containing the name of each column. // The field count of the record corresponds to the number of primary key columns. // Field [0] of the record contains the table name. // Returns ERROR_SUCCESS, ERROR_INVALID_HANDLE, ERROR_INVALID_TABLE [DllImport("msi", CharSet = CharSet.Auto)] public static extern int MsiDatabaseGetPrimaryKeys(IntPtr msihandle, string szTableName, // the name of a specific table ref IntPtr recordhandle); // returned record if ERROR_SUCCESS // ------------------------------------------------------------------------- // Record object functions // ------------------------------------------------------------------------- // Create a new record object with the requested number of fields // Field 0, not included in count, is used for format strings and op codes // All fields are initialized to null // Returns a handle to the created record, or 0 if memory could not be allocated [DllImport("msi")] public static extern IntPtr MsiCreateRecord( int Params); // the number of data fields // Report whether a record field is NULL // Returns TRUE if the field is null or does not exist // Returns FALSE if the field contains data, or the handle is invalid [DllImport("msi")] public static extern bool MsiRecordIsNull(IntPtr recordhandle, int Field); // Return the length of a record field // Returns 0 if field is NULL or non-existent // Returns sizeof(int) if integer data // Returns character count if string data (not counting null terminator) // Returns bytes count if stream data [DllImport("msi")] public static extern int MsiRecordDataSize(IntPtr recordhandle, int Field); // Set a record field to an integer value // Returns ERROR_SUCCESS, ERROR_INVALID_HANDLE, ERROR_INVALID_FIELD [DllImport("msi")] public static extern int MsiRecordSetInteger(IntPtr recordhandle, int Field, int Value); // Copy a string into the designated field // A null string pointer and an empty string both set the field to null // Returns ERROR_SUCCESS, ERROR_INVALID_HANDLE, ERROR_INVALID_FIELD [DllImport("msi", CharSet = CharSet.Auto)] public static extern int MsiRecordSetString(IntPtr recordhandle, int Field, string Value); // Return the integer value from a record field // Returns the value MSI_NULL_INTEGER if the field is null // or if the field is a string that cannot be converted to an integer [DllImport("msi")] public static extern int MsiRecordGetInteger(IntPtr recordhandle, int Field); // Return the string value of a record field // Integer fields will be converted to a string // Null and non-existent fields will report a value of 0 // Fields containing stream data will return ERROR_INVALID_DATATYPE // Returns ERROR_SUCCESS, ERROR_MORE_DATA, // ERROR_INVALID_HANDLE, ERROR_INVALID_FIELD, ERROR_BAD_ARGUMENTS [DllImport("msi", CharSet = CharSet.Auto)] public static extern int MsiRecordGetString(IntPtr recordhandle, int Field, string ValueBuf, // buffer for returned value ref int len); // in/out buffer character count // Returns the number of fields allocated in the record // Does not count field 0, used for formatting and op codes [DllImport("msi")] public static extern int MsiRecordGetFieldCount(IntPtr recordhandle); // Set a record stream field from a file // The contents of the specified file will be read into a stream object // The stream will be persisted if the record is inserted into the database // Execution of this function sets the error record, accessible via MsiGetLastErrorRecord [DllImport("msi", CharSet = CharSet.Auto)] public static extern int MsiRecordSetStream(IntPtr recordhandle, int Field, string FilePath); // path to file containing stream data // Read bytes from a record stream field into a buffer // Must set the in/out argument to the requested byte count to read // The number of bytes transferred is returned through the argument // If no more bytes are available, ERROR_SUCCESS is still returned [DllImport("msi", CharSet = CharSet.Auto)] public static extern int MsiRecordReadStream(IntPtr recordhandle, int Field, string DataBuf, // buffer to receive bytes from stream ref int len); // in/out buffer byte count // Clears all data fields in a record to NULL [DllImport("msi")] public static extern int MsiRecordClearData(IntPtr recordhandle); [DllImport("msi.dll", CharSet = CharSet.Unicode)] public static extern int MsiGetProductInfo(string product, string property, [Out] StringBuilder valueBuf, ref int len); [DllImport("msi.dll", SetLastError = true)] public static extern int MsiEnumProducts(int iProductIndex, StringBuilder lpProductBuf); // The MsiGetFileSignatureInformation function takes the path to a file that has been digitally // signed and returns the file's signer certificate and hash. [DllImport("msi")] public static extern int MsiGetFileSignatureInformation([In] string szSignedObjectPath, [In] uint dwFlags, out IntPtr ppcCertContext, [Out] byte[] pbHashData, ref uint pcbHashData); [DllImport("msi.dll", CharSet = CharSet.Unicode)] //http://msdn.microsoft.com/library/en-us/msi/setup/msienumcomponents.asp public static extern int MsiEnumComponents(int iComponentIndex, StringBuilder lpComponentBuf); [DllImport("msi.dll", CharSet = CharSet.Unicode)] public static extern INSTALLSTATE MsiGetComponentPath(string szProduct, string szComponent, StringBuilder lpPathBuf, ref int pcchPathBuf); [DllImport("msi.dll", CharSet = CharSet.Unicode)] public static extern int MsiQueryComponentState(string szProductCode, string szUserSid, [MarshalAs(UnmanagedType.I4)] MSIINSTALLCONTEXT dwContext, string szComponent, out INSTALLSTATE pdwState); public sealed class INSTALLPROPERTY { // Product info attributes: advertised information public static INSTALLPROPERTY PACKAGENAME = new("PackageName"); public static INSTALLPROPERTY TRANSFORMS = new("Transforms"); public static INSTALLPROPERTY LANGUAGE = new("Language"); public static INSTALLPROPERTY PRODUCTNAME = new("ProductName"); public static INSTALLPROPERTY ASSIGNMENTTYPE = new("AssignmentType"); public static INSTALLPROPERTY PACKAGECODE = new("PackageCode"); public static INSTALLPROPERTY VERSION = new("Version"); public static INSTALLPROPERTY PRODUCTICON = new("ProductIcon"); // Product info attributes: installed information public static INSTALLPROPERTY INSTALLEDPRODUCTNAME = new("InstalledProductName"); public static INSTALLPROPERTY VERSIONSTRING = new("VersionString"); public static INSTALLPROPERTY HELPLINK = new("HelpLink"); public static INSTALLPROPERTY HELPTELEPHONE = new("HelpTelephone"); public static INSTALLPROPERTY INSTALLLOCATION = new("InstallLocation"); public static INSTALLPROPERTY INSTALLSOURCE = new("InstallSource"); public static INSTALLPROPERTY INSTALLDATE = new("InstallDate"); public static INSTALLPROPERTY PUBLISHER = new("Publisher"); public static INSTALLPROPERTY LOCALPACKAGE = new("LocalPackage"); public static INSTALLPROPERTY URLINFOABOUT = new("URLInfoAbout"); public static INSTALLPROPERTY URLUPDATEINFO = new("URLUpdateInfo"); public static INSTALLPROPERTY VERSIONMINOR = new("VersionMinor"); public static INSTALLPROPERTY VERSIONMAJOR = new("VersionMajor"); private INSTALLPROPERTY(string name) { PropertyName = name; } public string PropertyName { get; } public override string ToString() { return PropertyName; } } } } ================================================ FILE: source/KlocTools/Properties/Localisation.Designer.cs ================================================ //------------------------------------------------------------------------------ // // This code was generated by a tool. // Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ namespace Klocman.Properties { using System; /// /// A strongly-typed resource class, for looking up localized strings, etc. /// // This class was auto-generated by the StronglyTypedResourceBuilder // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] public class Localisation { private static global::System.Resources.ResourceManager resourceMan; private static global::System.Globalization.CultureInfo resourceCulture; [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] internal Localisation() { } /// /// Returns the cached ResourceManager instance used by this class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] public static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Klocman.Properties.Localisation", typeof(Localisation).Assembly); resourceMan = temp; } return resourceMan; } } /// /// Overrides the current thread's CurrentUICulture property for all /// resource lookups using this strongly typed resource class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] public static global::System.Globalization.CultureInfo Culture { get { return resourceCulture; } set { resourceCulture = value; } } /// /// Looks up a localized string similar to Ask. /// public static string Enums_YesNoAsk_Ask { get { return ResourceManager.GetString("Enums_YesNoAsk_Ask", resourceCulture); } } /// /// Looks up a localized string similar to File name can't be empty.. /// public static string Error_SeparateArgsFromCommand_Empty { get { return ResourceManager.GetString("Error_SeparateArgsFromCommand_Empty", resourceCulture); } } /// /// Looks up a localized string similar to Ending quotation mark is missing.. /// public static string Error_SeparateArgsFromCommand_MissingQuotationMark { get { return ResourceManager.GetString("Error_SeparateArgsFromCommand_MissingQuotationMark", resourceCulture); } } /// /// Looks up a localized string similar to File name must contain an extension separated by a dot.. /// public static string Error_SeparateArgsFromCommand_NoDot { get { return ResourceManager.GetString("Error_SeparateArgsFromCommand_NoDot", resourceCulture); } } /// /// Looks up a localized string similar to Attributes. /// public static string FileInfo_Attributes { get { return ResourceManager.GetString("FileInfo_Attributes", resourceCulture); } } /// /// Looks up a localized string similar to Comment. /// public static string FileInfo_Comments { get { return ResourceManager.GetString("FileInfo_Comments", resourceCulture); } } /// /// Looks up a localized string similar to Company Name. /// public static string FileInfo_CompanyName { get { return ResourceManager.GetString("FileInfo_CompanyName", resourceCulture); } } /// /// Looks up a localized string similar to Creation Time. /// public static string FileInfo_CreationTime { get { return ResourceManager.GetString("FileInfo_CreationTime", resourceCulture); } } /// /// Looks up a localized string similar to Directory. /// public static string FileInfo_Directory { get { return ResourceManager.GetString("FileInfo_Directory", resourceCulture); } } /// /// Looks up a localized string similar to Exists on drive. /// public static string FileInfo_Exists { get { return ResourceManager.GetString("FileInfo_Exists", resourceCulture); } } /// /// Looks up a localized string similar to Description. /// public static string FileInfo_FileDescription { get { return ResourceManager.GetString("FileInfo_FileDescription", resourceCulture); } } /// /// Looks up a localized string similar to File Name. /// public static string FileInfo_FileName { get { return ResourceManager.GetString("FileInfo_FileName", resourceCulture); } } /// /// Looks up a localized string similar to File Version. /// public static string FileInfo_FileVersion { get { return ResourceManager.GetString("FileInfo_FileVersion", resourceCulture); } } /// /// Looks up a localized string similar to Full Name. /// public static string FileInfo_FullName { get { return ResourceManager.GetString("FileInfo_FullName", resourceCulture); } } /// /// Looks up a localized string similar to Internal Name. /// public static string FileInfo_InternalName { get { return ResourceManager.GetString("FileInfo_InternalName", resourceCulture); } } /// /// Looks up a localized string similar to Is read only. /// public static string FileInfo_IsReadOnly { get { return ResourceManager.GetString("FileInfo_IsReadOnly", resourceCulture); } } /// /// Looks up a localized string similar to Language. /// public static string FileInfo_Language { get { return ResourceManager.GetString("FileInfo_Language", resourceCulture); } } /// /// Looks up a localized string similar to Last Access Time. /// public static string FileInfo_LastAccessTime { get { return ResourceManager.GetString("FileInfo_LastAccessTime", resourceCulture); } } /// /// Looks up a localized string similar to Last Write Time. /// public static string FileInfo_LastWriteTime { get { return ResourceManager.GetString("FileInfo_LastWriteTime", resourceCulture); } } /// /// Looks up a localized string similar to Copyright. /// public static string FileInfo_LegalCopyright { get { return ResourceManager.GetString("FileInfo_LegalCopyright", resourceCulture); } } /// /// Looks up a localized string similar to Trademarks. /// public static string FileInfo_LegalTrademarks { get { return ResourceManager.GetString("FileInfo_LegalTrademarks", resourceCulture); } } /// /// Looks up a localized string similar to Original Filename. /// public static string FileInfo_OriginalFilename { get { return ResourceManager.GetString("FileInfo_OriginalFilename", resourceCulture); } } /// /// Looks up a localized string similar to Product Name. /// public static string FileInfo_ProductName { get { return ResourceManager.GetString("FileInfo_ProductName", resourceCulture); } } /// /// Looks up a localized string similar to Product Version. /// public static string FileInfo_ProductVersion { get { return ResourceManager.GetString("FileInfo_ProductVersion", resourceCulture); } } /// /// Looks up a localized string similar to Size. /// public static string FileInfo_Size { get { return ResourceManager.GetString("FileInfo_Size", resourceCulture); } } /// /// Looks up a localized string similar to Gigabytes. /// public static string FileSize_GB_Long { get { return ResourceManager.GetString("FileSize_GB_Long", resourceCulture); } } /// /// Looks up a localized string similar to GB. /// public static string FileSize_GB_Short { get { return ResourceManager.GetString("FileSize_GB_Short", resourceCulture); } } /// /// Looks up a localized string similar to Kilobytes. /// public static string FileSize_KB_Long { get { return ResourceManager.GetString("FileSize_KB_Long", resourceCulture); } } /// /// Looks up a localized string similar to KB. /// public static string FileSize_KB_Short { get { return ResourceManager.GetString("FileSize_KB_Short", resourceCulture); } } /// /// Looks up a localized string similar to Megabytes. /// public static string FileSize_MB_Long { get { return ResourceManager.GetString("FileSize_MB_Long", resourceCulture); } } /// /// Looks up a localized string similar to MB. /// public static string FileSize_MB_Short { get { return ResourceManager.GetString("FileSize_MB_Short", resourceCulture); } } /// /// Looks up a localized string similar to Terabytes. /// public static string FileSize_TB_Long { get { return ResourceManager.GetString("FileSize_TB_Long", resourceCulture); } } /// /// Looks up a localized string similar to TB. /// public static string FileSize_TB_Short { get { return ResourceManager.GetString("FileSize_TB_Short", resourceCulture); } } /// /// Looks up a localized string similar to No. /// public static string No { get { return ResourceManager.GetString("No", resourceCulture); } } /// /// Looks up a localized string similar to While this error does not require the application to shut down, some functionality might stop working. Most errors related to the filesystem can be safely ignored. /// ///Error message: {0} /// ///You can copy detailed information about this error to the clipboard by clicking the "Copy" button. Please consider sending this error information to the developer.. /// public static string PremadeDialogs_GenericError_Details { get { return ResourceManager.GetString("PremadeDialogs_GenericError_Details", resourceCulture); } } /// /// Looks up a localized string similar to The application has encountered an unexpected error. /// public static string PremadeDialogs_GenericError_Heading { get { return ResourceManager.GetString("PremadeDialogs_GenericError_Heading", resourceCulture); } } /// /// Looks up a localized string similar to Inner: . /// public static string PremadeDialogs_GenericError_InnerExceptionTitle { get { return ResourceManager.GetString("PremadeDialogs_GenericError_InnerExceptionTitle", resourceCulture); } } /// /// Looks up a localized string similar to Unexpected error. /// public static string PremadeDialogs_GenericError_Title { get { return ResourceManager.GetString("PremadeDialogs_GenericError_Title", resourceCulture); } } /// /// Looks up a localized string similar to Error details:. /// public static string PremadeDialogs_GenericErrorExtendedSafe_Heading { get { return ResourceManager.GetString("PremadeDialogs_GenericErrorExtendedSafe_Heading", resourceCulture); } } /// /// Looks up a localized string similar to You might lose any unsaved data. To prevent data loss close the applications manually.. /// public static string PremadeDialogs_KillRunningProcessesQuestion_Details { get { return ResourceManager.GetString("PremadeDialogs_KillRunningProcessesQuestion_Details", resourceCulture); } } /// /// Looks up a localized string similar to Are you sure you want to terminate all of the processes? . /// public static string PremadeDialogs_KillRunningProcessesQuestion_Message { get { return ResourceManager.GetString("PremadeDialogs_KillRunningProcessesQuestion_Message", resourceCulture); } } /// /// Looks up a localized string similar to Terminate running processes. /// public static string PremadeDialogs_KillRunningProcessesQuestion_Title { get { return ResourceManager.GetString("PremadeDialogs_KillRunningProcessesQuestion_Title", resourceCulture); } } /// /// Looks up a localized string similar to Path does not point to a valid .reg file. /// public static string RegistryTools_AddRegToRegistry_FileNotExist { get { return ResourceManager.GetString("RegistryTools_AddRegToRegistry_FileNotExist", resourceCulture); } } /// /// Looks up a localized string similar to Path cannot be empty or null. /// public static string RegistryTools_RemoveRegistryKey_PathEmptyNull { get { return ResourceManager.GetString("RegistryTools_RemoveRegistryKey_PathEmptyNull", resourceCulture); } } /// /// Looks up a localized string similar to Path cannot point to a root key. /// public static string RegistryTools_RemoveRegistryKey_PointsAtRoot { get { return ResourceManager.GetString("RegistryTools_RemoveRegistryKey_PointsAtRoot", resourceCulture); } } /// /// Looks up a localized string similar to Cannot remove the default value. /// public static string RegistryTools_RemoveRegistryKey_RemoveDefault { get { return ResourceManager.GetString("RegistryTools_RemoveRegistryKey_RemoveDefault", resourceCulture); } } /// /// Looks up a localized string similar to {0} days ago. /// public static string ToFuzzyTimeSinceString_Days_Since { get { return ResourceManager.GetString("ToFuzzyTimeSinceString_Days_Since", resourceCulture); } } /// /// Looks up a localized string similar to Yesterday. /// public static string ToFuzzyTimeSinceString_Days_Single { get { return ResourceManager.GetString("ToFuzzyTimeSinceString_Days_Single", resourceCulture); } } /// /// Looks up a localized string similar to {0} hours ago. /// public static string ToFuzzyTimeSinceString_Hours_Since { get { return ResourceManager.GetString("ToFuzzyTimeSinceString_Hours_Since", resourceCulture); } } /// /// Looks up a localized string similar to One hour ago. /// public static string ToFuzzyTimeSinceString_Hours_Single { get { return ResourceManager.GetString("ToFuzzyTimeSinceString_Hours_Single", resourceCulture); } } /// /// Looks up a localized string similar to Just now. /// public static string ToFuzzyTimeSinceString_JustNow { get { return ResourceManager.GetString("ToFuzzyTimeSinceString_JustNow", resourceCulture); } } /// /// Looks up a localized string similar to {0} minutes ago. /// public static string ToFuzzyTimeSinceString_Minutes_Since { get { return ResourceManager.GetString("ToFuzzyTimeSinceString_Minutes_Since", resourceCulture); } } /// /// Looks up a localized string similar to One minute ago. /// public static string ToFuzzyTimeSinceString_Minutes_Single { get { return ResourceManager.GetString("ToFuzzyTimeSinceString_Minutes_Single", resourceCulture); } } /// /// Looks up a localized string similar to {0} months ago. /// public static string ToFuzzyTimeSinceString_Months_Since { get { return ResourceManager.GetString("ToFuzzyTimeSinceString_Months_Since", resourceCulture); } } /// /// Looks up a localized string similar to One month ago. /// public static string ToFuzzyTimeSinceString_Months_Single { get { return ResourceManager.GetString("ToFuzzyTimeSinceString_Months_Single", resourceCulture); } } /// /// Looks up a localized string similar to {0} years ago. /// public static string ToFuzzyTimeSinceString_Years_Since { get { return ResourceManager.GetString("ToFuzzyTimeSinceString_Years_Since", resourceCulture); } } /// /// Looks up a localized string similar to One year ago. /// public static string ToFuzzyTimeSinceString_Years_Single { get { return ResourceManager.GetString("ToFuzzyTimeSinceString_Years_Single", resourceCulture); } } /// /// Looks up a localized string similar to Yes. /// public static string Yes { get { return ResourceManager.GetString("Yes", resourceCulture); } } } } ================================================ FILE: source/KlocTools/Properties/Localisation.ar.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 اسال لا يمكن ان يكون اسم الملف فارغا. انهاء علامة اقتباس مفقود. يجب ان يحتوي اسم الملف على ملحق مفصول بنقطه. غيغابايت ق ب كيلوبايت ك ب ميقا بايت م ب تيرابايت ت ب لا نعم {0} قبل ايام امس {0} قبل ساعات قبل ساعة واحدة الان {0} قبل دقائق قبل دقيقة واحدة {0} قبل شهور قبل شهر واحد {0} قبل سنوات قبل سنة واحدة الداخل: صادف التطبيق خطا غير متوقع خطا غير متوقع قد تفقد ايه بيانات غير محفوظه. لمنع فقدان البيانات اغلق التطبيقات يدويا. هل تريد بالتاكيد انهاء كافة العمليات ؟ انهاء عمليات التشغيل صالح .reg لا يشير المسار إلى ملف لا يمكن ان يكون المسار فارغا او خاليا لا يمكن ان يشير المسار الى مفتاح الجذر لا يمكن ازاله القيمة الافتراضية تفاصيل الخطا: بالرغم من ان هذا الخطا لا يتطلب ايقاف تشغيل التطبيق ، فقد تتوقف بعض الوظائف عن العمل. يمكن تجاهل معظم الاخطاء المتعلقة بالملفات بامان. {0} :رسالة الخطا يمكنك نسخ معلومات مفصله حول هذا الخطا الى الحافظة بالنقر فوق الزر "نسخ". الرجاء النظر في ارسال معلومات الخطا هذه الى المطور. وقت الانشاء اخر وقت وصول وقت الكتابة الاخير سمات قراءة فقط الاسم الكامل اسم الملف حجم دليل موجود على المحرك تعليق اسم الشركة وصف اصدار الملف الاسم الداخلي لغة حقوق النشر العلامات التجارية الاسم الكامل اسم الملف حجم ================================================ FILE: source/KlocTools/Properties/Localisation.cs.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Zeptat se Název souboru nemůže být prázdný. Ukončení-uvozovky chybí. Název souboru musí obsahovat příponu oddělenou tečkou. Gigabyt GB Kilobyt KB Megabyt MB Terabyt TB Ne Ano {0} dny Včera {0} před hodinou Před jednou hodinou Právě teď {0} před minutami Před jednou minutou {0} před měsícem Před měsícem {0} před lety Před rokem Vnitřní: Aplikace došlo k neočekávané chybě Neočekávaná chyba Mohly by jste přijít o neuložená data. Chcete-li zabránit ztrátě dat zavřete aplikace ručně. Jste si jisti, že chcete ukončit všechny procesy? Ukončit běžící procesy Název souboru neukazuje na platný soubor registrů Cesta nemůže být prázdná nebo null Cesta nemůže odkazovat na kořenového klíče Nelze odstranit standardní hodnotu Podrobnosti o chybě: Zatímco tato chyba nevyžaduje vypnoutí aplikace, některé funkce mohou přestat pracovat. Většina chyb souvisejících s souborový systém může být bezpečně ignorována. Chybová zpráva: {0} Podrobné informace o této chybě můžete zkopírovat do schránky klepnutím na tlačítko "Kopírovat". Zvažte možnost odeslání informace o této chybě vývojáři. Čas vytvoření Čas posledního přístupu Poslední čas zápisu Atributy Je jen pro čtení Celé jméno Název souboru Velikost Adresář Existuje na disku Komentář Název společnosti Popis Verze souboru Vnitřní název Jazyk Autorská práva Ochranná známka Původní název souboru Název produktu Verze produktu ================================================ FILE: source/KlocTools/Properties/Localisation.de.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Fragen Dateinname kann nicht leer sein Endung-Anführungszeichen fehlt. Der Dateiname muss eine Erweiterung durch einen Punkt getrennt enthalten. Gigabytes GB Kilobytes KB Megabytes MB Terabytes TB Nein Ja Die Anwendung ist ein unerwarteter Fehler aufgetreten Innen: Unerwarteter Fehler vor {0} Tagen Gestern vor {0} Stunden vor einer Stunde Gerade vor {0} Minuten vor einer Minute vor {0} Monaten vor einem Monat vor {0} Jahren vor einem Jahr Alle nicht gespeicherten Daten gehen möglicherweise verloren. Um Datenverlust zu verhindern, schließen Sie die Anwendungen manuell. Sind Sie sicher, dass Sie alle Prozesse beenden möchten? Laufende Prozesse beenden Dateiname verweist nicht auf eine gültige .reg-Datei Pfad kann nicht leer oder Null sein Pfad kann nicht auf einen Stammschlüssel zeigen Default-Wert kann nicht entfernt werden Attribute Größe Bemerkung Firmen Name Beschreibung Interner name Sprache Copyright Fehlerinformationen Während dieser Fehler nicht erfordert, dass die Anwendung heruntergefahren wird. Einige Funktionen funktionieren möglicherweise nicht mehr. Die meisten Fehler im Zusammenhang mit dem Dateisystem können problemlos ignoriert werden. Fehlermeldung: {0} Sie können detailierte Informationen dieses Fehlers in die Zwischenablage durch drücken der Copy Schaltfläche kopieren. Bitte überlege, diese Fehlerinformationen an den Entwickler zu senden. Erstellungsdatum Letzter Zugriff Letzte Änderung Schreibgeschützt Voller Name Datei Name Ordnerpfad Ist auf Laufwerk Datei Version Warenzeichen Wirklicher Dateiname Produkt Name Produkt Version ================================================ FILE: source/KlocTools/Properties/Localisation.es.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Preguntar El nombre del archivo no puede estar vacío. Falta la comilla final. El nombre del archivo debe contener una extensión separada por un punto. Gigabytes GB Kilobytes KB Megabytes MB Terabytes TB No Si Hace {0} días Ayer Hace {0} horas Hace una hora Justo ahora Hace {0} minutos Hace un minuto Hace {0} meses Hace un mes Hace {0} años Hace un año Interior: La aplicación ha detectado un error inesperado Error inesperado Puede perder los datos no guardados. Para evitarlo, cierre manualmente las aplicaciones. ¿Está seguro de que desea terminar todos los procesos? Terminar los procesos en ejecución Ruta de acceso no apunta a un archivo .reg válido La ruta de acceso no puede estar vacía o nula La ruta de acceso no puede apuntar a una clave raíz No se puede eliminar el valor predeterminado Detalles del error: Si bien este error no requiere cerrar BCU, algunas funciones pueden dejar de funcionar. La mayoría de los errores relacionados con el sistema de archivos pueden ser ignorados. Mensaje del error: {0} Puede copiar la información detallada sobre este error en el portapapeles haciendo clic en el botón "Copiar". Por favor, considere enviar esta información de error al desarrollador. Fecha de creación Fecha de último acceso Fecha de última escritura Atributos Es de sólo lectura Nombre completo Nombre del archivo Tamaño Directorio Existe en la unidad Comentario Nombre de la Compañía Descripción Versión del archivo Nombre interno Idioma Copyright Marcas registradas Nombre original Nombre del producto Versión del producto ================================================ FILE: source/KlocTools/Properties/Localisation.fr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Demander Non Oui Le nom de fichier ne peut être vide. Il manque le guillemet de fin. Le nom de fichier doit contenir une extension séparée par un point. Giga-octets Go Kilo-octets Ko Méga-octets Mo Téra-octets To Hier Il y a une heure Juste maintenant Il y a une minute Il y a un mois Il y a un an Il y a {0} jours Il y a {0} heures Il y a {0} minutes Il y a {0} mois Il y a {0} ans L'application a rencontré une erreur inattendue Intérieur : Erreur inattendue Vous pourriez perdre toute donnée non sauvegardée. Pour éviter une perte de donnée, fermez manuellement les applications. Êtes-vous sûr de vouloir arrêter tous les processus ? Arrêter les processus en cours Le chemin ne pointe pas sur un fichier .reg valide Le chemin ne peut pas être vide ou nul Le chemin ne peut pas pointer sur une clé racine Impossible de supprimer la valeur par défaut Bien que cette erreur ne nécessite pas l'arrêt de l'application, certaines fonctionnalités pourrait s'arrêter de fonctionner. La plupart des erreurs liées au système de fichiers peuvent être ignorées en toute sécurité. Message d'erreur : {0} Vous pouvez copier les informations détaillées concernant cette erreur dans le presse-papiers en cliquant sur le bouton "Copier". Veuillez envisager l'envoi de cette information d'erreur au développeur. Détails d'erreur: Heure de Création Heure de Dernier Accès Heure de Dernière Ecriture Attributs Est lecture seule Nom Complet Nom de Fichier Taille Dossier Existe sur le lecteur Commentaire Nom de Compagnie Description Version de Fichier Nom Interne Langue Copyright Marques déposées Nom de fichier Original Nom de Produit Version de Produit ================================================ FILE: source/KlocTools/Properties/Localisation.hu.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Kérdés A fájlnév nem lehet üres. A záró idézőjel hiányzik. A fájlnévnek tartalmaznia kell a kiterjesztést is, egy ponttal elválasztva. Gigabájt GB Kilobájt KB Megabájt MB Terabájt TB Nem Igen {0} napja Tegnap {0} órája Egy órával ezelőtt Csak most {0} perce Egy perccel ezelőtt {0} hónapja Egy hónappal ezelőtt {0} éve Egy évvel ezelőtt Belső: Az alkalmazás váratlan hibát észlelt Váratlan hiba Lehet, hogy a nem mentett adatai elfognak veszni. Az adatvesztés elkerülése érdekében zárja be az alkalmazást manuálisan. Biztos benne, hogy leállítja az összes folyamatot? Futó folyamatok leállítása Az útvonal nem mutathat egy érvényes .reg fájlra Az útvonal nem lehet üres, vagy nulla Az útvonal nem mutathat egy gyökérkulcsra Az alapérték nem távolítható el Hiba részletei: Emiatt a hiba végett, ugyan nem szükséges leállítania a kérelem, azonban néhány funkciója leállhat. A legtöbb ilyen hiba a fájlrendszer kapcsolódik, és biztonsággal figyelmen kívül hagyható. Hibaüzenet: {0} A hibával kapcsolatos részletes információkat kimásolhatja a Vágólapra, ha a "Másolás" gombra kattint. Kérjük, hogy ezeket az információkat küldje el a fejlesztőnek. Létrehozás ideje Utolsó hozzáférés időpontja Utolsó írás időpontja Attribútumok Csak olvasható Teljes név Fájlnév Méret Könyvtár Létezik a meghajtón Megjegyzés Vállalat neve Leírás Fájlverzió Belső név Nyelv Szerzői jog Védjegyek Eredeti fájlnév Terméknév Termékverzió ================================================ FILE: source/KlocTools/Properties/Localisation.it.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Chiedi Il nome del file non può essere vuoto. Mancano le virgolette finali. Il nome del file deve contenere un'estensione separata dal punto. Gigabyte GB Kilobyte KB Megabyte MB Terabyte TB No {0} giorni fa Ieri {0} ore fa Un'ora fa In questo momento {0} minuti fa Un minuto fa {0} mesi fa Un mese fa {0} anni fa Un anno fa Interno: L'applicazione ha riscontrato un errore inaspettato Errore inaspettato Potresti perdere dei dati non salvati. Per evitare la perdita dei dati chiudi l'applicazione manualmente. Sei sicuro di voler terminare tutti i processi? Terminare i processi in esecuzione Il percorso non punta ad un file .reg valido Il percorso non può essere vuoto o nullo Il percorso non può puntare ad una chiave radice Non si possono cancellare i valori di default Dettagli dell'errore: Sebbene questo errore non richieda di chiudere l'applicazione, alcune funzionalità potrebbero non operare correttamente. La maggior parte degli errori relativi al file system possono essere tranquillamente ignorati. Messaggio di errore: {0} Puoi copiare informazioni dettagliate nella clipboard premendo il tasto "Copia". Ti invitiamo ad inviare le informazioni sull'errore allo sviluppatore. Ora di creazione Ora dell'ultimo accesso Ora dell'ultima scrittura Attributi E' in sola lettura Nome completo Nome del file Grandezza Cartella Esiste sul disco Commento Nome del gruppo Descrizione Versione del file Nome interno Lingua Copyright Marchio depositato Nome del file di origine Nome del prodotto Versione del prodotto ================================================ FILE: source/KlocTools/Properties/Localisation.ja.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ファイル名にはドットで区切られた拡張子が必要です。 聞く ファイル名は空にできません。 終了引用符が欠けています。 ギガバイト GB キロバイト KB メガバイト MB テラバイト TB いいえ はい {0}日前 昨日 {0}時間前 1時間前 たった今 {0}分前 1分前 {0}ヶ月前 1ヶ月前 {0}年前 1年前 内部: アプリケーションが予期しないエラーに遭遇しました 予期しないエラー 保存されていないデータが失われる可能性があります。データ損失を防ぐために、アプリケーションを手動で閉じてください。 すべてのプロセスを終了してもよろしいですか? 実行中のプロセスを終了 パスが有効な .reg ファイルを指していません パスは空またはヌルにできません パスはルートキーを指すことはできません デフォルト値を削除できません エラーの詳細: このエラーはアプリケーションを終了する必要はありませんが、一部の機能が停止する可能性があります。 ファイルシステムに関連するほとんどのエラーは無視しても問題ありません。 エラーメッセージ: {0} "コピー"ボタンをクリックすることで、このエラーに関する詳細情報をクリップボードにコピーできます。 このエラー情報を開発者に送信することを検討してください。 作成日時 最終アクセス日時 最終書き込み日時 属性 読み取り専用 フルネーム ファイル名 サイズ ディレクトリ ドライブに存在 コメント 会社名 説明 ファイルバージョン 内部名 言語 著作権 商標 元のファイル名 製品名 製品バージョン ================================================ FILE: source/KlocTools/Properties/Localisation.nl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Vragen Bestandsnaam mag niet leeg zijn. De bestandsnaam moet een toevoeging gescheiden door een punt hebben. Gigabytes GB Kilobytes KB Megabytes MB Terabytes TB Nee Ja {0} dagen geleden Gisteren {0} uren geleden een uur geleden Nu {0} minuten geleden een minuut geleden {0} maanden geleden een maand geleden {0} maanden geleden een jaar geleden Binnen: In de applicatie is een onverwachte fout opgetreden. Onverwachte fout! Alle niet opgeslagen gegevens gaan mogelijk verloren. Om gegevensverlies te voorkomen, sluit u de applicaties handmatig. Weet u het zeker, dat u alle processen wilt beëindigen? Lopende processen beëindigen Het pad verwijst niet naar een geldig .reg bestand Het pad mag niet leeg of null zijn Het pad mag niet naar een bronsleutel verwijzen De standaard waarde mag niet verwijderd worden Fout details: Attributen Is alleen-lezen Volledige naam Bestandsnaam Grootte Map Bestaat op schijf Commentaar Bedrijfsnaam Beschrijving Bestandsversie Interne naam Taal Copyright Handelsmerken Originele bestandsnaam Productnaam Productversie Einde aanhalingsteken ontbreekt. Omdat deze fout niet vereist om het programma af te sluiten, is het mogelijk dat sommige functionaliteiten niet meer werken. De meeste fouten gerelateerd aan het bestandssysteem kunnen veilig worden genegeerd. Foutmelding: {0} U kunt gedetailliëerde informatie over deze fout kopiëren naar het klembord, met een klik op de knop "Kopiëren". Overweeg a.u.b. om deze informatie naar de ontwikkelaar te sturen. Tijd aangemaakt Tijd laatst gebruikt Tijd laatst geschreven ================================================ FILE: source/KlocTools/Properties/Localisation.pl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Pytaj Nie Tak Nazwa pliku nie może być pusta. Brak kończącego cudzysłowu. Nazwa pliku musi zawierać rozszerzenie po kropce. Gigabajtów Kilobajtów Megabajtów Terabajtów GB KB MB TB {0} dni temu Dzień temu {0} godzin temu Godzinę temu Przed chwilą {0} minut temu Minutę temu {0} miesięcy temu Miesiąc temu {0} lat temu Rok temu Aplikacja napotkała nieoczekiwany błąd Wewnętrzny: Nieoczekiwany błąd Niezapisane dane mogą zostać stracone. Aby tego uniknąć zamknij aplikacje ręcznie. Na pewno zamknąć wszystkie procesy? Zakończ działanie procesów Ścieżka nie wskazuje na prawidłowy plik .reg Ścieżka nie może być null lub pusta Ścieżka nie może wskazywać na klucz główny Nie można usunąć wartości domyślnej O ile błąd ten nie wymaga zamknięcia aplikacji, niektóre funkcje mogą przestać działać. Większość błędów związanych z systemem plików można bezpiecznie zignorować. Komunikat o błędzie: {0} Możesz skopiować szczegółowe informacje na temat tego błędu do schowka klikając przycisk "Kopiuj". Proszę rozważyć wysłanie informacji o błędzie do dewelopera. Szczegóły błędu: Czas utworzenia Czas ostatniego dostępu Czas ostatniego zapisu Atrybuty Jest tylko do odczytu Pełna nazwa Nazwa pliku Rozmiar Folder Istnieje na dysku Komentarz Nazwa firmy Opis Wersja pliku Wewnętrzna Nazwa Język Prawo autorskie Znaki towarowe Oryginalna nazwa pliku Nazwa produktu Wersja produktu ================================================ FILE: source/KlocTools/Properties/Localisation.pt-BR.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Perguntar O nome não pode estar vazio Faltam as aspas do final O nome do arquivo deve conter uma extensão separada por um ponto. Gigabytes GB Kilobytes KB Megabytes MB Terabytes TB Não Sim Há {0} dias atrás Ontem Há {0} horas atrás Há uma hora atrás Neste momento Há {0} minutos atrás Há um minuto atrás Há {0} meses Há um mês atrás Há {0} anos atrás Há um ano atrás Interno: O aplicativo encontrou um erro inesperado Erro inesperado Você pode perder os dados não salvos. Para evitar perda de dados, feche os aplicativos manualmente. Tem certeza de que deseja encerrar todos os processos? Encerrar processos em execução O caminho não aponta para um arquivo .reg válido O caminho não pode estar vazio ou nulo O caminho não pode apontar para uma chave de raiz Não é possível remover o valor padrão Detalhes do erro: Embora esse erro não exija que o aplicativo seja desligado, algumas funcionalidades podem deixar de funcionar. A maioria dos erros relacionados ao sistema de arquivos pode ser ignorado com segurança. Mensagem de erro: {0} Você pode copiar informações detalhadas sobre esse erro para a área de transferência clicando no botão "Copiar". Considere enviar estas informações de erro ao desenvolvedor. Data de criação Data do Último Acesso Data da Última Gravação Atributos Apenas leitura Nome Completo Nome do Arquivo Tamanho Diretório Existe no disco Comentário Nome da empresa Descrição Versão do Arquivo Nome Interno Idioma Direitos Autorais Marcas Comerciais Nome do Arquivo Original Nome do Produto Versão do Produto ================================================ FILE: source/KlocTools/Properties/Localisation.pt.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Perguntar O nome do ficheiro não pode estar vazio Faltam as aspas do final O nome do ficheiro deve conter uma extensão separada por um ponto Gigabytes GB Kilobytes KB Megabytes MB Terabytes TB Não Sim Há {0} dias atrás Ontem Há {0} horas atrás Há uma hora atrás Neste momento Há {0} minutos atrás Há um minuto atrás Há {0} meses Há um mês atrás Há {0} anos atrás Há um ano atrás Interior: O aplicativo encontrou um erro inesperado Erro inesperado Poderá perder os dados que não foram guardados. Para evitar a perda dos dados, feche manualmente as aplicações. Tem a certeza de que quer terminar todos os processos? Encerrar processos em execução O caminho não aponta para um ficheiro .reg válido O caminho não pode estar vazio ou nulo O caminho não pode apontar para uma chave de raiz Não é possível excluir o valor estabelecido por defeito Pormenores do erro: Embora este erro não provoque o corte do pedido, alguns recursos podem deixar de funcionar. A maioria dos erros relacionados com o sistema de arquivos pode ser ignorada com segurança. Mensagens de erro: {0} Pode copiar informações detalhadas sobre este erro na área de transferência clicando no botão "Copiar". Por favor, considere a hipótese de envio de informações de erro para o programador. Tempo de Criação Data do Último Acesso Data da Última Gravação Atributos Só para leitura Nome Completo Nome do Arquivo Tamanho Directório Existe no disco Comentário Razão Social Descrição Versão do Arquivo Nome Interno Idioma Direitos de Autor Marcas Comerciais Nome do Arquivo Original Nome do Produto Versão do Produto ================================================ FILE: source/KlocTools/Properties/Localisation.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Ask File name can't be empty. Ending quotation mark is missing. File name must contain an extension separated by a dot. Gigabytes GB Kilobytes KB Megabytes MB Terabytes TB No Yes {0} days ago Yesterday {0} hours ago One hour ago Just now {0} minutes ago One minute ago {0} months ago One month ago {0} years ago One year ago Inner: The application has encountered an unexpected error Unexpected error You might lose any unsaved data. To prevent data loss close the applications manually. Are you sure you want to terminate all of the processes? Terminate running processes Path does not point to a valid .reg file Path cannot be empty or null Path cannot point to a root key Cannot remove the default value Error details: While this error does not require the application to shut down, some functionality might stop working. Most errors related to the filesystem can be safely ignored. Error message: {0} You can copy detailed information about this error to the clipboard by clicking the "Copy" button. Please consider sending this error information to the developer. Creation Time Last Access Time Last Write Time Attributes Is read only Full Name File Name Size Directory Exists on drive Comment Company Name Description File Version Internal Name Language Copyright Trademarks Original Filename Product Name Product Version ================================================ FILE: source/KlocTools/Properties/Localisation.ru.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Спрашивать Имя файла не может быть пустым. Не хватает кавычки в конце. Имя файла должно содержать точку+расширение. Гигабайт Гб Килобайт Кб Мегабайт Мб Терабайт Тб Нет Да {0} дней назад Вчера {0} часов назад Один час назад Только что {0} минут назад Одну минуту назад {0} месяцев назад Один месяц назад {0} лет назад Год назад Внутренняя: Приложение обнаружило непредвиденную ошибку Непредвиденная ошибка Можно потерять несохранённые данные. Чтобы предотвратить потерю данных, закройте приложения вручную. Вы уверены, что хотите завершить все процессы? Завершить запущенные процессы Путь не указывает на действительный .REG файл Путь не может быть пустым или нулевым Путь не может указывать на корневой ключ Невозможно удалить значение по умолчанию Сведения об ошибке: Эта ошибка не требует закрытия приложения, но некоторые функции могут перестать работать. Большинство ошибок, связанных с файловой системой, могут быть проигнорированны. Сообщение об ошибке: {0} Вы можете скопировать подробную информацию об этой ошибке в буфер обмена, нажав "Копировать". Пожалуйста, подумайте об отправке информации про эту ошибку разработчику. Время создания Время последнего доступа Время последней записи Атрибуты Только чтение Полное имя Имя файла Размер Каталог Существует на диске Комментарий Название фирмы Описание Версия файла Внутреннее имя Язык Авторские права Товарные знаки Оригинальное имя файла Имя продукта Версия продукта ================================================ FILE: source/KlocTools/Properties/Localisation.sl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Vprašaj Ime datoteke ne sme biti prazno Manjka zaključni narekovaj. Ime datoteke mora imeti končnico, ločeno s piko. Gigabajtov GB Kilobajtov KB Megabajtov MB Terabajtov TB Ne Da Pred {0} dnevi Včeraj Pred {0} urami Pred eno uro Pravkar Pred {0} minutami Pred eno minuto Pred {0} mesecev Pred enim mesecem Pred {0} leti Pred enim letom Notranja: Nepričakovana napaka Morda boste izgubili neshranjene podatke. Da bi preprečili izgubo podatkov, ročno zaprite aplikacije. Ali ste prepričani, da želite prekiniti vse te procese Prekini delujoče procese Pot ne kaže na veljavno .reg datoteko Pot ne sme biti prazna ali 'null' Pot ne sme kazati na korenski ključ Ne morem odstraniti privzeto vrednost Aplikacija je naletela na nepričakovano napako Podrobnosti o napaki: Med to napako nipotrebno, zapreti aplikacije toda nekatere funkcije morda bodo prenehale delovati. Večino napak, ki se nanašajo na datotečni sistem lahko varno prezrete. Sporočilo o napaki: {0} Podrobne informacije o tej napaki lahko kopirate v odložišče s klikom na gumb "Kopiraj". Prosimo, da razvijalcu programa pošljete podatke o tej napaki. Čas zadnjega zapisovanja Atributi Je samo za branje Polno ime Ime datoteke Velikost Imenik Obstaja na pogonu Komentar Ime podjetja Opis Različica datoteke Notranje ime Jezik Avtorske pravice Blagovne znamke Izvirno ime datoteke Ime izdelka Različica izdelka Čas ustvarjanja Čas zadnjega dostopa ================================================ FILE: source/KlocTools/Properties/Localisation.sv.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Fråga Filnamn kan inte vara tomt. Avslutande citationstecken saknas. Filnamnet måste innehålla en filändelse separerad med en punkt. Gigabytes GB Kilobytes KB Megabytes MB Terabytes TB Nej Ja {0} dagar sedan Igår {0} timmar sedan En timme sedan Nu precis {0} minuter sedan En minut sedan {0} månader sedan En månad sedan {0} år sedan Ett år sedan Inre: Appen har stött på ett oväntat fel Oväntat fel Du kan förlora eventuella osparade data. För att förhindra förlust av data, stäng apparna manuellt. Är du säker på att du vill avsluta alla processer? Avsluta körande processer Sökvägen pekar inte på en giltig .reg-fil Sökvägen får inte vara tom eller null Sökvägen får inte peka på en rot-nyckel Det går inte att ta bort standardvärdet Feldetaljer: Medan detta fel inte kräver att programmet stängs av, kan viss funktionalitet sluta fungera. De flesta fel relaterade till filsystemet kan ignoreras utan risk. Felmeddelande: {0} Du kan kopiera detaljerad information om detta fel till urklipp genom att klicka på “Kopiera”-knappen. Överväg att skicka denna felinformation till utvecklaren. Skapelse Tid Senaste Åtkomsttid Senaste Skrivtid Attribut Är skrivskyddad Fullständigt Namn Filnamn Storlek Katalog Finns på enheten Kommentar Företagsnamn Beskrivning Filversion Internt Namn Språk Copyright Varumärken Ursprungligt Filnamn Produktnamn Produktversion ================================================ FILE: source/KlocTools/Properties/Localisation.tr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Sor Dosya ismi boş olamaz Tırnak işaretinin sonu eksik. Dosya adı nokta ile ayrılmış bir uzantı içermelidir. Gigabaytlar GB Kilobytlar KB Megabytlar MB Terabytlar TB Hayır Evet {0} gün önce Dün {0} saat önce Bir saat önce Şimdi {0} dakika önce Bir dakika önce {0} ay önce Bir ay önce {0} yıl önce Bir yıl önce Çevirisini bilmediğim bir hata sanırım, iyi şanslar <3 Uygulama beklenmedik bir hatayla karşılaştı Beklenmeyen hata Kaydedilmemiş verileri kaybedebilirsiniz. Veri kaybını önlemek için uygulamaları kaydedin. Tüm süreçleri sonlandırmak istediğinizden emin misiniz? Çalışan işlemleri sonlandırın Yol geçerli bir .reg dosyasını göstermiyor Yol boş veya bilinmeyen olamaz Yol bir kök anahtarı gösteremez Varsayılan değer kaldırılamıyor Hata detayları: Bu hata uygulamanın kapanmasını gerektirmese de, bazı işlevler çalışmayı durdurabilir. Dosya sistemiyle ilgili çoğu hata güvenli bir şekilde göz ardı edilebilir. Hata mesajı: {0} “Kopyala” düğmesine tıklayarak bu hatayla ilgili ayrıntılı bilgileri panoya kopyalayabilirsiniz. Lütfen bu hata bilgisini geliştiriciye göndermeyi düşünün. Oluşturma Zamanı Son Erişim Zamanı Son Yazım Zamanı Nitelikler Yalnızca okuma Tam İsim Dosya İsmi Boyut Dizi Sürücüde var Yorum Şirket İsmi Açıklama Dosya Versiyonu Dahili İsim Dil Telif Hakkı Ticari Markalar Orijinal Dosya Adı Ürün Adı Ürün Versiyonu ================================================ FILE: source/KlocTools/Properties/Localisation.vi.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Yêu cầu Tên tệp không được bỏ trống Dấu ngoặc kép ở cuối bị thiếu. Tên tệp phải có phần mở rộng được phân tách bằng dấu chấm. Gigabytes GB Kilobytes KB Megabytes MB Terabytes TB Không Đúng {0} ngày trước Hôm qua {0} giờ trước Một giờ trước Ngay bây giờ {0} phút trước Một phút trước {0} tháng trước Một tháng trước {0} năm trước Một năm trước Ứng dụng gặp lỗi không mong muốn Lỗi không mong muốn Bạn có thể mất dữ liệu chưa được lưu. Vui lòng đóng ứng dụng theo cách thủ công để tránh mất dữ liệu. Bạn có chắc là muốn chấm dứt tất cả các tiến trình không? Chấm dứt tiến trình đang chạy Đường dẫn không trỏ đến tệp .reg hợp lệ. Đường dẫn không được bỏ trống hoặc NULL. Đường dẫn không thể trỏ đến khóa gốc Không thể xóa giá trị mặc định Chi tiết lỗi: Lỗi này không yêu cầu phải tắt ứng dụng nhưng có thể khiến một số chức năng ngừng hoạt động. Hầu hết các lỗi liên quan đến hệ thống tập tin đều có thể được bỏ qua một cách an toàn. Thông báo lỗi: {0} Bạn có thể sao chép thông tin chi tiết về lỗi này vào bảng nhớ tạm của mình bằng cách nhấp vào nút "Sao chép". Vui lòng xem xét gửi thông tin lỗi này cho nhà phát triển. Thời điểm Tạo Lần Truy cập Cuối cùng Lần Thay đổi Cuối cùng Thuộc tính Chỉ đọc Tên đầy đủ Tên Tệp tin Kích thước Thư mục Tồn tại trên ổ đĩa Chú thích Tên Công ty Mô tả Phiên bản Tệp tin Tên Nội địa Ngôn ngữ Bản quyền Thương hiệu Tên Tệp tin Gốc Tên Sản phẩm Phiên bản Sản phẩm Inner: ================================================ FILE: source/KlocTools/Properties/Localisation.zh-Hans.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 询问 文件名不能为空。 缺少结束引号。 文件名必须包含由点分隔的扩展名。 吉字节 GB 千字节 KB 兆字节 MB 太字节 TB {0} 天前 昨天 {0} 小时前 一小时前 刚刚 {0} 分钟前 一分钟前 {0} 月前 一个月前 {0} 年前 一年前 内部: 应用程序遇到意外错误 意外错误 你可能会丢失任何未保存的数据。为防止数据丢失,请手动关闭应用程序。 确定要终止所有进程吗? 终止运行中的进程 路径未指向有效的.reg文件 路径不能为空或null 路径不能指向root键 无法删除默认值 错误详细信息: 虽然此错误不需要关闭应用程序,但某些功能可能会停止工作。大多数与文件系统相关的错误都可以安全地忽略。 错误消息: {0} 你可以通过单击"复制"按钮将有关此错误的详细信息复制到剪贴板。请考虑将此错误信息发送给开发人员。 创建时间 最近访问时间 最近写入时间 属性 是否只读 全名 文件名 大小 目录 在驱动器上 注释 公司名 描述 文件版本 内部名称 语言 版权 商标 源文件名 产品名称 产品版本 ================================================ FILE: source/KlocTools/Properties/Localisation.zh-Hant.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 詢問 檔案名稱不能為空。 缺少結束引號。 檔案名必須包含由點分隔的副檔名 十億位元組 GB 千位元組 KB 百萬位元組 MB 萬億位元組 TB {0} 天前 昨天 {0}小時前 一小時前 剛剛 {0}分鐘前 一分鐘前 {0}個月前 一個月前 {0}年前 一年前 內部: 應用程式遇到意外錯誤 意外錯誤 你可能會遺失任何未儲存的資料。為防止資料遺失,請手動關閉應用程式。 確定要中止所有程序嗎? 中止執行中的程序 路徑未指向有效的.reg檔案 路徑不能為空或Null 路徑不能指向root鍵 無法刪除預設值 錯誤詳細訊息: 雖然此錯誤不需要關閉應用程式,但某些功能可能會停止工作。大多數與系統文件相關的錯誤都可以安全的忽略。 錯誤訊息:{0} 你可以透過點擊"複製"按鈕將有關此錯誤的詳細訊息複製到剪貼簿。請考慮將此錯誤發送給開發人員。 建立時間 最近修改時間 最近寫入時間 屬性 唯讀 全名 檔案名 大小 目錄 在硬碟上 註釋 公司名 描述 檔案版本 內部名稱 語言 版權 商標 原始檔案名 產品名稱 產品版本 ================================================ FILE: source/KlocTools/Properties/Resources.Designer.cs ================================================ //------------------------------------------------------------------------------ // // This code was generated by a tool. // Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ namespace Klocman.Properties { using System; /// /// A strongly-typed resource class, for looking up localized strings, etc. /// // This class was auto-generated by the StronglyTypedResourceBuilder // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] public class Resources { private static global::System.Resources.ResourceManager resourceMan; private static global::System.Globalization.CultureInfo resourceCulture; [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] internal Resources() { } /// /// Returns the cached ResourceManager instance used by this class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] public static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Klocman.Properties.Resources", typeof(Resources).Assembly); resourceMan = temp; } return resourceMan; } } /// /// Overrides the current thread's CurrentUICulture property for all /// resource lookups using this strongly typed resource class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] public static global::System.Globalization.CultureInfo Culture { get { return resourceCulture; } set { resourceCulture = value; } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// public static System.Drawing.Bitmap centerline { get { object obj = ResourceManager.GetObject("centerline", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// public static System.Drawing.Bitmap facebookButton { get { object obj = ResourceManager.GetObject("facebookButton", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// public static System.Drawing.Bitmap twitterButton { get { object obj = ResourceManager.GetObject("twitterButton", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } } } ================================================ FILE: source/KlocTools/Properties/Resources.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ..\Resources\twitterButton.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\facebookButton.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\centerline.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ================================================ FILE: source/KlocTools/Resources/CommonStrings.Designer.cs ================================================ //------------------------------------------------------------------------------ // // This code was generated by a tool. // Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ namespace Klocman.Resources { using System; /// /// A strongly-typed resource class, for looking up localized strings, etc. /// // This class was auto-generated by the StronglyTypedResourceBuilder // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] public class CommonStrings { private static global::System.Resources.ResourceManager resourceMan; private static global::System.Globalization.CultureInfo resourceCulture; [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] internal CommonStrings() { } /// /// Returns the cached ResourceManager instance used by this class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] public static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Klocman.Resources.CommonStrings", typeof(CommonStrings).Assembly); resourceMan = temp; } return resourceMan; } } /// /// Overrides the current thread's CurrentUICulture property for all /// resource lookups using this strongly typed resource class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] public static global::System.Globalization.CultureInfo Culture { get { return resourceCulture; } set { resourceCulture = value; } } /// /// Looks up a localized string similar to Unknown. /// public static string Unknown { get { return ResourceManager.GetString("Unknown", resourceCulture); } } } } ================================================ FILE: source/KlocTools/Resources/CommonStrings.ar.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 مجهول Used when a value is not known or supported, for example unknown size ================================================ FILE: source/KlocTools/Resources/CommonStrings.cs.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Neznámý Used when a value is not known or supported, for example unknown size ================================================ FILE: source/KlocTools/Resources/CommonStrings.de.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Unbekannt Used when a value is not known or supported, for example unknown size ================================================ FILE: source/KlocTools/Resources/CommonStrings.es.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Desconocido Used when a value is not known or supported, for example unknown size ================================================ FILE: source/KlocTools/Resources/CommonStrings.fr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Inconnu Used when a value is not known or supported, for example unknown size ================================================ FILE: source/KlocTools/Resources/CommonStrings.hu.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Ismeretlen Used when a value is not known or supported, for example unknown size ================================================ FILE: source/KlocTools/Resources/CommonStrings.it.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Sconosciuto Used when a value is not known or supported, for example unknown size ================================================ FILE: source/KlocTools/Resources/CommonStrings.ja.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 不明 Used when a value is not known or supported, for example unknown size ================================================ FILE: source/KlocTools/Resources/CommonStrings.nl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Onbekend Used when a value is not known or supported, for example unknown size ================================================ FILE: source/KlocTools/Resources/CommonStrings.pl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Nieznany Used when a value is not known or supported, for example unknown size ================================================ FILE: source/KlocTools/Resources/CommonStrings.pt-BR.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Desconhecido Used when a value is not known or supported, for example unknown size ================================================ FILE: source/KlocTools/Resources/CommonStrings.pt.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Desconhecido Used when a value is not known or supported, for example unknown size ================================================ FILE: source/KlocTools/Resources/CommonStrings.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Unknown Used when a value is not known or supported, for example unknown size ================================================ FILE: source/KlocTools/Resources/CommonStrings.ru.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Неизвестно Used when a value is not known or supported, for example unknown size ================================================ FILE: source/KlocTools/Resources/CommonStrings.sl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Neznano Used when a value is not known or supported, for example unknown size ================================================ FILE: source/KlocTools/Resources/CommonStrings.sv.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Okänd Used when a value is not known or supported, for example unknown size ================================================ FILE: source/KlocTools/Resources/CommonStrings.tr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Bilinmiyor Used when a value is not known or supported, for example unknown size ================================================ FILE: source/KlocTools/Resources/CommonStrings.vi.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Không xác định Used when a value is not known or supported, for example unknown size ================================================ FILE: source/KlocTools/Resources/CommonStrings.zh-Hans.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 未知 Used when a value is not known or supported, for example unknown size ================================================ FILE: source/KlocTools/Resources/CommonStrings.zh-Hant.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 未知 Used when a value is not known or supported, for example unknown size ================================================ FILE: source/KlocTools/Sorters/ColumnSorter.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections; using System.Windows.Forms; using System.Text.RegularExpressions; namespace Klocman { public enum SortModifiers { SortByImage, SortByCheckbox, SortByText } /// /// This class is an implementation of the 'IComparer' interface. /// public sealed class ListViewColumnSorter : IComparer { /// /// Specifies the column to be sorted /// public int ColumnToSort { get; set; } /// /// Specifies the order in which to sort (i.e. 'Ascending'). /// public SortOrder OrderOfSort { get; set; } /// /// Case insensitive comparer object /// private NumberCaseInsensitiveComparer ObjectCompare; private ImageTextComparer FirstObjectCompare; private CheckboxTextComparer FirstObjectCompare2; private SortModifiers mySortModifier = SortModifiers.SortByText; public SortModifiers _SortModifier { set { mySortModifier = value; } get { return mySortModifier; } } /// /// Class constructor. Initializes various elements /// public ListViewColumnSorter() { // Initialize the column to '0' //ColumnToSort = 0; // Initialize the CaseInsensitiveComparer object ObjectCompare = new NumberCaseInsensitiveComparer(); FirstObjectCompare = new ImageTextComparer(); FirstObjectCompare2 = new CheckboxTextComparer(); } /// /// This method is inherited from the IComparer interface. It compares the two objects passed using a case insensitive comparison. /// /// First object to be compared /// Second object to be compared /// The result of the comparison. "0" if equal, negative if 'x' is less than 'y' and positive if 'x' is greater than 'y' public int Compare(object x, object y) { int compareResult = 0; ListViewItem listviewX, listviewY; // Cast the objects to be compared to ListViewItem objects listviewX = (ListViewItem)x; listviewY = (ListViewItem)y; ListView listViewMain = listviewX.ListView; // Calculate correct return value based on object comparison if (listViewMain.Sorting != SortOrder.Ascending && listViewMain.Sorting != SortOrder.Descending) { // Return '0' to indicate they are equal return compareResult; } if (mySortModifier.Equals(SortModifiers.SortByText) || ColumnToSort > 0) { // Compare the two items if (listviewX.SubItems.Count <= ColumnToSort && listviewY.SubItems.Count <= ColumnToSort) { compareResult = ObjectCompare.Compare(null, null); } else if (listviewX.SubItems.Count <= ColumnToSort && listviewY.SubItems.Count > ColumnToSort) { compareResult = ObjectCompare.Compare(null, listviewY.SubItems[ColumnToSort].Text.Trim()); } else if (listviewX.SubItems.Count > ColumnToSort && listviewY.SubItems.Count <= ColumnToSort) { compareResult = ObjectCompare.Compare(listviewX.SubItems[ColumnToSort].Text.Trim(), null); } else { compareResult = ObjectCompare.Compare(listviewX.SubItems[ColumnToSort].Text.Trim(), listviewY.SubItems[ColumnToSort].Text.Trim()); } } else { switch (mySortModifier) { case SortModifiers.SortByCheckbox: compareResult = FirstObjectCompare2.Compare(x, y); break; case SortModifiers.SortByImage: compareResult = FirstObjectCompare.Compare(x, y); break; default: compareResult = FirstObjectCompare.Compare(x, y); break; } } // Calculate correct return value based on object comparison if (OrderOfSort == SortOrder.Ascending) { // Ascending sort is selected, return normal result of compare operation return compareResult; } else if (OrderOfSort == SortOrder.Descending) { // Descending sort is selected, return negative result of compare operation return (-compareResult); } else { // Return '0' to indicate they are equal return 0; } } /// /// Gets or sets the number of the column to which to apply the sorting operation (Defaults to '0'). /// public int SortColumn { set { ColumnToSort = value; } get { return ColumnToSort; } } /// /// Gets or sets the order of sorting to apply (for example, 'Ascending' or 'Descending'). /// public SortOrder Order { set { OrderOfSort = value; } get { return OrderOfSort; } } } public sealed class ImageTextComparer : IComparer { //private CaseInsensitiveComparer ObjectCompare; private NumberCaseInsensitiveComparer ObjectCompare; public ImageTextComparer() { // Initialize the CaseInsensitiveComparer object ObjectCompare = new NumberCaseInsensitiveComparer(); } public int Compare(object x, object y) { //int compareResult; int image1, image2; ListViewItem listviewX, listviewY; // Cast the objects to be compared to ListViewItem objects listviewX = (ListViewItem)x; image1 = listviewX.ImageIndex; listviewY = (ListViewItem)y; image2 = listviewY.ImageIndex; if (image1 < image2) { return -1; } else if (image1 == image2) { return ObjectCompare.Compare(listviewX.Text.Trim(), listviewY.Text.Trim()); } else { return 1; } } } public sealed class CheckboxTextComparer : IComparer { private NumberCaseInsensitiveComparer ObjectCompare; public CheckboxTextComparer() { // Initialize the CaseInsensitiveComparer object ObjectCompare = new NumberCaseInsensitiveComparer(); } public int Compare(object x, object y) { // Cast the objects to be compared to ListViewItem objects ListViewItem listviewX = (ListViewItem)x; ListViewItem listviewY = (ListViewItem)y; if (listviewX.Checked && !listviewY.Checked) { return -1; } else if (listviewX.Checked.Equals(listviewY.Checked)) { if (listviewX.ImageIndex < listviewY.ImageIndex) { return -1; } else if (listviewX.ImageIndex == listviewY.ImageIndex) { return ObjectCompare.Compare(listviewX.Text.Trim(), listviewY.Text.Trim()); } else { return 1; } } else { return 1; } } } public sealed class NumberCaseInsensitiveComparer : CaseInsensitiveComparer { public NumberCaseInsensitiveComparer() { } public new int Compare(object x, object y) { if (x == null && y == null) { return 0; } else if (x == null && y != null) { return -1; } else if (x != null && y == null) { return 1; } var xs = x as string; var ys = y as string; if (xs != null && IsWholeNumber(xs) && ys != null && IsWholeNumber(ys)) { try { return base.Compare(Convert.ToUInt64(xs.Trim()), Convert.ToUInt64(ys.Trim())); } catch { return -1; } } else { return base.Compare(x, y); } } private bool IsWholeNumber(string strNumber) { Regex wholePattern = new Regex(@"^\d+$"); return wholePattern.IsMatch(strNumber); } } } ================================================ FILE: source/KlocTools/Subsystems/FontGrabber.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Text; using System.Linq; namespace Klocman.Subsystems { public sealed class FontGrabber { private readonly Dictionary _validFontFamilies = new(); public FontGrabber() { UpdateFontFamilies(); } public IEnumerable ValidFontFamilies => _validFontFamilies.Values; public IEnumerable ValidFontFamilyNames => _validFontFamilies.Keys; public Font GetFont(string familyName, float size, FontStyle style) { if (size <= 0) throw new ArgumentException("Font size must be higher than 0"); return _validFontFamilies.ContainsKey(familyName) ? new Font(_validFontFamilies[familyName], size, style) : null; } public FontFamily GetFontFamily(string familyName) { return _validFontFamilies.ContainsKey(familyName) ? _validFontFamilies[familyName] : null; //throw new ArgumentException("Invalid font family name"); } private void UpdateFontFamilies() { using (var installedFonts = new InstalledFontCollection()) { foreach (var t in installedFonts.Families.Where(t => t.IsStyleAvailable(FontStyle.Regular))) { _validFontFamilies.Add(t.Name, t); } } } } } ================================================ FILE: source/KlocTools/Subsystems/GlobalHotkeys.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Windows.Forms; using Klocman.Forms.Tools; namespace Klocman.Subsystems { public sealed class GlobalHotkeys : ReferencedComponent, ICollection { private readonly List _registeredHotkeys = new(); private Form _parentForm; [Browsable(false)] [ReadOnly(true)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public Form ParentForm { get { return _parentForm; } set { if (_parentForm != null) { _parentForm.KeyPreview = false; _parentForm.KeyDown -= KeyDown_Handler; } if (value != null) { value.KeyPreview = true; value.KeyDown += KeyDown_Handler; } _parentForm = value; } } /// /// Stop responding to keystrokes when the parent form is disabled /// [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public bool StopWhenFormIsDisabled { get; set; } /// /// Set SuppressKeyPress to true in the keypress eventargs if a hotkey was pressed. /// [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public bool SuppressKeyPresses { get; set; } = true; [Browsable(false)] public int Count => _registeredHotkeys.Count; [Browsable(false)] public bool IsReadOnly => false; /// The value of 'item' cannot be null. public void Add(HotkeyEntry item) { if (item == null) throw new ArgumentNullException(nameof(item)); if (item.Master != null) item.Master.ShortcutKeyDisplayString = item.ToString(); _registeredHotkeys.Add(item); } public void Clear() { _registeredHotkeys.ForEach(x => x.Dispose()); _registeredHotkeys.Clear(); } public bool Contains(HotkeyEntry item) { return _registeredHotkeys.Contains(item); } void ICollection.CopyTo(HotkeyEntry[] array, int arrayIndex) { throw new InvalidOperationException(); } public IEnumerator GetEnumerator() { return _registeredHotkeys.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return _registeredHotkeys.GetEnumerator(); } public bool Remove(HotkeyEntry item) { if (item == null) return false; item.Dispose(); return _registeredHotkeys.Remove(item); } protected override void OnContainerInitialized(object obj, EventArgs args) { if (ContainerControl is Form form) ParentForm = form; else if (ContainerControl.ParentForm != null) ParentForm = ContainerControl.ParentForm; else throw new InvalidOperationException("Could not find the parent form"); } protected override void Dispose(bool disposing) { if (disposing) { ParentForm = null; Clear(); } base.Dispose(disposing); } private void KeyDown_Handler(object sender, KeyEventArgs e) { if (_parentForm == null) throw new InvalidOperationException("Hotkey handler called when parent form was null"); foreach (var hotkey in _registeredHotkeys) { if (hotkey.Alt == e.Alt && hotkey.Ctrl == e.Control && hotkey.Shift == e.Shift && hotkey.KeyCode == e.KeyCode) { if (hotkey.EventHandler == null || !hotkey.IsEnabled || (StopWhenFormIsDisabled && !ParentForm.Enabled)) continue; hotkey.EventHandler(_parentForm, EventArgs.Empty); // Stops default windows "wtfding" sound and prevents event bubbling if (SuppressKeyPresses) e.SuppressKeyPress = true; // Do not process any more hotkeys return; } } } //TODO does not work very well, need to ask for description at hotkey creation public HotkeyInfo[] GetHotkeyList() { var query = from hotkey in _registeredHotkeys group hotkey by hotkey.EventHandler into groupedHotkeys select new HotkeyInfo { Master = (groupedHotkeys.FirstOrDefault(x => x.Master != null) ?? groupedHotkeys.First()).Master, Hotkeys = groupedHotkeys.Select(x => x.ToString()).OrderBy(x => x).ToArray() }; return query.OrderBy(x => x.Name).ToArray(); } //TODO does not work very well, need to ask for description at hotkey creation public class HotkeyInfo { public string[] Hotkeys; internal ToolStripMenuItem Master; public string Name { get { return (Master == null) ? string.Empty : new string(Master.Text.Where(x => !x.Equals('&')).ToArray()); } } public override string ToString() { return $"Name: {Name}, Hotkeys: {string.Join(", ", Hotkeys)}"; } } } } ================================================ FILE: source/KlocTools/Subsystems/HotkeyEntry.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Windows.Forms; using Klocman.Extensions; namespace Klocman.Subsystems { /// /// Represents a single hotkey. It gets disposed when removed from main hotkey collection, so don't use it outside /// public sealed class HotkeyEntry : IDisposable { private readonly Func _isEnabled; public HotkeyEntry(Keys key, Action eventHandlerDelegate, ToolStripMenuItem masterControl) { Shift = false; Ctrl = false; Alt = false; KeyCode = key; EventHandler = eventHandlerDelegate; Master = masterControl; } public HotkeyEntry(Keys key, ToolStripMenuItem masterControl) : this(key, (x, y) => masterControl.PerformClick(), masterControl) { } public HotkeyEntry(Keys key, ToolStripMenuItem masterControl, Func isEnabledDelegate) : this(key, masterControl) { _isEnabled = isEnabledDelegate; } public HotkeyEntry(Keys key, Action eventHandlerDelegate, ToolStripMenuItem masterControl, Func isEnabledDelegate) : this(key, eventHandlerDelegate, masterControl) { _isEnabled = isEnabledDelegate; } public HotkeyEntry(Keys key, bool altPressed, bool ctrlPressed, bool shiftPressed, ToolStripMenuItem masterControl) : this(key, masterControl) { Alt = altPressed; Ctrl = ctrlPressed; Shift = shiftPressed; } public HotkeyEntry(Keys key, bool altPressed, bool ctrlPressed, bool shiftPressed, Action eventHandlerDelegate, ToolStripMenuItem masterControl) : this(key, eventHandlerDelegate, masterControl) { Alt = altPressed; Ctrl = ctrlPressed; Shift = shiftPressed; } public HotkeyEntry(Keys key, bool altPressed, bool ctrlPressed, bool shiftPressed, ToolStripMenuItem masterControl, Func isEnabledDelegate) : this(key, altPressed, ctrlPressed, shiftPressed, masterControl) { _isEnabled = isEnabledDelegate; } public HotkeyEntry(Keys key, bool altPressed, bool ctrlPressed, bool shiftPressed, Action eventHandlerDelegate, ToolStripMenuItem masterControl, Func isEnabledDelegate) : this(key, altPressed, ctrlPressed, shiftPressed, eventHandlerDelegate, masterControl) { _isEnabled = isEnabledDelegate; } public bool Alt { get; } public bool Ctrl { get; } public string Description { get; set; } //Action _eventHandler; public Action EventHandler { get; set; } public bool IsEnabled { get { if (_isEnabled != null) return _isEnabled(); return true; } } public Keys KeyCode { get; } public ToolStripMenuItem Master { get; private set; } public bool Shift { get; } public void Dispose() { if (Master != null) { Master.ShortcutKeyDisplayString = string.Empty; Master = null; } EventHandler = null; } public override string ToString() { return (Ctrl ? "Ctrl+" : string.Empty).AppendIf(Shift, "Shift+").AppendIf(Alt, "Alt+") + KeyCode; } } } ================================================ FILE: source/KlocTools/Subsystems/RandomFilePicker.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.IO; using System.Linq; using Klocman.Collections; using Klocman.Extensions; namespace Klocman.Subsystems { public class RandomFilePicker { /// /// Method to use when selecting another folder/file /// public enum GotoType { Next, Previous, Random } private readonly List _directoryHistory = new(); //private readonly List _fileHistory = new List(); private readonly ObservedList _matchedDirectories = new(); private readonly Random _r = new(); /// /// Currently selected directory /// public string CurrentDirectory { get; private set; } = string.Empty; /// /// Currently selected file /// public string CurrentFile { get; private set; } /// /// Filters applied to file extensions /// public string[] ExtensionFilters { get; set; } = {}; /// /// Filters applied to filenames (exclude if hit) /// public string[] FilenameExcludeFilters { get; set; } = {}; /// /// If false, file extensions will be stripped when filtering by FilenameFilters. /// public bool FilenameFiltersIncludeExtension { get; set; } /// /// Filters applied to filenames (include if hit) /// public string[] FilenameFilters { get; set; } = {}; /// /// Filtered files in current directory /// public string[] FilesInCurrentDir { get; private set; } = {}; /// /// Directories that contain filtered files /// public string[] MatchedDirectories => _matchedDirectories.ToArray(); /// /// How deep to search directories for files /// public int MaximumDirectorySearchDepth { get; set; } = 4; /// /// Move from random to pseudo-random algorighm to prevent same /// directory or file being choosen multiple times in a short succession. /// public bool PreventDuplicates { get; set; } = true; /// /// Select another file /// public void GetNextFile(GotoType direction) { if (FilesInCurrentDir.Length == 0) { CurrentFile = string.Empty; return; } switch (direction) { case GotoType.Random: CurrentFile = FilesInCurrentDir[_r.Next(FilesInCurrentDir.Length)]; break; case GotoType.Next: CurrentFile = FilesInCurrentDir[Wrap(FilesInCurrentDir.GetPositionOfElement(CurrentFile) + 1, 0, FilesInCurrentDir.Length - 1)]; break; case GotoType.Previous: CurrentFile = FilesInCurrentDir[Wrap(FilesInCurrentDir.GetPositionOfElement(CurrentFile) - 1, 0, FilesInCurrentDir.Length - 1)]; break; } } /// /// Select another folder /// public void GetNextFolder(GotoType direction) { if (_matchedDirectories.Count == 0) { SetCurrentFolder(string.Empty); return; } switch (direction) { case GotoType.Random: { string randomDir; if (PreventDuplicates) { while (true) { if (_directoryHistory.Count == _matchedDirectories.Count) { _directoryHistory.RemoveRange(0, (int) Math.Ceiling(_directoryHistory.Count/2.0)); } randomDir = _matchedDirectories[_r.Next(_matchedDirectories.Count)]; if (!_directoryHistory.Contains(randomDir)) { _directoryHistory.Add(randomDir); break; } } } else { randomDir = _matchedDirectories[_r.Next(_matchedDirectories.Count)]; } SetCurrentFolder(randomDir); } break; case GotoType.Next: SetCurrentFolder( _matchedDirectories[Wrap(_matchedDirectories.IndexOf(CurrentDirectory) + 1, 0, _matchedDirectories.Count - 1)]); break; case GotoType.Previous: SetCurrentFolder( _matchedDirectories[Wrap(_matchedDirectories.IndexOf(CurrentDirectory) - 1, 0, _matchedDirectories.Count - 1)]); break; } } public bool SetCurrentFolder(string newPath) { try { FilesInCurrentDir = Directory.Exists(newPath) ? Directory.GetFiles(newPath).Where(CheckFilenameWithFilters).ToArray() : new string[] {}; CurrentDirectory = newPath; return true; } catch { FilesInCurrentDir = Array.Empty(); CurrentDirectory = null; return false; } } /// /// Scan for directories with matching files inside of supplied root directories /// public void ScanForDirectories(string[] rootDirectories) { ScanForDirectories(rootDirectories, null); } /// /// Scan for directories with matching files inside of supplied root directories and report directory hits using the /// delegate. /// public void ScanForDirectories(string[] rootDirectories, Action onDirectoryFound) { _matchedDirectories.Clear(); _directoryHistory.Clear(); if (onDirectoryFound != null) _matchedDirectories.ListChanged += onDirectoryFound; foreach (var directory in rootDirectories) { if (Directory.Exists(directory)) { _matchedDirectories.Add(directory); _matchedDirectories.AddRange(GetSubFolders(directory)); } } if (onDirectoryFound != null) _matchedDirectories.ListChanged -= onDirectoryFound; if (_matchedDirectories.Count == 0) { return; } _matchedDirectories.RemoveAll(obj => { var tempList = new List(Directory.GetFiles(obj)); if (tempList.Count == 0) { return true; } return !tempList.Any(CheckFilenameWithFilters); }); } private static int Wrap(int kX, int kLowerBound, int kUpperBound) { var rangeSize = kUpperBound - kLowerBound + 1; if (kX < kLowerBound) kX += rangeSize*((kLowerBound - kX)/rangeSize + 1); return kLowerBound + (kX - kLowerBound)%rangeSize; } private bool CheckFilenameWithFilters(string filePath) { //filePath = filePath.ToLower(); var fileName = FilenameFiltersIncludeExtension ? filePath : Path.GetDirectoryName(filePath) + '\\' + Path.GetFileNameWithoutExtension(filePath); var fileNameMatch = false; var fileExtMatch = false; if (FilenameFilters.Length == 0 || FilenameFilters.Any(filter => fileName.Contains(filter, StringComparison.CurrentCultureIgnoreCase))) fileNameMatch = true; if (FilenameExcludeFilters.Length > 0 && FilenameExcludeFilters.Any(x => fileName.Contains(x, StringComparison.CurrentCultureIgnoreCase))) fileNameMatch = false; if (!fileNameMatch) return false; var extension = Path.GetExtension(filePath); if (extension != null) { var fileExt = extension.ToLower(); if (ExtensionFilters.Length == 0) { fileExtMatch = true; } else { if (ExtensionFilters.Any(filter => fileExt.Contains(filter))) { fileExtMatch = true; } } } return fileExtMatch; } private IEnumerable GetSubFolders(string rootFolder, int depth = 0) { var subFolders = new List(Directory.GetDirectories(rootFolder)); if (subFolders.Count != 0 && depth < MaximumDirectorySearchDepth) { var subFoldersCopy = subFolders.ToArray(); foreach (var folder in subFoldersCopy) { subFolders.AddRange(GetSubFolders(folder, depth + 1)); } } return subFolders; } /// /// Recheck that specified directories still exist and contain files that conform to the filters. /// If any directory fails those checks it is removed from the list. /// /// Directories to check. If none are passed all directories are checked. public void RefreshDirectories(params string[] directoriesToRefresh) { var checkAll = directoriesToRefresh == null || directoriesToRefresh.Length > 0; _matchedDirectories.RemoveAll(obj => { if (checkAll || directoriesToRefresh!.Any(x => x.Equals(obj))) { if (!Directory.Exists(obj)) return true; var tempList = new List(Directory.GetFiles(obj)); if (tempList.Count == 0) { return true; } return !tempList.Any(CheckFilenameWithFilters); } return false; }); } } } ================================================ FILE: source/KlocTools/Subsystems/WindowHoverEventArgs.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; namespace Klocman.Subsystems { public sealed class WindowHoverEventArgs : EventArgs { public WindowHoverEventArgs(WindowHoverSearcher.WindowInfo targetWindow) { TargetWindow = targetWindow; } public WindowHoverSearcher.WindowInfo TargetWindow { get; } } } ================================================ FILE: source/KlocTools/Subsystems/WindowHoverSearcher.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Diagnostics; using System.Drawing; using System.Runtime.InteropServices; using System.Text; using System.Windows.Forms; namespace Klocman.Subsystems { /// /// Used to detect what window is under the cursor and return information about it. /// Can detect any window of any application and return the owning process. /// public class WindowHoverSearcher { private const int WmGettext = 0xD; private const int WmGettextlength = 0x000E; private readonly Control _mouseTarget; private WindowInfo _curWindow; private WindowInfo _lastWindow; public WindowHoverSearcher(Control mouseTarget) { _mouseTarget = mouseTarget; _mouseTarget.MouseDown += OnMouseDown; _mouseTarget.MouseMove += OnMouseMove; _mouseTarget.MouseUp += OnMouseUp; } [DllImport("user32.dll")] private static extern IntPtr WindowFromPoint(Point point); [DllImport("user32.dll", CharSet = CharSet.Auto)] private static extern int GetClassName(IntPtr handle, StringBuilder className, int maxCount); [DllImport("user32.dll")] private static extern int SendMessage(IntPtr handle, int msg, int param1, int param2); [DllImport("user32.dll")] private static extern int SendMessage(IntPtr handle, int msg, int param, StringBuilder text); [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool GetWindowRect(IntPtr handle, out Rect rect); [DllImport("user32.dll", SetLastError = true)] private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint processId); public event EventHandler PickingStarted; public event EventHandler HoveredWindowChanged; public event EventHandler WindowSelected; private void OnMouseDown(object sender, MouseEventArgs e) { if (e.Button != MouseButtons.Left) return; _mouseTarget.Cursor = Cursors.Cross; PickingStarted?.Invoke(this, EventArgs.Empty); } private void OnMouseMove(object sender, MouseEventArgs e) { if (e.Button != MouseButtons.Left) return; var pt = Cursor.Position; _curWindow = new WindowInfo(WindowFromPoint(pt)); if (_lastWindow == null) { ControlPaint.DrawReversibleFrame(_curWindow.WindowRect, Color.Black, FrameStyle.Thick); HoveredWindowChanged?.Invoke(this, new WindowHoverEventArgs(_curWindow)); } else if (!_curWindow.Handle.Equals(_lastWindow.Handle)) { ControlPaint.DrawReversibleFrame(_lastWindow.WindowRect, Color.Black, FrameStyle.Thick); ControlPaint.DrawReversibleFrame(_curWindow.WindowRect, Color.Black, FrameStyle.Thick); HoveredWindowChanged?.Invoke(this, new WindowHoverEventArgs(_curWindow)); } _lastWindow = _curWindow; } private void OnMouseUp(object sender, MouseEventArgs e) { if (e.Button != MouseButtons.Left) return; _mouseTarget.Cursor = Cursors.Default; if (_lastWindow == null) return; ControlPaint.DrawReversibleFrame(_lastWindow.WindowRect, Color.Black, FrameStyle.Thick); WindowSelected?.Invoke(this, new WindowHoverEventArgs(_lastWindow)); } private static string GetWindowClassName(IntPtr handle) { var buffer = new StringBuilder(128); GetClassName(handle, buffer, buffer.Capacity); return buffer.ToString(); } private static string GetWindowText(IntPtr handle) { var buffer = new StringBuilder(SendMessage(handle, WmGettextlength, 0, 0) + 1); SendMessage(handle, WmGettext, buffer.Capacity, buffer); return buffer.ToString(); } private static Rectangle GetWindowRectangle(IntPtr handle) { Rect rect; GetWindowRect(handle, out rect); return new Rectangle(rect.Left, rect.Top, (rect.Right - rect.Left) + 1, (rect.Bottom - rect.Top) + 1); } [StructLayout(LayoutKind.Sequential)] private struct Rect { public readonly int Left; public readonly int Top; public readonly int Right; public readonly int Bottom; } public class WindowInfo { private string _className; private int _processId; private Rectangle _windowRect; private string _windowText; public WindowInfo(IntPtr handle) { Handle = handle; } public IntPtr Handle { get; } public string ClassName => _className ?? (_className = GetWindowClassName(Handle)); public string WindowText => _windowText ?? (_windowText = GetWindowText(Handle)); public Rectangle WindowRect => !_windowRect.IsEmpty ? _windowRect : (_windowRect = GetWindowRectangle(Handle)); public int ProcessId { get { if (_processId == 0) { uint processId; GetWindowThreadProcessId(Handle, out processId); _processId = (int) processId; } return _processId; } } public Process GetRunningProcess() => ProcessId == 0 ? null : Process.GetProcessById(ProcessId); } } } ================================================ FILE: source/KlocTools/Tools/CompiledPropertyInfo.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Linq.Expressions; using System.Reflection; namespace Klocman.Tools { /// /// Compiled get and set methods with drastically improved performance. /// public class CompiledPropertyInfo { public CompiledPropertyInfo(PropertyInfo propertyInfo) : this(propertyInfo, null) { } public CompiledPropertyInfo(PropertyInfo propertyInfo, object tag) { if (propertyInfo == null) throw new ArgumentNullException(nameof(propertyInfo)); PropertyInfo = propertyInfo; Tag = tag; CompileProperty(propertyInfo); } private void CompileProperty(PropertyInfo propertyInfo) { var instanceParam = Expression.Parameter(typeof(TInstance), "instance"); if (propertyInfo.CanRead) { var getCall = Expression.Call(instanceParam, propertyInfo.GetGetMethod(true)!); var convertedGet = Expression.Convert(getCall, typeof(object)); var getLambda = Expression.Lambda>(convertedGet, instanceParam); CompiledGet = getLambda.Compile(); } if (propertyInfo.CanWrite) { var valueParam = Expression.Parameter(typeof(object), "value"); var convertedValue = Expression.Convert(valueParam, propertyInfo.PropertyType); var setCall = Expression.Call(instanceParam, propertyInfo.GetSetMethod(true)!, convertedValue); var setLambda = Expression.Lambda>(setCall, instanceParam, valueParam); CompiledSet = setLambda.Compile(); } } /// /// Takes instance containing this property, and returns a boxed property's value. /// Null if property doesn't have a getter. /// public Func CompiledGet { get; private set; } /// /// Takes instance containing this property and a boxed new value to set. /// Null if property doesn't have a setter. /// public Action CompiledSet { get; private set; } public PropertyInfo PropertyInfo { get; } public object Tag { get; set; } } } ================================================ FILE: source/KlocTools/Tools/CompressionTools.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System.IO; using System.IO.Compression; using System.Text; namespace Klocman.Tools { public static class CompressionTools { public static byte[] ZipString(string str) { var bytes = Encoding.UTF8.GetBytes(str); using (var msi = new MemoryStream(bytes)) using (var mso = new MemoryStream()) { using (var gs = new GZipStream(mso, CompressionMode.Compress)) { //msi.CopyTo(gs); msi.CopyTo(gs); } return mso.ToArray(); } } public static string UnzipString(byte[] bytes) { using (var msi = new MemoryStream(bytes)) using (var mso = new MemoryStream()) { using (var gs = new GZipStream(msi, CompressionMode.Decompress)) { //gs.CopyTo(mso); gs.CopyTo(mso); } return Encoding.UTF8.GetString(mso.ToArray()); } } public static byte[] BrotliDecompress(byte[] compressedData) { using (var msInput = new MemoryStream(compressedData)) using (var bs = new BrotliStream(msInput, CompressionMode.Decompress)) using (var msOutput = new MemoryStream()) { bs.CopyTo(msOutput); msOutput.Seek(0, SeekOrigin.Begin); return msOutput.ToArray(); } } public static byte[] BrotliCompress(string inputstr) { var bytes = Encoding.UTF8.GetBytes(inputstr); return BrotliCompress(bytes); } public static byte[] BrotliCompress(byte[] data) { using (var outputStream = new MemoryStream()) { using (var gZipStream = new BrotliStream(outputStream, CompressionLevel.Optimal)) gZipStream.Write(data, 0, data.Length); var result = outputStream.ToArray(); //Debug.WriteLine($"Compression result: {bytes.Length} -> {result.Length} ({(result.Length / (double)bytes.Length) * 100:F1}%)"); return result; } } } } ================================================ FILE: source/KlocTools/Tools/DrawingTools.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Imaging; using System.IO; using System.Runtime.InteropServices; using System.Security; using System.Text; namespace Klocman.Tools { public static class DrawingTools { /// /// Returns an icon representation of an image contained in the specified file. /// This function is identical to System.Drawing.Icon.ExtractAssociatedIcon, xcept this version works for UNC paths. /// /// The path to the file that contains an image. /// The System.Drawing.Icon representation of the image contained in the specified file. /// filePath does not indicate a valid file. public static Icon ExtractAssociatedIcon(string filePath) { if (filePath == null) throw new ArgumentNullException(nameof(filePath)); Uri uri; try { uri = new Uri(filePath); } catch (UriFormatException) { filePath = Path.GetFullPath(filePath); uri = new Uri(filePath); } if (uri.IsFile) { if (!File.Exists(filePath)) throw new FileNotFoundException(filePath); var iconPath = new StringBuilder(260); iconPath.Append(filePath); var index = 0; var handle = SafeNativeMethods.ExtractAssociatedIcon(new HandleRef(null, IntPtr.Zero), iconPath, ref index); if (handle != IntPtr.Zero) return Icon.FromHandle(handle); } return null; } /// /// This class suppresses stack walks for unmanaged code permission. /// (System.Security.SuppressUnmanagedCodeSecurityAttribute is applied to this class.) /// This class is for methods that are safe for anyone to call. /// Callers of these methods are not required to perform a full security review to make sure that the /// usage is secure because the methods are harmless for any caller. /// [SuppressUnmanagedCodeSecurity] internal static class SafeNativeMethods { [DllImport("shell32.dll", EntryPoint = "ExtractAssociatedIcon", CharSet = CharSet.Auto)] internal static extern IntPtr ExtractAssociatedIcon(HandleRef hInst, StringBuilder iconPath, ref int index); } public static Color ColorLerp(Color from, Color to, float ratio) { var aDiff = to.A - from.A; var rDiff = to.R - from.R; var gDiff = to.G - from.G; var bDiff = to.B - from.B; return Color.FromArgb((byte)(from.A + ratio * aDiff), (byte)(from.R + ratio * rDiff), (byte)(from.G + ratio * gDiff), (byte)(from.B + ratio * bDiff)); } /// The operation failed. public static Bitmap ResizeBitmap(Image sourceBmp, int newWidth, int newHeight) { var result = new Bitmap(newWidth, newHeight); using (var g = Graphics.FromImage(result)) { g.SmoothingMode = SmoothingMode.HighSpeed; g.CompositingQuality = CompositingQuality.HighSpeed; g.DrawImage(sourceBmp, 0, 0, newWidth, newHeight); } return result; } /// /// Roughly converts Image to an Icon. /// http://stackoverflow.com/a/21389253/4309247 /// Tested on .NET 4.5 and Windows 8.1. Beware of the possibility of "fringes" you'll see on PNG images with transparency on the edges. /// /// Image to convert /// public static Icon IconFromImage(Image img) { var ms = new MemoryStream(); var bw = new BinaryWriter(ms); // Header bw.Write((short)0); // 0 : reserved bw.Write((short)1); // 2 : 1=ico, 2=cur bw.Write((short)1); // 4 : number of images // Image directory var w = img.Width; if (w >= 256) w = 0; bw.Write((byte)w); // 0 : width of image var h = img.Height; if (h >= 256) h = 0; bw.Write((byte)h); // 1 : height of image bw.Write((byte)0); // 2 : number of colors in palette bw.Write((byte)0); // 3 : reserved bw.Write((short)0); // 4 : number of color planes bw.Write((short)0); // 6 : bits per pixel var sizeHere = ms.Position; bw.Write(0); // 8 : image size var start = (int)ms.Position + 4; bw.Write(start); // 12: offset of image data // Image data img.Save(ms, ImageFormat.Png); var imageSize = (int)ms.Position - start; ms.Seek(sizeHere, SeekOrigin.Begin); bw.Write(imageSize); ms.Seek(0, SeekOrigin.Begin); // And load it return new Icon(ms); } } } ================================================ FILE: source/KlocTools/Tools/FilesystemTools.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.IO; using System.Management; using System.Runtime.InteropServices; using Klocman.Extensions; namespace Klocman.Tools { public static class FilesystemTools { /// /// Check the architecture of the executable. E.g. 64bit. /// Returns Unknown if the architecture is unsupported or not specified. /// /// Full path to the executable file. public static MachineType CheckExecutableMachineType(string filename) { if (!filename.EndsWith(".exe", StringComparison.InvariantCultureIgnoreCase)) { throw new IOException("Not a Windows .exe file."); } using (var stream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { stream.Position = 0x3c; var fileData = new byte[1024]; var bytesRead = stream.Read(fileData, 0, 1024); for (var i = 0; i < bytesRead; i++) { // Look for the PE signature (PE\0\0) if (i + 5 >= bytesRead) break; if (fileData[i] != 0x50) continue; if (fileData[i + 1] != 0x45 || fileData[i + 2] != 0 || fileData[i + 3] != 0) continue; // Join two bytes representing the architecture var machineId = fileData[i + 5] << 8 | fileData[i + 4]; switch (machineId) { case 0x8664: return MachineType.X64; case 0x14c: return MachineType.X86; case 0x200: return MachineType.Ia64; case 0xaa64: case 0xA641: case 0xA64E: return MachineType.ARM64; default: return MachineType.Unknown; } } } return MachineType.Unknown; } public static void CopyRecursive(string sourcePath, string targetPath) { CopyRecursive(new DirectoryInfo(sourcePath), new DirectoryInfo(targetPath)); } public static void CopyRecursive(DirectoryInfo source, DirectoryInfo target) { // Check if the target directory exists, if not, create it. if (Directory.Exists(target.FullName) == false) { Directory.CreateDirectory(target.FullName); } // Copy each file into it’s new directory. foreach (var fi in source.GetFiles()) { //Console.WriteLine(@"Copying {0}\{1}", target.FullName, fi.Name); fi.CopyTo(Path.Combine(target.ToString(), fi.Name), true); } // Copy each subdirectory using recursion. foreach (var diSourceSubDir in source.GetDirectories()) { var nextTargetSubDir = target.CreateSubdirectory(diSourceSubDir.Name); CopyRecursive(diSourceSubDir, nextTargetSubDir); } } public static bool CreateSymlink(string symlinkFileName, string targetFileName, SymbolicLinkType type) { return CreateSymbolicLink(symlinkFileName, targetFileName, type) != 0; } public static void MoveDirectory(string sourcePath, string targetPath) { MoveDirectory(new DirectoryInfo(sourcePath), new DirectoryInfo(targetPath)); } public static void MoveDirectory(DirectoryInfo source, DirectoryInfo target) { if (source.RootEquals(target)) Directory.Move(source.FullName, target.FullName); else { CopyRecursive(source, target); source.Delete(true); } } public static void CompressDirectory(string dirFullName) => CompressDirectory(dirFullName, ManagementOptions.InfiniteTimeout); public static void CompressDirectory(string dirFullName, TimeSpan timeout) { var objPath = "Win32_Directory.Name=" + "\"" + dirFullName.Replace(@"\", @"\\") + "\""; using (var dir = new ManagementObject(objPath)) { var outParams = dir.InvokeMethod("Compress", null, new InvokeMethodOptions { Timeout = timeout }); if (outParams == null) throw new ArgumentNullException(nameof(outParams)); var ret = (uint)outParams.Properties["ReturnValue"].Value; if (ret != 0) throw new IOException("Win32_Directory.Compress returned " + ret); } } [DllImport("shlwapi.dll")] public static extern bool PathIsNetworkPath(string pszPath); [DllImport("kernel32.dll", EntryPoint = "CreateSymbolicLinkW", CharSet = CharSet.Unicode)] private static extern int CreateSymbolicLink([In] string lpSymlinkFileName, [In] string lpTargetFileName, SymbolicLinkType dwFlags); } } ================================================ FILE: source/KlocTools/Tools/GuidTools.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Text.RegularExpressions; namespace Klocman.Tools { public static class GuidTools { private const string GuidMatchPattern = "^[A-Fa-f0-9]{32}$|^({|\\()?[A-Fa-f0-9]{8}-([A-Fa-f0-9]{4}-){3}[A-Fa-f0-9]{12}(}|\\))?$|^({)?[0xA-Fa-f0-9]{3,10}(, {0,1}[0xA-Fa-f0-9]{3,6}){2}, {0,1}({)([0xA-Fa-f0-9]{3,4}, {0,1}){7}[0xA-Fa-f0-9]{3,4}(}})$"; private static readonly Regex GuidMatchRegex = new(GuidMatchPattern, RegexOptions.Compiled); /// /// Extract and parse a guid from the supplied string. Throws if no guid is found. /// /// The value of 'source' cannot be null. /// Failed to parse the input public static Guid ExtractGuidFromString(string source) { if (source == null) throw new ArgumentNullException(nameof(source)); try { var braceIndex = source.IndexOfAny(new[] {'{', '('}); if (braceIndex >= 0) { var endingBraceIndex = source.IndexOfAny(new[] {'}', ')'}); if (endingBraceIndex < 0) throw new ArgumentException("Invalid brace format"); source = source.Substring(braceIndex, endingBraceIndex - braceIndex + 1); } return new Guid(source); } catch (Exception ex) { throw new ArgumentException("Failed to parse the input", ex); } //throw new NotImplementedException(); } /// /// Try to parse the supplied string into a guid. Faster than catching exceptions. /// public static bool GuidTryParse(string s, out Guid result) { result = Guid.Empty; if (string.IsNullOrEmpty(s) || !GuidMatchRegex.IsMatch(s)) { return false; } result = new Guid(s); return true; } /// /// Try to extract and parse a guid from the supplied string. /// result = Guid.Empty if operation fails. /// public static bool TryExtractGuid(string source, out Guid result) { result = Guid.Empty; if (string.IsNullOrEmpty(source)) return false; var braceIndex = source.IndexOfAny(new[] {'{', '('}); if (braceIndex >= 0) { var endingBraceIndex = source.IndexOfAny(new[] {'}', ')'}); source = endingBraceIndex > braceIndex ? source.Substring(braceIndex, endingBraceIndex - braceIndex + 1) : source.Substring(braceIndex + 1); } return GuidTryParse(source, out result); } } } ================================================ FILE: source/KlocTools/Tools/MachineType.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using Klocman.Localising; using Klocman.Resources; namespace Klocman.Tools { public enum MachineType { [LocalisedName(typeof(CommonStrings), nameof(CommonStrings.Unknown))] Unknown, X86, X64, Ia64, ARM64 } } ================================================ FILE: source/KlocTools/Tools/PathTools.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Management; using System.Text.RegularExpressions; using Klocman.Extensions; using Microsoft.Win32; namespace Klocman.Tools { public static class PathTools { private static Dictionary _volumeIdLookup; private static readonly char[] PathTrimChars = { '\\', '/', '"', // SPACE '\u0020', // NO-BREAK SPACE '\u00A0', // OGHAM SPACE MARK '\u1680', // EN QUAD '\u2000', // EM QUAD '\u2001', // EN SPACE '\u2002', // EM SPACE '\u2003', // THREE-PER-EM SPACE '\u2004', // FOUR-PER-EM SPACE '\u2005', // SIX-PER-EM SPACE '\u2006', // FIGURE SPACE '\u2007', // PUNCTUATION SPACE '\u2008', // THIN SPACE '\u2009', // HAIR SPACE '\u200A', // NARROW NO-BREAK SPACE '\u202F', // MEDIUM MATHEMATICAL SPACE '\u205F', // and IDEOGRAPHIC SPACE '\u3000', // LINE SEPARATOR '\u2028', // PARAGRAPH SEPARATOR '\u2029', // CHARACTER TABULATION '\u0009', // LINE FEED '\u000A', // LINE TABULATION '\u000B', // FORM FEED '\u000C', // CARRIAGE RETURN '\u000D', // NEXT LINE '\u0085' }; private static void PopulateVolumeIdLookup() { try { _volumeIdLookup = new Dictionary(); var searcher = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_Volume"); foreach (var queryObj in searcher.Get().OfType()) { var id = (queryObj["DeviceID"] as string)?.TrimEnd('\\', '/'); var dl = queryObj["DriveLetter"] as string; if (string.IsNullOrEmpty(id) || string.IsNullOrEmpty(dl)) continue; _volumeIdLookup.Add(id, dl); } } catch (ManagementException e) { Console.WriteLine($@"An error occurred while querying for WMI data: {e.Message}"); } } /// /// Convert path from the \\?\Volume{} form to the drive letter form. /// Only works for volumes with assigned drive letters. /// /// Path to any element with volume in \\?\Volume{} form. public static string ResolveVolumeIdToPath(string volumePath) { if (_volumeIdLookup == null) PopulateVolumeIdLookup(); _volumeIdLookup.ForEach(x => volumePath = volumePath.Replace(x.Key, x.Value, StringComparison.OrdinalIgnoreCase)); return volumePath; } /// /// Get full path of an application available in current environment. Same as writing it's name in CMD. /// /// Name of the exectuable, including the extension /// public static string GetFullPathOfExecutable(string filename) { IEnumerable paths = new[] { Environment.CurrentDirectory }; var pathVariable = Environment.GetEnvironmentVariable("PATH"); if (pathVariable != null) paths = paths.Concat(pathVariable.Split(';')); var combinations = paths.Select(x => Path.Combine(x, filename)); return combinations.FirstOrDefault(File.Exists) ?? GetExecutablePathFromAppPaths(filename); } /// name of the exectuable, including .exe private static string GetExecutablePathFromAppPaths(string exename) { const string appPaths = @"Software\Microsoft\Windows\CurrentVersion\App Paths"; var executableEntry = Path.Combine(appPaths, exename); using (var key = Registry.CurrentUser.OpenSubKey(executableEntry) ?? Registry.LocalMachine.OpenSubKey(executableEntry)) { return key?.GetStringSafe(null); } } /// /// Get full directory path of directory that contains the item pointed at by the path string. /// public static string GetDirectory(string fullPath) { var trimmed = fullPath.TrimEnd('"', ' ', '\\').TrimStart('"', ' '); if (trimmed.Contains('\\')) { var index = trimmed.LastIndexOf('\\'); if (index < trimmed.Length) { return trimmed.Substring(0, index); } } return string.Empty; } /// /// Get the topmost part of the path. If this is not a valid path return string.Empty. /// public static string GetName(string fullPath) { var trimmed = fullPath.TrimEnd('"', ' ', '\\'); if (trimmed.Contains('\\')) { var index = trimmed.LastIndexOf('\\') + 1; if (index < trimmed.Length) { return trimmed.Substring(index); } } return string.Empty; } /// /// Trim supplied path to the required depth. /// /// Path to be trimmed /// Maximal depth of the path, 0 will show only the root node /// Trimmed path public static string GetPathUpToLevel(string path, int maxLevel) { return GetPathUpToLevel(path, maxLevel, false); } /// /// Trim supplied path or full filename to the required depth. /// /// Path to be trimmed /// Maximal depth of the path, 0 will show only the root node /// If true, the last part of the path will be ignored, since it is a filename /// Trimmed path public static string GetPathUpToLevel(string path, int maxLevel, bool containsFilename) { if (string.IsNullOrEmpty(path)) return string.Empty; string directory; try { directory = containsFilename ? Path.GetDirectoryName(path) : Path.GetFullPath(path); if (string.IsNullOrEmpty(directory)) return string.Empty; } catch (Exception) { return string.Empty; } var directoryParts = directory.Split(new[] { '\\' }, StringSplitOptions.RemoveEmptyEntries); if (directoryParts.Length >= 1) { var result = string.Empty; for (var i = 0; i < maxLevel + 1 && i < directoryParts.Length; i++) { result = string.Concat(result, directoryParts[i], "\\"); } return result; } return string.Empty; } // Try to get the windows directory, returns null if failed public static DirectoryInfo GetWindowsDirectory() { try { var windowsDirectory = Environment.GetEnvironmentVariable("SystemRoot"); if (windowsDirectory != null) return new DirectoryInfo(windowsDirectory); } catch { //Check other } try { var windowsDirectory = Environment.GetEnvironmentVariable("windir"); if (windowsDirectory != null) return new DirectoryInfo(windowsDirectory); } catch { //Messed up environment variables or security too high } return null; } /// /// Change path to normal case. Example: C:\PROGRAM FILES => C:\Program files /// public static string PathToNormalCase(string path) { var directoryParts = NormalizePath(path).Split(new[] { '\\' }, StringSplitOptions.RemoveEmptyEntries); if (directoryParts.Length < 1) return string.Empty; var result = string.Empty; for (var i = 0; i < directoryParts.Length; i++) { var part = directoryParts[i].ToLower(); result = string.Concat(result, part.Substring(0, 1).ToUpperInvariant() + part.Substring(1), "\\"); } return result; } public static bool PathsEqual(string path1, string path2) { if (string.IsNullOrEmpty(path1) || string.IsNullOrEmpty(path2)) return false; try { path1 = path1.SafeNormalize().Trim(PathTrimChars); path2 = path2.SafeNormalize().Trim(PathTrimChars); return path1.Equals(path2, StringComparison.InvariantCultureIgnoreCase); } catch { // Fall back to ordinal in case SafeNormalize isn't safe enough return path1.Trim(PathTrimChars).Equals(path2.Trim(PathTrimChars), StringComparison.OrdinalIgnoreCase); } } /// /// Remove unnecessary spaces, quotes and path separators from start and end of the path. /// Might produce different path than intended in case it contains invalid unicode characters. /// public static string NormalizePath(string path1) { if (path1 == null) throw new ArgumentNullException(nameof(path1)); return path1.SafeNormalize().Trim(PathTrimChars); } public static bool PathsEqual(FileSystemInfo path1, FileSystemInfo path2) { if (path1 == null || path2 == null) return false; return PathsEqual(path1.FullName, path2.FullName); } /// /// Replace all invalid file name characters from a string with _ so that it can be used as a file name. /// public static string SanitizeFileName(string name) { var invalidChars = Regex.Escape(new string(Path.GetInvalidFileNameChars())); var invalidRegStr = string.Format(@"([{0}]*\.+$)|([{0}]+)", invalidChars); return Regex.Replace(name, invalidRegStr, "_"); } /// /// Version of Path.Combine with much less restrictive input checks, and additional path cleanup. /// public static string GenerousCombine(string path1, string path2) { if (path1 == null || path2 == null) throw new ArgumentNullException(path1 == null ? nameof(path1) : nameof(path2)); path1 = NormalizePath(path1); path2 = NormalizePath(path2); if (path2.Length == 0) return path1; if (path1.Length == 0 || Path.IsPathRooted(path2)) return path2; return path1 + Path.DirectorySeparatorChar + path2; } /// /// Get a cleaned up list of all paths in the PATH variables of both current user and the machine. Duplicates are removed. /// public static IEnumerable GetAllEnvironmentPaths() { var parts = Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.User)?.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries) ?? Enumerable.Empty(); parts = parts.Concat(Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.Machine)?.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries) ?? Enumerable.Empty()); return parts.Where(x => !string.IsNullOrEmpty(x)).Select(NormalizePath).Select(Path.GetFullPath).DistinctBy(s => s.ToLower()); } /// /// Check if subPath is a sub path inside basePath. /// If isFilesystemPath is true then attempt to normalize the path to its absolute form on the filesystem. Set to false for registry and other paths. /// public static bool SubPathIsInsideBasePath(string basePath, string subPath, bool normalizeFilesystemPath, bool includeExactMatch) { if (basePath == null) return false; basePath = NormalizePath(basePath).Replace('\\', '/'); if (string.IsNullOrEmpty(basePath)) return false; if (normalizeFilesystemPath) { try { basePath = Path.GetFullPath(basePath).Replace('\\', '/'); } catch (SystemException) { } } if (subPath == null) return false; subPath = NormalizePath(subPath).Replace('\\', '/'); if (string.IsNullOrEmpty(subPath)) return false; if (normalizeFilesystemPath) { try { subPath = Path.GetFullPath(subPath).Replace('\\', '/'); } catch (SystemException) { } } return subPath.StartsWith(basePath + '/', StringComparison.InvariantCultureIgnoreCase) || includeExactMatch && subPath.Equals(basePath, StringComparison.InvariantCultureIgnoreCase); } } } ================================================ FILE: source/KlocTools/Tools/ProcessStartCommand.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Diagnostics; namespace Klocman.Tools { public class ProcessStartCommand { public ProcessStartCommand(string filename) : this(filename, string.Empty) { } /// The values of 'filename' and 'args' cannot be null. public ProcessStartCommand(string filename, string args) { if (filename == null) throw new ArgumentNullException(nameof(filename)); if (args == null) throw new ArgumentNullException(nameof(args)); FileName = filename.Trim().Trim('"', '\''); Arguments = args.Trim(); } public string Arguments { get; set; } public string FileName { get; set; } public static bool TryParse(string command, out ProcessStartCommand result) { try { result = ProcessTools.SeparateArgsFromCommand(command); } catch (Exception) { result = null; } return (result != null); } public string ToCommandLine() { return ToString(); } public override string ToString() { return string.IsNullOrEmpty(Arguments) ? $"\"{FileName}\"" : $"\"{FileName}\" {Arguments}"; } public ProcessStartInfo ToProcessStartInfo() { return new ProcessStartInfo(FileName, Arguments) { UseShellExecute = true }; } } } ================================================ FILE: source/KlocTools/Tools/ProcessTools.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Globalization; using System.IO; using System.Linq; using System.Management; using System.Reflection; using System.Runtime.InteropServices; using Klocman.Extensions; using Klocman.Properties; namespace Klocman.Tools { public static class ProcessTools { public static bool Is64BitProcess => IntPtr.Size == 8; /// /// Kill all of process's children, grandchildren, etc. /// /// Process ID. public static void KillChildProcesses(int pid) { foreach (var id in GetChildProcesses(pid)) { KillProcessAndChildProcesses(id); } } /// /// Get IDs of all child processes /// public static IEnumerable GetChildProcesses(int pid) { try { using (var searcher = new ManagementObjectSearcher("Select * From Win32_Process Where ParentProcessID=" + pid)) { var moc = searcher.Get(); var childProcesses = moc.Cast().Select(mo => Convert.ToInt32(mo["ProcessID"])).ToList(); return childProcesses; } } catch { Process processById; try { processById = Process.GetProcessById(pid); } catch (Exception a) { Console.WriteLine(a); return Enumerable.Empty(); } return processById.GetChildProcesses().Select(x => x.Id); } } /// /// Kill a process, and all of its children, grandchildren, etc. /// /// Process ID. public static void KillProcessAndChildProcesses(int pid) { KillChildProcesses(pid); try { var proc = Process.GetProcessById(pid); proc.Kill(); } catch (ArgumentException) { // Process already exited. } } /// processName /// /// There are problems accessing the performance counter API's used to get /// process information. This exception is specific to Windows NT, Windows 2000, and Windows XP. /// public static bool SafeKillProcess(string processName) { if (string.IsNullOrEmpty(processName)) throw new ArgumentException(@"Process name can't be null or empty", nameof(processName)); foreach (var p in Process.GetProcessesByName(processName)) { try { p.Kill(); p.WaitForExit(); // possibly with a timeout return true; } catch (Win32Exception) { // process was terminating or can't be terminated - deal with it return false; } catch (InvalidOperationException) { // process has already exited - might be able to let this one go return true; } catch { return false; } } return true; } private static readonly char[] SeparateArgsFromCommandInvalidChars = Path.GetInvalidFileNameChars().Concat(new[] { ',', ';' }).ToArray(); //static readonly char[] pathFilterChars = StringTools.InvalidPathChars.Except(new char[] { '"' }).ToArray(); /// /// Attempts to separate filename (or filename with path) from the supplied arguments. /// /// /// /// The value of 'fullCommand' cannot be null. /// fullCommand can't be empty /// Filename is in invalid format public static ProcessStartCommand SeparateArgsFromCommand(string fullCommand) { if (fullCommand == null) throw new ArgumentNullException(nameof(fullCommand)); // Get rid of whitespaces fullCommand = fullCommand.Trim(); if (string.IsNullOrEmpty(fullCommand)) throw new ArgumentException(Localisation.Error_SeparateArgsFromCommand_Empty, nameof(fullCommand)); var firstDot = fullCommand.IndexOf('.'); if (firstDot < 0) return SeparateNonDottedCommand(fullCommand); // Check if the path is in format: ExecutableName C:\Argname.exe { var pathRoot = fullCommand.IndexOf(":\\", StringComparison.InvariantCulture); var firstSpace = fullCommand.IndexOf(' '); if (firstSpace >= 0 && firstSpace < pathRoot) { var filenameBreaker = fullCommand.IndexOfAny(SeparateArgsFromCommandInvalidChars, 0, pathRoot - 1); if (filenameBreaker < 0) { var slashIndex = fullCommand.IndexOf('\\'); if (slashIndex >= 0 && slashIndex > pathRoot) { var rootSpace = fullCommand.LastIndexOf(' ', pathRoot); return new ProcessStartCommand(fullCommand.Substring(0, rootSpace).TrimEnd(), fullCommand.Substring(rootSpace)); } } } } // Check if the path is contained inside of quotation marks. // Assume that the quotation mark must come before the dot. Otherwise, it is likely that the arguments use quotations. var pathEnd = fullCommand.IndexOf('"', 0, firstDot); if (pathEnd >= 0) { // If yes, find the closing quotation mark and set its index as path end pathEnd = fullCommand.IndexOf('"', pathEnd + 1); if (pathEnd < 0) { // If no ending quote has been found, explode gracefully. throw new FormatException(Localisation.Error_SeparateArgsFromCommand_MissingQuotationMark); } pathEnd += 1; //? } // If quotation marks were missing, check for any invalid characters after last dot // in case of eg: c:\test.dir thing\filename.exe?0 used to get icons if (pathEnd < 0) { var endIndex = 0; while (true) { var dot = fullCommand.IndexOf('.', endIndex); if (dot < 0) break; var filenameBreaker = fullCommand.IndexOfAny(SeparateArgsFromCommandInvalidChars, dot); var space = fullCommand.IndexOf(' ', dot); if (filenameBreaker < 0) { if (space < 0) break; filenameBreaker = space; } var dash = fullCommand.IndexOf('\\', dot); if (filenameBreaker < dash || dash < 0) { pathEnd = space < 0 ? filenameBreaker : space; break; } var nextBreaker = fullCommand.IndexOfAny(SeparateArgsFromCommandInvalidChars, filenameBreaker + 1); var nextDash = fullCommand.IndexOf('\\', filenameBreaker + 1); if (nextBreaker > 0 && (nextDash < 0 || nextBreaker < nextDash)) { var nextDot = fullCommand.IndexOf('.', filenameBreaker + 1); if (nextDot < 0 || nextBreaker < nextDot) { pathEnd = space < 0 ? filenameBreaker : space; break; } } endIndex = dash; } // old //pathEnd = fullCommand.IndexOfAny(" ,:;?-=", fullCommand.LastIndexOf('.')); } return SeparateCommand(fullCommand, pathEnd); } private static ProcessStartCommand SeparateCommand(string fullCommand, int splitIndex) { // Begin extracting filename and arguments string filename; var args = string.Empty; if (splitIndex < 0 || splitIndex >= fullCommand.Length) { // Looks like there were no arguments, assume whole command is a filename filename = fullCommand; } else { // pathEnd shows the end of the filename (and start of the arguments) filename = fullCommand.Substring(0, splitIndex).TrimEnd(); args = fullCommand.Substring(splitIndex).TrimStart(); } filename = filename.Trim('"'); // Get rid of the quotation marks return new ProcessStartCommand(filename, args); } private static ProcessStartCommand SeparateNonDottedCommand(string fullCommand) { // Look for the first root of a path var pathRoot = fullCommand.IndexOf(":\\", StringComparison.InvariantCulture); var pathRootEnd = pathRoot < 0 ? 0 : pathRoot + 2; var breakChars = SeparateArgsFromCommandInvalidChars.Except(new[] { '\\' }).ToArray(); // Check if there are any invalid path chars before the start we found. If yes, our path is most likely an argument. if (pathRootEnd > 0 && fullCommand.IndexOfAny(breakChars, 0, pathRootEnd - 2) >= 0) pathRootEnd = 0; var breakIndex = fullCommand.IndexOfAny(breakChars, pathRootEnd); // If there are no invalid path chars, it's probably just a naked filename or directory path. if (breakIndex < 0) return new ProcessStartCommand(fullCommand.Trim('"')); // The invalid char has to have at least 1 space before it to count as an argument. Otherwise the input is likely garbage. if (breakIndex > 0 && fullCommand[breakIndex - 1] == ' ') return new ProcessStartCommand(fullCommand.Substring(0, breakIndex - 1).TrimEnd(), fullCommand.Substring(breakIndex)); throw new FormatException(Localisation.Error_SeparateArgsFromCommand_NoDot + "\n" + fullCommand); } /// /// Change default culture info for new threads /// /// public static void SetDefaultCulture(CultureInfo culture) { var type = typeof(CultureInfo); if (Environment.Version.Major < 4) { // Fields used before .Net 4.0 try { type.InvokeMember("m_userDefaultCulture", BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Static, null, culture, new object[] { culture }); type.InvokeMember("m_userDefaultUICulture", BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Static, null, culture, new object[] { culture }); return; } catch { //Ignore failure, try next } } try { type.InvokeMember("s_userDefaultCulture", BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Static, null, culture, new object[] { culture }); type.InvokeMember("s_userDefaultUICulture", BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Static, null, culture, new object[] { culture }); } catch { //Ignore failure } } /// /// Bring to foreground main window of all processes with name of the executing process /// public static void ShowMainWindow() { ShowMainWindow(Process.GetCurrentProcess().ProcessName); } /// /// Bring to foreground main window of all processes with supplied name /// /// Name of the processes to bring to foreground public static void ShowMainWindow(string processName) { foreach (var p in Process.GetProcessesByName(processName)) { ShowWindow(p.MainWindowHandle, 1); //SW_SHOWNORMAL = 1 SetForegroundWindow(p.MainWindowHandle); } } [DllImport("user32.dll", SetLastError = true)] private static extern bool SetForegroundWindow(IntPtr hwnd); [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] private static extern bool ShowWindow(IntPtr hwnd, int nCmdShow); public static Icon GetIconFromEntryExe() { var location = Assembly.GetEntryAssembly()?.Location; if (location == null) throw new ArgumentException("Failed to get location of EntryAssembly"); if (location.EndsWith(".dll")) location = location.Substring(0, location.Length - 3) + "exe"; var icon = DrawingTools.ExtractAssociatedIcon(location); return icon; } /// /// Process.GetProcessById but doesn't throw on issues and instead returns null /// public static Process GetProcessByIdSafe(int processId) { try { return Process.GetProcessById(processId); } catch { return null; } } } } ================================================ FILE: source/KlocTools/Tools/ReflectionTools.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Reflection; using Klocman.Extensions; namespace Klocman.Tools { public static class ReflectionTools { /// /// Get the name of a static or instance property from a property access lambda. /// /// Type of the property /// Type of a class that contains the property /// You must pass a lambda formed like this 'x => x.Property' or this 'x => class.Property' /// The name of the property public static string GetPropertyName(Expression> memberLamda) { return GetPropertyInfo(memberLamda).Name; } /// /// Get the PropertyInfo of a static or instance property from a property access lambda. /// /// Type of the property /// Type of a class that contains the property /// You must pass a lambda formed like this 'x => x.Property' or this 'x => class.Property' /// The name of the property public static PropertyInfo GetPropertyInfo(Expression> memberLamda) { if (memberLamda == null) throw new ArgumentNullException(nameof(memberLamda)); if (memberLamda.Body is not MemberExpression memberSelectorExpression) throw new ArgumentException(@"You must pass a lambda of the form: 'x => x.Property' or 'x => class.Property'", nameof(memberLamda)); var property = memberSelectorExpression.Member as PropertyInfo; if (property == null) throw new ArgumentException(@"You must pass a lambda of the form: 'x => x.Property' or 'x => class.Property'", nameof(memberLamda)); return property; } /// /// Try to set specified property to the supplied object. Ignores setter access protection. /// Will throw an exception if the setter doesn't exist or any of the parameters is invalid. /// /// Type of a class that contains the property /// Instance of the class that contains the property /// You must pass a lambda formed like this 'x => x.Property' or this 'x => class.Property' /// Value to set the property to. public static void SetPropertyValue(TClass classInstance, Expression> memberLamda, object value) { var memberSelectorExpression = memberLamda.Body as MemberExpression; var property = memberSelectorExpression?.Member as PropertyInfo; if (property != null) { property.SetValue(classInstance, value, null); } } /// /// Create compiled get and set methods with drastically improved performance. /// /// Type of the class containing this property /// Property info to compile public static CompiledPropertyInfo CompileAccessors(this PropertyInfo propertyInfo) { return new CompiledPropertyInfo(propertyInfo); } /// /// Search for types that implement TBase in all assemblies in current domain. /// /// Base that returned types have to implement /// Filter out abstract types /// Filter out interfaces public static IEnumerable GetTypesImplementingBase(bool ignoreAbstract = true, bool ignoreInterfaces = true) where TBase : class { return GetTypesImplementingBase(AppDomain.CurrentDomain.GetAssemblies(), ignoreAbstract, ignoreInterfaces); } /// /// Search for types that implement TBase in specified assemblies. /// /// Base that returned types have to implement /// Assemblies to search for types /// Filter out abstract types /// Filter out interfaces public static IEnumerable GetTypesImplementingBase(Assembly[] assembliesToSearch, bool ignoreAbstract = true, bool ignoreInterfaces = true) where TBase : class { var baseType = typeof(TBase); if (baseType.IsSealed) throw new TypeLoadException("TBase can't be a sealed type"); var result = assembliesToSearch.Attempt(x => x.GetTypes()).SelectMany(x => x); if (ignoreAbstract) result = result.Where(x => !x.IsAbstract); if (ignoreInterfaces) result = result.Where(x => !x.IsInterface); return result.Where(x => baseType.IsAssignableFrom(x)); } } } ================================================ FILE: source/KlocTools/Tools/RegistryTools.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Text; using Klocman.Extensions; using Klocman.Properties; using Microsoft.Win32; namespace Klocman.Tools { public static class RegistryTools { private const string HklmShortRootName = "HKLM"; private const string HklmRootName = "HKEY_LOCAL_MACHINE"; private const string HkcrRootName = "HKEY_CLASSES_ROOT"; private const string HkcrShortRootName = "HKCR"; private const string HkcuRootName = "HKEY_CURRENT_USER"; private const string HkcuShortRootName = "HKCU"; private const string HkuRootName = "HKEY_USERS"; private const string HkuShortRootName = "HKUS"; private const string HkuShortRootName2 = "HKU"; private const string HkccRootName = "HKEY_CURRENT_CONFIG"; private const string HkccShortRootName = "HKCC"; /// /// Rename subkey. /// public static void RenameSubKey(this RegistryKey parentKey, string subKeyName, string newSubKeyName) { CopySubKey(parentKey, subKeyName, newSubKeyName); parentKey.DeleteSubKeyTree(subKeyName); } /// /// Move subkey under a new parent. /// public static void MoveSubKey(this RegistryKey parentKey, string subKeyName, RegistryKey newParentKey, string newSubKeyName) { CopySubKey(parentKey, subKeyName, newParentKey, newSubKeyName); parentKey.DeleteSubKeyTree(subKeyName); } /// /// Copy subkey. /// public static void CopySubKey(this RegistryKey parentKey, string subKeyName, string newSubKeyName) { CopySubKey(parentKey, subKeyName, parentKey, newSubKeyName); } /// /// Copy subkey to a different parent key. /// public static void CopySubKey(this RegistryKey parentKey, string subKeyName, RegistryKey newParentKey, string newSubKeyName) { using (var destinationKey = newParentKey.CreateSubKey(newSubKeyName)) using (var sourceKey = parentKey.OpenSubKey(subKeyName, true)) RecurseCopyKey(sourceKey, destinationKey); } private static void RecurseCopyKey(RegistryKey sourceKey, RegistryKey destinationKey) { foreach (var valueName in sourceKey.GetValueNames()) { var valueData = sourceKey.GetValue(valueName); var valueKind = sourceKey.GetValueKind(valueName); destinationKey.SetValue(valueName, valueData!, valueKind); } foreach (var sourceSubKeyName in sourceKey.GetSubKeyNames()) { using (var destSubKey = destinationKey.CreateSubKey(sourceSubKeyName)) using (var sourceSubKey = sourceKey.OpenSubKey(sourceSubKeyName, true)) RecurseCopyKey(sourceSubKey, destSubKey); } } public static void AddRegToRegistry(string fullFilename, bool silent) { if (fullFilename == null) throw new ArgumentNullException(nameof(fullFilename)); if (!File.Exists(fullFilename) || !fullFilename.EndsWith(".reg", StringComparison.CurrentCultureIgnoreCase)) throw new ArgumentException(Localisation.RegistryTools_AddRegToRegistry_FileNotExist, nameof(fullFilename)); RunRegeditCommand($"{(silent ? "/s " : string.Empty)}\"{fullFilename}\""); } /// /// Export all of the supplied keys to a .reg file using Regedit /// /// /// /// False if nothing was written, else true public static bool ExportRegistry(string outputFileName, IEnumerable registryPaths) { var result = new List(); var firstPass = true; foreach (var regPath in registryPaths) { var output = ExportRegistryHelper(regPath); if (output == null || output.Length < 2) continue; if (!firstPass) { output = output.SubArray(1, output.Length - 1); } firstPass = false; result.AddRange(output); } if (result.Count < 2) return false; File.WriteAllLines(outputFileName, result.ToArray(), Encoding.Unicode); return true; } /// /// Write specified unescaped values to a .reg file /// /// Filename with extension to save as /// Full, rooted registry path of the key containing the values /// Value names and their string values public static void ExportRegistryStringValues(string outputFileName, string containingKeyPath, params KeyValuePair[] values) { var builder = new StringBuilder(); builder.AppendLine(@"Windows Registry Editor Version 5.00"); foreach (var value in values) { builder.AppendLine(); builder.AppendFormat(@"[{0}]", containingKeyPath); builder.AppendLine(); builder.AppendFormat("\"{0}\"=\"{1}\"", value.Key, (value.Value ?? string.Empty).Replace(@"\", @"\\").Replace("\"", "\\\"")); builder.AppendLine(); } File.WriteAllText(outputFileName, builder.ToString()); } /// Registry export failed because of filesystem or permission error. public static void ExportRegistry(string outputFileName, string registryPath) { RunRegeditCommand($"/e \"{outputFileName}\" \"{registryPath}\""); } /// /// Open registry key using its fully qualified path. The key is opened read-only. /// Root key can be named by either its long or short name. (long: "HKEY_LOCAL_MACHINE", short: "HKLM") /// /// Full path of the requested registry key public static RegistryKey OpenRegistryKey(string fullPath) { return OpenRegistryKey(fullPath, false); } /// /// Open registry key using its fully qualified path. /// Root key can be named by either its long or short name. (long: "HKEY_LOCAL_MACHINE", short: "HKLM") /// /// Full path of the requested registry key /// If false, key is opened read-only /// If true, return null instead of throwin an exception if the key is inaccessible public static RegistryKey OpenRegistryKey(string fullPath, bool writable, bool ignoreAccessExceptions) { if(!ignoreAccessExceptions) return OpenRegistryKey(fullPath, writable); try { return OpenRegistryKey(fullPath, writable); } catch (Exception ex) { if (ex is UnauthorizedAccessException || ex is System.Security.SecurityException || ex is IOException) { Debug.WriteLine(ex); return null; } throw; } } /// /// Open registry key using its fully qualified path. /// Root key can be named by either its long or short name. (long: "HKEY_LOCAL_MACHINE", short: "HKLM") /// /// Full path of the requested registry key /// If false, key is opened read-only public static RegistryKey OpenRegistryKey(string fullPath, bool writable) { if (fullPath == null) throw new ArgumentNullException(nameof(fullPath)); if (fullPath.Length < 4) throw new ArgumentException("Path is too short/invalid"); var rootKey = GetRootHive(fullPath); var result = rootKey.OpenSubKey(StripKeyRoot(fullPath), writable); //if (result == null) // throw new ArgumentException("Invalid subpath"); return result; } [return: NotNull] private static RegistryKey GetRootHive(string fullPath) { RegistryKey rootKey; switch (GetKeyRoot(fullPath, true)) { case HklmShortRootName: rootKey = Registry.LocalMachine; break; case HkcrShortRootName: rootKey = Registry.ClassesRoot; break; case HkcuShortRootName: rootKey = Registry.CurrentUser; break; case HkuShortRootName: case HkuShortRootName2: rootKey = Registry.Users; break; case HkccShortRootName: rootKey = Registry.CurrentConfig; break; default: throw new ArgumentException("Path root is invalid or missing"); } return rootKey; } /// /// Return registry key at supplied path. If the key or its parents don't exist, create them before returning. /// The returned RegistryKey is writable. /// /// Path of the key to open or create. Not case-sensitive. public static RegistryKey CreateSubKeyRecursively(string fullPath) { if (fullPath == null) throw new ArgumentNullException(nameof(fullPath)); if (fullPath.Length < 4) throw new ArgumentException("Path is too short/invalid"); var previousKey = GetRootHive(fullPath); var parts = StripKeyRoot(fullPath).Split(new[] { '\\', '/' }, StringSplitOptions.RemoveEmptyEntries); for (var i = 0; i < parts.Length; i++) { var newKey = previousKey!.CreateSubKey(parts[i]); // Don't try to close the root key if (i > 0) previousKey.Close(); previousKey = newKey; } return previousKey; } public static string GetKeyRoot(string fullPath, bool shortStyle) { if (fullPath == null) throw new ArgumentNullException(nameof(fullPath)); if (fullPath.Length < 3) throw new ArgumentException("Path is too short/invalid"); var firstSplitter = fullPath.IndexOf('\\'); if (firstSplitter < 0) firstSplitter = fullPath.Length; var rootName = fullPath.Substring(0, firstSplitter).ToUpperInvariant(); switch (rootName) { case HklmRootName: case HklmShortRootName: return shortStyle ? HklmShortRootName : HklmRootName; case HkcrRootName: case HkcrShortRootName: return shortStyle ? HkcrShortRootName : HkcrRootName; case HkcuRootName: case HkcuShortRootName: return shortStyle ? HkcuShortRootName : HkcuRootName; case HkuRootName: case HkuShortRootName: case HkuShortRootName2: return shortStyle ? HkuShortRootName : HkuRootName; case HkccRootName: case HkccShortRootName: return shortStyle ? HkccShortRootName : HkccRootName; default: throw new ArgumentException("Path root is invalid or missing"); } } public static string StripKeyRoot(string fullPath) { if (fullPath == null) throw new ArgumentNullException(nameof(fullPath)); if (fullPath.Length < 4) throw new ArgumentException("Path is too short/invalid"); var firstSplitter = fullPath.IndexOf('\\'); if (firstSplitter < 0) firstSplitter = fullPath.Length; return firstSplitter >= fullPath.Length - 1 ? string.Empty : fullPath.Substring(firstSplitter + 1); } /*/// Path can't be empty or null public static string GetParentRegistryPath(string fullRegistryPath) { if (string.IsNullOrEmpty(fullRegistryPath)) throw new ArgumentException("Path can't be empty or null", "fullRegistryPath"); fullRegistryPath.TrimEnd('\\'); var lastIndex = fullRegistryPath.LastIndexOf('\\'); return fullRegistryPath.Substring(0, lastIndex); }*/ public static void RemoveRegistryKey(string fullRegistryPath) { if (string.IsNullOrEmpty(fullRegistryPath)) throw new ArgumentException(Localisation.RegistryTools_RemoveRegistryKey_PathEmptyNull, nameof(fullRegistryPath)); if (fullRegistryPath.Count(x => x.Equals('\\')) < 2) throw new ArgumentException(Localisation.RegistryTools_RemoveRegistryKey_PointsAtRoot, nameof(fullRegistryPath)); using (var key = OpenRegistryKey(Path.GetDirectoryName(fullRegistryPath), true)) { if (key != null) { var subkeyName = Path.GetFileName(fullRegistryPath); // Check if key exists before attempting to remove to avoid an exception if (key.GetSubKeyNames().Contains(subkeyName, StringComparison.OrdinalIgnoreCase)) key.DeleteSubKeyTree(subkeyName); } } } public static void RemoveRegistryValue(string fullRegistryPath, string valueName) { if (string.IsNullOrEmpty(fullRegistryPath)) throw new ArgumentException(Localisation.RegistryTools_RemoveRegistryKey_PathEmptyNull, nameof(fullRegistryPath)); if (string.IsNullOrEmpty(valueName)) throw new ArgumentException(Localisation.RegistryTools_RemoveRegistryKey_RemoveDefault, nameof(valueName)); if (fullRegistryPath.Count(x => x.Equals('\\')) < 2) throw new ArgumentException(Localisation.RegistryTools_RemoveRegistryKey_PointsAtRoot, nameof(fullRegistryPath)); using (var key = OpenRegistryKey(fullRegistryPath, true)) { key?.DeleteValue(valueName); } } private static void RunRegeditCommand(string command) { foreach (var process in Process.GetProcessesByName("regedit")) { try { process.Kill(); } catch (InvalidOperationException) { } catch (Win32Exception) { } } var startInfo = new ProcessStartInfo("regedit.exe", command) { UseShellExecute = false }; var pr = startInfo.Start(); if (!pr.WaitForExit(50000)) { pr.Kill(); throw new IOException("regedit.exe failed to execute properly"); } if (pr.ExitCode != 0) throw new IOException("regedit.exe returned error code: " + pr.ExitCode); } private static string[] ExportRegistryHelper(string registryPath) { // Check if the key exists try { OpenRegistryKey(registryPath).Close(); } catch { return null; } var temp = Path.GetTempPath(); var tempDirectory = Directory.CreateDirectory(Path.Combine(temp, "BCU")); var tempFile = Path.Combine(tempDirectory.FullName, "tempBackup.reg"); File.Delete(tempFile); try { RunRegeditCommand($"/e \"{tempFile}\" \"{registryPath}\""); return File.ReadAllLines(tempFile, Encoding.Unicode); } finally { File.Delete(tempFile); } } /// Could not complete this operation. public static void OpenRegKeyInRegedit(string registryPath) { try { if (!ProcessTools.SafeKillProcess("regedit")) throw new IOException("Could not close running instance of Regedit"); var regeditSettings = Registry.CurrentUser.CreateSubKey(@"Software\Microsoft\Windows\CurrentVersion\Applets\Regedit", RegistryKeyPermissionCheck.ReadWriteSubTree); if (regeditSettings == null) throw new IOException("Failed to set the last user registry key"); regeditSettings.SetValue("LastKey", registryPath, RegistryValueKind.String); Process.Start("regedit.exe"); } catch (Exception ex) { throw new IOException("Failed to open regedit.exe", ex); } } } } ================================================ FILE: source/KlocTools/Tools/SerializationTools.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Xml.Serialization; namespace Klocman.Tools { public static class SerializationTools { public static T DeserializeFromXml(string fullFilename) { var serializer = new XmlSerializer(typeof(T)); using (var reader = new StreamReader(fullFilename)) { var deserialized = serializer.Deserialize(reader.BaseStream); return (T)deserialized; } } public static void SerializeToXml(string fullFilename, T input, XmlAttributeOverrides attributeOverrides = null) { var serializer = new XmlSerializer(typeof(T), attributeOverrides); using (var writer = new StreamWriter(fullFilename)) { serializer.Serialize(writer.BaseStream, input); } } public static IDictionary DeserializeDictionary(string filename) { var l = DeserializeFromXml>>(filename); return l.ToDictionary(x => x.Key, x => x.Data); } public static void SerializeDictionary(IDictionary source, string filename) { SerializeToXml(filename, source.Select(x => new DictSerializeData(x.Key, x.Value)).ToList()); } [Serializable] public class DictSerializeData { public DictSerializeData() { } public DictSerializeData(TKey key, TValue data) { Key = key; Data = data; } public TValue Data { get; set; } public TKey Key { get; set; } } } } ================================================ FILE: source/KlocTools/Tools/Sift4.cs ================================================ using System; using System.Collections.Generic; using System.Linq; namespace Klocman.Tools { /// /// Algorithm by Siderite /// https://siderite.blogspot.com/2014/11/super-fast-and-accurate-string-distance.html#at2217133354 /// public class Sift4 { private readonly Options _options; public Sift4(Options options) { if (options == null) options = new Options(); if (options.Tokenizer == null) { options.Tokenizer = s => s == null ? Array.Empty() : s.ToCharArray().Select(c => c.ToString()).ToArray(); } if (options.TokenMatcher == null) { options.TokenMatcher = (t1, t2) => t1 == t2; } if (options.MatchingEvaluator == null) { options.MatchingEvaluator = (t1, t2) => 1; } if (options.LocalLengthEvaluator == null) { options.LocalLengthEvaluator = l => l; } if (options.TranspositionCostEvaluator == null) { options.TranspositionCostEvaluator = (c1, c2) => 1; } if (options.TranspositionsEvaluator == null) { options.TranspositionsEvaluator = (l, t) => l - t; } _options = options; } /// /// General distance algorithm uses all the parameters in the options object and works on tokens /// /// /// /// /// public double GeneralDistance(string s1, string s2, int maxOffset) { var t1 = _options.Tokenizer(s1); var t2 = _options.Tokenizer(s2); var l1 = t1.Length; var l2 = t2.Length; if (l1 == 0) return _options.LocalLengthEvaluator(l2); if (l2 == 0) return _options.LocalLengthEvaluator(l1); var c1 = 0; //cursor for string 1 var c2 = 0; //cursor for string 2 var lcss = 0.0; //largest common subsequence var localCs = 0.0; //local common substring var trans = 0.0; //cost of transpositions ('axb' vs 'xba') var offsetArr = new LinkedList(); //offset pair array, for computing the transpositions while ((c1 < l1) && (c2 < l2)) { if (_options.TokenMatcher(t1[c1], t2[c2])) { localCs += _options.MatchingEvaluator(t1[c1], t2[c2]); var isTransposition = false; var op = offsetArr.First; while (op != null) { //see if current match is a transposition var ofs = op.Value; if (c1 <= ofs.C1 || c2 <= ofs.C2) { // when two matches cross, the one considered a transposition is the one with the largest difference in offsets isTransposition = Math.Abs(c2 - c1) >= Math.Abs(ofs.C2 - ofs.C1); if (isTransposition) { trans += _options.TranspositionCostEvaluator(c1, c2); } else { if (!ofs.IsTransposition) { ofs.IsTransposition = true; trans += _options.TranspositionCostEvaluator(ofs.C1, ofs.C2); } } break; } var nextOp = op.Next; if (c1 > ofs.C2 && c2 > ofs.C1) { offsetArr.Remove(op); } op = nextOp; } offsetArr.AddLast(new OffsetPair(c1, c2) { IsTransposition = isTransposition }); } else { lcss += _options.LocalLengthEvaluator(localCs); localCs = 0; if (c1 != c2) { c1 = c2 = Math.Min(c1, c2); //using min allows the computation of transpositions } //if matching tokens are found, remove 1 from both cursors (they get incremented at the end of the loop) //so that we can have only one code block handling matches for (var i = 0; i < maxOffset && (c1 + i < l1 || c2 + i < l2); i++) { if ((c1 + i < l1) && _options.TokenMatcher(t1[c1 + i], t2[c2])) { c1 += i - 1; c2--; break; } if ((c2 + i < l2) && _options.TokenMatcher(t1[c1], t2[c2 + i])) { c1--; c2 += i - 1; break; } } } c1++; c2++; if (_options.MaxDistance != null) { var temporaryDistance = _options.LocalLengthEvaluator(Math.Max(c1, c2)) - _options.TranspositionsEvaluator(lcss, trans); if (temporaryDistance >= _options.MaxDistance) return Math.Round(temporaryDistance, MidpointRounding.AwayFromZero); } // this covers the case where the last match is on the last token in list, so that it can compute transpositions correctly if ((c1 >= l1) || (c2 >= l2)) { lcss += _options.LocalLengthEvaluator(localCs); localCs = 0; c1 = c2 = Math.Min(c1, c2); } } lcss += _options.LocalLengthEvaluator(localCs); return Math.Round(_options.LocalLengthEvaluator(Math.Max(l1, l2)) - _options.TranspositionsEvaluator(lcss, trans), MidpointRounding.AwayFromZero); //apply transposition cost to the final result } /// /// Static distance algorithm working on strings, computing transpositions as well as stopping when maxDistance was reached. /// /// /// /// /// /// public static double CommonDistance(string s1, string s2, int maxOffset, int maxDistance = 0) { var l1 = s1 == null ? 0 : s1.Length; var l2 = s2 == null ? 0 : s2.Length; if (l1 == 0) return l2; if (l2 == 0) return l1; var c1 = 0; //cursor for string 1 var c2 = 0; //cursor for string 2 var lcss = 0; //largest common subsequence var localCs = 0; //local common substring var trans = 0; //number of transpositions ('axb' vs 'xba') var offsetArr = new LinkedList(); //offset pair array, for computing the transpositions while ((c1 < l1) && (c2 < l2)) { if (s1![c1] == s2![c2]) { localCs++; var isTransposition = false; var op = offsetArr.First; while (op != null) { //see if current match is a transposition var ofs = op.Value; if (c1 <= ofs.C1 || c2 <= ofs.C2) { // when two matches cross, the one considered a transposition is the one with the largest difference in offsets isTransposition = Math.Abs(c2 - c1) >= Math.Abs(ofs.C2 - ofs.C1); if (isTransposition) { trans++; } else { if (!ofs.IsTransposition) { ofs.IsTransposition = true; trans++; } } break; } var nextOp = op.Next; if (c1 > ofs.C2 && c2 > ofs.C1) { offsetArr.Remove(op); } op = nextOp; } offsetArr.AddLast(new OffsetPair(c1, c2) { IsTransposition = isTransposition }); } else { lcss += localCs; localCs = 0; if (c1 != c2) { c1 = c2 = Math.Min(c1, c2); //using min allows the computation of transpositions } //if matching tokens are found, remove 1 from both cursors (they get incremented at the end of the loop) //so that we can have only one code block handling matches for (var i = 0; i < maxOffset && (c1 + i < l1 || c2 + i < l2); i++) { if ((c1 + i < l1) && s1[c1 + i] == s2[c2]) { c1 += i - 1; c2--; break; } if ((c2 + i < l2) && s1[c1] == s2[c2 + i]) { c1--; c2 += i - 1; break; } } } c1++; c2++; if (maxDistance > 0) { var temporaryDistance = Math.Max(c1, c2) - (lcss - trans); if (temporaryDistance >= maxDistance) return temporaryDistance; } // this covers the case where the last match is on the last token in list, so that it can compute transpositions correctly if ((c1 >= l1) || (c2 >= l2)) { lcss += localCs; localCs = 0; c1 = c2 = Math.Min(c1, c2); } } lcss += localCs; return Math.Max(l1, l2) - (lcss - trans); //apply transposition cost to the final result } /// /// Standard Sift algorithm, using strings and taking only maxOffset as a parameter /// /// /// /// /// public static int SimplestDistance(string s1, string s2, int maxOffset) { var l1 = s1 == null ? 0 : s1.Length; var l2 = s2 == null ? 0 : s2.Length; if (l1 == 0) return l2; if (l2 == 0) return l1; var c1 = 0; //cursor for string 1 var c2 = 0; //cursor for string 2 var lcss = 0; //largest common subsequence var localCs = 0; //local common substring while ((c1 < l1) && (c2 < l2)) { if (s1![c1] == s2![c2]) { localCs++; } else { lcss += localCs; localCs = 0; if (c1 != c2) { c1 = c2 = Math.Max(c1, c2); } //if matching tokens are found, remove 1 from both cursors (they get incremented at the end of the loop) //so that we can have only one code block handling matches for (var i = 0; i < maxOffset && (c1 + i < l1 && c2 + i < l2); i++) { if ((c1 + i < l1) && s1[c1 + i] == s2[c2]) { c1 += i - 1; c2--; break; } if ((c2 + i < l2) && s1[c1] == s2[c2 + i]) { c1--; c2 += i - 1; break; } } } c1++; c2++; } lcss += localCs; return Math.Max(l1, l2) - lcss; } private class OffsetPair { public int C1 { get; set; } public int C2 { get; set; } public bool IsTransposition { get; set; } public OffsetPair(int c1, int c2) { C1 = c1; C2 = c2; IsTransposition = false; } } public class Options { /// /// If set, the algorithm will stop if the distance reaches this value /// public int? MaxDistance { get; set; } /// /// The function that turns strings into a list of tokens (also strings) /// public Func Tokenizer { get; set; } /// /// The function that determines if two tokens are matching (similar to characters being the same in the simple algorithm) /// public Func TokenMatcher { get; set; } /// /// The function that determines the value of a match of two tokens (the equivalent of adding 1 to the lcss when two characters match) /// This assumes that the TokenMatcher function is a lot less expensive than this evaluator. If that is not the case, /// you can optimize the speed of the algorithm by using only the matching evaluator and then calculating if two tokens match on the returned value. /// public Func MatchingEvaluator { get; set; } /// /// Determines if the local value (computed on subsequent matched tokens) must be modified. /// In case one wants to reward longer matched substrings, for example, this is what you need to change. /// public Func LocalLengthEvaluator { get; set; } /// /// The function determining the cost of an individual transposition, based on its counter positions. /// public Func TranspositionCostEvaluator { get; set; } /// /// The function determining how the cost of transpositions affects the final result /// Change it if it doesn't suit you. /// public Func TranspositionsEvaluator { get; set; } } } } ================================================ FILE: source/KlocTools/Tools/SleepControls.cs ================================================ using System; using System.Runtime.InteropServices; using System.Windows.Forms; namespace Klocman.Tools { public static class SleepControls { public static bool PreventSleepOrShutdown(IntPtr windowHandle, string blockReason) { try { SetThreadExecutionState(ExecutionState.EsContinuous | ExecutionState.EsSystemRequired); return ShutdownBlockReasonCreate(windowHandle, blockReason); } catch (SystemException ex) { Console.WriteLine(ex); return false; } } public static bool AllowSleepOrShutdown(IntPtr windowHandle) { try { SetThreadExecutionState(ExecutionState.EsContinuous); return ShutdownBlockReasonDestroy(windowHandle); } catch (SystemException ex) { Console.WriteLine(ex); return false; } } [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern ExecutionState SetThreadExecutionState(ExecutionState esFlags); [Flags] private enum ExecutionState : uint { EsAwaymodeRequired = 0x00000040, EsContinuous = 0x80000000, EsDisplayRequired = 0x00000002, EsSystemRequired = 0x00000001 } [DllImport("user32.dll")] private static extern bool ShutdownBlockReasonCreate(IntPtr hWnd, [MarshalAs(UnmanagedType.LPWStr)] string pwszReason); [DllImport("user32.dll")] private static extern bool ShutdownBlockReasonDestroy(IntPtr hWnd); public static bool PutToSleep() { try { return Application.SetSuspendState(PowerState.Suspend, true, true) || Application.SetSuspendState(PowerState.Hibernate, true, true); } catch (SystemException ex) { Console.WriteLine(ex); return false; } } } } ================================================ FILE: source/KlocTools/Tools/StringTools.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using Klocman.Extensions; namespace Klocman.Tools { public static class StringTools { /// /// Atetmpt to extract percentage from a string. "Test 63% of tests" returns 63. "Nope 11" returns -1; /// /// String to parse. Only the first percent sign is parsed. public static int TryExtractPercentage(string toParse) { var index = toParse.IndexOf('%'); if (index <= 0) return -1; var numIndex = -1; for (var i = index - 1; i >= 0; i--) { if (toParse[i] >= '0' && toParse[i] <= '9') numIndex = i; else break; } if (numIndex < index && numIndex >= 0) { var number = toParse.Substring(numIndex, index - numIndex); int resultInt; if (int.TryParse(number, out resultInt)) return resultInt; } return -1; } /// /// Calculate string similarity by using Damereau-Levenshein Distance algorithm. /// The lower the score, the more similar the strings are. /// public static int CompareSimilarity(string s, string t) { if (string.IsNullOrEmpty(s)) { if (string.IsNullOrEmpty(t)) return 0; return t.Length; } if (string.IsNullOrEmpty(t)) { return s.Length; } var n = s.Length; var m = t.Length; var d = new int[n + 1, m + 1]; // initialize the top and right of the table to 0, 1, 2, ... for (var i = 0; i <= n; d[i, 0] = i++) { } for (var j = 1; j <= m; d[0, j] = j++) { } for (var i = 1; i <= n; i++) { for (var j = 1; j <= m; j++) { var cost = t[j - 1] == s[i - 1] ? 0 : 1; var min1 = d[i - 1, j] + 1; var min2 = d[i, j - 1] + 1; var min3 = d[i - 1, j - 1] + cost; d[i, j] = Math.Min(Math.Min(min1, min2), min3); } } return d[n, m]; } public static IEnumerable InvalidFileNameChars => Path.GetInvalidFileNameChars(); public static IEnumerable InvalidPathChars => Path.GetInvalidPathChars(); public static IEnumerable NewLineChars => new[] { Environment.NewLine, "\n", "\r" }; /// /// Get a unique name based on the supplied baseName. If baseName is found in the otherItems enumerable it is postfixed /// by a number. /// The number is increased by 1 if the new name with the number is in the enumerable. /// /// /// /// baseName if it was not found in otherItems, or baseName(number) if it was /// The value of 'baseName' cannot be null. /// Unique name reached int.MaxValue public static string GetUniqueName(string baseName, IEnumerable otherItems) { if (baseName == null) throw new ArgumentNullException(nameof(baseName)); baseName = baseName.Trim().SafeNormalize(); if (otherItems == null) return baseName; var baseNameCounted = baseName; var otherItemList = otherItems.Select(x => x.ToLower()).ToList(); for (var i = 0; i < int.MaxValue; i++) { if (i != 0) baseNameCounted = $"{baseName} ({i})"; if (!otherItemList.Contains(baseNameCounted.ToLower())) return baseNameCounted; } throw new ArgumentOutOfRangeException(nameof(otherItems), @"Unique name reached int.MaxValue"); } public static bool StringContainsFilter(string input, string filter) { input = input.StripAccents(); var filters = filter.StripAccents().Split(' '); return filters.All(str => input.IndexOf(str, StringComparison.OrdinalIgnoreCase) != -1); } /// /// Strip version number from the end of a string. "MyApp 1.023.1" -> "MyApp" /// If string is null or empty, string.Empty is returned. /// /// /// public static string StripStringFromVersionNumber(string input) { if (input == null) return string.Empty; int previousLen; do { previousLen = input.Length; input = input.Trim(); if (input.Length == 0) return string.Empty; if (input.EndsWith(")", StringComparison.Ordinal)) { var bracketLocation = input.LastIndexOf('('); if (bracketLocation > 4) { input = input.Substring(0, bracketLocation).TrimEnd(); } } input = input.ExtendedTrimEndAny( new[] { "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", ".", ",", "-", "_" }, StringComparison.InvariantCultureIgnoreCase).TrimEnd(); if (input.EndsWith(" v", StringComparison.InvariantCultureIgnoreCase)) input = input.Substring(0, input.Length - 2); input = input.ExtendedTrimEndAny(new[] { "Application", "Helper", " v", " CE" }, StringComparison.InvariantCultureIgnoreCase); input = input.TrimEnd(); } while (previousLen != input.Length); return input; } public static string ReplaceNonCharacters(string input, char replacement) { var sb = new StringBuilder(input.Length); for (var i = 0; i < input.Length; i++) { if (char.IsSurrogatePair(input, i)) { int c = char.ConvertToUtf32(input, i); i++; if (IsValidCodePoint(c)) sb.Append(char.ConvertFromUtf32(c)); else sb.Append(replacement); } else { char c = input[i]; if (IsValidCodePoint(c)) sb.Append(c); else sb.Append(replacement); } } return sb.ToString(); } private static bool IsValidCodePoint(int point) { return point < 0xfdd0 || point >= 0xfdf0 && (point & 0xffff) != 0xffff && (point & 0xfffe) != 0xfffe && point <= 0x10ffff; } public static string Replace(this string str, string oldValue, string newValue, StringComparison comparison) { var sb = new StringBuilder(); var previousIndex = 0; var index = str.IndexOf(oldValue, comparison); while (index != -1) { sb.Append(str.Substring(previousIndex, index - previousIndex)); sb.Append(newValue); index += oldValue.Length; previousIndex = index; index = str.IndexOf(oldValue, index, comparison); } sb.Append(str.Substring(previousIndex)); return sb.ToString(); } } } ================================================ FILE: source/KlocTools/Tools/SymbolicLinkType.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ namespace Klocman.Tools { public enum SymbolicLinkType { File = 0, Directory = 1 } } ================================================ FILE: source/KlocTools/Tools/WindowsTools.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Net.NetworkInformation; using System.Runtime.InteropServices; using System.Security.Principal; using System.Text; using System.Text.RegularExpressions; using System.Windows.Forms; using Klocman.Extensions; using Klocman.Native; using Microsoft.Win32; namespace Klocman.Tools { public static class WindowsTools { public static Version Windows10 => new(10, 0); public static Version Windows8P1 => new(6, 3); public static Version WindowsServer2012R2 => new(6, 3); public static Version Windows8 => new(6, 2); public static Version WindowsServer2012 => new(6, 2); public static Version Windows7 => new(6, 1); public static Version WindowsServer2008R2 => new(6, 1); public static Version WindowsServer2008 => new(6, 0); public static Version WindowsVista => new(6, 0); public static Version WindowsServer2003R2 => new(5, 2); public static Version WindowsServer2003 => new(5, 2); public static Version WindowsXp64 => new(5, 2); public static Version WindowsXp => new(5, 1); public static Version Windows2000 => new(5, 0); /// /// Check if .NET Framework v4 is available. Returns null if not installed, or highest installed version. /// /// If true, check for full version, otherwise check for client version. public static Version CheckNetFramework4Installed(bool full) { using (var ndpKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\")) { if (ndpKey == null) return null; var keys = ndpKey.GetSubKeyNames(); if (!keys.Contains("v4")) return null; using (var netKey = ndpKey.OpenSubKey("v4")) { if (netKey == null) return null; keys = netKey.GetSubKeyNames(); var subKeyName = full ? "Full" : "Client"; if (!keys.Contains(subKeyName)) return null; using (var subKey = netKey.OpenSubKey(subKeyName)) { if (subKey?.GetValue("Install", "")?.ToString() != "1") return null; var version = subKey.GetStringSafe("Version"); return string.IsNullOrEmpty(version) ? new Version(4, 0, 0) : new Version(version); } } } } /// /// Check if .NET Framework v3.5 is available. /// public static bool CheckNetFramework35Installed() { try { AppDomain.CurrentDomain.Load( "System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"); return true; } catch { return false; } } private static readonly string CplPath = Path.Combine(Environment.SystemDirectory, "control.exe"); private static readonly IEnumerable LibraryTypes = new[] { "DLL", "SYS" }; private static readonly IEnumerable SystemExecutableTypes = new[] { "BAT", "BIN", "CMD", "COM", "CPL", "EXE", "GADGET", "INF1", "INS", "INX", "ISU", "JOB", "JSE", "LNK", "MSC", "MSI", "MSP", "MST", "PAF", "PIF", "PS1", "REG", "RGS", "SCT", "SHB", "SHS", "U3P", "VB", "VBE", "VBS", "VBSCRIPT", "WS", "WSF" }; private static readonly IEnumerable ThirdPartyExecutableTypes = new[] { "0XE", "73K", "89K", "A6P", "AC", "ACC", "ACR", "ACTM", "AHK", "AIR", "APP", "ARSCRIPT", "AS", "ASB", "AWK", "AZW2", "BEAM", "BTM", "CEL", "CELX", "CHM", "COF", "CRT", "DEK", "DLD", "DMC", "DOCM", "DOTM", "DXL", "EAR", "EBM", "EBS", "EBS2", "ECF", "EHAM", "ELF", "ES", "EX4", "EXOPC", "EZS", "FAS", "FKY", "FPI", "FRS", "FXP", "GS", "HAM", "HMS", "HPF", "HTA", "IIM", "IPF", "ISP", "JAR", "JS", "JSX", "KIX", "LO", "LS", "MAM", "MCR", "MEL", "MPX", "MRC", "MS", "MS", "MXE", "NEXE", "OBS", "ORE", "OTM", "PEX", "PLX", "POTM", "PPAM", "PPSM", "PPTM", "PRC", "PVD", "PWC", "PYC", "PYO", "QPX", "RBX", "ROX", "RPJ", "S2A", "SBS", "SCA", "SCAR", "SCB", "SCR", "SCRIPT", "SMM", "SPR", "TCP", "THM", "TLB", "TMS", "UDF", "UPX", "URL", "VLX", "VPM", "WCM", "WIDGET", "WIZ", "WPK", "WPM", "XAP", "XBAP", "XLAM", "XLM", "XLSM", "XLTM", "XQT", "XYS", "ZL9" }; private static long _uniqueUserId; public static string DefaultValueName => string.Empty; public static string GetEnvironmentPath(CSIDL target) { var path = new StringBuilder(260); NativeMethods.SHGetSpecialFolderPath(IntPtr.Zero, path, (int)target, false); return path.ToString(); } /// /// Return 32 bit program files directory. /// public static string GetProgramFilesX86Path() { var result = Environment.GetEnvironmentVariable("ProgramFiles(x86)"); if (result.IsNotEmpty()) return result; return GetEnvironmentPath(CSIDL.CSIDL_PROGRAM_FILES); } /// /// Returns path of the system drive, for example C:\ /// public static string GetSystemDrive() { return Path.GetPathRoot(GetEnvironmentPath(CSIDL.CSIDL_WINDOWS)); } /// /// Returns name of the system drive, for example C: (without the slash) /// public static string GetSystemDriveName() { return Path.GetPathRoot(GetEnvironmentPath(CSIDL.CSIDL_WINDOWS))?.TrimEnd('\\', '/'); } /// /// Based on User Sid, not guaranteed to be unique, but should be good enough. /// public static long GetUniqueUserId() { if (_uniqueUserId == 0) { var digitsOnly = new Regex(@"[^\d]"); var parts = digitsOnly.Replace(GetUserSid().Value, " ") .Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); foreach (var part in parts) { _uniqueUserId += long.Parse(part); } } return _uniqueUserId; } public static SecurityIdentifier GetUserSid() { return WindowsIdentity.GetCurrent().User; } /// /// Returns executable paths of all installed web browsers /// public static string[] GetInstalledWebBrowsers() { // Check for built-in browsers that obviously don't have to conform to standards var results = new List(new[] { Path.Combine(GetProgramFilesX86Path(), @"Internet Explorer\iexplore.exe"), Path.Combine(GetEnvironmentPath(CSIDL.CSIDL_PROGRAM_FILES), @"Internet Explorer\iexplore.exe"), Path.Combine(GetEnvironmentPath(CSIDL.CSIDL_WINDOWS), @"SystemApps\Microsoft.MicrosoftEdge_8wekyb3d8bbwe\MicrosoftEdgeCP.exe"), Path.Combine(GetEnvironmentPath(CSIDL.CSIDL_WINDOWS), @"SystemApps\Microsoft.MicrosoftEdge_8wekyb3d8bbwe\MicrosoftEdge.exe") }.Where(File.Exists)); // Check for 3rd party browsers in standard reg keys foreach (var internetKeyName in new[] { @"SOFTWARE\Clients\StartMenuInternet", @"SOFTWARE\WOW6432Node\Clients\StartMenuInternet" }) { using (var key = Registry.LocalMachine.OpenSubKey(internetKeyName)) { if (key == null) continue; foreach (var registryKey in key.GetSubKeyNames()) { var subkey = registryKey + @"\shell\open\command"; try { using var commandKey = key.OpenSubKey(subkey); var path = commandKey?.GetStringSafe(null); if (path != null) results.Add(path.Trim('\"')); } catch (SystemException e) { // Most likey access denied, safe to ignore since these are not critical Console.WriteLine($@"Failed to open {key.Name}\{subkey} - {e}"); } } } } return results.Distinct((x, y) => x.Equals(y, StringComparison.InvariantCultureIgnoreCase)).ToArray(); } /// /// Check if the file can be executed. /// Only the string is compared, the path or file doesn't have to exist. /// /// Path containing the file name, it must contain the extension. The file doesn't have to exist. /// Should file types executed by third party applications be included? public static bool IsExectuable(string filename, bool onlySystemTypes) { return IsExectuable(filename, onlySystemTypes, false); } /// /// Check if the file can be executed and optionally if it's a library. /// Only the string is compared, the path or file doesn't have to exist. /// /// Path containing the file name, it must contain the extension. The file doesn't have to exist. /// Should file types executed by third party applications be included? /// Should library file types be included in the comparison? public static bool IsExectuable(string filename, bool onlySystemTypes, bool includeLibraries) { filename = filename.ExtendedTrimEndAny(new[] { "'", "\"" }, StringComparison.CurrentCultureIgnoreCase); if (includeLibraries && LibraryTypes.Any(x => filename.EndsWith(x, StringComparison.CurrentCultureIgnoreCase))) return true; if (SystemExecutableTypes.Any(x => filename.EndsWith(x, StringComparison.CurrentCultureIgnoreCase))) return true; if (!onlySystemTypes && ThirdPartyExecutableTypes.Any(x => filename.EndsWith(x, StringComparison.CurrentCultureIgnoreCase))) return true; return false; } /// /// Indicates whether any network connection is available /// Filter connections below a specified speed, as well as virtual network cards. /// /// /// true if a network connection is available; otherwise, false. /// public static bool IsNetworkAvailable() { return IsNetworkAvailable(0); } /// /// Indicates whether any network connection is available. /// Filter connections below a specified speed, as well as virtual network cards. /// /// The minimum speed required. Passing 0 will not filter connection using speed. /// /// true if a network connection is available; otherwise, false. /// public static bool IsNetworkAvailable(long minimumSpeed) { if (!NetworkInterface.GetIsNetworkAvailable()) return false; foreach (var ni in NetworkInterface.GetAllNetworkInterfaces()) { // discard because of standard reasons if ((ni.OperationalStatus != OperationalStatus.Up) || (ni.NetworkInterfaceType == NetworkInterfaceType.Loopback) || (ni.NetworkInterfaceType == NetworkInterfaceType.Tunnel)) continue; // this allow to filter modems, serial, etc. if (ni.Speed < minimumSpeed) continue; // discard virtual cards (virtual box, virtual pc, etc.) if ((ni.Description.Contains("virtual", StringComparison.OrdinalIgnoreCase)) || (ni.Name.Contains("virtual", StringComparison.OrdinalIgnoreCase))) continue; // discard "Microsoft Loopback Adapter", it will not show as NetworkInterfaceType.Loopback but as Ethernet Card. if (ni.Description.Equals("Microsoft Loopback Adapter", StringComparison.OrdinalIgnoreCase)) continue; return true; } return false; } /// /// Open target control panel applet and return immidiately. /// /// Failed to open control panel entry public static void OpenControlPanelApplet(ControlPanelCanonicalNames target) { try { new ProcessStartInfo(CplPath, "/name Microsoft." + target) { UseShellExecute = true }.Start(); } catch (Exception ex) { throw new IOException("Failed to open control panel entry", ex); } } /// The value of 'objectPath' cannot be null. /// Failed to start explorer. public static void OpenExplorerFocusedOnObject(string objectPath) { if (objectPath == null) { throw new ArgumentNullException(nameof(objectPath)); } try { new ProcessStartInfo("explorer.exe", string.Format("/select,\"{0}\"", objectPath)).Start(); } catch (ArgumentNullException) { throw; } catch (Exception e) { throw new IOException(e.Message, e); } } public static string ResolveShortcut(string filename) { var link = new NativeMethods.ShellLink(); // ReSharper disable once SuspiciousTypeConversion.Global ((NativeMethods.IPersistFile)link).Load(filename, NativeMethods.STGM_READ); var sb = new StringBuilder(NativeMethods.MAX_PATH); var data = new NativeMethods.WIN32_FIND_DATAW(); // ReSharper disable once SuspiciousTypeConversion.Global ((NativeMethods.IShellLinkW)link).GetPath(sb, sb.Capacity, ref data, 0); return sb.ToString(); } /// /// Flash a window to indicate a need of attention /// public static bool FlashWindowEx(Form form) { var hWnd = form.Handle; var fInfo = new NativeMethods.FLASHWINFO(); fInfo.cbSize = Convert.ToUInt32(Marshal.SizeOf(fInfo)); fInfo.hwnd = hWnd; if (!form.Focused) { fInfo.dwFlags = NativeMethods.FLASHW_ALL | NativeMethods.FLASHW_TIMERNOFG; fInfo.uCount = uint.MaxValue; fInfo.dwTimeout = 0; } else { fInfo.dwFlags = NativeMethods.FLASHW_ALL | NativeMethods.FLASHW_TIMER; fInfo.uCount = 3; fInfo.dwTimeout = 0; } return NativeMethods.FlashWindowEx(ref fInfo); } private static class NativeMethods { [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool FlashWindowEx(ref FLASHWINFO pwfi); [StructLayout(LayoutKind.Sequential)] internal struct FLASHWINFO { /// /// The size of the structure in bytes. /// public uint cbSize; /// /// A Handle to the Window to be Flashed. The window can be either opened or minimized. /// public IntPtr hwnd; /// /// The Flash Status. /// public uint dwFlags; /// /// The number of times to Flash the window. /// public uint uCount; /// /// The rate at which the Window is to be flashed, in milliseconds. If Zero, the function uses the default cursor blink rate. /// public uint dwTimeout; } /// /// Stop flashing. The system restores the window to its original stae. /// internal const uint FLASHW_STOP = 0; /// /// Flash the window caption. /// internal const uint FLASHW_CAPTION = 1; /// /// Flash the taskbar button. /// internal const uint FLASHW_TRAY = 2; /// /// Flash both the window caption and taskbar button. /// This is equivalent to setting the FLASHW_CAPTION | FLASHW_TRAY flags. /// internal const uint FLASHW_ALL = 3; /// /// Flash continuously, until the FLASHW_STOP flag is set. /// internal const uint FLASHW_TIMER = 4; /// /// Flash continuously until the window comes to the foreground. /// internal const uint FLASHW_TIMERNOFG = 12; internal const uint STGM_READ = 0; internal const int MAX_PATH = 260; //public const int CSIDL_COMMON_STARTMENU = 0x16; // All Users\Start Menu [DllImport("shell32.dll", CharSet = CharSet.Unicode)] internal static extern bool SHGetSpecialFolderPath(IntPtr hwndOwner, [Out] StringBuilder lpszPath, int nFolder, bool fCreate); /* [DllImport("shfolder.dll", CharSet = CharSet.Auto)] internal static extern int SHGetFolderPath(IntPtr hwndOwner, int nFolder, IntPtr hToken, int dwFlags, StringBuilder lpszPath); */ [Flags] internal enum SLGP_FLAGS { /// Retrieves the standard short (8.3 format) file name SLGP_SHORTPATH = 0x1, /// Retrieves the Universal Naming Convention (UNC) path name of the file SLGP_UNCPRIORITY = 0x2, /// /// Retrieves the raw path name. A raw path is something that might not exist and may include environment /// variables that need to be expanded /// SLGP_RAWPATH = 0x4 } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] internal struct WIN32_FIND_DATAW { public readonly uint dwFileAttributes; public readonly long ftCreationTime; public readonly long ftLastAccessTime; public readonly long ftLastWriteTime; public readonly uint nFileSizeHigh; public readonly uint nFileSizeLow; public readonly uint dwReserved0; public readonly uint dwReserved1; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public readonly string cFileName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)] public readonly string cAlternateFileName; } [Flags] internal enum SLR_FLAGS { /// /// Do not display a dialog box if the link cannot be resolved. When SLR_NO_UI is set, /// the high-order word of fFlags can be set to a time-out value that specifies the /// maximum amount of time to be spent resolving the link. The function returns if the /// link cannot be resolved within the time-out duration. If the high-order word is set /// to zero, the time-out duration will be set to the default value of 3,000 milliseconds /// (3 seconds). To specify a value, set the high word of fFlags to the desired time-out /// duration, in milliseconds. /// SLR_NO_UI = 0x1, /// Obsolete and no longer used SLR_ANY_MATCH = 0x2, /// /// If the link object has changed, update its path and list of identifiers. /// If SLR_UPDATE is set, you do not need to call IPersistFile::IsDirty to determine /// whether or not the link object has changed. /// SLR_UPDATE = 0x4, /// Do not update the link information SLR_NOUPDATE = 0x8, /// Do not execute the search heuristics SLR_NOSEARCH = 0x10, /// Do not use distributed link tracking SLR_NOTRACK = 0x20, /// /// Disable distributed link tracking. By default, distributed link tracking tracks /// removable media across multiple devices based on the volume name. It also uses the /// Universal Naming Convention (UNC) path to track remote file systems whose drive letter /// has changed. Setting SLR_NOLINKINFO disables both types of tracking. /// SLR_NOLINKINFO = 0x40, /// Call the Microsoft Windows Installer SLR_INVOKE_MSI = 0x80 } /// The IShellLink interface allows Shell links to be created, modified, and resolved [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("000214F9-0000-0000-C000-000000000046")] internal interface IShellLinkW { /// Retrieves the path and file name of a Shell link object void GetPath([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile, int cchMaxPath, ref WIN32_FIND_DATAW pfd, SLGP_FLAGS fFlags); /// Retrieves the list of item identifiers for a Shell link object void GetIDList(out IntPtr ppidl); /// Sets the pointer to an item identifier list (PIDL) for a Shell link object. void SetIDList(IntPtr pidl); /// Retrieves the description string for a Shell link object void GetDescription([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszName, int cchMaxName); /// Sets the description for a Shell link object. The description can be any application-defined string void SetDescription([MarshalAs(UnmanagedType.LPWStr)] string pszName); /// Retrieves the name of the working directory for a Shell link object void GetWorkingDirectory([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszDir, int cchMaxPath); /// Sets the name of the working directory for a Shell link object void SetWorkingDirectory([MarshalAs(UnmanagedType.LPWStr)] string pszDir); /// Retrieves the command-line arguments associated with a Shell link object void GetArguments([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszArgs, int cchMaxPath); /// Sets the command-line arguments for a Shell link object void SetArguments([MarshalAs(UnmanagedType.LPWStr)] string pszArgs); /// Retrieves the hot key for a Shell link object void GetHotkey(out short pwHotkey); /// Sets a hot key for a Shell link object void SetHotkey(short wHotkey); /// Retrieves the show command for a Shell link object void GetShowCmd(out int piShowCmd); /// Sets the show command for a Shell link object. The show command sets the initial show state of the window. void SetShowCmd(int iShowCmd); /// Retrieves the location (path and index) of the icon for a Shell link object void GetIconLocation([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszIconPath, int cchIconPath, out int piIcon); /// Sets the location (path and index) of the icon for a Shell link object void SetIconLocation([MarshalAs(UnmanagedType.LPWStr)] string pszIconPath, int iIcon); /// Sets the relative path to the Shell link object void SetRelativePath([MarshalAs(UnmanagedType.LPWStr)] string pszPathRel, int dwReserved); /// Attempts to find the target of a Shell link, even if it has been moved or renamed void Resolve(IntPtr hwnd, SLR_FLAGS fFlags); /// Sets the path and file name of a Shell link object void SetPath([MarshalAs(UnmanagedType.LPWStr)] string pszFile); } [ComImport, Guid("0000010c-0000-0000-c000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] internal interface IPersist { [PreserveSig] void GetClassID(out Guid pClassID); } [ComImport, Guid("0000010b-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] internal interface IPersistFile : IPersist { new void GetClassID(out Guid pClassID); [PreserveSig] int IsDirty(); [PreserveSig] void Load([In, MarshalAs(UnmanagedType.LPWStr)] string pszFileName, uint dwMode); [PreserveSig] void Save([In, MarshalAs(UnmanagedType.LPWStr)] string pszFileName, [In, MarshalAs(UnmanagedType.Bool)] bool fRemember); [PreserveSig] void SaveCompleted([In, MarshalAs(UnmanagedType.LPWStr)] string pszFileName); [PreserveSig] void GetCurFile([In, MarshalAs(UnmanagedType.LPWStr)] string ppszFileName); } // CLSID_ShellLink from ShlGuid.h [ ComImport, Guid("00021401-0000-0000-C000-000000000046") ] internal class ShellLink { } } } } ================================================ FILE: source/KlocTools/YesNoAsk.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using Klocman.Localising; using Klocman.Properties; namespace Klocman { public enum YesNoAsk { [LocalisedName(typeof (Localisation), nameof(Localisation.Enums_YesNoAsk_Ask))] Ask = 0, [LocalisedName(typeof (Localisation), nameof(Localisation.Yes))] Yes, [LocalisedName(typeof (Localisation), nameof(Localisation.No))] No } } ================================================ FILE: source/Licence.licenseheader ================================================ extensions: designer.cs generated.cs extensions: .cs .cpp .h /* Copyright (c) 2026 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ extensions: .aspx .ascx <%-- Copyright (c) 2026 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 --%> extensions: .xml .config .xsd ================================================ FILE: source/NBug_custom/Core/Reporting/BugReport.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- using System; using System.IO; using System.Xml.Serialization; using NBug.Core.Reporting.Info; using NBug.Core.Reporting.MiniDump; using NBug.Core.UI; using NBug.Core.Util; using NBug.Core.Util.Logging; using NBug.Core.Util.Serialization; using NBug.Core.Util.Storage; namespace NBug.Core.Reporting { internal class BugReport { /// /// First parameters is the serializable exception object that is about to be processed, second parameter is any custom /// data /// object that the user wants to include in the report. /// internal static event Action ProcessingException; internal ExecutionFlow Report(Exception exception, ExceptionThread exceptionThread) { try { Logger.Trace("Starting to generate a bug report for the exception."); var serializableException = new SerializableException(exception); var report = new Report(serializableException); var handler = ProcessingException; if (handler != null) { Logger.Trace("Notifying the user before handling the exception."); // Allowing user to add any custom information to the report handler(exception, report); } var uiDialogResult = UISelector.DisplayBugReportUI(exceptionThread, serializableException, report); if (uiDialogResult.Report == SendReport.Send) { CreateReportZip(serializableException, report); } return uiDialogResult.Execution; } catch (Exception ex) { Logger.Error( "An exception occurred during bug report generation process. See the inner exception for details.", ex); return ExecutionFlow.BreakExecution; // Since an internal exception occured } } private void AddAdditionalFiles(ZipStorer zipStorer) { foreach (var mask in Settings.AdditionalReportFiles) { // Join before spliting because the mask may have some folders inside it var fullPath = Path.Combine(Settings.NBugDirectory, mask); var dir = Path.GetDirectoryName(fullPath); var file = Path.GetFileName(fullPath); if (!Directory.Exists(dir)) { continue; } if (file.Contains("*") || file.Contains("?")) { foreach (var item in Directory.GetFiles(dir!, file)) { AddToZip(zipStorer, Settings.NBugDirectory, item); } } else { AddToZip(zipStorer, Settings.NBugDirectory, fullPath); } } } private void AddToZip(ZipStorer zipStorer, string basePath, string path) { path = Path.GetFullPath(path); // If this is not inside basePath, lets change the basePath so at least some directories are kept if (!path.StartsWith(basePath)) { basePath = Path.GetDirectoryName(path); } if (Directory.Exists(path)) { foreach (var file in Directory.GetFiles(path)) { AddToZip(zipStorer, basePath, file); } foreach (var dir in Directory.GetDirectories(path)) { AddToZip(zipStorer, basePath, dir); } } else if (File.Exists(path)) { var nameInZip = path.Substring(basePath.Length); if (nameInZip.StartsWith("\\") || nameInZip.StartsWith("/")) { nameInZip = nameInZip.Substring(1); } nameInZip = Path.Combine("files", nameInZip); zipStorer.AddFile(ZipStorer.Compression.Deflate, path, nameInZip, string.Empty); } } private void CreateReportZip(SerializableException serializableException, Report report) { // Test if it has NOT been more than x many days since entry assembly was last modified) if (Settings.StopReportingAfter < 0 || File.GetLastWriteTime(Settings.EntryAssembly.Location) .AddDays(Settings.StopReportingAfter) .CompareTo(DateTime.Now) > 0) { // Test if there is already more than enough queued report files if (Settings.MaxQueuedReports < 0 || Storer.GetReportCount() < Settings.MaxQueuedReports) { var reportFileName = "Exception_" + DateTime.UtcNow.ToFileTime() + ".zip"; var minidumpFilePath = Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "Exception_MiniDump_" + DateTime.UtcNow.ToFileTime() + ".mdmp"); using (var storer = new Storer()) using (var zipStorer = ZipStorer.Create(storer.CreateReportFile(reportFileName), string.Empty)) using (var stream = new MemoryStream()) { // Store the exception var serializer = XmlSerializer.FromTypes(new[] {typeof (SerializableException)})[0]; //var serializer = new XmlSerializer(typeof(SerializableException)); serializer.Serialize(stream, serializableException); stream.Position = 0; zipStorer.AddStream(ZipStorer.Compression.Deflate, StoredItemFile.Exception, stream, DateTime.UtcNow, string.Empty); // Store the report stream.SetLength(0); try { serializer = report.CustomInfo != null ? new XmlSerializer(typeof (Report), new[] {report.CustomInfo.GetType()}) : new XmlSerializer(typeof (Report)); serializer.Serialize(stream, report); } catch (Exception exception) { Logger.Error( string.Format( "The given custom info of type [{0}] cannot be serialized. Make sure that given type and inner types are XML serializable.", report.CustomInfo.GetType()), exception); report.CustomInfo = null; serializer = new XmlSerializer(typeof (Report)); serializer.Serialize(stream, report); } stream.Position = 0; zipStorer.AddStream(ZipStorer.Compression.Deflate, StoredItemFile.Report, stream, DateTime.UtcNow, string.Empty); // Add the memory minidump to the report file (only if configured so) if (DumpWriter.Write(minidumpFilePath)) { zipStorer.AddFile(ZipStorer.Compression.Deflate, minidumpFilePath, StoredItemFile.MiniDump, string.Empty); File.Delete(minidumpFilePath); } // Add any user supplied files in the report (if any) if (Settings.AdditionalReportFiles.Count != 0) { AddAdditionalFiles(zipStorer); } } Logger.Trace( "Created a new report file. Currently the number of report files queued to be send is: " + Storer.GetReportCount()); } else { Logger.Trace( "Current report count is at its limit as per 'Settings.MaxQueuedReports (" + Settings.MaxQueuedReports + ")' setting: Skipping bug report generation."); } } else { Logger.Trace( "As per setting 'Settings.StopReportingAfter(" + Settings.StopReportingAfter + ")', bug reporting feature was enabled for a certain amount of time which has now expired: Bug reporting is now disabled."); if (Storer.GetReportCount() > 0) { Logger.Trace( "As per setting 'Settings.StopReportingAfter(" + Settings.StopReportingAfter + ")', bug reporting feature was enabled for a certain amount of time which has now expired: Truncating all expired bug reports."); Storer.TruncateReportFiles(0); } } } } } ================================================ FILE: source/NBug_custom/Core/Reporting/Feedback.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- using System; using NBug.Core.Reporting.Info; using NBug.Core.Util.Logging; namespace NBug.Core.Reporting { internal class Feedback { private Report report; internal Feedback() { try { report = new Report(null); } catch (Exception exception) { Logger.Error( "An exception occurred while sending a user feedback. See the inner exception for details.", exception); } } } } ================================================ FILE: source/NBug_custom/Core/Reporting/Info/AssemblyInfo.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- namespace NBug.Core.Reporting.Info { public class AssemblyInfo { } } ================================================ FILE: source/NBug_custom/Core/Reporting/Info/ConfigurationInfo.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- namespace NBug.Core.Reporting.Info { public class ConfigurationInfo { } } ================================================ FILE: source/NBug_custom/Core/Reporting/Info/GeneralInfo.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- using System; using System.Diagnostics; using System.Globalization; using System.Reflection; using NBug.Core.Util.Serialization; namespace NBug.Core.Reporting.Info { [Serializable] public class GeneralInfo { /// /// Initializes a new instance of the class. This is the default constructor provided for /// XML /// serialization and de-serialization. /// public GeneralInfo() { } internal GeneralInfo(SerializableException serializableException) { // this.HostApplication = Settings.EntryAssembly.GetName().Name; // Does not get the extensions of the file! HostApplication = Settings.EntryAssembly.GetLoadedModules()[0].Name; // this.HostApplicationVersion = Settings.EntryAssembly.GetName().Version.ToString(); // Gets AssemblyVersion not AssemblyFileVersion HostApplicationVersion = NBugVersion = FileVersionInfo.GetVersionInfo(Settings.EntryAssembly.Location).FileVersion; // this.NBugVersion = System.Reflection.Assembly.GetCallingAssembly().GetName().Version.ToString(); // Gets AssemblyVersion not AssemblyFileVersion NBugVersion = FileVersionInfo.GetVersionInfo(Assembly.GetCallingAssembly().Location).FileVersion; CLRVersion = Environment.Version.ToString(); DateTime = System.DateTime.UtcNow.ToString(CultureInfo.InvariantCulture); if (serializableException != null) { ExceptionType = serializableException.Type; if (!string.IsNullOrEmpty(serializableException.TargetSite)) { TargetSite = serializableException.TargetSite; } else if (serializableException.InnerException != null && !string.IsNullOrEmpty(serializableException.InnerException.TargetSite)) { TargetSite = serializableException.InnerException.TargetSite; } ExceptionMessage = serializableException.Message; } } public string CLRVersion { get; set; } public string DateTime { get; set; } public string ExceptionMessage { get; set; } public string ExceptionType { get; set; } public string HostApplication { get; set; } /// /// Gets or sets AssemblyFileVersion of host assembly. /// public string HostApplicationVersion { get; set; } /// /// Gets or sets AssemblyFileVersion of NBug.dll assembly. /// public string NBugVersion { get; set; } public string TargetSite { get; set; } public string UserDescription { get; set; } } } ================================================ FILE: source/NBug_custom/Core/Reporting/Info/Report.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- using System; using System.IO; using System.Xml; using System.Xml.Linq; using System.Xml.Serialization; using NBug.Core.Util.Serialization; namespace NBug.Core.Reporting.Info { [Serializable] public class Report { /// /// Initializes a new instance of the class to be filled with information later on. /// public Report() { } internal Report(SerializableException serializableException) { GeneralInfo = new GeneralInfo(serializableException); } /// /// Gets or sets a custom object property to store user supplied information in the bug report. You need to handle /// event to fill this property with required information. /// public object CustomInfo { get; set; } /// /// Gets or sets the general information about the exception and the system to be presented in the bug report. /// public GeneralInfo GeneralInfo { get; set; } /*/// /// Gets or sets a custom object property to store user supplied information in the bug report. You need to handle /// event to fill this property with required information. /// public object StaticInfo { get; set; }*/ public override string ToString() { var serializer = CustomInfo != null ? new XmlSerializer(typeof (Report), new[] {CustomInfo.GetType()}) : new XmlSerializer(typeof (Report)); using (var stream = new MemoryStream()) { stream.SetLength(0); serializer.Serialize(stream, this); stream.Position = 0; var doc = XDocument.Load(XmlReader.Create(stream)); return doc.Root.ToString(); } } } } ================================================ FILE: source/NBug_custom/Core/Reporting/Info/SystemInfo.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- namespace NBug.Core.Reporting.Info { public class SystemInfo { } } ================================================ FILE: source/NBug_custom/Core/Reporting/MiniDump/DumpTypeFlag.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- using System; namespace NBug.Core.Reporting.MiniDump { [Flags] internal enum DumpTypeFlag : uint { // From dbghelp.h: Normal = 0x00000000, WithDataSegs = 0x00000001, WithFullMemory = 0x00000002, WithHandleData = 0x00000004, FilterMemory = 0x00000008, ScanMemory = 0x00000010, WithUnloadedModules = 0x00000020, WithIndirectlyReferencedMemory = 0x00000040, FilterModulePaths = 0x00000080, WithProcessThreadData = 0x00000100, WithPrivateReadWriteMemory = 0x00000200, WithoutOptionalData = 0x00000400, WithFullMemoryInfo = 0x00000800, WithThreadInfo = 0x00001000, WithCodeSegs = 0x00002000, WithoutAuxiliaryState = 0x00004000, WithFullAuxiliaryState = 0x00008000, WithPrivateWriteCopyMemory = 0x00010000, IgnoreInaccessibleMemory = 0x00020000, ValidTypeFlags = 0x0003ffff } } ================================================ FILE: source/NBug_custom/Core/Reporting/MiniDump/DumpWriter.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- using System; using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; using NBug.Core.Util.Exceptions; using NBug.Core.Util.Logging; using NBug.Enums; namespace NBug.Core.Reporting.MiniDump { /// /// Sample usage: /// /// using (FileStream fs = new FileStream("minidump.mdmp", FileMode.Create, FileAccess.ReadWrite, FileShare.Write)) /// { /// DumpWriter.Write(fs.SafeFileHandle, DumpTypeFlag.WithDataSegs | DumpTypeFlag.WithHandleData); /// } /// /// /// Code snippet is from http://blogs.msdn.com/b/dondu/archive/2010/10/24/writing-minidumps-in-c.aspx internal static class DumpWriter { /// /// Creates a new memory dump and writes it to the specified file (only if Settings.MiniDumpType != MiniDumpType.None). /// /// The minidump file path. Overwritten if exists. /// True if Settings.MiniDumpType settings is set to anything else then MiniDumpType.None. internal static bool Write(string minidumpFilePath) { if (Settings.MiniDumpType != MiniDumpType.None) { bool created; using (var fileStream = new FileStream(minidumpFilePath, FileMode.Create, FileAccess.Write)) { created = Write(fileStream.SafeFileHandle, Settings.MiniDumpType.ToString()); } if (created) { return true; } File.Delete(minidumpFilePath); return false; } return false; } [DllImport("kernel32.dll", EntryPoint = "GetCurrentThreadId", ExactSpelling = true, SetLastError = true)] private static extern uint GetCurrentThreadId(); [DllImport("dbghelp.dll", EntryPoint = "MiniDumpWriteDump", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)] private static extern bool MiniDumpWriteDump( IntPtr hProcess, uint processId, SafeHandle hFile, uint dumpType, ref MiniDumpExceptionInformation expParam, IntPtr userStreamParam, IntPtr callbackParam); // Overload supporting MiniDumpExceptionInformation == NULL [DllImport("dbghelp.dll", EntryPoint = "MiniDumpWriteDump", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)] private static extern bool MiniDumpWriteDump( IntPtr hProcess, uint processId, SafeHandle hFile, uint dumpType, IntPtr expParam, IntPtr userStreamParam, IntPtr callbackParam); private static bool Write(SafeHandle fileHandle, string dumpType) { if (dumpType.ToLower() == MiniDumpType.Tiny.ToString().ToLower()) { return Write(fileHandle, DumpTypeFlag.WithIndirectlyReferencedMemory | DumpTypeFlag.ScanMemory); } if (dumpType.ToLower() == MiniDumpType.Normal.ToString().ToLower()) { return Write(fileHandle, DumpTypeFlag.Normal); } if (dumpType.ToLower() == MiniDumpType.Full.ToString().ToLower()) { return Write(fileHandle, DumpTypeFlag.WithFullMemory); } throw NBugConfigurationException.Create(() => Settings.MiniDumpType, "Parameter supplied for settings property is invalid."); } private static bool Write(SafeHandle fileHandle, DumpTypeFlag dumpTypeFlag) { var currentProcess = Process.GetCurrentProcess(); var currentProcessHandle = currentProcess.Handle; var currentProcessId = (uint) currentProcess.Id; MiniDumpExceptionInformation exp; exp.ThreadId = GetCurrentThreadId(); exp.ClientPointers = false; exp.ExceptionPointers = IntPtr.Zero; exp.ExceptionPointers = Marshal.GetExceptionPointers(); var bRet = false; try { if (exp.ExceptionPointers == IntPtr.Zero) { bRet = MiniDumpWriteDump(currentProcessHandle, currentProcessId, fileHandle, (uint) dumpTypeFlag, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); } else { bRet = MiniDumpWriteDump(currentProcessHandle, currentProcessId, fileHandle, (uint) dumpTypeFlag, ref exp, IntPtr.Zero, IntPtr.Zero); } } catch (DllNotFoundException) { Logger.Warning( "dbghelp.dll was not found inside the application folder, the system path or SDK folder. Minidump was not generated. If you are not planning on using the minidump feature, you can disable it with the Configurator tool."); return false; } if (!bRet) { Logger.Error( "Cannot write the minidump. MiniDumpWriteDump (dbghelp.dll) function returned error code: " + Marshal.GetLastWin32Error()); return false; } return true; } /* typedef struct _MINIDUMP_EXCEPTION_INFORMATION { * DWORD ThreadId; * PEXCEPTION_POINTERS ExceptionPointers; * BOOL ClientPointers; * } MINIDUMP_EXCEPTION_INFORMATION, *PMINIDUMP_EXCEPTION_INFORMATION; */ [StructLayout(LayoutKind.Sequential, Pack = 4)] // Pack=4 is important! So it works also for x64! private struct MiniDumpExceptionInformation { public uint ThreadId; public IntPtr ExceptionPointers; [MarshalAs(UnmanagedType.Bool)] public bool ClientPointers; } } } ================================================ FILE: source/NBug_custom/Core/Submission/Custom/Custom.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- using System.IO; using NBug.Core.Reporting.Info; using NBug.Core.Util.Serialization; using NBug.Events; namespace NBug.Core.Submission.Custom { public class CustomFactory : IProtocolFactory { public string SupportedType { get { return "Custom"; } } public IProtocol FromConnectionString(string connectionString) { return new Custom(connectionString); } } public class Custom : ProtocolBase { public Custom(string connectionString) : base(connectionString) { } public Custom() { } public override bool Send(string fileName, Stream file, Report report, SerializableException exception) { if (Settings.CustomSubmissionHandle == null) return false; var e = new CustomSubmissionEventArgs(fileName, file, report, exception); Settings.CustomSubmissionHandle.DynamicInvoke(this, e); return e.Result; } } } ================================================ FILE: source/NBug_custom/Core/Submission/Database/Ado.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- namespace NBug.Core.Submission.Database { internal class Ado { } } ================================================ FILE: source/NBug_custom/Core/Submission/Database/MsSql.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- namespace NBug.Core.Submission.Database { internal class MsSql { } } ================================================ FILE: source/NBug_custom/Core/Submission/Database/MySql.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- namespace NBug.Core.Submission.Database { internal class MySql { } } ================================================ FILE: source/NBug_custom/Core/Submission/Dispatcher.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- using System; using System.IO; using System.Threading; using System.Xml.Serialization; using NBug.Core.Reporting.Info; using NBug.Core.Util.Logging; using NBug.Core.Util.Serialization; using NBug.Core.Util.Storage; namespace NBug.Core.Submission { //using System.Threading.Tasks; internal class Dispatcher { /// /// Initializes a new instance of the Dispatcher class to send queued reports. /// /// /// Decides whether to start the dispatching process asynchronously on a background thread. /// internal Dispatcher(bool isAsynchronous) { // Test if it has NOT been more than x many days since entry assembly was last modified) // This is the exact verifier code in the BugReport.cs of CreateReportZip() function if (Settings.StopReportingAfter < 0 || File.GetLastWriteTime(Settings.EntryAssembly.Location) .AddDays(Settings.StopReportingAfter) .CompareTo(DateTime.Now) > 0) { if (isAsynchronous) { // Log and swallow NBug's internal exceptions by default new Thread(Dispatch).Start(); /* Task.Factory.StartNew(this.Dispatch) .ContinueWith( t => Logger.Error("An exception occurred while dispatching bug report. Check the inner exception for details", t.Exception), TaskContinuationOptions.OnlyOnFaulted);*/ } else { try { Dispatch(); } catch (Exception exception) { Logger.Error( "An exception occurred while dispatching bug report. Check the inner exception for details.", exception); } } } } private void Dispatch() { // Make sure that we are not interfering with the crucial startup work); if (!Settings.RemoveThreadSleep) { Thread.Sleep(Settings.SleepBeforeSend*1000); } // Truncate extra report files and try to send the first one in the queue Storer.TruncateReportFiles(); // Now go through configured destinations and submit to all automatically for (var hasReport = true; hasReport;) { using (var storer = new Storer()) using (var stream = storer.GetFirstReportFile()) { if (stream != null) { // Extract crash/exception report data from the zip file. Delete the zip file if no data can be retrieved (i.e. corrupt file) ExceptionData exceptionData; try { exceptionData = GetDataFromZip(stream); } catch (Exception exception) { storer.DeleteCurrentReportFile(); Logger.Error( "An exception occurred while extraction report data from zip file. Check the inner exception for details.", exception); return; } // Now submit the report file to all configured bug report submission targets if (EnumerateDestinations(stream, exceptionData) == false) { break; } // Delete the file after it was sent storer.DeleteCurrentReportFile(); } else { hasReport = false; } } } } /// /// Enumerate all protocols to see if they are properly configured and send using the ones that are configured /// as many times as necessary. /// /// The file to read the report from. /// /// Returns if the sending was successful. /// Returns if the report was submitted to at least one destination. /// private bool EnumerateDestinations(Stream reportFile, ExceptionData exceptionData) { var sentSuccessfullyAtLeastOnce = false; var fileName = Path.GetFileName(((FileStream) reportFile).Name); foreach (var destination in Settings.Destinations) { try { Logger.Trace(string.Format("Submitting bug report via {0}.", destination.GetType().Name)); if (destination.Send(fileName, reportFile, exceptionData.Report, exceptionData.Exception)) { sentSuccessfullyAtLeastOnce = true; } } catch (Exception exception) { Logger.Error( string.Format( "An exception occurred while submitting bug report with {0}. Check the inner exception for details.", destination.GetType().Name), exception); } } return sentSuccessfullyAtLeastOnce; } private ExceptionData GetDataFromZip(Stream stream) { var results = new ExceptionData(); var zipStorer = ZipStorer.Open(stream, FileAccess.Read); using (Stream zipItemStream = new MemoryStream()) { var zipDirectory = zipStorer.ReadCentralDir(); foreach (var entry in zipDirectory) { if (Path.GetFileName(entry.FilenameInZip) == StoredItemFile.Exception) { zipItemStream.SetLength(0); zipStorer.ExtractFile(entry, zipItemStream); zipItemStream.Position = 0; var deserializer = XmlSerializer.FromTypes(new[] {typeof (SerializableException)})[0]; //var deserializer = new XmlSerializer(typeof(SerializableException)); results.Exception = (SerializableException) deserializer.Deserialize(zipItemStream); zipItemStream.Position = 0; } else if (Path.GetFileName(entry.FilenameInZip) == StoredItemFile.Report) { zipItemStream.SetLength(0); zipStorer.ExtractFile(entry, zipItemStream); zipItemStream.Position = 0; var deserializer = XmlSerializer.FromTypes(new[] {typeof (Report)})[0]; //var deserializer = new XmlSerializer(typeof(Report)); results.Report = (Report) deserializer.Deserialize(zipItemStream); zipItemStream.Position = 0; } } } return results; } private class ExceptionData { public SerializableException Exception { get; set; } public Report Report { get; set; } } } } ================================================ FILE: source/NBug_custom/Core/Submission/IProtocol.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- using System.IO; using NBug.Core.Reporting.Info; using NBug.Core.Util.Serialization; namespace NBug.Core.Submission { /// /// Implement this to support sending data to a specific location. /// We recommend you base your implementation on ProtocolBase. /// public interface IProtocol { /// /// Connection string suitable for serialization. /// string ConnectionString { get; } /// /// Send the report file to the destination. /// /// Name of the file (e.g. "Exception_12345.zip") /// File stream /// Report /// /// True if report was sent successfully. bool Send(string fileName, Stream file, Report report, SerializableException exception); } } ================================================ FILE: source/NBug_custom/Core/Submission/IProtocolFactory.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- namespace NBug.Core.Submission { /// /// The protocol factory creates an IProtocol instance. /// This interface is to get around the fact that the IProtocol interface /// cannot be guaranteed to contain a constructor that takes a connection /// string. At the same time, we allow the protocol implementation to supply /// the name of its connection string Type parameter. /// The protocol factory is only used for protocols that originate as connection /// strings in a configuration file. /// Note! Your implementation of this class MUST HAVE a parameterless constructor. /// public interface IProtocolFactory { string SupportedType { get; } IProtocol FromConnectionString(string connectionString); } } ================================================ FILE: source/NBug_custom/Core/Submission/ProtocolBase.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- using System; using System.IO; using System.Linq; using System.Reflection; using NBug.Core.Reporting.Info; using NBug.Core.Util; using NBug.Core.Util.Serialization; namespace NBug.Core.Submission { public abstract class ProtocolBase : IProtocol { /// /// Initializes a new instance of the ProtocolBase class to be extended by derived types. /// /// Connection string to be parsed. protected ProtocolBase(string connectionString) { var fields = ConnectionStringParser.Parse(connectionString); var properties = GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public); foreach ( var property in properties.Where(property => property.Name != "Type" && fields.ContainsKey(property.Name))) { if (property.PropertyType == typeof (bool)) { property.SetValue(this, Convert.ToBoolean(fields[property.Name].Trim()), null); } else if (property.PropertyType == typeof (int)) { property.SetValue(this, Convert.ToInt32(fields[property.Name].Trim()), null); } else if (property.PropertyType.BaseType == typeof (Enum)) { property.SetValue(this, Enum.Parse(property.PropertyType, fields[property.Name]), null); } else { property.SetValue(this, fields[property.Name], null); } } } protected ProtocolBase() { } /// /// Gets serialized representation of the connection string. /// public string ConnectionString { get { var connectionString = string.Format("Type={0};", GetType().Name); var properties = GetType() .GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.SetProperty | BindingFlags.GetProperty) .Where(p => p.Name != "ConnectionString"); foreach (var property in properties) { var prop = property.GetValue(this, null); if (prop != null) { var val = prop.ToString(); if (!string.IsNullOrEmpty(val)) { // Escape = and ; characters connectionString += string.Format( "{0}={1};", property.Name.Replace(";", @"\;").Replace("=", @"\="), val.Replace(";", @"\;").Replace("=", @"\=")); } } } return connectionString; } } // Password field may contain the illegal ';' character so it is always the last field and isolated public abstract bool Send(string fileName, Stream file, Report report, SerializableException exception); internal string GetSettingsPasswordField(string connectionString) { return connectionString.Substring(connectionString.ToLower().IndexOf("password=", StringComparison.Ordinal) + 9) .Substring(0, connectionString.Substring(connectionString.ToLower().IndexOf("password=", StringComparison.Ordinal) + 9).Length - 1); } } } ================================================ FILE: source/NBug_custom/Core/Submission/Protocols.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2010 - 2011 Teoman Soygul. Licensed under LGPLv3 (http://www.gnu.org/licenses/lgpl.html). // // -------------------------------------------------------------------------------------------------------------------- namespace NBug.Core.Submission { // Actually enum names should be singular words! public enum Protocols { Mail, Redmine, BugNET, FTP, HTTP, AzureBlobStorage } } ================================================ FILE: source/NBug_custom/Core/Submission/Tracker/BugNet.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- using System.IO; using NBug.Core.Reporting.Info; using NBug.Core.Util.Serialization; namespace NBug.Core.Submission.Tracker { internal class BugNet : ProtocolBase { internal BugNet(string connectionString) : base(connectionString) { } internal BugNet() { } public override bool Send(string fileName, Stream file, Report report, SerializableException exception) { //HttpWebRequest request; //suppress unused Warning return true; } } } ================================================ FILE: source/NBug_custom/Core/Submission/Tracker/Bugzilla.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- namespace NBug.Core.Submission.Tracker { internal class Bugzilla { } } ================================================ FILE: source/NBug_custom/Core/Submission/Tracker/GitHub.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- namespace NBug.Core.Submission.Tracker { internal class GitHub { } } ================================================ FILE: source/NBug_custom/Core/Submission/Tracker/GoogleCode.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- namespace NBug.Core.Submission.Tracker { internal class GoogleCode { } } ================================================ FILE: source/NBug_custom/Core/Submission/Tracker/Mantis/AccountData.cs ================================================ using System; using System.Diagnostics; using System.Xml.Serialization; namespace NBug.Core.Submission.Tracker.Mantis { [Serializable, DebuggerStepThrough, SoapType(Namespace = "http://futureware.biz/mantisconnect")] public class AccountData { private string emailField; private string idField; private string nameField; private string real_nameField; [SoapElement(DataType = "integer")] public string id { get { return idField; } set { idField = value; } } public string name { get { return nameField; } set { nameField = value; } } public string real_name { get { return real_nameField; } set { real_nameField = value; } } public string email { get { return emailField; } set { emailField = value; } } } } ================================================ FILE: source/NBug_custom/Core/Submission/Tracker/Mantis/AttachmentData.cs ================================================ using System; using System.Xml.Serialization; namespace NBug.Core.Submission.Tracker.Mantis { [Serializable, SoapType(Namespace = "http://futureware.biz/mantisconnect")] public class AttachmentData { private string content_typeField; private DateTime date_submittedField; private bool date_submittedFieldSpecified; private string download_urlField; private string filenameField; private string idField; private string sizeField; private string user_idField; [SoapElement(DataType = "integer")] public string id { get { return idField; } set { idField = value; } } public string filename { get { return filenameField; } set { filenameField = value; } } [SoapElement(DataType = "integer")] public string size { get { return sizeField; } set { sizeField = value; } } public string content_type { get { return content_typeField; } set { content_typeField = value; } } public DateTime date_submitted { get { return date_submittedField; } set { date_submittedField = value; } } [SoapIgnore] public bool date_submittedSpecified { get { return date_submittedFieldSpecified; } set { date_submittedFieldSpecified = value; } } [SoapElement(DataType = "anyURI")] public string download_url { get { return download_urlField; } set { download_urlField = value; } } [SoapElement(DataType = "integer")] public string user_id { get { return user_idField; } set { user_idField = value; } } } } ================================================ FILE: source/NBug_custom/Core/Submission/Tracker/Mantis/CustomFieldValueForIssueData.cs ================================================ using System; using System.Xml.Serialization; namespace NBug.Core.Submission.Tracker.Mantis { [Serializable, SoapType(Namespace = "http://futureware.biz/mantisconnect")] public class CustomFieldValueForIssueData { private ObjectRef fieldField; private string valueField; public ObjectRef field { get { return fieldField; } set { fieldField = value; } } public string value { get { return valueField; } set { valueField = value; } } } } ================================================ FILE: source/NBug_custom/Core/Submission/Tracker/Mantis/IssueData.cs ================================================ using System; using System.Xml.Serialization; namespace NBug.Core.Submission.Tracker.Mantis { [Serializable, SoapType(Namespace = "http://futureware.biz/mantisconnect")] public class IssueData { private string additional_informationField; private AttachmentData[] attachmentsField; private string buildField; private string categoryField; private CustomFieldValueForIssueData[] custom_fieldsField; private DateTime date_submittedField; private bool date_submittedFieldSpecified; private string descriptionField; private DateTime due_dateField; private bool due_dateFieldSpecified; private ObjectRef etaField; private string fixed_in_versionField; private AccountData handlerField; private string idField; private DateTime last_updatedField; private bool last_updatedFieldSpecified; private AccountData[] monitorsField; private IssueNoteData[] notesField; private string os_buildField; private string osField; private string platformField; private ObjectRef priorityField; private ObjectRef projectField; private ObjectRef projectionField; private RelationshipData[] relationshipsField; private AccountData reporterField; private ObjectRef reproducibilityField; private ObjectRef resolutionField; private ObjectRef severityField; private string sponsorship_totalField; private ObjectRef statusField; private string steps_to_reproduceField; private bool stickyField; private bool stickyFieldSpecified; private string summaryField; private ObjectRef[] tagsField; private string target_versionField; private string versionField; private ObjectRef view_stateField; [SoapElement(DataType = "integer")] public string id { get { return idField; } set { idField = value; } } public ObjectRef view_state { get { return view_stateField; } set { view_stateField = value; } } public DateTime last_updated { get { return last_updatedField; } set { last_updatedField = value; } } [SoapIgnore] public bool last_updatedSpecified { get { return last_updatedFieldSpecified; } set { last_updatedFieldSpecified = value; } } public ObjectRef project { get { return projectField; } set { projectField = value; } } public string category { get { return categoryField; } set { categoryField = value; } } public ObjectRef priority { get { return priorityField; } set { priorityField = value; } } public ObjectRef severity { get { return severityField; } set { severityField = value; } } public ObjectRef status { get { return statusField; } set { statusField = value; } } public AccountData reporter { get { return reporterField; } set { reporterField = value; } } public string summary { get { return summaryField; } set { summaryField = value; } } public string version { get { return versionField; } set { versionField = value; } } public string build { get { return buildField; } set { buildField = value; } } public string platform { get { return platformField; } set { platformField = value; } } public string os { get { return osField; } set { osField = value; } } public string os_build { get { return os_buildField; } set { os_buildField = value; } } public ObjectRef reproducibility { get { return reproducibilityField; } set { reproducibilityField = value; } } public DateTime date_submitted { get { return date_submittedField; } set { date_submittedField = value; } } [SoapIgnore] public bool date_submittedSpecified { get { return date_submittedFieldSpecified; } set { date_submittedFieldSpecified = value; } } [SoapElement(DataType = "integer")] public string sponsorship_total { get { return sponsorship_totalField; } set { sponsorship_totalField = value; } } public AccountData handler { get { return handlerField; } set { handlerField = value; } } public ObjectRef projection { get { return projectionField; } set { projectionField = value; } } public ObjectRef eta { get { return etaField; } set { etaField = value; } } public ObjectRef resolution { get { return resolutionField; } set { resolutionField = value; } } public string fixed_in_version { get { return fixed_in_versionField; } set { fixed_in_versionField = value; } } public string target_version { get { return target_versionField; } set { target_versionField = value; } } public string description { get { return descriptionField; } set { descriptionField = value; } } public string steps_to_reproduce { get { return steps_to_reproduceField; } set { steps_to_reproduceField = value; } } public string additional_information { get { return additional_informationField; } set { additional_informationField = value; } } public AttachmentData[] attachments { get { return attachmentsField; } set { attachmentsField = value; } } public RelationshipData[] relationships { get { return relationshipsField; } set { relationshipsField = value; } } public IssueNoteData[] notes { get { return notesField; } set { notesField = value; } } public CustomFieldValueForIssueData[] custom_fields { get { return custom_fieldsField; } set { custom_fieldsField = value; } } public DateTime due_date { get { return due_dateField; } set { due_dateField = value; } } [SoapIgnore] public bool due_dateSpecified { get { return due_dateFieldSpecified; } set { due_dateFieldSpecified = value; } } public AccountData[] monitors { get { return monitorsField; } set { monitorsField = value; } } public bool sticky { get { return stickyField; } set { stickyField = value; } } [SoapIgnore] public bool stickySpecified { get { return stickyFieldSpecified; } set { stickyFieldSpecified = value; } } public ObjectRef[] tags { get { return tagsField; } set { tagsField = value; } } } } ================================================ FILE: source/NBug_custom/Core/Submission/Tracker/Mantis/IssueNoteData.cs ================================================ using System; using System.Xml.Serialization; namespace NBug.Core.Submission.Tracker.Mantis { [Serializable, SoapType(Namespace = "http://futureware.biz/mantisconnect")] public class IssueNoteData { private DateTime date_submittedField; private bool date_submittedFieldSpecified; private string idField; private DateTime last_modifiedField; private bool last_modifiedFieldSpecified; private string note_attrField; private string note_typeField; private AccountData reporterField; private string textField; private string time_trackingField; private ObjectRef view_stateField; [SoapElement(DataType = "integer")] public string id { get { return idField; } set { idField = value; } } public AccountData reporter { get { return reporterField; } set { reporterField = value; } } public string text { get { return textField; } set { textField = value; } } public ObjectRef view_state { get { return view_stateField; } set { view_stateField = value; } } public DateTime date_submitted { get { return date_submittedField; } set { date_submittedField = value; } } [SoapIgnore] public bool date_submittedSpecified { get { return date_submittedFieldSpecified; } set { date_submittedFieldSpecified = value; } } public DateTime last_modified { get { return last_modifiedField; } set { last_modifiedField = value; } } [SoapIgnore] public bool last_modifiedSpecified { get { return last_modifiedFieldSpecified; } set { last_modifiedFieldSpecified = value; } } [SoapElement(DataType = "integer")] public string time_tracking { get { return time_trackingField; } set { time_trackingField = value; } } [SoapElement(DataType = "integer")] public string note_type { get { return note_typeField; } set { note_typeField = value; } } public string note_attr { get { return note_attrField; } set { note_attrField = value; } } } } ================================================ FILE: source/NBug_custom/Core/Submission/Tracker/Mantis/ObjectRef.cs ================================================ using System; using System.Xml.Serialization; namespace NBug.Core.Submission.Tracker.Mantis { [Serializable, SoapType(Namespace = "http://futureware.biz/mantisconnect")] public class ObjectRef { private string idField; private string nameField; [SoapElement(DataType = "integer")] public string id { get { return idField; } set { idField = value; } } public string name { get { return nameField; } set { nameField = value; } } } } ================================================ FILE: source/NBug_custom/Core/Submission/Tracker/Mantis/ProjectVersionData.cs ================================================ using System; using System.Xml.Serialization; namespace NBug.Core.Submission.Tracker.Mantis { [Serializable, SoapType(Namespace = "http://futureware.biz/mantisconnect")] public class ProjectVersionData { private DateTime date_orderField; private bool date_orderFieldSpecified; private string descriptionField; private string idField; private string nameField; private bool obsoleteField; private bool obsoleteFieldSpecified; private string project_idField; private bool releasedField; private bool releasedFieldSpecified; [SoapElement(DataType = "integer")] public string id { get { return idField; } set { idField = value; } } public string name { get { return nameField; } set { nameField = value; } } [SoapElement(DataType = "integer")] public string project_id { get { return project_idField; } set { project_idField = value; } } public DateTime date_order { get { return date_orderField; } set { date_orderField = value; } } [SoapIgnore] public bool date_orderSpecified { get { return date_orderFieldSpecified; } set { date_orderFieldSpecified = value; } } public string description { get { return descriptionField; } set { descriptionField = value; } } public bool released { get { return releasedField; } set { releasedField = value; } } [SoapIgnore] public bool releasedSpecified { get { return releasedFieldSpecified; } set { releasedFieldSpecified = value; } } public bool obsolete { get { return obsoleteField; } set { obsoleteField = value; } } [SoapIgnore] public bool obsoleteSpecified { get { return obsoleteFieldSpecified; } set { obsoleteFieldSpecified = value; } } } } ================================================ FILE: source/NBug_custom/Core/Submission/Tracker/Mantis/RelationshipData.cs ================================================ using System; using System.Xml.Serialization; namespace NBug.Core.Submission.Tracker.Mantis { [Serializable, SoapType(Namespace = "http://futureware.biz/mantisconnect")] public class RelationshipData { private string idField; private string target_idField; private ObjectRef typeField; [SoapElement(DataType = "integer")] public string id { get { return idField; } set { idField = value; } } public ObjectRef type { get { return typeField; } set { typeField = value; } } [SoapElement(DataType = "integer")] public string target_id { get { return target_idField; } set { target_idField = value; } } } } ================================================ FILE: source/NBug_custom/Core/Submission/Tracker/Mantis/UserData.cs ================================================ using System; using System.Xml.Serialization; namespace NBug.Core.Submission.Tracker.Mantis { [Serializable, SoapType(Namespace = "http://futureware.biz/mantisconnect")] public class UserData { private string access_levelField; private AccountData account_dataField; private string timezoneField; public AccountData account_data { get { return account_dataField; } set { account_dataField = value; } } [SoapElement(DataType = "integer")] public string access_level { get { return access_levelField; } set { access_levelField = value; } } public string timezone { get { return timezoneField; } set { timezoneField = value; } } } } ================================================ FILE: source/NBug_custom/Core/Submission/Tracker/Mantis/nusoap.php.patch ================================================ --- nusoap.php.org 2013-11-12 14:04:05.000000000 +0100 +++ nusoap.php 2013-11-08 21:13:00.000000000 +0100 @@ -148,8 +148,8 @@ * @var string * @access public */ - var $soap_defencoding = 'ISO-8859-1'; - //var $soap_defencoding = 'UTF-8'; + //var $soap_defencoding = 'ISO-8859-1'; + var $soap_defencoding = 'UTF-8'; /** * namespaces in an array of prefix => uri @@ -1052,24 +1052,24 @@ * @return string The serialization of the fault instance. * @access public */ - function serialize(){ - $ns_string = ''; - foreach($this->namespaces as $k => $v){ - $ns_string .= "\n xmlns:$k=\"$v\""; - } - $return_msg = - 'soap_defencoding.'"?>'. - '\n". - ''. - ''. - $this->serialize_val($this->faultcode, 'faultcode'). - $this->serialize_val($this->faultactor, 'faultactor'). - $this->serialize_val($this->faultstring, 'faultstring'). - $this->serialize_val($this->faultdetail, 'detail'). - ''. - ''. - ''; - return $return_msg; + function serialize() { + $ns_string = ''; + foreach( $this->namespaces as $k => $v ) { + $ns_string .= "\n xmlns:$k=\"$v\""; + } + $return_msg = + 'soap_defencoding . '"?>' . + '\n" . + '' . + '' . + $this->serialize_val( $this->faultcode, 'faultcode' ) . + $this->serialize_val( $this->faultstring, 'faultstring' ) . + $this->serialize_val( $this->faultactor, 'faultactor' ) . + $this->serialize_val( $this->faultdetail, 'detail' ) . + '' . + '' . + ''; + return $return_msg; } } ================================================ FILE: source/NBug_custom/Core/Submission/Tracker/Redmine.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- using System; using System.IO; using System.Net; using System.Text; using System.Xml.Linq; using NBug.Core.Reporting.Info; using NBug.Core.Util.Logging; using NBug.Core.Util.Serialization; namespace NBug.Core.Submission.Tracker { public class RedmineFactory : IProtocolFactory { public string SupportedType { get { return "Redmine"; } } public IProtocol FromConnectionString(string connectionString) { return new Redmine(connectionString); } } public class Redmine : ProtocolBase { public Redmine(string connectionString) : base(connectionString) { } public Redmine() { } public string ApiKey { get; set; } public string AssignedToId { get; set; } public string AuthorId { get; set; } // Connection string format (single line) // Warning: There should be no semicolon (;) or equals sign (=) used in any field except for password // Note: Url should be a full url with a trailing slash (/), like: http://....../ /* Type=Redmine; * Url=http://tracker.mydomain.com/; * ProjectId=myproject; * TrackerId=; * PriorityId=; * CategoryId=; * CustomSubject=; * FixedVersionId=; * AssignedToId=; * ParentId=; * StatusId=; * AuthorId=; * ApiKey=myapikey; */ public string CategoryId { get; set; } public string CustomSubject { get; set; } public string FixedVersionId { get; set; } public string ParentId { get; set; } public string PriorityId { get; set; } public string ProjectId { get; set; } public string StatusId { get; set; } public string TrackerId { get; set; } public string Url { get; set; } public override bool Send(string fileName, Stream file, Report report, SerializableException exception) { HttpWebRequest request; if (string.IsNullOrEmpty(ApiKey)) { request = (HttpWebRequest) WebRequest.Create(new Uri(Url + "issues.xml")); } else { request = (HttpWebRequest) WebRequest.Create(new Uri(Url + "issues.xml?key=" + ApiKey)); } // Used POST as per http://www.redmine.org/projects/redmine/wiki/Rest_Issues#Creating-an-issue request.Method = "POST"; request.ContentType = "application/xml"; request.Accept = "application/xml"; request.ServicePoint.Expect100Continue = false; // Patch #11593. Some servers seem to have problem accepting the Expect: 100-continue header // Redmine v1.1.1 REST XML templates (* indicate required fields) // Note: <*_id> fields always ask for numeric values /* * * *Example * *myproject * * * * * * * * * * * * * * * * */ var subject = "NBug: " + report.GeneralInfo.HostApplication + " (" + report.GeneralInfo.HostApplicationVersion + "): " + report.GeneralInfo.ExceptionType + " @ " + report.GeneralInfo.TargetSite; var description = "
" + report + Environment.NewLine + Environment.NewLine + exception + "
"; var redmineRequestXml = new XElement("issue", new XElement("project_id", ProjectId)); if (!string.IsNullOrEmpty(TrackerId)) { redmineRequestXml.Add(new XElement("tracker_id", TrackerId)); } if (!string.IsNullOrEmpty(PriorityId)) { redmineRequestXml.Add(new XElement("priority_id", PriorityId)); } if (!string.IsNullOrEmpty(CategoryId)) { redmineRequestXml.Add(new XElement("category_id", CategoryId)); } // Add the subject and make sure that it is less than 255 characters or Redmine trows an HTTP error code 422 : Unprocessable Entity if (!string.IsNullOrEmpty(CustomSubject)) { var sbj = CustomSubject + " : " + subject; redmineRequestXml.Add(sbj.Length > 254 ? new XElement("subject", sbj.Substring(0, 254)) : new XElement("subject", sbj)); } else { redmineRequestXml.Add(subject.Length > 254 ? new XElement("subject", subject.Substring(0, 254)) : new XElement("subject", subject)); } if (!string.IsNullOrEmpty(description)) { redmineRequestXml.Add(new XElement("description", description)); } if (!string.IsNullOrEmpty(FixedVersionId)) { redmineRequestXml.Add(new XElement("fixed_version_id", FixedVersionId)); } if (!string.IsNullOrEmpty(AssignedToId)) { redmineRequestXml.Add(new XElement("assigned_to_id", AssignedToId)); } if (!string.IsNullOrEmpty(ParentId)) { redmineRequestXml.Add(new XElement("parent_id", ParentId)); } if (!string.IsNullOrEmpty(StatusId)) { redmineRequestXml.Add(new XElement("status_id", StatusId)); } if (!string.IsNullOrEmpty(AuthorId)) { redmineRequestXml.Add(new XElement("author_id", AuthorId)); } var bytes = Encoding.UTF8.GetBytes(redmineRequestXml.ToString()); request.ContentLength = bytes.Length; using (var putStream = request.GetRequestStream()) { putStream.Write(bytes, 0, bytes.Length); } // Log the response from Redmine RESTful service using (var response = (HttpWebResponse) request.GetResponse()) using (var reader = new StreamReader(response.GetResponseStream())) { Logger.Info("Response from Redmine Issue Tracker: " + reader.ReadToEnd()); } return true; } } } ================================================ FILE: source/NBug_custom/Core/Submission/Tracker/Trac.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- using System.IO; using NBug.Core.Reporting.Info; using NBug.Core.Util.Serialization; namespace NBug.Core.Submission.Tracker { internal class Trac : ProtocolBase { protected Trac(string connectionString) : base(connectionString) { } // Connection string format (single line) // Warning: There should be no semicolon (;) or equals sign (=) used in any field except for password // Warning: No fild value value should contain the phrase 'password=' // Warning: XML-RPC.NET assembly should be referenced // Note: Url should be a full url without a trailing slash (/), like: http://...... // Note: Anononymous URL is: http://trac-hacks.org/xmlrpc and authenticated URL is: http://trac-hacks.org/login/xmlrpc /* Type=Trac; * Url=http://tracker.mydomain.com/xmlrpc; */ public override bool Send(string fileName, Stream file, Report report, SerializableException exception) { return true; } } } ================================================ FILE: source/NBug_custom/Core/Submission/Web/Ftp.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- using System; using System.IO; using System.Net; using NBug.Core.Reporting.Info; using NBug.Core.Util.Logging; using NBug.Core.Util.Serialization; namespace NBug.Core.Submission.Web { public static class CompatibilityExtensions { // Only useful before .NET 4 public static void CopyTo(this Stream input, Stream output) { var buffer = new byte[16*1024]; // Fairly arbitrary size int bytesRead; while ((bytesRead = input.Read(buffer, 0, buffer.Length)) > 0) { output.Write(buffer, 0, bytesRead); } } } internal class FtpFactory : IProtocolFactory { public string SupportedType { get { return "Ftp"; } } public IProtocol FromConnectionString(string connectionString) { return new Ftp(connectionString); } } public class Ftp : ProtocolBase { public Ftp(string connectionString) : base(connectionString) { } public Ftp() { } public string Password { get; set; } // Connection string format (single line) // Warning: There should be no semicolon (;) or equals sign (=) used in any field except for password. // Warning: No fild value value should contain the phrase 'password=' // Note: Url should be a full url with a trailing slash (/), like: ftp://....../ /* Type=FTP; * Url=ftp://tracker.mydomain.com/myproject/; * UseSSL=false; * Username=; * Password=; */ public string Url { get; set; } public string Username { get; set; } public string Usessl { get; set; } public override bool Send(string fileName, Stream file, Report report, SerializableException exception) { var request = (FtpWebRequest) WebRequest.Create(new Uri(Url + fileName)); if (!string.IsNullOrEmpty(Usessl)) { request.EnableSsl = Convert.ToBoolean(Usessl.ToLower()); } if (!string.IsNullOrEmpty(Username)) { request.Credentials = new NetworkCredential(Username, Password); } request.Method = WebRequestMethods.Ftp.UploadFile; request.Proxy = null; // Otherwise we'll get an exception: The requested FTP command is not supported when a HTTP proxy is used using (var requestStream = request.GetRequestStream()) { file.Position = 0; file.CopyTo(requestStream); file.Position = 0; } using (var response = (FtpWebResponse) request.GetResponse()) using (var reader = new StreamReader(response.GetResponseStream() ?? throw new InvalidOperationException("GetResponseStream null"))) { var responseString = reader.ReadToEnd(); // Null on successful transfer if (!string.IsNullOrEmpty(responseString)) { Logger.Info("Response from FTP server: " + responseString); } Logger.Info("Response from FTP server: " + response.StatusDescription); } return true; } } } ================================================ FILE: source/NBug_custom/Core/Submission/Web/Http.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- using System.IO; using NBug.Core.Reporting.Info; using NBug.Core.Util.Logging; using NBug.Core.Util.Serialization; using NBug.Core.Util.Web; namespace NBug.Core.Submission.Web { public class HttpFactory : IProtocolFactory { public string SupportedType { get { return "Http"; } } public IProtocol FromConnectionString(string connectionString) { return new Http(connectionString); } } public class Http : ProtocolBase { public Http(string connectionString) : base(connectionString) { } public Http() { } // Connection string format (single line) // Warning: There should be no semicolon (;) or equals sign (=) used in any field. // Note: Url should be a full url with a trailing slash (/) or file extension (i.e. .php), like: http://....../ -or- http://....../upload.php /* Type=Http; * Url=http://tracker.mydomain.com/myproject/upload.php; */ public string Url { get; set; } public override bool Send(string fileName, Stream file, Report report, SerializableException exception) { // Advanced method with ability to post variables along with file (do not forget to urlencode the query parameters) // http://www.codeproject.com/KB/cs/uploadfileex.aspx // http://stackoverflow.com/questions/566462/upload-files-with-httpwebrequest-multipart-form-data // http://stackoverflow.com/questions/767790/how-do-i-upload-an-image-file-using-a-post-request-in-c // http://netomatix.com/HttpPostData.aspx /* upload.php file my look like the one below (note that uploaded files are not statically named in this case script may need modification) * * */ file.Position = 0; var response = StreamUpload.Create().Add(file, "file", fileName, "application/zip").Upload(Url).Response(); Logger.Info("Response from HTTP server: " + response); file.Position = 0; return true; } } } ================================================ FILE: source/NBug_custom/Core/Submission/Web/Mail.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- using System; using System.IO; using System.Net; using System.Net.Mail; using NBug.Core.Reporting.Info; using NBug.Core.Util.Logging; using NBug.Core.Util.Serialization; namespace NBug.Core.Submission.Web { public class MailFactory : IProtocolFactory { public string SupportedType { get { return "Mail"; } } public IProtocol FromConnectionString(string connectionString) { return new Mail(connectionString); } } public class Mail : ProtocolBase { public Mail(string connectionString) : base(connectionString) { } public Mail() { Port = 25; } // Connection string format (single line) // Warning: There should be no semicolon (;) or equals sign (=) used in any field except for password. // Warning: Password filed should be the last item. // Warning: No fild value value should contain the phrase 'password=' // Note: Normal ports may be 25/26 depending on the host! // Note: Priority can be High, Normal, Low (Normal by default). /* Type=Mail; * From=my_tracker@gmail.com; * FromName=NBug Error Reporter; * To=bugtracker@mycompany.com,someone@dummy.com,my_tracker@gmail.com; * Cc=; * Bcc=; * ReplyTo=; * UseAttachment=false; * CustomSubject=; * CustomBody=; * SmtpServer=smtp.gmail.com; * UseSSL=yes; * Port=465; * Priority=; * UseAuthentication=yes; * Username=my_tracker@gmail.com; * Password=mypassword; */ public string Bcc { get; set; } public string Cc { get; set; } public string CustomBody { get; set; } public string CustomSubject { get; set; } public string From { get; set; } public string FromName { get; set; } public string Password { get; set; } public int Port { get; set; } public MailPriority Priority { get; set; } public string ReplyTo { get; set; } public string SmtpServer { get; set; } public string To { get; set; } public bool UseAttachment { get; set; } public bool UseAuthentication { get; set; } public bool UseSsl { get; set; } public string Username { get; set; } public override bool Send(string fileName, Stream file, Report report, SerializableException exception) { if (string.IsNullOrEmpty(From) || string.IsNullOrEmpty(To)) { return false; } if (string.IsNullOrEmpty(ReplyTo)) { ReplyTo = From; } if (Port <= 0) { Port = UseSsl ? 465 : 25; } if (!UseAttachment) { UseAttachment = false; } // Make sure that we can use authentication even with emtpy username and password if (!string.IsNullOrEmpty(Username)) { UseAuthentication = true; } //using (var smtpClient = new SmtpClient()) using (var message = new MailMessage()) { var smtpClient = new SmtpClient(); if (!string.IsNullOrEmpty(SmtpServer)) { smtpClient.Host = SmtpServer; } smtpClient.Port = Port; if (UseAuthentication) { smtpClient.Credentials = new NetworkCredential(Username, Password); } smtpClient.EnableSsl = UseSsl; if (!string.IsNullOrEmpty(Cc)) { message.CC.Add(Cc); } if (!string.IsNullOrEmpty(Bcc)) { message.Bcc.Add(Bcc); } message.Priority = Priority; message.To.Add(To); message.ReplyToList.Add(new MailAddress(ReplyTo)); message.From = !string.IsNullOrEmpty(FromName) ? new MailAddress(From, FromName) : new MailAddress(From); if (UseAttachment) { file.Position = 0; message.Attachments.Add(new Attachment(file, fileName)); } if (!string.IsNullOrEmpty(CustomSubject)) { message.Subject = CustomSubject; } else { message.Subject = "NBug: " + report.GeneralInfo.HostApplication + " (" + report.GeneralInfo.HostApplicationVersion + "): " + report.GeneralInfo.ExceptionType + " @ " + report.GeneralInfo.TargetSite; } if (!string.IsNullOrEmpty(CustomBody)) { message.Body = CustomBody + Environment.NewLine + Environment.NewLine + report + Environment.NewLine + Environment.NewLine + exception; } else { message.Body = report + Environment.NewLine + Environment.NewLine + exception; } smtpClient.Send(message); Logger.Trace("Submitted bug report email to: " + To); return true; } } } } ================================================ FILE: source/NBug_custom/Core/UI/Console/ConsoleUI.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- using System; using NBug.Core.Reporting.Info; using NBug.Core.Util.Exceptions; using NBug.Core.Util.Serialization; using NBug.Enums; namespace NBug.Core.UI.Console { internal static class ConsoleUI { internal static UIDialogResult ShowDialog(UIMode uiMode, SerializableException exception, Report report) { if (uiMode == UIMode.Minimal) { // Do not interact with the user System.Console.WriteLine(Environment.NewLine + Settings.Resources.UI_Console_Minimal_Message); return new UIDialogResult(ExecutionFlow.BreakExecution, SendReport.Send); } if (uiMode == UIMode.Normal) { System.Console.WriteLine(Environment.NewLine + Settings.Resources.UI_Console_Normal_Message); return new UIDialogResult(ExecutionFlow.BreakExecution, SendReport.Send); } if (uiMode == UIMode.Full) { System.Console.WriteLine(Environment.NewLine + Settings.Resources.UI_Console_Full_Message); return new UIDialogResult(ExecutionFlow.BreakExecution, SendReport.Send); } throw NBugConfigurationException.Create(() => Settings.UIMode, "Parameter supplied for settings property is invalid."); } } } ================================================ FILE: source/NBug_custom/Core/UI/Custom/CustomUI.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- using NBug.Core.Reporting.Info; using NBug.Core.Util.Exceptions; using NBug.Core.Util.Serialization; using NBug.Enums; using NBug.Events; namespace NBug.Core.UI.Custom { /// /// This class is used to prevent statically referencing any WPF dlls from the UISelector.cs thus prevents /// any unnecessary assembly from getting loaded into the memory. /// internal static class CustomUI { internal static UIDialogResult ShowDialog(UIMode uiMode, SerializableException exception, Report report) { if (Settings.CustomUIHandle != null) { var e = new CustomUIEventArgs(uiMode, exception, report); Settings.CustomUIHandle.DynamicInvoke(null, e); return e.Result; } throw NBugConfigurationException.Create(() => Settings.UIMode, "Parameter supplied for settings property is invalid."); } } } ================================================ FILE: source/NBug_custom/Core/UI/Developer/InternalExceptionViewer.Designer.cs ================================================ namespace NBug.Core.UI.Developer { using NBug.Core.UI.WinForms.Panels; partial class InternalExceptionViewer { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.quitButton = new System.Windows.Forms.Button(); this.debugButton = new System.Windows.Forms.Button(); this.bugReportButton = new System.Windows.Forms.Button(); this.messageLabel = new System.Windows.Forms.Label(); this.topToolStrip = new System.Windows.Forms.ToolStrip(); this.documentationToolStripButton = new System.Windows.Forms.ToolStripButton(); this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); this.forumToolStripLabel = new System.Windows.Forms.ToolStripLabel(); this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); this.trackerToolStripLabel = new System.Windows.Forms.ToolStripLabel(); this.exceptionLabel = new System.Windows.Forms.Label(); this.exceptionTextBox = new System.Windows.Forms.TextBox(); this.invalidSettingLabel = new System.Windows.Forms.Label(); this.invalidSettingTextBox = new System.Windows.Forms.TextBox(); this.targetSiteTextBox = new System.Windows.Forms.TextBox(); this.targetSiteLabel = new System.Windows.Forms.Label(); this.exceptionMessageTextBox = new System.Windows.Forms.TextBox(); this.exceptionStackGroupBox = new System.Windows.Forms.GroupBox(); this.exceptionDetails = new NBug.Core.UI.WinForms.Panels.ExceptionDetails(); this.warningPictureBox = new System.Windows.Forms.PictureBox(); this.topToolStrip.SuspendLayout(); this.exceptionStackGroupBox.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.warningPictureBox)).BeginInit(); this.SuspendLayout(); // // quitButton // this.quitButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.quitButton.Location = new System.Drawing.Point(455, 511); this.quitButton.Name = "quitButton"; this.quitButton.Size = new System.Drawing.Size(75, 23); this.quitButton.TabIndex = 0; this.quitButton.Text = "&Quit"; this.quitButton.UseVisualStyleBackColor = true; this.quitButton.Click += new System.EventHandler(this.QuitButton_Click); // // debugButton // this.debugButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.debugButton.Image = global::NBug.Properties.Resources.VS2010_16; this.debugButton.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; this.debugButton.Location = new System.Drawing.Point(364, 511); this.debugButton.Name = "debugButton"; this.debugButton.Size = new System.Drawing.Size(85, 23); this.debugButton.TabIndex = 1; this.debugButton.Text = " &Debug"; this.debugButton.UseVisualStyleBackColor = true; this.debugButton.Click += new System.EventHandler(this.DebugButton_Click); // // bugReportButton // this.bugReportButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.bugReportButton.Enabled = false; this.bugReportButton.Image = global::NBug.Properties.Resources.Send; this.bugReportButton.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; this.bugReportButton.Location = new System.Drawing.Point(205, 511); this.bugReportButton.Name = "bugReportButton"; this.bugReportButton.Size = new System.Drawing.Size(128, 23); this.bugReportButton.TabIndex = 2; this.bugReportButton.Text = " &Send Bug Report"; this.bugReportButton.UseVisualStyleBackColor = true; this.bugReportButton.Click += new System.EventHandler(this.BugReportButton_Click); // // messageLabel // this.messageLabel.AutoSize = true; this.messageLabel.Location = new System.Drawing.Point(56, 38); this.messageLabel.MaximumSize = new System.Drawing.Size(465, 39); this.messageLabel.MinimumSize = new System.Drawing.Size(465, 39); this.messageLabel.Name = "messageLabel"; this.messageLabel.Size = new System.Drawing.Size(465, 39); this.messageLabel.TabIndex = 3; this.messageLabel.Text = "A configuration or runtime exception has occured."; // // topToolStrip // this.topToolStrip.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden; this.topToolStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.documentationToolStripButton, this.toolStripSeparator1, this.forumToolStripLabel, this.toolStripSeparator2, this.trackerToolStripLabel}); this.topToolStrip.Location = new System.Drawing.Point(0, 0); this.topToolStrip.Name = "topToolStrip"; this.topToolStrip.Size = new System.Drawing.Size(541, 25); this.topToolStrip.TabIndex = 5; // // documentationToolStripButton // this.documentationToolStripButton.Image = global::NBug.Properties.Resources.Help_16; this.documentationToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta; this.documentationToolStripButton.Name = "documentationToolStripButton"; this.documentationToolStripButton.Size = new System.Drawing.Size(148, 22); this.documentationToolStripButton.Tag = "http://www.nbusy.com/projects/nbug/documentation"; this.documentationToolStripButton.Text = "Online &Documentation"; this.documentationToolStripButton.Click += new System.EventHandler(this.DocumentationToolStripButton_Click); // // toolStripSeparator1 // this.toolStripSeparator1.Name = "toolStripSeparator1"; this.toolStripSeparator1.Size = new System.Drawing.Size(6, 25); // // forumToolStripLabel // this.forumToolStripLabel.Image = global::NBug.Properties.Resources.Forum_16; this.forumToolStripLabel.IsLink = true; this.forumToolStripLabel.Name = "forumToolStripLabel"; this.forumToolStripLabel.Size = new System.Drawing.Size(117, 22); this.forumToolStripLabel.Tag = "http://www.nbusy.com/forum/f11/"; this.forumToolStripLabel.Text = "Discussion Forum"; this.forumToolStripLabel.Click += new System.EventHandler(this.ForumToolStripLabel_Click); // // toolStripSeparator2 // this.toolStripSeparator2.Name = "toolStripSeparator2"; this.toolStripSeparator2.Size = new System.Drawing.Size(6, 25); // // trackerToolStripLabel // this.trackerToolStripLabel.Image = global::NBug.Properties.Resources.Error_16; this.trackerToolStripLabel.IsLink = true; this.trackerToolStripLabel.Name = "trackerToolStripLabel"; this.trackerToolStripLabel.Size = new System.Drawing.Size(86, 22); this.trackerToolStripLabel.Tag = "http://www.nbusy.com/tracker/projects/nbug"; this.trackerToolStripLabel.Text = "Bug Tracker"; this.trackerToolStripLabel.Click += new System.EventHandler(this.TrackerToolStripLabel_Click); // // exceptionLabel // this.exceptionLabel.AutoSize = true; this.exceptionLabel.Location = new System.Drawing.Point(11, 96); this.exceptionLabel.Name = "exceptionLabel"; this.exceptionLabel.Size = new System.Drawing.Size(57, 13); this.exceptionLabel.TabIndex = 6; this.exceptionLabel.Text = "Exception:"; // // exceptionTextBox // this.exceptionTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.exceptionTextBox.Location = new System.Drawing.Point(74, 93); this.exceptionTextBox.Name = "exceptionTextBox"; this.exceptionTextBox.Size = new System.Drawing.Size(226, 20); this.exceptionTextBox.TabIndex = 7; // // invalidSettingLabel // this.invalidSettingLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.invalidSettingLabel.AutoSize = true; this.invalidSettingLabel.Enabled = false; this.invalidSettingLabel.Location = new System.Drawing.Point(320, 96); this.invalidSettingLabel.Name = "invalidSettingLabel"; this.invalidSettingLabel.Size = new System.Drawing.Size(77, 13); this.invalidSettingLabel.TabIndex = 8; this.invalidSettingLabel.Text = "Invalid Setting:"; // // invalidSettingTextBox // this.invalidSettingTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.invalidSettingTextBox.Enabled = false; this.invalidSettingTextBox.Location = new System.Drawing.Point(403, 93); this.invalidSettingTextBox.Name = "invalidSettingTextBox"; this.invalidSettingTextBox.Size = new System.Drawing.Size(121, 20); this.invalidSettingTextBox.TabIndex = 9; // // targetSiteTextBox // this.targetSiteTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.targetSiteTextBox.Location = new System.Drawing.Point(74, 122); this.targetSiteTextBox.Name = "targetSiteTextBox"; this.targetSiteTextBox.Size = new System.Drawing.Size(450, 20); this.targetSiteTextBox.TabIndex = 11; // // targetSiteLabel // this.targetSiteLabel.AutoSize = true; this.targetSiteLabel.Location = new System.Drawing.Point(10, 125); this.targetSiteLabel.Name = "targetSiteLabel"; this.targetSiteLabel.Size = new System.Drawing.Size(62, 13); this.targetSiteLabel.TabIndex = 10; this.targetSiteLabel.Text = "Target Site:"; // // exceptionMessageTextBox // this.exceptionMessageTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.exceptionMessageTextBox.Location = new System.Drawing.Point(14, 151); this.exceptionMessageTextBox.Multiline = true; this.exceptionMessageTextBox.Name = "exceptionMessageTextBox"; this.exceptionMessageTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; this.exceptionMessageTextBox.Size = new System.Drawing.Size(510, 35); this.exceptionMessageTextBox.TabIndex = 12; // // exceptionStackGroupBox // this.exceptionStackGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.exceptionStackGroupBox.Controls.Add(this.exceptionDetails); this.exceptionStackGroupBox.Location = new System.Drawing.Point(14, 198); this.exceptionStackGroupBox.Name = "exceptionStackGroupBox"; this.exceptionStackGroupBox.Size = new System.Drawing.Size(516, 304); this.exceptionStackGroupBox.TabIndex = 13; this.exceptionStackGroupBox.TabStop = false; this.exceptionStackGroupBox.Text = "Full Exception Stack"; // // exceptionDetails // this.exceptionDetails.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.exceptionDetails.InformationColumnWidth = 350; this.exceptionDetails.Location = new System.Drawing.Point(6, 16); this.exceptionDetails.Name = "exceptionDetails"; this.exceptionDetails.PropertyColumnWidth = 144; this.exceptionDetails.Size = new System.Drawing.Size(504, 282); this.exceptionDetails.TabIndex = 0; // // warningPictureBox // this.warningPictureBox.Location = new System.Drawing.Point(13, 41); this.warningPictureBox.Name = "warningPictureBox"; this.warningPictureBox.Size = new System.Drawing.Size(32, 32); this.warningPictureBox.TabIndex = 14; this.warningPictureBox.TabStop = false; // // InternalExceptionViewer // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(541, 542); this.Controls.Add(this.quitButton); this.Controls.Add(this.bugReportButton); this.Controls.Add(this.warningPictureBox); this.Controls.Add(this.debugButton); this.Controls.Add(this.exceptionStackGroupBox); this.Controls.Add(this.exceptionMessageTextBox); this.Controls.Add(this.targetSiteTextBox); this.Controls.Add(this.messageLabel); this.Controls.Add(this.topToolStrip); this.Controls.Add(this.targetSiteLabel); this.Controls.Add(this.invalidSettingLabel); this.Controls.Add(this.exceptionLabel); this.Controls.Add(this.exceptionTextBox); this.Controls.Add(this.invalidSettingTextBox); this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "InternalExceptionViewer"; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; this.Text = "NBug Internal Exception Viewer"; this.TopMost = true; this.topToolStrip.ResumeLayout(false); this.topToolStrip.PerformLayout(); this.exceptionStackGroupBox.ResumeLayout(false); ((System.ComponentModel.ISupportInitialize)(this.warningPictureBox)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); } #endregion private System.Windows.Forms.Button quitButton; private System.Windows.Forms.Button debugButton; private System.Windows.Forms.Button bugReportButton; private System.Windows.Forms.Label messageLabel; private System.Windows.Forms.ToolStrip topToolStrip; private System.Windows.Forms.ToolStripButton documentationToolStripButton; private System.Windows.Forms.ToolStripLabel forumToolStripLabel; private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; private System.Windows.Forms.ToolStripSeparator toolStripSeparator2; private System.Windows.Forms.ToolStripLabel trackerToolStripLabel; private System.Windows.Forms.Label exceptionLabel; private System.Windows.Forms.TextBox exceptionTextBox; private System.Windows.Forms.Label invalidSettingLabel; private System.Windows.Forms.TextBox invalidSettingTextBox; private System.Windows.Forms.TextBox targetSiteTextBox; private System.Windows.Forms.Label targetSiteLabel; private System.Windows.Forms.TextBox exceptionMessageTextBox; private System.Windows.Forms.GroupBox exceptionStackGroupBox; private ExceptionDetails exceptionDetails; private System.Windows.Forms.PictureBox warningPictureBox; } } ================================================ FILE: source/NBug_custom/Core/UI/Developer/InternalExceptionViewer.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- using System; using System.Diagnostics; using System.Drawing; using System.Windows.Forms; using NBug.Core.Util.Exceptions; using NBug.Core.Util.Serialization; using NBug.Properties; namespace NBug.Core.UI.Developer { internal partial class InternalExceptionViewer : Form { internal InternalExceptionViewer() { InitializeComponent(); Icon = Resources.NBug_icon_16; warningPictureBox.Image = SystemIcons.Warning.ToBitmap(); } internal void ShowDialog(Exception exception) { if (exception is NBugConfigurationException) { ShowDialog(exception as NBugConfigurationException); } else if (exception is NBugRuntimeException) { ShowDialog(exception as NBugRuntimeException); } else { messageLabel.Text = "An internal runtime exception has occurred. This maybe due to a configuration failure or an internal bug. You may choose to debug the exception or send a bug report to NBug developers. You may also use discussion forum to get help."; bugReportButton.Enabled = true; DisplayExceptionDetails(exception); } } internal void ShowDialog(NBugConfigurationException configurationException) { messageLabel.Text = "An internal configuration exception has occurred. Please correct the invalid configuration regarding the information below. You may also use discussion forum to get help or read the online documentation's configuration section."; invalidSettingLabel.Enabled = true; invalidSettingTextBox.Enabled = true; invalidSettingTextBox.Text = configurationException.MisconfiguredProperty; DisplayExceptionDetails(configurationException); } internal void ShowDialog(NBugRuntimeException runtimeException) { messageLabel.Text = "An internal runtime exception has occurred. This maybe due to a configuration failure or an internal bug. You may choose to debug the exception or send a bug report to NBug developers. You may also use discussion forum to get help."; bugReportButton.Enabled = true; DisplayExceptionDetails(runtimeException); } private void BugReportButton_Click(object sender, EventArgs e) { MessageBox.Show( "Internal bug reporting feature is not implemented yet but you can still manually submit a bug report using the bug tracker.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information); bugReportButton.Enabled = false; } private void DebugButton_Click(object sender, EventArgs e) { // Let the exception propagate down to SEH Close(); } private void DisplayExceptionDetails(Exception exception) { exceptionTextBox.Text = exception.GetType().ToString(); exceptionMessageTextBox.Text = exception.Message; if (exception.TargetSite != null) { targetSiteTextBox.Text = exception.TargetSite.ToString(); } else if (exception.InnerException != null && exception.InnerException.TargetSite != null) { targetSiteTextBox.Text = exception.InnerException.TargetSite.ToString(); } exceptionDetails.Initialize(new SerializableException(exception)); ShowDialog(); } private void DocumentationToolStripButton_Click(object sender, EventArgs e) { Process.Start(documentationToolStripButton.Tag.ToString()); } private void ForumToolStripLabel_Click(object sender, EventArgs e) { Process.Start(forumToolStripLabel.Tag.ToString()); } private void QuitButton_Click(object sender, EventArgs e) { Environment.Exit(0); } private void TrackerToolStripLabel_Click(object sender, EventArgs e) { Process.Start(trackerToolStripLabel.Tag.ToString()); } } } ================================================ FILE: source/NBug_custom/Core/UI/Developer/InternalExceptionViewer.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 17, 11 49 ================================================ FILE: source/NBug_custom/Core/UI/Developer/InternalLogViewer.Designer.cs ================================================ namespace NBug.Core.UI.Developer { partial class InternalLogViewer { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.components = new System.ComponentModel.Container(); this.detailsTextBox = new System.Windows.Forms.TextBox(); this.detailsLabel = new System.Windows.Forms.Label(); this.loggerListView = new System.Windows.Forms.ListView(); this.categoryColumnHeader = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.timeColumnHeader = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.messageColumnHeader = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.entriesLabel = new System.Windows.Forms.Label(); this.quitButton = new System.Windows.Forms.Button(); this.notifyIcon = new System.Windows.Forms.NotifyIcon(this.components); this.hideButton = new System.Windows.Forms.Button(); this.SuspendLayout(); // // detailsTextBox // this.detailsTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.detailsTextBox.Location = new System.Drawing.Point(5, 261); this.detailsTextBox.Multiline = true; this.detailsTextBox.Name = "detailsTextBox"; this.detailsTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; this.detailsTextBox.Size = new System.Drawing.Size(526, 80); this.detailsTextBox.TabIndex = 7; // // detailsLabel // this.detailsLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.detailsLabel.AutoSize = true; this.detailsLabel.Location = new System.Drawing.Point(5, 245); this.detailsLabel.Name = "detailsLabel"; this.detailsLabel.Size = new System.Drawing.Size(42, 13); this.detailsLabel.TabIndex = 6; this.detailsLabel.Text = "Details:"; // // loggerListView // this.loggerListView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.loggerListView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { this.categoryColumnHeader, this.timeColumnHeader, this.messageColumnHeader}); this.loggerListView.FullRowSelect = true; this.loggerListView.Location = new System.Drawing.Point(5, 21); this.loggerListView.MultiSelect = false; this.loggerListView.Name = "loggerListView"; this.loggerListView.ShowItemToolTips = true; this.loggerListView.Size = new System.Drawing.Size(526, 217); this.loggerListView.TabIndex = 4; this.loggerListView.UseCompatibleStateImageBehavior = false; this.loggerListView.View = System.Windows.Forms.View.Details; this.loggerListView.Click += new System.EventHandler(this.LoggerListView_Click); // // categoryColumnHeader // this.categoryColumnHeader.Text = "Category"; // // timeColumnHeader // this.timeColumnHeader.Text = "Time"; // // messageColumnHeader // this.messageColumnHeader.Text = "Message"; this.messageColumnHeader.Width = 402; // // entriesLabel // this.entriesLabel.AutoSize = true; this.entriesLabel.Location = new System.Drawing.Point(5, 5); this.entriesLabel.Name = "entriesLabel"; this.entriesLabel.Size = new System.Drawing.Size(42, 13); this.entriesLabel.TabIndex = 5; this.entriesLabel.Text = "Entries:"; // // quitButton // this.quitButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.quitButton.Location = new System.Drawing.Point(366, 347); this.quitButton.Name = "quitButton"; this.quitButton.Size = new System.Drawing.Size(75, 23); this.quitButton.TabIndex = 8; this.quitButton.Text = "&Quit"; this.quitButton.UseVisualStyleBackColor = true; this.quitButton.Click += new System.EventHandler(this.QuitButton_Click); // // notifyIcon // this.notifyIcon.BalloonTipText = "NBug Developer Interface"; this.notifyIcon.BalloonTipTitle = "NBug (Debug Mode)"; this.notifyIcon.Text = "NBug Developer Interface"; this.notifyIcon.Visible = true; this.notifyIcon.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.NotifyIcon_MouseDoubleClick); // // hideButton // this.hideButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.hideButton.Location = new System.Drawing.Point(456, 347); this.hideButton.Name = "hideButton"; this.hideButton.Size = new System.Drawing.Size(75, 23); this.hideButton.TabIndex = 9; this.hideButton.Text = "&Hide"; this.hideButton.UseVisualStyleBackColor = true; this.hideButton.Click += new System.EventHandler(this.HideButton_Click); // // InternalLogViewer // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(536, 373); this.Controls.Add(this.hideButton); this.Controls.Add(this.quitButton); this.Controls.Add(this.detailsTextBox); this.Controls.Add(this.detailsLabel); this.Controls.Add(this.loggerListView); this.Controls.Add(this.entriesLabel); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; this.MaximizeBox = false; this.Name = "InternalLogViewer"; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; this.Text = "NBug Internal Log Viewer"; this.Resize += new System.EventHandler(this.InternalLogViewer_Resize); this.ResumeLayout(false); this.PerformLayout(); } #endregion private System.Windows.Forms.TextBox detailsTextBox; private System.Windows.Forms.Label detailsLabel; private System.Windows.Forms.ListView loggerListView; private System.Windows.Forms.ColumnHeader categoryColumnHeader; private System.Windows.Forms.ColumnHeader timeColumnHeader; private System.Windows.Forms.ColumnHeader messageColumnHeader; private System.Windows.Forms.Label entriesLabel; private System.Windows.Forms.Button quitButton; private System.Windows.Forms.NotifyIcon notifyIcon; private System.Windows.Forms.Button hideButton; } } ================================================ FILE: source/NBug_custom/Core/UI/Developer/InternalLogViewer.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- using System; using System.Threading; using System.Windows.Forms; using NBug.Enums; using NBug.Properties; namespace NBug.Core.UI.Developer { internal partial class InternalLogViewer : Form { private static bool closed; private static ManualResetEvent handleCreated; private static bool initialized; private static InternalLogViewer viewer; internal InternalLogViewer() { InitializeComponent(); Icon = Resources.NBug_icon_16; notifyIcon.Icon = Resources.NBug_icon_16; } public static void InitializeInternalLogViewer() { if (!initialized) { initialized = true; viewer = new InternalLogViewer(); handleCreated = new ManualResetEvent(false); viewer.HandleCreated += (sender, e) => handleCreated.Set(); //Task.Factory.StartNew(() => Application.Run(viewer)); new Thread(() => Application.Run(viewer)).Start(); handleCreated.WaitOne(); } } public static void LogEntry(string message, LoggerCategory category) { InitializeInternalLogViewer(); if (!closed) { viewer.Invoke((MethodInvoker) (() => viewer.InternalLogEntry(message, category))); } } internal void InternalLogEntry(string message, LoggerCategory category) { loggerListView.Items.Add( new ListViewItem(new[] {category.ToString().Remove(0, 4), DateTime.Now.ToString("HH:mm:ss"), message})); } private void HideButton_Click(object sender, EventArgs e) { Hide(); } private void InternalLogViewer_Resize(object sender, EventArgs e) { if (WindowState == FormWindowState.Minimized) { Hide(); } } private void LoggerListView_Click(object sender, EventArgs e) { detailsTextBox.Text = loggerListView.SelectedItems[0].SubItems[2].Text; } private void NotifyIcon_MouseDoubleClick(object sender, MouseEventArgs e) { if (WindowState == FormWindowState.Minimized) { WindowState = FormWindowState.Normal; } Show(); Activate(); } private void QuitButton_Click(object sender, EventArgs e) { notifyIcon.Visible = false; notifyIcon.Dispose(); notifyIcon = null; closed = true; Close(); } } } ================================================ FILE: source/NBug_custom/Core/UI/Developer/InternalLogViewer.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 16, 14 47 ================================================ FILE: source/NBug_custom/Core/UI/UIDialogResult.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- namespace NBug.Core.UI { public enum SendReport { Send, DoNotSend } public enum ExecutionFlow { /// /// This will handle all unhandled exceptions to be able to continue execution. /// ContinueExecution, /// /// This will handle all unhandled exceptions and exit the application. /// BreakExecution } public struct UIDialogResult { internal ExecutionFlow Execution; internal SendReport Report; public UIDialogResult(ExecutionFlow execution, SendReport report) { Execution = execution; Report = report; } } } ================================================ FILE: source/NBug_custom/Core/UI/UISelector.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- using System; using NBug.Core.Reporting.Info; using NBug.Core.UI.Console; using NBug.Core.UI.Custom; using NBug.Core.UI.WinForms; using NBug.Core.UI.WPF; using NBug.Core.Util; using NBug.Core.Util.Exceptions; using NBug.Core.Util.Serialization; using NBug.Enums; namespace NBug.Core.UI { /// /// Initializes a new instance of the UISelector class which displays the user an appropriate user interface in the /// event of unhandled exceptions. /// internal static class UISelector { internal static UIDialogResult DisplayBugReportUI(ExceptionThread exceptionThread, SerializableException serializableException, Report report) { if (exceptionThread == ExceptionThread.Task) { // Do not interfere with the default behaviour for continuation on background thread exceptions. Just log and send'em (no UI...) return new UIDialogResult(ExecutionFlow.ContinueExecution, SendReport.Send); } if (Settings.UIMode == UIMode.Auto) { // First of, test to see if the call is from an UI thread and if so, use the same UI type (WinForms, WPF, etc.) if (exceptionThread == ExceptionThread.UI_WinForms) { return WinFormsUI.ShowDialog(UIMode.Minimal, serializableException, report); } if (exceptionThread == ExceptionThread.UI_WPF) { return WPFUI.ShowDialog(UIMode.Minimal, serializableException, report); } if (exceptionThread == ExceptionThread.Main) { // If the call is not from a non-UI thread like the main app thread, it may be from the current appdomain but // the application may still be using an UI. Or it may be coming from an exception filter where UI type is undefined yet. switch (DiscoverUI()) { case UIProvider.WinForms: return WinFormsUI.ShowDialog(UIMode.Minimal, serializableException, report); case UIProvider.WPF: return WPFUI.ShowDialog(UIMode.Minimal, serializableException, report); case UIProvider.Console: return ConsoleUI.ShowDialog(UIMode.Minimal, serializableException, report); case UIProvider.Custom: return CustomUI.ShowDialog(UIMode.Minimal, serializableException, report); default: throw new NBugRuntimeException("UISelector.DiscoverUI() returned an invalid UI type."); } } throw new NBugRuntimeException(string.Format("Parameter supplied for '{0}' is not valid.", typeof (ExceptionThread).Name)); } if (Settings.UIMode == UIMode.None) { // Do not display an UI for UIMode.None if (Settings.ExitApplicationImmediately) { return new UIDialogResult(ExecutionFlow.BreakExecution, SendReport.Send); } return new UIDialogResult(ExecutionFlow.ContinueExecution, SendReport.Send); } if (Settings.UIProvider == UIProvider.Console) { return ConsoleUI.ShowDialog(Settings.UIMode, serializableException, report); } if (Settings.UIProvider == UIProvider.WinForms) { return WinFormsUI.ShowDialog(Settings.UIMode, serializableException, report); } if (Settings.UIProvider == UIProvider.WPF) { return WPFUI.ShowDialog(Settings.UIMode, serializableException, report); } if (Settings.UIProvider == UIProvider.Custom) { return CustomUI.ShowDialog(UIMode.Minimal, serializableException, report); } if (Settings.UIProvider == UIProvider.Auto) { // In this case, UIProvider = Auto & UIMode != Auto so just discover the UI provider and use the selected UI mode switch (DiscoverUI()) { case UIProvider.WinForms: return WinFormsUI.ShowDialog(Settings.UIMode, serializableException, report); case UIProvider.WPF: return WPFUI.ShowDialog(Settings.UIMode, serializableException, report); case UIProvider.Console: return ConsoleUI.ShowDialog(Settings.UIMode, serializableException, report); case UIProvider.Custom: return CustomUI.ShowDialog(UIMode.Minimal, serializableException, report); default: throw new NBugRuntimeException("UISelector.DiscoverUI() returned an invalid UI type."); } } throw NBugConfigurationException.Create(() => Settings.UIProvider, "Parameter supplied for settings property is invalid."); } internal static void DisplayFeedbackUI() { } private static UIProvider DiscoverUI() { // First of search for loaded assemblies in the current domain foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) { switch (assembly.GetName().Name) { case "System.Windows.Forms": return UIProvider.WinForms; case "PresentationFramework": return UIProvider.WPF; } } // Eventhough UI assemblies may not be loaded, they may still be referenced. Search for them for a second time foreach (var assembly in Settings.EntryAssembly.GetReferencedAssemblies()) { switch (assembly.Name) { case "System.Windows.Forms": return UIProvider.WinForms; case "PresentationFramework": return UIProvider.WPF; } } // If there is no known UI assembly loaded or referenced, the application is probably a console app return UIProvider.Console; } } } ================================================ FILE: source/NBug_custom/Core/UI/WPF/WPFUI.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- using NBug.Core.Reporting.Info; using NBug.Core.UI.WinForms; using NBug.Core.Util.Exceptions; using NBug.Core.Util.Serialization; using NBug.Enums; namespace NBug.Core.UI.WPF { /// /// This class is used to prevent statically referencing any WPF dlls from the UISelector.cs thus prevents /// any unnecessary assembly from getting loaded into the memory. /// internal static class WPFUI { internal static UIDialogResult ShowDialog(UIMode uiMode, SerializableException exception, Report report) { if (uiMode == UIMode.Minimal) { return new Minimal().ShowDialog(report); } if (uiMode == UIMode.Normal) { using (var ui = new Normal()) { return ui.ShowDialog(report); } } if (uiMode == UIMode.Full) { using (var ui = new Full()) { return ui.ShowDialog(exception, report); } } throw NBugConfigurationException.Create(() => Settings.UIMode, "Parameter supplied for settings property is invalid."); } } } ================================================ FILE: source/NBug_custom/Core/UI/WinForms/Feedback.Designer.cs ================================================ namespace NBug.Core.UI.WinForms { partial class Feedback { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.suggestionTypeGroupBox = new System.Windows.Forms.GroupBox(); this.featureRequestRadioButton = new System.Windows.Forms.RadioButton(); this.commentRadioButton = new System.Windows.Forms.RadioButton(); this.errorReportRadioButton = new System.Windows.Forms.RadioButton(); this.suggestionRadioButton = new System.Windows.Forms.RadioButton(); this.feedbackLabel = new System.Windows.Forms.Label(); this.feedbackPictureBox = new System.Windows.Forms.PictureBox(); this.emailLabel = new System.Windows.Forms.Label(); this.remarksLabel = new System.Windows.Forms.Label(); this.textBox1 = new System.Windows.Forms.TextBox(); this.textBox2 = new System.Windows.Forms.TextBox(); this.sendButton = new System.Windows.Forms.Button(); this.closeButton = new System.Windows.Forms.Button(); this.suggestionTypeGroupBox.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.feedbackPictureBox)).BeginInit(); this.SuspendLayout(); // // suggestionTypeGroupBox // this.suggestionTypeGroupBox.Controls.Add(this.featureRequestRadioButton); this.suggestionTypeGroupBox.Controls.Add(this.commentRadioButton); this.suggestionTypeGroupBox.Controls.Add(this.errorReportRadioButton); this.suggestionTypeGroupBox.Controls.Add(this.suggestionRadioButton); this.suggestionTypeGroupBox.Location = new System.Drawing.Point(12, 61); this.suggestionTypeGroupBox.Name = "suggestionTypeGroupBox"; this.suggestionTypeGroupBox.Size = new System.Drawing.Size(382, 42); this.suggestionTypeGroupBox.TabIndex = 0; this.suggestionTypeGroupBox.TabStop = false; this.suggestionTypeGroupBox.Text = "Suggestion Type:"; // // featureRequestRadioButton // this.featureRequestRadioButton.AutoSize = true; this.featureRequestRadioButton.Location = new System.Drawing.Point(263, 17); this.featureRequestRadioButton.Name = "featureRequestRadioButton"; this.featureRequestRadioButton.Size = new System.Drawing.Size(104, 17); this.featureRequestRadioButton.TabIndex = 3; this.featureRequestRadioButton.TabStop = true; this.featureRequestRadioButton.Text = "Feature Request"; this.featureRequestRadioButton.UseVisualStyleBackColor = true; // // commentRadioButton // this.commentRadioButton.AutoSize = true; this.commentRadioButton.Location = new System.Drawing.Point(100, 17); this.commentRadioButton.Name = "commentRadioButton"; this.commentRadioButton.Size = new System.Drawing.Size(69, 17); this.commentRadioButton.TabIndex = 2; this.commentRadioButton.TabStop = true; this.commentRadioButton.Text = "Comment"; this.commentRadioButton.UseVisualStyleBackColor = true; // // errorReportRadioButton // this.errorReportRadioButton.AutoSize = true; this.errorReportRadioButton.Location = new System.Drawing.Point(175, 17); this.errorReportRadioButton.Name = "errorReportRadioButton"; this.errorReportRadioButton.Size = new System.Drawing.Size(82, 17); this.errorReportRadioButton.TabIndex = 1; this.errorReportRadioButton.TabStop = true; this.errorReportRadioButton.Text = "Error Report"; this.errorReportRadioButton.UseVisualStyleBackColor = true; // // suggestionRadioButton // this.suggestionRadioButton.AutoSize = true; this.suggestionRadioButton.Location = new System.Drawing.Point(16, 17); this.suggestionRadioButton.Name = "suggestionRadioButton"; this.suggestionRadioButton.Size = new System.Drawing.Size(78, 17); this.suggestionRadioButton.TabIndex = 0; this.suggestionRadioButton.TabStop = true; this.suggestionRadioButton.Text = "Suggestion"; this.suggestionRadioButton.UseVisualStyleBackColor = true; // // feedbackLabel // this.feedbackLabel.Location = new System.Drawing.Point(50, 14); this.feedbackLabel.Name = "feedbackLabel"; this.feedbackLabel.Size = new System.Drawing.Size(344, 28); this.feedbackLabel.TabIndex = 1; this.feedbackLabel.Text = "Please fill in the form below to submit your feedback. Selecting the proper feedb" + "ack type will help us better understand your opinion."; // // feedbackPictureBox // this.feedbackPictureBox.Image = global::NBug.Properties.Resources.Feedback; this.feedbackPictureBox.Location = new System.Drawing.Point(12, 12); this.feedbackPictureBox.Name = "feedbackPictureBox"; this.feedbackPictureBox.Size = new System.Drawing.Size(32, 32); this.feedbackPictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize; this.feedbackPictureBox.TabIndex = 2; this.feedbackPictureBox.TabStop = false; // // emailLabel // this.emailLabel.AutoSize = true; this.emailLabel.Location = new System.Drawing.Point(9, 122); this.emailLabel.Name = "emailLabel"; this.emailLabel.Size = new System.Drawing.Size(127, 13); this.emailLabel.TabIndex = 3; this.emailLabel.Text = "E-mail Address (Optional):"; // // remarksLabel // this.remarksLabel.AutoSize = true; this.remarksLabel.Location = new System.Drawing.Point(9, 150); this.remarksLabel.Name = "remarksLabel"; this.remarksLabel.Size = new System.Drawing.Size(52, 13); this.remarksLabel.TabIndex = 4; this.remarksLabel.Text = "Remarks:"; // // textBox1 // this.textBox1.Location = new System.Drawing.Point(142, 119); this.textBox1.Name = "textBox1"; this.textBox1.Size = new System.Drawing.Size(146, 20); this.textBox1.TabIndex = 5; // // textBox2 // this.textBox2.Location = new System.Drawing.Point(12, 166); this.textBox2.Multiline = true; this.textBox2.Name = "textBox2"; this.textBox2.Size = new System.Drawing.Size(382, 110); this.textBox2.TabIndex = 6; // // sendButton // this.sendButton.Image = global::NBug.Properties.Resources.Send; this.sendButton.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; this.sendButton.Location = new System.Drawing.Point(319, 284); this.sendButton.Name = "sendButton"; this.sendButton.Size = new System.Drawing.Size(75, 23); this.sendButton.TabIndex = 7; this.sendButton.Text = " &Send"; this.sendButton.UseVisualStyleBackColor = true; // // closeButton // this.closeButton.Location = new System.Drawing.Point(233, 284); this.closeButton.Name = "closeButton"; this.closeButton.Size = new System.Drawing.Size(75, 23); this.closeButton.TabIndex = 8; this.closeButton.Text = "&Close"; this.closeButton.UseVisualStyleBackColor = true; // // Feedback // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(406, 314); this.Controls.Add(this.closeButton); this.Controls.Add(this.sendButton); this.Controls.Add(this.textBox2); this.Controls.Add(this.textBox1); this.Controls.Add(this.remarksLabel); this.Controls.Add(this.emailLabel); this.Controls.Add(this.feedbackPictureBox); this.Controls.Add(this.feedbackLabel); this.Controls.Add(this.suggestionTypeGroupBox); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "Feedback"; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "Feedback"; this.suggestionTypeGroupBox.ResumeLayout(false); this.suggestionTypeGroupBox.PerformLayout(); ((System.ComponentModel.ISupportInitialize)(this.feedbackPictureBox)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); } #endregion private System.Windows.Forms.GroupBox suggestionTypeGroupBox; private System.Windows.Forms.RadioButton featureRequestRadioButton; private System.Windows.Forms.RadioButton commentRadioButton; private System.Windows.Forms.RadioButton errorReportRadioButton; private System.Windows.Forms.RadioButton suggestionRadioButton; private System.Windows.Forms.Label feedbackLabel; private System.Windows.Forms.PictureBox feedbackPictureBox; private System.Windows.Forms.Label emailLabel; private System.Windows.Forms.Label remarksLabel; private System.Windows.Forms.TextBox textBox1; private System.Windows.Forms.TextBox textBox2; private System.Windows.Forms.Button sendButton; private System.Windows.Forms.Button closeButton; } } ================================================ FILE: source/NBug_custom/Core/UI/WinForms/Feedback.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- using System.Windows.Forms; using NBug.Properties; namespace NBug.Core.UI.WinForms { internal partial class Feedback : Form { public Feedback() { InitializeComponent(); Icon = Resources.NBug_icon_16; } } } ================================================ FILE: source/NBug_custom/Core/UI/WinForms/Feedback.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ================================================ FILE: source/NBug_custom/Core/UI/WinForms/Full.Designer.cs ================================================ namespace NBug.Core.UI.WinForms { using NBug.Core.UI.WinForms.Panels; partial class Full { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.components = new System.ComponentModel.Container(); System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Full)); this.mainTabs = new System.Windows.Forms.TabControl(); this.generalTabPage = new System.Windows.Forms.TabPage(); this.warningLabel = new System.Windows.Forms.Label(); this.exceptionTypeLabel = new System.Windows.Forms.Label(); this.exceptionTextBox = new System.Windows.Forms.TextBox(); this.descriptionTextBox = new System.Windows.Forms.TextBox(); this.errorDescriptionLabel = new System.Windows.Forms.Label(); this.clrTextBox = new System.Windows.Forms.TextBox(); this.clrLabel = new System.Windows.Forms.Label(); this.dateTimeTextBox = new System.Windows.Forms.TextBox(); this.dateTimeLabel = new System.Windows.Forms.Label(); this.nbugTextBox = new System.Windows.Forms.TextBox(); this.nbugLabel = new System.Windows.Forms.Label(); this.applicationTextBox = new System.Windows.Forms.TextBox(); this.applicationLabel = new System.Windows.Forms.Label(); this.targetSiteTextBox = new System.Windows.Forms.TextBox(); this.targetSiteLabel = new System.Windows.Forms.Label(); this.exceptionMessageTextBox = new System.Windows.Forms.TextBox(); this.warningPictureBox = new System.Windows.Forms.PictureBox(); this.exceptionTabPage = new System.Windows.Forms.TabPage(); this.exceptionDetails = new NBug.Core.UI.WinForms.Panels.ExceptionDetails(); this.reportContentsTabPage = new System.Windows.Forms.TabPage(); this.reportPreviewTextBox = new System.Windows.Forms.TextBox(); this.previewLabel = new System.Windows.Forms.Label(); this.contentsLabel = new System.Windows.Forms.Label(); this.reportContentsListView = new System.Windows.Forms.ListView(); this.nameColumnHeader = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.descriptionColumnHeader = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.sizeColumnHeader = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.sendAndQuitButton = new System.Windows.Forms.Button(); this.quitButton = new System.Windows.Forms.Button(); this.toolTip = new System.Windows.Forms.ToolTip(this.components); this.mainTabs.SuspendLayout(); this.generalTabPage.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.warningPictureBox)).BeginInit(); this.exceptionTabPage.SuspendLayout(); this.reportContentsTabPage.SuspendLayout(); this.SuspendLayout(); // // mainTabs // this.mainTabs.Controls.Add(this.generalTabPage); this.mainTabs.Controls.Add(this.exceptionTabPage); this.mainTabs.Controls.Add(this.reportContentsTabPage); this.mainTabs.Location = new System.Drawing.Point(9, 6); this.mainTabs.Margin = new System.Windows.Forms.Padding(0); this.mainTabs.Name = "mainTabs"; this.mainTabs.SelectedIndex = 0; this.mainTabs.Size = new System.Drawing.Size(475, 361); this.mainTabs.TabIndex = 0; // // generalTabPage // this.generalTabPage.Controls.Add(this.warningLabel); this.generalTabPage.Controls.Add(this.exceptionTypeLabel); this.generalTabPage.Controls.Add(this.exceptionTextBox); this.generalTabPage.Controls.Add(this.descriptionTextBox); this.generalTabPage.Controls.Add(this.errorDescriptionLabel); this.generalTabPage.Controls.Add(this.clrTextBox); this.generalTabPage.Controls.Add(this.clrLabel); this.generalTabPage.Controls.Add(this.dateTimeTextBox); this.generalTabPage.Controls.Add(this.dateTimeLabel); this.generalTabPage.Controls.Add(this.nbugTextBox); this.generalTabPage.Controls.Add(this.nbugLabel); this.generalTabPage.Controls.Add(this.applicationTextBox); this.generalTabPage.Controls.Add(this.applicationLabel); this.generalTabPage.Controls.Add(this.targetSiteTextBox); this.generalTabPage.Controls.Add(this.targetSiteLabel); this.generalTabPage.Controls.Add(this.exceptionMessageTextBox); this.generalTabPage.Controls.Add(this.warningPictureBox); this.generalTabPage.Location = new System.Drawing.Point(4, 22); this.generalTabPage.Name = "generalTabPage"; this.generalTabPage.Padding = new System.Windows.Forms.Padding(3); this.generalTabPage.Size = new System.Drawing.Size(467, 335); this.generalTabPage.TabIndex = 0; this.generalTabPage.Text = "General"; this.generalTabPage.UseVisualStyleBackColor = true; // // warningLabel // this.warningLabel.Location = new System.Drawing.Point(64, 12); this.warningLabel.Name = "warningLabel"; this.warningLabel.Size = new System.Drawing.Size(388, 43); this.warningLabel.TabIndex = 18; this.warningLabel.Text = resources.GetString("warningLabel.Text"); // // exceptionTypeLabel // this.exceptionTypeLabel.Image = global::NBug.Properties.Resources.NBug_Icon_PNG_16; this.exceptionTypeLabel.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; this.exceptionTypeLabel.Location = new System.Drawing.Point(21, 69); this.exceptionTypeLabel.Name = "exceptionTypeLabel"; this.exceptionTypeLabel.Size = new System.Drawing.Size(106, 16); this.exceptionTypeLabel.TabIndex = 17; this.exceptionTypeLabel.Text = "Exception Type:"; this.exceptionTypeLabel.TextAlign = System.Drawing.ContentAlignment.MiddleRight; // // exceptionTextBox // this.exceptionTextBox.Location = new System.Drawing.Point(135, 68); this.exceptionTextBox.Name = "exceptionTextBox"; this.exceptionTextBox.Size = new System.Drawing.Size(317, 20); this.exceptionTextBox.TabIndex = 2; // // descriptionTextBox // this.descriptionTextBox.Location = new System.Drawing.Point(13, 267); this.descriptionTextBox.Multiline = true; this.descriptionTextBox.Name = "descriptionTextBox"; this.descriptionTextBox.Size = new System.Drawing.Size(439, 60); this.descriptionTextBox.TabIndex = 15; // // errorDescriptionLabel // this.errorDescriptionLabel.AutoSize = true; this.errorDescriptionLabel.Location = new System.Drawing.Point(10, 251); this.errorDescriptionLabel.Name = "errorDescriptionLabel"; this.errorDescriptionLabel.Size = new System.Drawing.Size(315, 13); this.errorDescriptionLabel.TabIndex = 14; this.errorDescriptionLabel.Text = "Please add a brief description of how we can reproduce the error:"; // // clrTextBox // this.clrTextBox.Location = new System.Drawing.Point(307, 216); this.clrTextBox.Name = "clrTextBox"; this.clrTextBox.Size = new System.Drawing.Size(145, 20); this.clrTextBox.TabIndex = 13; // // clrLabel // this.clrLabel.AutoSize = true; this.clrLabel.Location = new System.Drawing.Point(259, 219); this.clrLabel.Name = "clrLabel"; this.clrLabel.Size = new System.Drawing.Size(31, 13); this.clrLabel.TabIndex = 12; this.clrLabel.Text = "CLR:"; // // dateTimeTextBox // this.dateTimeTextBox.Location = new System.Drawing.Point(78, 216); this.dateTimeTextBox.Name = "dateTimeTextBox"; this.dateTimeTextBox.Size = new System.Drawing.Size(145, 20); this.dateTimeTextBox.TabIndex = 11; // // dateTimeLabel // this.dateTimeLabel.AutoSize = true; this.dateTimeLabel.Location = new System.Drawing.Point(10, 219); this.dateTimeLabel.Name = "dateTimeLabel"; this.dateTimeLabel.Size = new System.Drawing.Size(61, 13); this.dateTimeLabel.TabIndex = 10; this.dateTimeLabel.Text = "Date/Time:"; // // nbugTextBox // this.nbugTextBox.Location = new System.Drawing.Point(307, 182); this.nbugTextBox.Name = "nbugTextBox"; this.nbugTextBox.Size = new System.Drawing.Size(145, 20); this.nbugTextBox.TabIndex = 9; // // nbugLabel // this.nbugLabel.AutoSize = true; this.nbugLabel.Location = new System.Drawing.Point(259, 185); this.nbugLabel.Name = "nbugLabel"; this.nbugLabel.Size = new System.Drawing.Size(37, 13); this.nbugLabel.TabIndex = 8; this.nbugLabel.Text = "NBug:"; // // applicationTextBox // this.applicationTextBox.Location = new System.Drawing.Point(78, 182); this.applicationTextBox.Name = "applicationTextBox"; this.applicationTextBox.Size = new System.Drawing.Size(145, 20); this.applicationTextBox.TabIndex = 7; // // applicationLabel // this.applicationLabel.AutoSize = true; this.applicationLabel.Location = new System.Drawing.Point(10, 185); this.applicationLabel.Name = "applicationLabel"; this.applicationLabel.Size = new System.Drawing.Size(62, 13); this.applicationLabel.TabIndex = 6; this.applicationLabel.Text = "Application:"; // // targetSiteTextBox // this.targetSiteTextBox.Location = new System.Drawing.Point(78, 148); this.targetSiteTextBox.Name = "targetSiteTextBox"; this.targetSiteTextBox.Size = new System.Drawing.Size(374, 20); this.targetSiteTextBox.TabIndex = 5; // // targetSiteLabel // this.targetSiteLabel.AutoSize = true; this.targetSiteLabel.Location = new System.Drawing.Point(10, 151); this.targetSiteLabel.Name = "targetSiteLabel"; this.targetSiteLabel.Size = new System.Drawing.Size(62, 13); this.targetSiteLabel.TabIndex = 4; this.targetSiteLabel.Text = "Target Site:"; // // exceptionMessageTextBox // this.exceptionMessageTextBox.Location = new System.Drawing.Point(13, 98); this.exceptionMessageTextBox.Multiline = true; this.exceptionMessageTextBox.Name = "exceptionMessageTextBox"; this.exceptionMessageTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; this.exceptionMessageTextBox.Size = new System.Drawing.Size(439, 35); this.exceptionMessageTextBox.TabIndex = 3; // // warningPictureBox // this.warningPictureBox.Location = new System.Drawing.Point(16, 15); this.warningPictureBox.Name = "warningPictureBox"; this.warningPictureBox.Size = new System.Drawing.Size(32, 32); this.warningPictureBox.TabIndex = 1; this.warningPictureBox.TabStop = false; // // exceptionTabPage // this.exceptionTabPage.Controls.Add(this.exceptionDetails); this.exceptionTabPage.Location = new System.Drawing.Point(4, 22); this.exceptionTabPage.Name = "exceptionTabPage"; this.exceptionTabPage.Padding = new System.Windows.Forms.Padding(3); this.exceptionTabPage.Size = new System.Drawing.Size(467, 335); this.exceptionTabPage.TabIndex = 2; this.exceptionTabPage.Text = "Exception"; this.exceptionTabPage.UseVisualStyleBackColor = true; // // exceptionDetails // this.exceptionDetails.InformationColumnWidth = 350; this.exceptionDetails.Location = new System.Drawing.Point(3, 3); this.exceptionDetails.Name = "exceptionDetails"; this.exceptionDetails.PropertyColumnWidth = 101; this.exceptionDetails.Size = new System.Drawing.Size(461, 330); this.exceptionDetails.TabIndex = 0; // // reportContentsTabPage // this.reportContentsTabPage.Controls.Add(this.reportPreviewTextBox); this.reportContentsTabPage.Controls.Add(this.previewLabel); this.reportContentsTabPage.Controls.Add(this.contentsLabel); this.reportContentsTabPage.Controls.Add(this.reportContentsListView); this.reportContentsTabPage.Location = new System.Drawing.Point(4, 22); this.reportContentsTabPage.Name = "reportContentsTabPage"; this.reportContentsTabPage.Padding = new System.Windows.Forms.Padding(3); this.reportContentsTabPage.Size = new System.Drawing.Size(467, 335); this.reportContentsTabPage.TabIndex = 3; this.reportContentsTabPage.Text = "Report Contents"; this.reportContentsTabPage.UseVisualStyleBackColor = true; this.reportContentsTabPage.Enter += new System.EventHandler(this.ReportContentsTabPage_Enter); // // reportPreviewTextBox // this.reportPreviewTextBox.Location = new System.Drawing.Point(6, 148); this.reportPreviewTextBox.Multiline = true; this.reportPreviewTextBox.Name = "reportPreviewTextBox"; this.reportPreviewTextBox.Size = new System.Drawing.Size(455, 172); this.reportPreviewTextBox.TabIndex = 5; // // previewLabel // this.previewLabel.AutoSize = true; this.previewLabel.Location = new System.Drawing.Point(6, 131); this.previewLabel.Name = "previewLabel"; this.previewLabel.Size = new System.Drawing.Size(48, 13); this.previewLabel.TabIndex = 4; this.previewLabel.Text = "Preview:"; // // contentsLabel // this.contentsLabel.AutoSize = true; this.contentsLabel.Location = new System.Drawing.Point(6, 7); this.contentsLabel.Name = "contentsLabel"; this.contentsLabel.Size = new System.Drawing.Size(288, 13); this.contentsLabel.TabIndex = 3; this.contentsLabel.Text = "Double-click an item to open it with the associated program."; // // reportContentsListView // this.reportContentsListView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { this.nameColumnHeader, this.descriptionColumnHeader, this.sizeColumnHeader}); this.reportContentsListView.Location = new System.Drawing.Point(6, 24); this.reportContentsListView.Name = "reportContentsListView"; this.reportContentsListView.Size = new System.Drawing.Size(455, 97); this.reportContentsListView.TabIndex = 0; this.reportContentsListView.UseCompatibleStateImageBehavior = false; this.reportContentsListView.View = System.Windows.Forms.View.Details; // // nameColumnHeader // this.nameColumnHeader.Text = "Name"; this.nameColumnHeader.Width = 120; // // descriptionColumnHeader // this.descriptionColumnHeader.Text = "Description"; this.descriptionColumnHeader.Width = 240; // // sizeColumnHeader // this.sizeColumnHeader.Text = "Size"; this.sizeColumnHeader.Width = 80; // // sendAndQuitButton // this.sendAndQuitButton.Image = global::NBug.Properties.Resources.Send; this.sendAndQuitButton.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; this.sendAndQuitButton.Location = new System.Drawing.Point(382, 374); this.sendAndQuitButton.Name = "sendAndQuitButton"; this.sendAndQuitButton.Size = new System.Drawing.Size(102, 23); this.sendAndQuitButton.TabIndex = 1; this.sendAndQuitButton.Text = "&Send and Quit"; this.sendAndQuitButton.TextAlign = System.Drawing.ContentAlignment.MiddleRight; this.sendAndQuitButton.UseVisualStyleBackColor = true; this.sendAndQuitButton.Click += new System.EventHandler(this.SendAndQuitButton_Click); // // quitButton // this.quitButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.quitButton.Location = new System.Drawing.Point(296, 374); this.quitButton.Name = "quitButton"; this.quitButton.Size = new System.Drawing.Size(75, 23); this.quitButton.TabIndex = 2; this.quitButton.Text = "&Quit"; this.quitButton.UseVisualStyleBackColor = true; this.quitButton.Click += new System.EventHandler(this.QuitButton_Click); // // toolTip // this.toolTip.AutomaticDelay = 100; this.toolTip.UseAnimation = false; this.toolTip.UseFading = false; // // Full // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.CancelButton = this.quitButton; this.ClientSize = new System.Drawing.Size(494, 403); this.Controls.Add(this.quitButton); this.Controls.Add(this.sendAndQuitButton); this.Controls.Add(this.mainTabs); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "Full"; this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; this.Text = "{HostApplication} Error"; this.TopMost = true; this.mainTabs.ResumeLayout(false); this.generalTabPage.ResumeLayout(false); this.generalTabPage.PerformLayout(); ((System.ComponentModel.ISupportInitialize)(this.warningPictureBox)).EndInit(); this.exceptionTabPage.ResumeLayout(false); this.reportContentsTabPage.ResumeLayout(false); this.reportContentsTabPage.PerformLayout(); this.ResumeLayout(false); } #endregion private System.Windows.Forms.TabControl mainTabs; private System.Windows.Forms.TabPage generalTabPage; private System.Windows.Forms.Button sendAndQuitButton; private System.Windows.Forms.Button quitButton; private System.Windows.Forms.TabPage exceptionTabPage; private System.Windows.Forms.PictureBox warningPictureBox; private System.Windows.Forms.TextBox exceptionMessageTextBox; private System.Windows.Forms.TextBox exceptionTextBox; private System.Windows.Forms.TextBox targetSiteTextBox; private System.Windows.Forms.Label targetSiteLabel; private System.Windows.Forms.TextBox nbugTextBox; private System.Windows.Forms.Label nbugLabel; private System.Windows.Forms.TextBox applicationTextBox; private System.Windows.Forms.Label applicationLabel; private System.Windows.Forms.TextBox descriptionTextBox; private System.Windows.Forms.Label errorDescriptionLabel; private System.Windows.Forms.TextBox clrTextBox; private System.Windows.Forms.Label clrLabel; private System.Windows.Forms.TextBox dateTimeTextBox; private System.Windows.Forms.Label dateTimeLabel; private System.Windows.Forms.TabPage reportContentsTabPage; private System.Windows.Forms.TextBox reportPreviewTextBox; private System.Windows.Forms.Label previewLabel; private System.Windows.Forms.Label contentsLabel; private System.Windows.Forms.ListView reportContentsListView; private System.Windows.Forms.ColumnHeader nameColumnHeader; private System.Windows.Forms.ColumnHeader descriptionColumnHeader; private System.Windows.Forms.ColumnHeader sizeColumnHeader; private System.Windows.Forms.Label exceptionTypeLabel; private System.Windows.Forms.ToolTip toolTip; private System.Windows.Forms.Label warningLabel; private ExceptionDetails exceptionDetails; } } ================================================ FILE: source/NBug_custom/Core/UI/WinForms/Full.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- using System; using System.Drawing; using System.Windows.Forms; using NBug.Core.Reporting.Info; using NBug.Core.Util.Serialization; using NBug.Properties; namespace NBug.Core.UI.WinForms { internal partial class Full : Form { private UIDialogResult uiDialogResult; internal Full() { InitializeComponent(); Icon = Resources.NBug_icon_16; warningLabel.Text = Settings.Resources.UI_Dialog_Full_Message; generalTabPage.Text = Settings.Resources.UI_Dialog_Full_General_Tab; exceptionTabPage.Text = Settings.Resources.UI_Dialog_Full_Exception_Tab; reportContentsTabPage.Text = Settings.Resources.UI_Dialog_Full_Report_Contents_Tab; errorDescriptionLabel.Text = Settings.Resources.UI_Dialog_Full_How_to_Reproduce_the_Error_Notification; quitButton.Text = Settings.Resources.UI_Dialog_Full_Quit_Button; sendAndQuitButton.Text = Settings.Resources.UI_Dialog_Full_Send_and_Quit_Button; mainTabs.TabPages.Remove(mainTabs.TabPages["reportContentsTabPage"]); } internal UIDialogResult ShowDialog(SerializableException exception, Report report) { Text = string.Format("{0} {1}", report.GeneralInfo.HostApplication, Settings.Resources.UI_Dialog_Full_Title); // Fill in the 'General' tab warningPictureBox.Image = SystemIcons.Warning.ToBitmap(); exceptionTextBox.Text = exception.Type; exceptionMessageTextBox.Text = exception.Message; targetSiteTextBox.Text = exception.TargetSite; applicationTextBox.Text = report.GeneralInfo.HostApplication + " [" + report.GeneralInfo.HostApplicationVersion + "]"; nbugTextBox.Text = report.GeneralInfo.NBugVersion; dateTimeTextBox.Text = report.GeneralInfo.DateTime; clrTextBox.Text = report.GeneralInfo.CLRVersion; // Fill in the 'Exception' tab exceptionDetails.Initialize(exception); ShowDialog(); // Write back the user description (as we passed 'report' as a reference since it is a refence object anyway) report.GeneralInfo.UserDescription = descriptionTextBox.Text; return uiDialogResult; } private void QuitButton_Click(object sender, EventArgs e) { uiDialogResult = new UIDialogResult(ExecutionFlow.BreakExecution, SendReport.DoNotSend); Close(); } private void ReportContentsTabPage_Enter(object sender, EventArgs e) { /*using (Storer storer = new Storer()) using (ZipStorer zipStorer = ZipStorer.Open(storer.GetFirstReportFile(), FileAccess.Read)) using (Stream zipItemStream = new MemoryStream()) { List zipDirectory = zipStorer.ReadCentralDir(); foreach (ZipStorer.ZipFileEntry entry in zipDirectory) { zipItemStream.SetLength(0); zipStorer.ExtractFile(entry, zipItemStream); zipItemStream.Position = 0; this.reportContentsListView.Items.Add(entry.FilenameInZip); } }*/ } private void SendAndQuitButton_Click(object sender, EventArgs e) { uiDialogResult = new UIDialogResult(ExecutionFlow.BreakExecution, SendReport.Send); Close(); } } } ================================================ FILE: source/NBug_custom/Core/UI/WinForms/Full.es.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 La aplicación ha colapsado y ahora se cerrará. Si hace clic en Salir, la aplicación se cerrará inmediatamente. Si hace clic en Enviar y Salir, la aplicación se cerrará y se enviará un informe de error. ================================================ FILE: source/NBug_custom/Core/UI/WinForms/Full.fr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 L'application a planté et elle va maintenant être arrêtée. Si vous cliquez sur Quitter, l'application se fermera immédiatement. Si vous cliquez sur Envoyer et Quitter, l'application se fermera et un rapport de bogue sera envoyé. ================================================ FILE: source/NBug_custom/Core/UI/WinForms/Full.hu.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Az alkalmazás összeomlott, és most bezárul. Ha a Kilépés gombra kattint, az alkalmazás azonnal bezárul. Ha a Küldés és kilépés gombra kattint, az alkalmazás bezárul, és hibajelentést küld. ================================================ FILE: source/NBug_custom/Core/UI/WinForms/Full.ja.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 アプリケーションがクラッシュし、これから終了します。 「終了」をクリックすると、アプリケーションは即座に閉じます。 「送信して終了」をクリックすると、アプリケーションは閉じ、バグレポートが送信されます。 ================================================ FILE: source/NBug_custom/Core/UI/WinForms/Full.nl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 De toepassing is gecrasht en wordt nu afgesloten. Als u op Verlaten klikt, wordt de toepassing onmiddellijk afgesloten. Als u op "Verzenden en afsluiten" klikt, wordt de toepassing afgesloten en wordt er een bugrapport verzonden. ================================================ FILE: source/NBug_custom/Core/UI/WinForms/Full.pt-BR.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 A aplicação encontrou um erro e será encerrada agora. Se você clicar em "Sair", o aplicativo será fechado imediatamente. Se você clicar em "Enviar e Sair", o aplicativo será fechado e um relatório de erro será enviado. ================================================ FILE: source/NBug_custom/Core/UI/WinForms/Full.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 The application has crashed and it will now be dismissed. If you click Quit, the application will close immediately. If you click Send and Quit, the application will close and a bug report will be send. 18, 13 45 ================================================ FILE: source/NBug_custom/Core/UI/WinForms/Full.sv.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Programmet har kraschat och kommer nu att avslutas. Om du klickar på Avsluta stängs programmet omedelbart. Om du klickar på Skicka och Avsluta kommer programmet att stängas och en felrapport kommer att skickas. ================================================ FILE: source/NBug_custom/Core/UI/WinForms/Full.tr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Uygulama çökmüştür ve şimdi kapatılacaktır. Eğer Çık'a tıklarsanız, uygulama hemen kapanacaktır. Gönder ve Çık'a tıklarsanız, uygulama kapanacak ve bir hata raporu gönderilecektir. ================================================ FILE: source/NBug_custom/Core/UI/WinForms/Full.vi.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Ứng dụng đã gặp sự cố và sẽ tự động đóng. Nếu bạn nhấp chuột vào nút "Thoát", ứng dụng sẽ đóng ngay lập tức. Nếu bạn nhấp chuột vào nút "Gửi và Thoát", ứng dụng sẽ đóng và đồng thời gửi một báo cáo lỗi về sự cố này. ================================================ FILE: source/NBug_custom/Core/UI/WinForms/Full.zh-Hans.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 应用程序已崩溃,现在将被关闭。如果单击“Quit”,应用程序将立即关闭。如果单击Send and Quit,应用程序将关闭并发送错误报告。 ================================================ FILE: source/NBug_custom/Core/UI/WinForms/Full.zh-Hant.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 應用程式已當機,現在將被關閉。如果點擊"Quit",應用程式將立即關閉,如果點擊Send and Quit,應用程式將關閉並傳送錯誤報告。 ================================================ FILE: source/NBug_custom/Core/UI/WinForms/Minimal.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- using System.Windows.Forms; using NBug.Core.Reporting.Info; using NBug.Properties; namespace NBug.Core.UI.WinForms { internal class Minimal { internal UIDialogResult ShowDialog(Report report) { MessageBox.Show( new Form {TopMost = true}, Settings.Resources.UI_Dialog_Minimal_Message, report.GeneralInfo.HostApplication + " " + Localization.UI_Dialog_Minimal_Title, MessageBoxButtons.OK, MessageBoxIcon.Warning); return new UIDialogResult(ExecutionFlow.BreakExecution, SendReport.Send); } } } ================================================ FILE: source/NBug_custom/Core/UI/WinForms/Normal.Designer.cs ================================================ namespace NBug.Core.UI.WinForms { partial class Normal { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.warningPictureBox = new System.Windows.Forms.PictureBox(); this.warningLabel = new System.Windows.Forms.Label(); this.exceptionMessageLabel = new System.Windows.Forms.Label(); this.quitButton = new System.Windows.Forms.Button(); this.continueButton = new System.Windows.Forms.Button(); ((System.ComponentModel.ISupportInitialize)(this.warningPictureBox)).BeginInit(); this.SuspendLayout(); // // warningPictureBox // this.warningPictureBox.Location = new System.Drawing.Point(12, 12); this.warningPictureBox.Name = "warningPictureBox"; this.warningPictureBox.Size = new System.Drawing.Size(32, 32); this.warningPictureBox.TabIndex = 0; this.warningPictureBox.TabStop = false; // // warningLabel // this.warningLabel.Location = new System.Drawing.Point(77, 12); this.warningLabel.Name = "warningLabel"; this.warningLabel.Size = new System.Drawing.Size(347, 47); this.warningLabel.TabIndex = 4; this.warningLabel.Text = "Unhandled exception has occurred in your application. If you click Continue, the " + "application will ignore this error and attempt to continue. If you click quit, t" + "he application will close immediately."; // // exceptionMessageLabel // this.exceptionMessageLabel.Location = new System.Drawing.Point(77, 64); this.exceptionMessageLabel.Name = "exceptionMessageLabel"; this.exceptionMessageLabel.Size = new System.Drawing.Size(347, 47); this.exceptionMessageLabel.TabIndex = 3; // // quitButton // this.quitButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.quitButton.Location = new System.Drawing.Point(329, 119); this.quitButton.Name = "quitButton"; this.quitButton.Size = new System.Drawing.Size(100, 23); this.quitButton.TabIndex = 1; this.quitButton.Text = "Quit"; this.quitButton.UseVisualStyleBackColor = true; this.quitButton.Click += new System.EventHandler(this.QuitButton_Click); // // continueButton // this.continueButton.Location = new System.Drawing.Point(223, 119); this.continueButton.Name = "continueButton"; this.continueButton.Size = new System.Drawing.Size(100, 23); this.continueButton.TabIndex = 2; this.continueButton.Text = "Continue"; this.continueButton.UseVisualStyleBackColor = true; this.continueButton.Click += new System.EventHandler(this.ContinueButton_Click); // // Normal // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.CancelButton = this.quitButton; this.ClientSize = new System.Drawing.Size(436, 148); this.Controls.Add(this.continueButton); this.Controls.Add(this.quitButton); this.Controls.Add(this.exceptionMessageLabel); this.Controls.Add(this.warningLabel); this.Controls.Add(this.warningPictureBox); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "Normal"; this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; this.Text = "{HostApplication} Error"; this.TopMost = true; ((System.ComponentModel.ISupportInitialize)(this.warningPictureBox)).EndInit(); this.ResumeLayout(false); } #endregion private System.Windows.Forms.PictureBox warningPictureBox; private System.Windows.Forms.Label warningLabel; private System.Windows.Forms.Label exceptionMessageLabel; private System.Windows.Forms.Button quitButton; private System.Windows.Forms.Button continueButton; } } ================================================ FILE: source/NBug_custom/Core/UI/WinForms/Normal.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- using System; using System.Drawing; using System.Windows.Forms; using NBug.Core.Reporting.Info; using NBug.Properties; namespace NBug.Core.UI.WinForms { internal partial class Normal : Form { private UIDialogResult uiDialogResult; internal Normal() { InitializeComponent(); Icon = Resources.NBug_icon_16; warningPictureBox.Image = SystemIcons.Warning.ToBitmap(); warningLabel.Text = Settings.Resources.UI_Dialog_Normal_Message; continueButton.Text = Settings.Resources.UI_Dialog_Normal_Continue_Button; quitButton.Text = Settings.Resources.UI_Dialog_Normal_Quit_Button; } internal UIDialogResult ShowDialog(Report report) { Text = string.Format("{0} {1}", report.GeneralInfo.HostApplication, Settings.Resources.UI_Dialog_Normal_Title); exceptionMessageLabel.Text = report.GeneralInfo.ExceptionMessage; ShowDialog(); return uiDialogResult; } private void ContinueButton_Click(object sender, EventArgs e) { uiDialogResult = new UIDialogResult(ExecutionFlow.ContinueExecution, SendReport.Send); Close(); } private void QuitButton_Click(object sender, EventArgs e) { uiDialogResult = new UIDialogResult(ExecutionFlow.BreakExecution, SendReport.Send); Close(); } } } ================================================ FILE: source/NBug_custom/Core/UI/WinForms/Normal.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ================================================ FILE: source/NBug_custom/Core/UI/WinForms/Panels/ExceptionDetailView.Designer.cs ================================================ namespace NBug.Core.UI.WinForms.Panels { partial class ExceptionDetailView { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.propertyLabel = new System.Windows.Forms.Label(); this.propertyTextBox = new System.Windows.Forms.TextBox(); this.propertyInformationTextBox = new System.Windows.Forms.TextBox(); this.closeButton = new System.Windows.Forms.Button(); this.topPanel = new System.Windows.Forms.Panel(); this.statusStrip = new System.Windows.Forms.StatusStrip(); this.topPanel.SuspendLayout(); this.SuspendLayout(); // // propertyLabel // this.propertyLabel.AutoSize = true; this.propertyLabel.Location = new System.Drawing.Point(2, 8); this.propertyLabel.Name = "propertyLabel"; this.propertyLabel.Size = new System.Drawing.Size(49, 13); this.propertyLabel.TabIndex = 0; this.propertyLabel.Text = "Property:"; // // propertyTextBox // this.propertyTextBox.Location = new System.Drawing.Point(57, 5); this.propertyTextBox.Name = "propertyTextBox"; this.propertyTextBox.Size = new System.Drawing.Size(441, 20); this.propertyTextBox.TabIndex = 2; // // propertyInformationTextBox // this.propertyInformationTextBox.Dock = System.Windows.Forms.DockStyle.Fill; this.propertyInformationTextBox.Location = new System.Drawing.Point(0, 32); this.propertyInformationTextBox.Multiline = true; this.propertyInformationTextBox.Name = "propertyInformationTextBox"; this.propertyInformationTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Both; this.propertyInformationTextBox.Size = new System.Drawing.Size(567, 169); this.propertyInformationTextBox.TabIndex = 3; this.propertyInformationTextBox.WordWrap = false; // // closeButton // this.closeButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.closeButton.Location = new System.Drawing.Point(504, 6); this.closeButton.Name = "closeButton"; this.closeButton.Size = new System.Drawing.Size(60, 20); this.closeButton.TabIndex = 1; this.closeButton.Text = "&Close"; this.closeButton.UseVisualStyleBackColor = true; this.closeButton.Click += new System.EventHandler(this.CloseButton_Click); // // topPanel // this.topPanel.Controls.Add(this.closeButton); this.topPanel.Dock = System.Windows.Forms.DockStyle.Top; this.topPanel.Location = new System.Drawing.Point(0, 0); this.topPanel.Name = "topPanel"; this.topPanel.Size = new System.Drawing.Size(567, 32); this.topPanel.TabIndex = 4; // // statusStrip // this.statusStrip.AutoSize = false; this.statusStrip.Location = new System.Drawing.Point(0, 201); this.statusStrip.Name = "statusStrip"; this.statusStrip.Size = new System.Drawing.Size(567, 17); this.statusStrip.TabIndex = 5; // // ExceptionDetailView // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.CancelButton = this.closeButton; this.ClientSize = new System.Drawing.Size(567, 218); this.Controls.Add(this.propertyInformationTextBox); this.Controls.Add(this.statusStrip); this.Controls.Add(this.propertyTextBox); this.Controls.Add(this.propertyLabel); this.Controls.Add(this.topPanel); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.SizableToolWindow; this.Name = "ExceptionDetailView"; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "Property Details"; this.TopMost = true; this.topPanel.ResumeLayout(false); this.ResumeLayout(false); this.PerformLayout(); } #endregion private System.Windows.Forms.Label propertyLabel; private System.Windows.Forms.TextBox propertyTextBox; private System.Windows.Forms.TextBox propertyInformationTextBox; private System.Windows.Forms.Button closeButton; private System.Windows.Forms.Panel topPanel; private System.Windows.Forms.StatusStrip statusStrip; } } ================================================ FILE: source/NBug_custom/Core/UI/WinForms/Panels/ExceptionDetailView.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- using System; using System.Windows.Forms; namespace NBug.Core.UI.WinForms.Panels { internal partial class ExceptionDetailView : Form { public ExceptionDetailView() { InitializeComponent(); } internal void ShowDialog(string property, string info) { propertyTextBox.Text = property; propertyInformationTextBox.Text = info; ShowDialog(); } private void CloseButton_Click(object sender, EventArgs e) { Close(); } } } ================================================ FILE: source/NBug_custom/Core/UI/WinForms/Panels/ExceptionDetailView.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 17, 17 ================================================ FILE: source/NBug_custom/Core/UI/WinForms/Panels/ExceptionDetails.Designer.cs ================================================ namespace NBug.Core.UI.WinForms.Panels { partial class ExceptionDetails { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Component Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.components = new System.ComponentModel.Container(); this.exceptionDetailsListView = new System.Windows.Forms.ListView(); this.propertyColumnHeader = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.informationColumnHeader = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.exceptionDetailsLabel = new System.Windows.Forms.Label(); this.exceptionLabel = new System.Windows.Forms.Label(); this.exceptionTreeView = new System.Windows.Forms.TreeView(); this.toolTip = new System.Windows.Forms.ToolTip(this.components); this.SuspendLayout(); // // exceptionDetailsListView // this.exceptionDetailsListView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.exceptionDetailsListView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { this.propertyColumnHeader, this.informationColumnHeader}); this.exceptionDetailsListView.FullRowSelect = true; this.exceptionDetailsListView.GridLines = true; this.exceptionDetailsListView.Location = new System.Drawing.Point(3, 110); this.exceptionDetailsListView.MultiSelect = false; this.exceptionDetailsListView.Name = "exceptionDetailsListView"; this.exceptionDetailsListView.Size = new System.Drawing.Size(455, 217); this.exceptionDetailsListView.TabIndex = 5; this.exceptionDetailsListView.UseCompatibleStateImageBehavior = false; this.exceptionDetailsListView.View = System.Windows.Forms.View.Details; this.exceptionDetailsListView.ItemMouseHover += new System.Windows.Forms.ListViewItemMouseHoverEventHandler(this.ExceptionDetailsListView_ItemMouseHover); this.exceptionDetailsListView.DoubleClick += new System.EventHandler(this.ExceptionDetailsListView_DoubleClick); // // propertyColumnHeader // this.propertyColumnHeader.Text = "Property"; this.propertyColumnHeader.Width = 101; // // informationColumnHeader // this.informationColumnHeader.Text = "Information"; this.informationColumnHeader.Width = 350; // // exceptionDetailsLabel // this.exceptionDetailsLabel.AutoSize = true; this.exceptionDetailsLabel.Location = new System.Drawing.Point(3, 92); this.exceptionDetailsLabel.Name = "exceptionDetailsLabel"; this.exceptionDetailsLabel.Size = new System.Drawing.Size(265, 13); this.exceptionDetailsLabel.TabIndex = 7; this.exceptionDetailsLabel.Text = "Exception Details (double click on items to see details):"; // // exceptionLabel // this.exceptionLabel.AutoSize = true; this.exceptionLabel.Location = new System.Drawing.Point(3, 4); this.exceptionLabel.Name = "exceptionLabel"; this.exceptionLabel.Size = new System.Drawing.Size(68, 13); this.exceptionLabel.TabIndex = 6; this.exceptionLabel.Text = "Exception(s):"; // // exceptionTreeView // this.exceptionTreeView.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.exceptionTreeView.Location = new System.Drawing.Point(3, 22); this.exceptionTreeView.Name = "exceptionTreeView"; this.exceptionTreeView.Size = new System.Drawing.Size(455, 60); this.exceptionTreeView.TabIndex = 4; this.exceptionTreeView.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.ExceptionTreeView_AfterSelect); // // ExceptionDetails // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.Controls.Add(this.exceptionDetailsListView); this.Controls.Add(this.exceptionDetailsLabel); this.Controls.Add(this.exceptionLabel); this.Controls.Add(this.exceptionTreeView); this.Name = "ExceptionDetails"; this.Size = new System.Drawing.Size(461, 330); this.ResumeLayout(false); this.PerformLayout(); } #endregion private System.Windows.Forms.ListView exceptionDetailsListView; private System.Windows.Forms.ColumnHeader propertyColumnHeader; private System.Windows.Forms.ColumnHeader informationColumnHeader; private System.Windows.Forms.Label exceptionDetailsLabel; private System.Windows.Forms.Label exceptionLabel; private System.Windows.Forms.TreeView exceptionTreeView; private System.Windows.Forms.ToolTip toolTip; } } ================================================ FILE: source/NBug_custom/Core/UI/WinForms/Panels/ExceptionDetails.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Windows.Forms; using NBug.Core.Util.Serialization; namespace NBug.Core.UI.WinForms.Panels { internal partial class ExceptionDetails : UserControl { private readonly Dictionary exceptionDetailsList = new(); public ExceptionDetails() { InitializeComponent(); } [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public int InformationColumnWidth { get { return exceptionDetailsListView.Columns[1].Width; } set { exceptionDetailsListView.Columns[1].Width = value; } } [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public int PropertyColumnWidth { get { return exceptionDetailsListView.Columns[0].Width; } set { exceptionDetailsListView.Columns[0].Width = value; } } internal void Initialize(SerializableException exception) { exceptionDetailsList.Add(exceptionTreeView.Nodes.Add(exception.Type), exception); if (exception.InnerException != null) { FillInnerExceptionTree(exception.InnerException, exceptionTreeView.Nodes[0]); } if (exception.InnerExceptions != null) { foreach (var innerException in exception.InnerExceptions) { FillInnerExceptionTree(innerException, exceptionTreeView.Nodes[0]); } } exceptionTreeView.ExpandAll(); DisplayExceptionDetails(exceptionTreeView.Nodes[0]); } private void DisplayExceptionDetails(TreeNode node) { var exception = exceptionDetailsList[node]; exceptionDetailsListView.SuspendLayout(); exceptionDetailsListView.Items.Clear(); if (exception.Type != null) { exceptionDetailsListView.Items.Add("Exception").SubItems.Add(exception.Type); } if (exception.Message != null) { exceptionDetailsListView.Items.Add("Message").SubItems.Add(exception.Message); } if (exception.TargetSite != null) { exceptionDetailsListView.Items.Add("Target Site").SubItems.Add(exception.TargetSite); } if (exception.InnerException != null) { exceptionDetailsListView.Items.Add("Inner Exception").SubItems.Add(exception.InnerException.Type); } if (exception.Source != null) { exceptionDetailsListView.Items.Add("Source").SubItems.Add(exception.Source); } if (exception.HelpLink != null) { exceptionDetailsListView.Items.Add("Help Link").SubItems.Add(exception.HelpLink); } if (exception.StackTrace != null) { exceptionDetailsListView.Items.Add("Stack Trace").SubItems.Add(exception.StackTrace); } if (exception.Data != null) { foreach (var pair in exception.Data) { exceptionDetailsListView.Items.Add(string.Format("Data[\"{0}\"]", pair.Key)) .SubItems.Add(pair.Value.ToString()); } } if (exception.ExtendedInformation != null) { foreach (var info in exception.ExtendedInformation) { var item = exceptionDetailsListView.Items.Add(info.Key); item.UseItemStyleForSubItems = false; item.Font = new Font(Font, FontStyle.Bold); item.SubItems.Add(info.Value.ToString()); } } exceptionDetailsListView.ResumeLayout(); } private void ExceptionDetailsListView_DoubleClick(object sender, EventArgs e) { using (var detailView = new ExceptionDetailView()) { detailView.ShowDialog(exceptionDetailsListView.SelectedItems[0].Text, exceptionDetailsListView.SelectedItems[0].SubItems[1].Text); } } private void ExceptionDetailsListView_ItemMouseHover(object sender, ListViewItemMouseHoverEventArgs e) { toolTip.RemoveAll(); toolTip.Show(e.Item.SubItems[1].Text, exceptionDetailsListView); } private void ExceptionTreeView_AfterSelect(object sender, TreeViewEventArgs e) { DisplayExceptionDetails(e.Node); } private void FillInnerExceptionTree(SerializableException innerException, TreeNode innerNode) { exceptionDetailsList.Add(innerNode.Nodes.Add(innerException.Type), innerException); if (innerException.InnerException != null) { FillInnerExceptionTree(innerException.InnerException, innerNode.Nodes[0]); } } } } ================================================ FILE: source/NBug_custom/Core/UI/WinForms/Panels/ExceptionDetails.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 17, 17 ================================================ FILE: source/NBug_custom/Core/UI/WinForms/WinFormsUI.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- using NBug.Core.Reporting.Info; using NBug.Core.Util.Exceptions; using NBug.Core.Util.Serialization; using NBug.Enums; namespace NBug.Core.UI.WinForms { /// /// This class is used to prevent statically referencing any WinForms dll from the UISelector.cs thus prevents /// any unnecessary assembly from getting loaded into the memory. /// internal static class WinFormsUI { internal static UIDialogResult ShowDialog(UIMode uiMode, SerializableException exception, Report report) { if (uiMode == UIMode.Minimal) { return new Minimal().ShowDialog(report); } if (uiMode == UIMode.Normal) { using (var ui = new Normal()) { return ui.ShowDialog(report); } } if (uiMode == UIMode.Full) { using (var ui = new Full()) { return ui.ShowDialog(exception, report); } } throw NBugConfigurationException.Create(() => Settings.UIMode, "Parameter supplied for settings property is invalid."); } } } ================================================ FILE: source/NBug_custom/Core/Util/ConnectionStringParser.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- using System; using System.Collections.Generic; using System.Text.RegularExpressions; using NBug.Core.Util.Exceptions; namespace NBug.Core.Util { public static class ConnectionStringParser { // Currently ; and = characters are illegal and needs preparsing and escaping public static Dictionary Parse(string connectionString) { try { // Pre-processing the connection string, detect escape sequence, trim trailing semicolon var data = new Dictionary(); var fields = Regex.Split(connectionString.TrimEnd(';'), @"(? // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- namespace NBug.Core.Util { internal enum ExceptionThread { Main, UI_WinForms, UI_WPF, Task } } ================================================ FILE: source/NBug_custom/Core/Util/Exceptions/NBugConfigurationException.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- using System; using System.Linq.Expressions; namespace NBug.Core.Util.Exceptions { [Serializable] public class NBugConfigurationException : NBugException { public NBugConfigurationException(string message, Exception inner) : base(message, inner) { MisconfiguredProperty = string.Empty; } private NBugConfigurationException(string propertyName, string message) : base(message) { MisconfiguredProperty = propertyName; } public string MisconfiguredProperty { get; set; } public static NBugConfigurationException Create(Expression> propertyExpression, string message) { return new NBugConfigurationException(((MemberExpression) propertyExpression.Body).Member.Name, message); } } } ================================================ FILE: source/NBug_custom/Core/Util/Exceptions/NBugException.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- using System; using System.Runtime.Serialization; namespace NBug.Core.Util.Exceptions { [Serializable] public class NBugException : Exception { public NBugException() { } public NBugException(string message) : base(message) { } public NBugException(string message, Exception inner) : base(message, inner) { } protected NBugException(SerializationInfo info, StreamingContext context) : base(info, context) { } } } ================================================ FILE: source/NBug_custom/Core/Util/Exceptions/NBugRuntimeException.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- using System; namespace NBug.Core.Util.Exceptions { [Serializable] public class NBugRuntimeException : NBugException { public NBugRuntimeException(string message, Exception inner) : base(message, inner) { } public NBugRuntimeException(string message) : base(message) { } } } ================================================ FILE: source/NBug_custom/Core/Util/Logging/Logger.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- using System; using System.Diagnostics; using System.IO; using System.Linq.Expressions; using NBug.Core.UI.Developer; using NBug.Core.Util.Exceptions; using NBug.Enums; namespace NBug.Core.Util.Logging { /// /// Uses method to log important messages. Also provides /// a /// event. If is set to true, a default "NBug.log" file is written to disk. /// /// /// A sample trace listener can easily be added to the current application with an app.config file looking as below: /// /// {?xml version="1.0"?} /// {configuration} /// {configSections} /// {/configSections} /// {system.diagnostics} /// {trace autoflush="true" indentsize="2"} /// {listeners} /// {add name="testAppListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="MyApplication.log" /} /// {/listeners} /// {/trace} /// {/system.diagnostics} /// {/configuration} /// /// internal static class Logger { [DebuggerStepThrough] static Logger() { if (Settings.WriteLogToDisk) { LogWritten += (message, category) => File.AppendAllText(Path.Combine(Settings.NBugDirectory, "NBug.log"), category + ": " + message + Environment.NewLine); } } /// /// First parameters is message string, second one is the category. /// internal static event Action LogWritten; [DebuggerStepThrough] internal static void Error(string message) { Write(message, LoggerCategory.NBugError); if (Settings.DisplayDeveloperUI) { using (var viewer = new InternalExceptionViewer()) { viewer.ShowDialog(new NBugRuntimeException(message)); } } if (Settings.ThrowExceptions) { throw new NBugRuntimeException(message); } } [DebuggerStepThrough] internal static void Error(string message, Exception exception) { Write(message + Environment.NewLine + "Exception: " + exception, LoggerCategory.NBugError); if (Settings.DisplayDeveloperUI) { using (var viewer = new InternalExceptionViewer()) { viewer.ShowDialog(exception); } } if (Settings.ThrowExceptions) { throw new NBugRuntimeException(message, exception); } } [DebuggerStepThrough] internal static void Error(Expression> propertyExpression, string message) { Write(message + " Misconfigured Property: " + ((MemberExpression) propertyExpression.Body).Member.Name, LoggerCategory.NBugError); if (Settings.DisplayDeveloperUI) { using (var viewer = new InternalExceptionViewer()) { viewer.ShowDialog(NBugConfigurationException.Create(propertyExpression, message)); } } if (Settings.ThrowExceptions) { throw NBugConfigurationException.Create(propertyExpression, message); } } [DebuggerStepThrough] internal static void Info(string message) { Write(message, LoggerCategory.NBugInfo); } [DebuggerStepThrough] internal static void Trace(string message) { Write(message, LoggerCategory.NBugTrace); } [DebuggerStepThrough] internal static void Warning(string message) { Write(message, LoggerCategory.NBugWarning); } [DebuggerStepThrough] private static void Write(string message, LoggerCategory category) { System.Diagnostics.Trace.Write(message + Environment.NewLine, category.ToString()); if (Settings.DisplayDeveloperUI) { // InternalLogViewer.LogEntry(message, category); } var handler = LogWritten; if (handler != null) { handler(message, category); } } } } ================================================ FILE: source/NBug_custom/Core/Util/ProtectedConfiguration.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- namespace NBug.Core.Util { internal class ProtectedConfiguration { } } ================================================ FILE: source/NBug_custom/Core/Util/PublicResources.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- using NBug.Properties; namespace NBug.Core.Util { public class PublicResources { private string ui_Console_Full_Message; private string ui_Console_Minimal_Message; private string ui_Console_Normal_Message; private string ui_Dialog_Full_Exception_Tab; private string ui_Dialog_Full_General_Tab; private string ui_Dialog_Full_How_to_Reproduce_the_Error_Notification; private string ui_Dialog_Full_Message; private string ui_Dialog_Full_Quit_Button; private string ui_Dialog_Full_Report_Contents_Tab; private string ui_Dialog_Full_Send_and_Quit_Button; private string ui_Dialog_Full_Title; private string ui_Dialog_Minimal_Message; private string ui_Dialog_Normal_Continue_Button; private string ui_Dialog_Normal_Message; private string ui_Dialog_Normal_Quit_Button; private string ui_Dialog_Normal_Title; public string UI_Console_Full_Message { get { return ui_Console_Full_Message ?? Localization.UI_Console_Full_Message; } set { ui_Console_Full_Message = value; } } public string UI_Console_Minimal_Message { get { return ui_Console_Minimal_Message ?? Localization.UI_Console_Minimal_Message; } set { ui_Console_Minimal_Message = value; } } public string UI_Console_Normal_Message { get { return ui_Console_Normal_Message ?? Localization.UI_Console_Normal_Message; } set { ui_Console_Normal_Message = value; } } public string UI_Dialog_Full_Exception_Tab { get { return ui_Dialog_Full_Exception_Tab ?? Localization.UI_Dialog_Full_Exception_Tab; } set { ui_Dialog_Full_Exception_Tab = value; } } public string UI_Dialog_Full_General_Tab { get { return ui_Dialog_Full_General_Tab ?? Localization.UI_Dialog_Full_General_Tab; } set { ui_Dialog_Full_General_Tab = value; } } public string UI_Dialog_Full_How_to_Reproduce_the_Error_Notification { get { return ui_Dialog_Full_How_to_Reproduce_the_Error_Notification ?? Localization.UI_Dialog_Full_How_to_Reproduce_the_Error_Notification; } set { ui_Dialog_Full_How_to_Reproduce_the_Error_Notification = value; } } public string UI_Dialog_Full_Message { get { return ui_Dialog_Full_Message ?? Localization.UI_Dialog_Full_Message; } set { ui_Dialog_Full_Message = value; } } public string UI_Dialog_Full_Quit_Button { get { return ui_Dialog_Full_Quit_Button ?? Localization.UI_Dialog_Full_Quit_Button; } set { ui_Dialog_Full_Quit_Button = value; } } public string UI_Dialog_Full_Report_Contents_Tab { get { return ui_Dialog_Full_Report_Contents_Tab ?? Localization.UI_Dialog_Full_Report_Contents_Tab; } set { ui_Dialog_Full_Report_Contents_Tab = value; } } public string UI_Dialog_Full_Send_and_Quit_Button { get { return ui_Dialog_Full_Send_and_Quit_Button ?? Localization.UI_Dialog_Full_Send_and_Quit_Button; } set { ui_Dialog_Full_Send_and_Quit_Button = value; } } public string UI_Dialog_Full_Title { get { return ui_Dialog_Full_Title ?? Localization.UI_Dialog_Full_Title; } set { ui_Dialog_Full_Title = value; } } public string UI_Dialog_Minimal_Message { get { return ui_Dialog_Minimal_Message ?? Localization.UI_Dialog_Minimal_Message; } set { ui_Dialog_Minimal_Message = value; } } public string UI_Dialog_Normal_Continue_Button { get { return ui_Dialog_Normal_Continue_Button ?? Localization.UI_Dialog_Normal_Continue_Button; } set { ui_Dialog_Normal_Continue_Button = value; } } public string UI_Dialog_Normal_Message { get { return ui_Dialog_Normal_Message ?? Localization.UI_Dialog_Normal_Message; } set { ui_Dialog_Normal_Message = value; } } public string UI_Dialog_Normal_Quit_Button { get { return ui_Dialog_Normal_Quit_Button ?? Localization.UI_Dialog_Normal_Quit_Button; } set { ui_Dialog_Normal_Quit_Button = value; } } public string UI_Dialog_Normal_Title { get { return ui_Dialog_Normal_Title ?? Localization.UI_Dialog_Normal_Title; } set { ui_Dialog_Normal_Title = value; } } } } ================================================ FILE: source/NBug_custom/Core/Util/Serialization/SerializableDictionary.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- using System; using System.Collections.Generic; using System.Xml; using System.Xml.Linq; using System.Xml.Schema; using System.Xml.Serialization; namespace NBug.Core.Util.Serialization { [Serializable] [XmlRoot("dictionary")] public class SerializableDictionary : Dictionary, IXmlSerializable { /// /// Initializes a new instance of the class. /// This is the default constructor provided for XML serializer. /// public SerializableDictionary() { } public SerializableDictionary(IDictionary dictionary) { if (dictionary == null) { throw new ArgumentNullException(); } foreach (var pair in dictionary) { Add(pair.Key, pair.Value); } } public XmlSchema GetSchema() { return null; } public void ReadXml(XmlReader reader) { /*if (reader.IsEmptyElement) { return; }*/ var inner = reader.ReadSubtree(); var xElement = XElement.Load(inner); if (xElement.HasElements) { foreach (var element in xElement.Elements()) { Add((TKey) Convert.ChangeType(element.Name.ToString(), typeof (TKey)), (TValue) Convert.ChangeType(element.Value, typeof (TValue))); } } inner.Close(); if (!reader.IsEmptyElement) reader.ReadEndElement(); } public void WriteXml(XmlWriter writer) { foreach (var key in Keys) { writer.WriteStartElement(key.ToString().Replace(" ", "")); // Check to see if we can actually serialize element if (this[key].GetType().IsSerializable) { // if it's Serializable doesn't mean serialization will succeed (IE. GUID and SQLError types) try { writer.WriteValue(this[key]); } catch (Exception) { // we're not Throwing anything here, otherwise evil thing will happen writer.WriteValue(this[key].ToString()); } } else { // If Type has custom implementation of ToString() we'll get something useful here // Otherwise we'll get Type string. (Still better than crashing). writer.WriteValue(this[key].ToString()); } writer.WriteEndElement(); } } } } ================================================ FILE: source/NBug_custom/Core/Util/Serialization/SerializableException.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- using System; using System.Collections; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; using System.Threading; using System.Xml; using System.Xml.Linq; using System.Xml.Serialization; namespace NBug.Core.Util.Serialization { [Serializable] public class SerializableException { /// /// Initializes a new instance of the class. /// Default constructor provided for XML serialization and de-serialization. /// public SerializableException() { } public SerializableException(Exception exception) { if (exception == null) { throw new ArgumentNullException(); } var oldCulture = Thread.CurrentThread.CurrentCulture; var oldUICulture = Thread.CurrentThread.CurrentUICulture; try { // Prefer messages in English, instead of in language of the user. Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; Type = exception.GetType().ToString(); if (exception.Data.Count != 0) { foreach (DictionaryEntry entry in exception.Data) { if (entry.Value != null) { // Assign 'Data' property only if there is at least one entry with non-null value if (Data == null) { Data = new SerializableDictionary(); } Data.Add(entry.Key, entry.Value); } } } if (exception.HelpLink != null) { HelpLink = exception.HelpLink; } if (exception.InnerException != null) { InnerException = new SerializableException(exception.InnerException); } /* if (exception is AggregateException) { this.InnerExceptions = new List(); foreach (var innerException in ((AggregateException)exception).InnerExceptions) { this.InnerExceptions.Add(new SerializableException(innerException)); } this.InnerExceptions.RemoveAt(0); }*/ Message = exception.Message != string.Empty ? exception.Message : string.Empty; if (exception.Source != null) { Source = exception.Source; } if (exception.StackTrace != null) { StackTrace = exception.StackTrace; } if (exception.TargetSite != null) { TargetSite = string.Format("{0} @ {1}", exception.TargetSite, exception.TargetSite.DeclaringType); } ExtendedInformation = GetExtendedInformation(exception); } finally { Thread.CurrentThread.CurrentCulture = oldCulture; Thread.CurrentThread.CurrentUICulture = oldUICulture; } } public SerializableDictionary Data { get; set; } public SerializableDictionary ExtendedInformation { get; set; } public string HelpLink { get; set; } public SerializableException InnerException { get; set; } public List InnerExceptions { get; set; } public string Message { get; set; } public string Source { get; set; } public string StackTrace { get; set; } // This will make TargetSite property XML serializable but RuntimeMethodInfo class does not have a parameterless // constructor thus the serializer throws an exception if full info is used public string TargetSite { get; set; } public string Type { get; set; } public override string ToString() { var serializer = XmlSerializer.FromTypes(new[] {typeof (SerializableException)})[0]; //var serializer = new XmlSerializer(typeof(SerializableException)); using (var stream = new MemoryStream()) { stream.SetLength(0); serializer.Serialize(stream, this); stream.Position = 0; var doc = XDocument.Load(XmlReader.Create(stream)); return doc.Root.ToString(); } } private SerializableDictionary GetExtendedInformation(Exception exception) { var extendedProperties = (from property in exception.GetType().GetProperties() where property.Name != "Data" && property.Name != "InnerExceptions" && property.Name != "InnerException" && property.Name != "Message" && property.Name != "Source" && property.Name != "StackTrace" && property.Name != "TargetSite" && property.Name != "HelpLink" && property.CanRead select property).ToArray(); if (extendedProperties.Any()) { var extendedInformation = new SerializableDictionary(); foreach ( var property in extendedProperties.Where(property => property.GetValue(exception, null) != null)) { extendedInformation.Add(property.Name, property.GetValue(exception, null)); } return extendedInformation; } return null; } } } ================================================ FILE: source/NBug_custom/Core/Util/Storage/StoragePath.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- using System; namespace NBug.Core.Util.Storage { /// /// This structure holds the information about storage path. It does emit its internal data either as string or /// type according to usage so it must be handled with care. /// public struct StoragePath { private static Enums.StoragePath storagePathEnum; private static string storagePathString; internal StoragePath(Enums.StoragePath storagePath) { storagePathEnum = storagePath; } internal StoragePath(string storagePath) { storagePathString = storagePath; storagePathEnum = Enums.StoragePath.Custom; } public static implicit operator StoragePath(Enums.StoragePath path) { return new StoragePath(path); } public static implicit operator StoragePath(string path) { foreach (Enums.StoragePath value in Enum.GetValues(typeof (Enums.StoragePath))) { if (value.ToString() == path) { return new StoragePath(value); } } return new StoragePath(path); } public static implicit operator Enums.StoragePath(StoragePath path) { return storagePathEnum; } public static implicit operator string(StoragePath path) { return storagePathString; } } } ================================================ FILE: source/NBug_custom/Core/Util/Storage/StoredItemFile.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- namespace NBug.Core.Util.Storage { internal enum StoredItemType { Exception, Report, MiniDump } // This class must remain internal otherwise it should not use constant strings internal static class StoredItemFile { internal const string Exception = "Exception.xml"; internal const string MiniDump = "MiniDump.mdmp"; internal const string Report = "Report.xml"; } } ================================================ FILE: source/NBug_custom/Core/Util/Storage/Storer.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- using System; using System.Collections.Generic; using System.IO; using System.IO.IsolatedStorage; using System.Linq; using NBug.Core.Util.Exceptions; using NBug.Core.Util.Logging; namespace NBug.Core.Util.Storage { /// /// Initializes a new instance of the Storage class. This class implements interface /// so it is better used with a using {...} statement. /// /// This class should be instantiated to work with a single file at once. internal class Storer : IDisposable { private bool disposed; private IsolatedStorageFile isoStore; private Stream stream; public string FileName { get; set; } public string FilePath { get; set; } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } ~Storer() { Dispose(false); } private static IEnumerable EnumerateFiles(string directory) { return Directory.GetFiles(directory) .Where(x => x.Substring(x.LastIndexOf('\\')).Contains("Exception_") && x.EndsWith(".zip")); } internal static int GetReportCount() { if (Settings.StoragePath == Enums.StoragePath.WindowsTemp) { var path = Path.Combine(Path.GetTempPath(), Settings.EntryAssembly.GetName().Name); return Directory.Exists(path) ? EnumerateFiles(path).Count() : 0; //.EnumerateFiles(path, "Exception_*.zip").Count() : 0; } if (Settings.StoragePath == Enums.StoragePath.CurrentDirectory) { return Directory.Exists(Settings.NBugDirectory) ? EnumerateFiles(Settings.NBugDirectory).Count() : 0; } if (Settings.StoragePath == Enums.StoragePath.IsolatedStorage) { using ( var isoFile = IsolatedStorageFile.GetStore( IsolatedStorageScope.User | IsolatedStorageScope.Assembly | IsolatedStorageScope.Domain, null, null)) { return isoFile.GetFileNames("Exception_*.zip").Count(); } } if (Settings.StoragePath == Enums.StoragePath.Custom) { var path = Path.GetFullPath(Settings.StoragePath); return Directory.Exists(path) ? EnumerateFiles(path).Count() : 0; } throw NBugConfigurationException.Create(() => Settings.StoragePath, "Parameter supplied for settings property is invalid."); } /// /// This function will get rid of the oldest files first. /// internal static void TruncateReportFiles() { TruncateReportFiles(Settings.MaxQueuedReports); } /// /// This function will get rid of the oldest files first. /// /// /// Maximum number of queued files to be stored. Setting this to 0 deletes all files. Settings this /// to anything less than zero will store infinite number of files. /// internal static void TruncateReportFiles(int maxQueuedReports) { if (maxQueuedReports < 0) { } else if (Settings.StoragePath == Enums.StoragePath.WindowsTemp) { var path = Path.Combine(Path.GetTempPath(), Settings.EntryAssembly.GetName().Name); TruncateFiles(path, maxQueuedReports); } else if (Settings.StoragePath == Enums.StoragePath.CurrentDirectory) { TruncateFiles(Settings.NBugDirectory, maxQueuedReports); } else if (Settings.StoragePath == Enums.StoragePath.IsolatedStorage) { using ( var isoFile = IsolatedStorageFile.GetStore( IsolatedStorageScope.User | IsolatedStorageScope.Assembly | IsolatedStorageScope.Domain, null, null)) { var reportCount = isoFile.GetFileNames("Exception_*.zip").Count(); if (reportCount > maxQueuedReports) { var extraCount = reportCount - maxQueuedReports; if (maxQueuedReports == 0) { Logger.Trace("Truncating all report files from the isolated storage."); } else { Logger.Trace("Truncating extra " + extraCount + " report files from the isolates storage."); } foreach (var file in isoFile.GetFileNames("Exception_*.zip")) { extraCount--; File.Delete(file); if (extraCount == 0) { break; } } } } } else if (Settings.StoragePath == Enums.StoragePath.Custom) { var path = Path.GetFullPath(Settings.StoragePath); TruncateFiles(path, maxQueuedReports); } else { throw NBugConfigurationException.Create(() => Settings.StoragePath, "Parameter supplied for settings property is invalid."); } } internal Stream CreateReportFile(string reportFileName) { FileName = reportFileName; if (Settings.StoragePath == Enums.StoragePath.WindowsTemp) { var directoryPath = Path.Combine(Path.GetTempPath(), Settings.EntryAssembly.GetName().Name); if (Directory.Exists(directoryPath) == false) { Directory.CreateDirectory(directoryPath); } FilePath = Path.Combine(directoryPath, FileName); Logger.Trace("Creating report file to Windows temp path: " + FilePath); return stream = new FileStream(FilePath, FileMode.Create, FileAccess.Write, FileShare.None); } if (Settings.StoragePath == Enums.StoragePath.CurrentDirectory) { FilePath = Path.Combine(Settings.NBugDirectory, FileName); Logger.Trace("Creating report file to entry assembly directory path: " + FilePath); return stream = new FileStream(FilePath, FileMode.Create, FileAccess.Write, FileShare.None); } if (Settings.StoragePath == Enums.StoragePath.IsolatedStorage) { FilePath = null; Logger.Trace("Creating report file to isolated storage path: [Isolated Storage Directory]\\" + FileName); return stream = new IsolatedStorageFileStream(FileName, FileMode.Create, FileAccess.Write, FileShare.None); } if (Settings.StoragePath == Enums.StoragePath.Custom) { var directoryPath = Path.GetFullPath(Settings.StoragePath); // In case this is a relative path if (Directory.Exists(directoryPath) == false) { Directory.CreateDirectory(directoryPath); } FilePath = Path.Combine(directoryPath, FileName); Logger.Trace("Creating report file to custom path: " + FilePath); return stream = new FileStream(FilePath, FileMode.Create, FileAccess.Write, FileShare.None); } throw NBugConfigurationException.Create(() => Settings.StoragePath, "Parameter supplied for settings property is invalid."); } internal void DeleteCurrentReportFile() { stream.Close(); if (stream is IsolatedStorageFileStream) { Logger.Trace("Deleting report file from isolated storage: " + FileName); isoStore.DeleteFile(FileName); } else { Logger.Trace("Deleting report file from path: " + FilePath); File.Delete(FilePath); } } /// /// Returns the first-in-queue report file. If there are no files queued, returns . /// /// Report file stream. internal Stream GetFirstReportFile() { if (disposed) { throw new ObjectDisposedException( "NBug.Utils.Storage was already destroyed and out of scope when accessed."); } if (Settings.StoragePath == Enums.StoragePath.WindowsTemp) { var path = Path.Combine(Path.GetTempPath(), Settings.EntryAssembly.GetName().Name); if (Directory.Exists(path) && EnumerateFiles(path).Any()) { try { FilePath = EnumerateFiles(path).First(); FileName = Path.GetFileName(FilePath); return stream = new FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.None); } catch (IOException exception) { // If the file is locked (as per IOException), then probably another instance of the library is already accessing // the file so let the other instance handle the file Logger.Error( "Cannot access the report file at Windows temp directory (it is probably locked, see the inner exception): " + FilePath, exception); return null; } } return null; } if (Settings.StoragePath == Enums.StoragePath.CurrentDirectory) { var path = Settings.NBugDirectory; if (path != null && Directory.Exists(path) && EnumerateFiles(path).Any()) { try { FilePath = EnumerateFiles(path).First(); FileName = Path.GetFileName(FilePath); return stream = new FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.None); } catch (IOException exception) { // If the file is locked (as per IOException), then probably another instance of the library is already accessing // the file so let the other instance handle the file Logger.Error( "Cannot access the report file at entry assembly directory (it is probably locked, see the inner exception): " + FilePath, exception); return null; } } return null; } if (Settings.StoragePath == Enums.StoragePath.IsolatedStorage) { isoStore = IsolatedStorageFile.GetStore( IsolatedStorageScope.User | IsolatedStorageScope.Assembly | IsolatedStorageScope.Domain, null, null); if (isoStore.GetFileNames("Exception_*.zip").Any()) { try { FilePath = null; FileName = isoStore.GetFileNames("Exception_*.zip").First(); stream = new IsolatedStorageFileStream(FileName, FileMode.Open, FileAccess.Read, FileShare.None); return stream; } catch (IOException exception) { // If the file is locked (as per IOException), then probably another instance of the library is already accessing // the file so let the other instance handle the file Logger.Error( "Cannot access the report file at isolated storage (it is probably locked, see the inner exception): [Isolated Storage Directory]\\" + FileName, exception); return null; } } return null; } if (Settings.StoragePath == Enums.StoragePath.Custom) { var path = Path.GetFullPath(Settings.StoragePath); if (Directory.Exists(path) && EnumerateFiles(path).Any()) { try { FilePath = EnumerateFiles(path).First(); FileName = Path.GetFileName(FilePath); return stream = new FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.None); } catch (IOException exception) { // If the file is locked (as per IOException), then probably another instance of the library is already accessing // the file so let the other instance handle the file Logger.Error( "Cannot access the report file from the given custom path (it is probably locked, see the inner exception): " + FilePath, exception); return null; } } return null; } throw NBugConfigurationException.Create(() => Settings.StoragePath, "Parameter supplied for settings property is invalid."); } private static void TruncateFiles(string path, int maxQueuedReports) { if (Directory.Exists(path)) { var reportCount = EnumerateFiles(path).Count(); if (reportCount > maxQueuedReports) { var extraCount = reportCount - maxQueuedReports; if (maxQueuedReports == 0) { Logger.Trace("Truncating all report files from: " + path); } else { Logger.Trace("Truncating extra " + extraCount + " report files from: " + path); } foreach (var file in EnumerateFiles(path)) { extraCount--; File.Delete(file); if (extraCount == 0) { break; } } } } } private void Dispose(bool disposing) { if (!disposed) { if (disposing) { // Dispose managed resources if (stream != null) { stream.Close(); } if (isoStore != null) { isoStore.Close(); } } // Clean up unmanaged resources } disposed = true; } } } ================================================ FILE: source/NBug_custom/Core/Util/Storage/ZipStorer.cs ================================================ // ZipStorer, by Jaime Olivares // Website: zipstorer.codeplex.com // Version: 2.35 (March 14, 2010) using System; using System.Collections.Generic; using System.IO; using System.IO.Compression; using System.Text; namespace NBug.Core.Util.Storage { /// /// Unique class for compression/decompression file. Represents a Zip file. /// internal class ZipStorer : IDisposable { #region Enums /// /// Compression method enumeration /// public enum Compression : ushort { /// /// Uncompressed storage /// Store = 0, /// /// Deflate compression method /// Deflate = 8 } #endregion Enums // File access for Open method // Static constructor. Just invoked once in order to create the CRC32 lookup table. #region Constructors and Destructors /// /// Initializes static members of the class. /// static ZipStorer() { // Generate CRC32 table CrcTable = new uint[256]; for (var i = 0; i < CrcTable.Length; i++) { var c = (uint) i; for (var j = 0; j < 8; j++) { if ((c & 1) != 0) { c = 3988292384 ^ (c >> 1); } else { c >>= 1; } } CrcTable[i] = c; } } #endregion Constructors and Destructors #region Implemented Interfaces #region IDisposable /// /// Closes the Zip file stream /// public void Dispose() { Close(); } #endregion IDisposable #endregion Implemented Interfaces /// /// Represents an entry in Zip file directory /// public struct ZipFileEntry { #region Public Methods /// /// Overriden method /// /// /// Filename in Zip /// public override string ToString() { return FilenameInZip; } #endregion Public Methods #region Constants and Fields /// /// User comment for file /// public string Comment; /// /// Compressed file size /// public uint CompressedSize; /// /// 32-bit checksum of entire file /// public uint Crc32; /// /// True if UTF8 encoding for filename and comments, false if default (CP 437) /// public bool EncodeUTF8; /// /// Offset of file inside Zip storage /// public uint FileOffset; /// /// Original file size /// public uint FileSize; /// /// Full path and filename as stored in Zip /// public string FilenameInZip; /// /// Offset of header information inside Zip storage /// public uint HeaderOffset; /// /// Size of header information /// public uint HeaderSize; /// /// Compression method /// public Compression Method; /// /// Last modification time of file /// public DateTime ModifyTime; #endregion Constants and Fields } #region Constants and Fields /// /// True if UTF8 encoding for filename and comments, false if default (CP 437) /// public bool EncodeUTF8; /// /// Force deflate algotithm even if it inflates the stored file. Off by default. /// public bool ForceDeflating; /// /// The crc table. /// private static readonly uint[] CrcTable; // Default filename encoder /// /// The default encoding. /// private static readonly Encoding DefaultEncoding = Encoding.ASCII; // List of files to store /// /// The files. /// private readonly List Files = new(); /// /// The access. /// private FileAccess Access; // Filename of storage file // Central dir image /// /// The central dir image. /// private byte[] CentralDirImage; /// /// The comment. /// private string Comment = string.Empty; // Existing files in zip /// /// The existing files. /// private ushort ExistingFiles; /// /// The file name. /// private string FileName; // Stream object of storage file /// /// The zip file stream. /// private Stream ZipFileStream; #endregion Constants and Fields #region Public Methods /// /// Method to create a new storage file /// /// /// Full path of Zip file to create /// /// /// General comment for Zip file /// /// /// A valid ZipStorer object /// public static ZipStorer Create(string _filename, string _comment) { Stream stream = new FileStream(_filename, FileMode.Create, FileAccess.ReadWrite); var zip = Create(stream, _comment); zip.Comment = _comment; zip.FileName = _filename; return zip; } /// /// Method to create a new zip storage in a stream /// /// /// /// /// /// /// A valid ZipStorer object /// public static ZipStorer Create(Stream _stream, string _comment) { var zip = new ZipStorer(); zip.Comment = _comment; zip.ZipFileStream = _stream; zip.Access = FileAccess.Write; return zip; } /// /// Method to open an existing storage file /// /// /// Full path of Zip file to open /// /// /// File access mode as used in FileStream constructor /// /// /// A valid ZipStorer object /// public static ZipStorer Open(string _filename, FileAccess _access) { Stream stream = new FileStream( _filename, FileMode.Open, _access == FileAccess.Read ? FileAccess.Read : FileAccess.ReadWrite); var zip = Open(stream, _access); zip.FileName = _filename; return zip; } /// /// Method to open an existing storage from stream /// /// /// Already opened stream with zip contents /// /// /// File access mode for stream operations /// /// /// A valid ZipStorer object /// public static ZipStorer Open(Stream _stream, FileAccess _access) { if (!_stream.CanSeek && _access != FileAccess.Read) { throw new InvalidOperationException("Stream cannot seek"); } var zip = new ZipStorer(); // zip.FileName = _filename; zip.ZipFileStream = _stream; zip.Access = _access; if (zip.ReadFileInfo()) { return zip; } throw new InvalidDataException(); } /// /// Removes one of many files in storage. It creates a new Zip file. /// /// /// Reference to the current Zip object /// /// /// List of Entries to remove from storage /// /// /// True if success, false if not /// /// /// This method only works for storage of type FileStream /// public static bool RemoveEntries(ref ZipStorer _zip, List _zfes) { if (!(_zip.ZipFileStream is FileStream)) { throw new InvalidOperationException("RemoveEntries is allowed just over streams of type FileStream"); } // Get full list of entries var fullList = _zip.ReadCentralDir(); // In order to delete we need to create a copy of the zip file excluding the selected items var tempZipName = Path.GetTempFileName(); var tempEntryName = Path.GetTempFileName(); try { var tempZip = Create(tempZipName, string.Empty); foreach (var zfe in fullList) { if (!_zfes.Contains(zfe)) { if (_zip.ExtractFile(zfe, tempEntryName)) { tempZip.AddFile(zfe.Method, tempEntryName, zfe.FilenameInZip, zfe.Comment); } } } _zip.Close(); tempZip.Close(); File.Delete(_zip.FileName); File.Move(tempZipName, _zip.FileName); _zip = Open(_zip.FileName, _zip.Access); } catch { return false; } finally { if (File.Exists(tempZipName)) { File.Delete(tempZipName); } if (File.Exists(tempEntryName)) { File.Delete(tempEntryName); } } return true; } /// /// Add full contents of a file into the Zip storage /// /// /// Compression method /// /// /// Full path of file to add to Zip storage /// /// /// Filename and path as desired in Zip directory /// /// /// Comment for stored file /// public void AddFile(Compression _method, string _pathname, string _filenameInZip, string _comment) { if (Access == FileAccess.Read) { throw new InvalidOperationException("Writing is not alowed"); } var stream = new FileStream(_pathname, FileMode.Open, FileAccess.Read); AddStream(_method, _filenameInZip, stream, File.GetLastWriteTime(_pathname), _comment); stream.Close(); } /// /// Add full contents of a stream into the Zip storage /// /// /// Compression method /// /// /// Filename and path as desired in Zip directory /// /// /// Stream object containing the data to store in Zip /// /// /// Modification time of the data to store /// /// /// Comment for stored file /// public void AddStream(Compression _method, string _filenameInZip, Stream _source, DateTime _modTime, string _comment) { if (Access == FileAccess.Read) { throw new InvalidOperationException("Writing is not alowed"); } long offset; if (Files.Count == 0) { offset = 0; } else { var last = Files[Files.Count - 1]; offset = last.HeaderOffset + last.HeaderSize; } // Prepare the fileinfo var zfe = new ZipFileEntry(); zfe.Method = _method; zfe.EncodeUTF8 = EncodeUTF8; zfe.FilenameInZip = NormalizedFilename(_filenameInZip); zfe.Comment = _comment == null ? string.Empty : _comment; // Even though we write the header now, it will have to be rewritten, since we don't know compressed size or crc. zfe.Crc32 = 0; // to be updated later zfe.HeaderOffset = (uint) ZipFileStream.Position; // offset within file of the start of this local record zfe.ModifyTime = _modTime; // Write local header WriteLocalHeader(ref zfe); zfe.FileOffset = (uint) ZipFileStream.Position; // Write file to zip (store) Store(ref zfe, _source); //_source.Close(); UpdateCrcAndSizes(ref zfe); Files.Add(zfe); } /// /// Updates central directory (if pertinent) and close the Zip storage /// /// /// This is a required step, unless automatic dispose is used /// public void Close() { if (Access != FileAccess.Read) { var centralOffset = (uint) ZipFileStream.Position; uint centralSize = 0; if (CentralDirImage != null) { ZipFileStream.Write(CentralDirImage, 0, CentralDirImage.Length); } for (var i = 0; i < Files.Count; i++) { var pos = ZipFileStream.Position; WriteCentralDirRecord(Files[i]); centralSize += (uint) (ZipFileStream.Position - pos); } if (CentralDirImage != null) { WriteEndRecord(centralSize + (uint) CentralDirImage.Length, centralOffset); } else { WriteEndRecord(centralSize, centralOffset); } } if (ZipFileStream != null) { ZipFileStream.Flush(); ZipFileStream.Dispose(); ZipFileStream = null; } } /// /// Copy the contents of a stored file into a physical file /// /// /// Entry information of file to extract /// /// /// Name of file to store uncompressed data /// /// /// True if success, false if not. /// /// /// Unique compression methods are Store and Deflate /// public bool ExtractFile(ZipFileEntry _zfe, string _filename) { // Make sure the parent directory exist var path = Path.GetDirectoryName(_filename); if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } // Check it is directory. If so, do nothing if (Directory.Exists(_filename)) { return true; } Stream output = new FileStream(_filename, FileMode.Create, FileAccess.Write); var result = ExtractFile(_zfe, output); if (result) { output.Close(); } File.SetCreationTime(_filename, _zfe.ModifyTime); File.SetLastWriteTime(_filename, _zfe.ModifyTime); return result; } /// /// Copy the contents of a stored file into an opened stream /// /// /// Entry information of file to extract /// /// /// Stream to store the uncompressed data /// /// /// True if success, false if not. /// /// /// Unique compression methods are Store and Deflate /// public bool ExtractFile(ZipFileEntry _zfe, Stream _stream) { if (!_stream.CanWrite) { throw new InvalidOperationException("Stream cannot be written"); } // check signature var signature = new byte[4]; ZipFileStream.Seek(_zfe.HeaderOffset, SeekOrigin.Begin); ZipFileStream.Read(signature, 0, 4); if (BitConverter.ToUInt32(signature, 0) != 0x04034b50) { return false; } // Select input stream for inflating or just reading Stream inStream; if (_zfe.Method == Compression.Store) { inStream = ZipFileStream; } else if (_zfe.Method == Compression.Deflate) { inStream = new DeflateStream(ZipFileStream, CompressionMode.Decompress, true); } else { return false; } // Buffered copy var buffer = new byte[16384]; ZipFileStream.Seek(_zfe.FileOffset, SeekOrigin.Begin); var bytesPending = _zfe.FileSize; while (bytesPending > 0) { var bytesRead = inStream.Read(buffer, 0, (int) Math.Min(bytesPending, buffer.Length)); _stream.Write(buffer, 0, bytesRead); bytesPending -= (uint) bytesRead; } _stream.Flush(); if (_zfe.Method == Compression.Deflate) { inStream.Dispose(); } return true; } /// /// Read all the file records in the central directory /// /// /// List of all entries in directory /// public List ReadCentralDir() { if (CentralDirImage == null) { throw new InvalidOperationException("Central directory currently does not exist"); } var result = new List(); for (var pointer = 0; pointer < CentralDirImage.Length;) { var signature = BitConverter.ToUInt32(CentralDirImage, pointer); if (signature != 0x02014b50) { break; } var encodeUTF8 = (BitConverter.ToUInt16(CentralDirImage, pointer + 8) & 0x0800) != 0; var method = BitConverter.ToUInt16(CentralDirImage, pointer + 10); var modifyTime = BitConverter.ToUInt32(CentralDirImage, pointer + 12); var crc32 = BitConverter.ToUInt32(CentralDirImage, pointer + 16); var comprSize = BitConverter.ToUInt32(CentralDirImage, pointer + 20); var fileSize = BitConverter.ToUInt32(CentralDirImage, pointer + 24); var filenameSize = BitConverter.ToUInt16(CentralDirImage, pointer + 28); var extraSize = BitConverter.ToUInt16(CentralDirImage, pointer + 30); var commentSize = BitConverter.ToUInt16(CentralDirImage, pointer + 32); var headerOffset = BitConverter.ToUInt32(CentralDirImage, pointer + 42); var headerSize = (uint) (46 + filenameSize + extraSize + commentSize); var encoder = encodeUTF8 ? Encoding.UTF8 : DefaultEncoding; var zfe = new ZipFileEntry(); zfe.Method = (Compression) method; zfe.FilenameInZip = encoder.GetString(CentralDirImage, pointer + 46, filenameSize); zfe.FileOffset = GetFileOffset(headerOffset); zfe.FileSize = fileSize; zfe.CompressedSize = comprSize; zfe.HeaderOffset = headerOffset; zfe.HeaderSize = headerSize; zfe.Crc32 = crc32; zfe.ModifyTime = DosTimeToDateTime(modifyTime); if (commentSize > 0) { zfe.Comment = encoder.GetString(CentralDirImage, pointer + 46 + filenameSize + extraSize, commentSize); } result.Add(zfe); pointer += 46 + filenameSize + extraSize + commentSize; } return result; } #endregion Public Methods /* DOS Date and time: MS-DOS date. The date is a packed value with the following format. Bits Description 0-4 Day of the month (131) 5-8 Month (1 = January, 2 = February, and so on) 9-15 Year offset from 1980 (add 1980 to get actual year) MS-DOS time. The time is a packed value with the following format. Bits Description 0-4 Second divided by 2 5-10 Minute (059) 11-15 Hour (023 on a 24-hour clock) */ #region Methods /// /// The date time to dos time. /// /// /// The _dt. /// /// /// The date time to dos time. /// private uint DateTimeToDosTime(DateTime _dt) { return (uint) ((_dt.Second/2) | (_dt.Minute << 5) | (_dt.Hour << 11) | (_dt.Day << 16) | (_dt.Month << 21) | ((_dt.Year - 1980) << 25)); } /// /// The dos time to date time. /// /// /// The _dt. /// /// /// private DateTime DosTimeToDateTime(uint _dt) { return new DateTime( (int) (_dt >> 25) + 1980, (int) (_dt >> 21) & 15, (int) (_dt >> 16) & 31, (int) (_dt >> 11) & 31, (int) (_dt >> 5) & 63, (int) (_dt & 31)*2); } /// /// The get file offset. /// /// /// The _header offset. /// /// /// The get file offset. /// private uint GetFileOffset(uint _headerOffset) { var buffer = new byte[2]; ZipFileStream.Seek(_headerOffset + 26, SeekOrigin.Begin); ZipFileStream.Read(buffer, 0, 2); var filenameSize = BitConverter.ToUInt16(buffer, 0); ZipFileStream.Read(buffer, 0, 2); var extraSize = BitConverter.ToUInt16(buffer, 0); return (uint) (30 + filenameSize + extraSize + _headerOffset); } /* CRC32 algorithm The 'magic number' for the CRC is 0xdebb20e3. The proper CRC pre and post conditioning is used, meaning that the CRC register is pre-conditioned with all ones (a starting value of 0xffffffff) and the value is post-conditioned by taking the one's complement of the CRC residual. If bit 3 of the general purpose flag is set, this field is set to zero in the local header and the correct value is put in the data descriptor and in the central directory. */ // Replaces backslashes with slashes to store in zip header /// /// The normalized filename. /// /// /// The _filename. /// /// /// The normalized filename. /// private string NormalizedFilename(string _filename) { var filename = _filename.Replace('\\', '/'); var pos = filename.IndexOf(':'); if (pos >= 0) { filename = filename.Remove(0, pos + 1); } return filename.Trim('/'); } // Reads the end-of-central-directory record /// /// The read file info. /// /// /// The read file info. /// private bool ReadFileInfo() { if (ZipFileStream.Length < 22) { return false; } try { ZipFileStream.Seek(-17, SeekOrigin.End); var br = new BinaryReader(ZipFileStream); do { ZipFileStream.Seek(-5, SeekOrigin.Current); var sig = br.ReadUInt32(); if (sig == 0x06054b50) { ZipFileStream.Seek(6, SeekOrigin.Current); var entries = br.ReadUInt16(); var centralSize = br.ReadInt32(); var centralDirOffset = br.ReadUInt32(); var commentSize = br.ReadUInt16(); // check if comment field is the very last data in file if (ZipFileStream.Position + commentSize != ZipFileStream.Length) { return false; } // Copy entire central directory to a memory buffer ExistingFiles = entries; CentralDirImage = new byte[centralSize]; ZipFileStream.Seek(centralDirOffset, SeekOrigin.Begin); ZipFileStream.Read(CentralDirImage, 0, centralSize); // Leave the pointer at the begining of central dir, to append new files ZipFileStream.Seek(centralDirOffset, SeekOrigin.Begin); return true; } } while (ZipFileStream.Position > 0); } catch { } return false; } /// /// The store. /// /// /// The _zfe. /// /// /// The _source. /// private void Store(ref ZipFileEntry _zfe, Stream _source) { var buffer = new byte[16384]; int bytesRead; uint totalRead = 0; Stream outStream; var posStart = ZipFileStream.Position; var sourceStart = _source.Position; if (_zfe.Method == Compression.Store) { outStream = ZipFileStream; } else { outStream = new DeflateStream(ZipFileStream, CompressionMode.Compress, true); } _zfe.Crc32 = 0 ^ 0xffffffff; do { bytesRead = _source.Read(buffer, 0, buffer.Length); totalRead += (uint) bytesRead; if (bytesRead > 0) { outStream.Write(buffer, 0, bytesRead); for (uint i = 0; i < bytesRead; i++) { _zfe.Crc32 = CrcTable[(_zfe.Crc32 ^ buffer[i]) & 0xFF] ^ (_zfe.Crc32 >> 8); } } } while (bytesRead == buffer.Length); outStream.Flush(); if (_zfe.Method == Compression.Deflate) { outStream.Dispose(); } _zfe.Crc32 ^= 0xffffffff; _zfe.FileSize = totalRead; _zfe.CompressedSize = (uint) (ZipFileStream.Position - posStart); // Verify for real compression if (_zfe.Method == Compression.Deflate && !ForceDeflating && _source.CanSeek && _zfe.CompressedSize > _zfe.FileSize) { // Start operation again with Store algorithm _zfe.Method = Compression.Store; ZipFileStream.Position = posStart; ZipFileStream.SetLength(posStart); _source.Position = sourceStart; Store(ref _zfe, _source); } } /// /// The update crc and sizes. /// /// /// The _zfe. /// private void UpdateCrcAndSizes(ref ZipFileEntry _zfe) { var lastPos = ZipFileStream.Position; // remember position ZipFileStream.Position = _zfe.HeaderOffset + 8; ZipFileStream.Write(BitConverter.GetBytes((ushort) _zfe.Method), 0, 2); // zipping method ZipFileStream.Position = _zfe.HeaderOffset + 14; ZipFileStream.Write(BitConverter.GetBytes(_zfe.Crc32), 0, 4); // Update CRC ZipFileStream.Write(BitConverter.GetBytes(_zfe.CompressedSize), 0, 4); // Compressed size ZipFileStream.Write(BitConverter.GetBytes(_zfe.FileSize), 0, 4); // Uncompressed size ZipFileStream.Position = lastPos; // restore position } /// /// The write central dir record. /// /// /// The _zfe. /// private void WriteCentralDirRecord(ZipFileEntry _zfe) { var encoder = _zfe.EncodeUTF8 ? Encoding.UTF8 : DefaultEncoding; var encodedFilename = encoder.GetBytes(_zfe.FilenameInZip); var encodedComment = encoder.GetBytes(_zfe.Comment); ZipFileStream.Write(new byte[] {80, 75, 1, 2, 23, 0xB, 20, 0}, 0, 8); ZipFileStream.Write(BitConverter.GetBytes((ushort) (_zfe.EncodeUTF8 ? 0x0800 : 0)), 0, 2); // filename and comment encoding ZipFileStream.Write(BitConverter.GetBytes((ushort) _zfe.Method), 0, 2); // zipping method ZipFileStream.Write(BitConverter.GetBytes(DateTimeToDosTime(_zfe.ModifyTime)), 0, 4); // zipping date and time ZipFileStream.Write(BitConverter.GetBytes(_zfe.Crc32), 0, 4); // file CRC ZipFileStream.Write(BitConverter.GetBytes(_zfe.CompressedSize), 0, 4); // compressed file size ZipFileStream.Write(BitConverter.GetBytes(_zfe.FileSize), 0, 4); // uncompressed file size ZipFileStream.Write(BitConverter.GetBytes((ushort) encodedFilename.Length), 0, 2); // Filename in zip ZipFileStream.Write(BitConverter.GetBytes((ushort) 0), 0, 2); // extra length ZipFileStream.Write(BitConverter.GetBytes((ushort) encodedComment.Length), 0, 2); ZipFileStream.Write(BitConverter.GetBytes((ushort) 0), 0, 2); // disk=0 ZipFileStream.Write(BitConverter.GetBytes((ushort) 0), 0, 2); // file type: binary ZipFileStream.Write(BitConverter.GetBytes((ushort) 0), 0, 2); // Internal file attributes ZipFileStream.Write(BitConverter.GetBytes((ushort) 0x8100), 0, 2); // External file attributes (normal/readable) ZipFileStream.Write(BitConverter.GetBytes(_zfe.HeaderOffset), 0, 4); // Offset of header ZipFileStream.Write(encodedFilename, 0, encodedFilename.Length); ZipFileStream.Write(encodedComment, 0, encodedComment.Length); } /* End of central dir record: end of central dir signature 4 bytes (0x06054b50) number of this disk 2 bytes number of the disk with the start of the central directory 2 bytes total number of entries in the central dir on this disk 2 bytes total number of entries in the central dir 2 bytes size of the central directory 4 bytes offset of start of central directory with respect to the starting disk number 4 bytes zipfile comment length 2 bytes zipfile comment (variable size) */ /// /// The write end record. /// /// /// The _size. /// /// /// The _offset. /// private void WriteEndRecord(uint _size, uint _offset) { var encoder = EncodeUTF8 ? Encoding.UTF8 : DefaultEncoding; var encodedComment = encoder.GetBytes(Comment); ZipFileStream.Write(new byte[] {80, 75, 5, 6, 0, 0, 0, 0}, 0, 8); ZipFileStream.Write(BitConverter.GetBytes((ushort) Files.Count + ExistingFiles), 0, 2); ZipFileStream.Write(BitConverter.GetBytes((ushort) Files.Count + ExistingFiles), 0, 2); ZipFileStream.Write(BitConverter.GetBytes(_size), 0, 4); ZipFileStream.Write(BitConverter.GetBytes(_offset), 0, 4); ZipFileStream.Write(BitConverter.GetBytes((ushort) encodedComment.Length), 0, 2); ZipFileStream.Write(encodedComment, 0, encodedComment.Length); } /// /// The write local header. /// /// /// The _zfe. /// private void WriteLocalHeader(ref ZipFileEntry _zfe) { var pos = ZipFileStream.Position; var encoder = _zfe.EncodeUTF8 ? Encoding.UTF8 : DefaultEncoding; var encodedFilename = encoder.GetBytes(_zfe.FilenameInZip); ZipFileStream.Write(new byte[] {80, 75, 3, 4, 20, 0}, 0, 6); // No extra header ZipFileStream.Write(BitConverter.GetBytes((ushort) (_zfe.EncodeUTF8 ? 0x0800 : 0)), 0, 2); // filename and comment encoding ZipFileStream.Write(BitConverter.GetBytes((ushort) _zfe.Method), 0, 2); // zipping method ZipFileStream.Write(BitConverter.GetBytes(DateTimeToDosTime(_zfe.ModifyTime)), 0, 4); // zipping date and time ZipFileStream.Write(new byte[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 12); // unused CRC, un/compressed size, updated later ZipFileStream.Write(BitConverter.GetBytes((ushort) encodedFilename.Length), 0, 2); // filename length ZipFileStream.Write(BitConverter.GetBytes((ushort) 0), 0, 2); // extra length ZipFileStream.Write(encodedFilename, 0, encodedFilename.Length); _zfe.HeaderSize = (uint) (ZipFileStream.Position - pos); } #endregion Methods } } ================================================ FILE: source/NBug_custom/Core/Util/Web/StreamUpload.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // // Originates from: http://www.andrescottwilson.com/posting-content-from-memory-stream-using-httpwebrequest-c/ // Changed for NBug by Michal Turecki // // -------------------------------------------------------------------------------------------------------------------- using System; using System.Collections.Specialized; using System.Globalization; using System.IO; using System.Net; using System.Text; namespace NBug.Core.Util.Web { public class StreamUpload { private readonly string boundary = string.Empty; private readonly MemoryStream outputStream = new(); private ICredentials credentials; private WebResponse response; public StreamUpload() { boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x", NumberFormatInfo.InvariantInfo); } public static StreamUpload Create() { return new StreamUpload(); } public StreamUpload Add(string name, string value) { WriteBoundaryToStream(outputStream, Environment.NewLine); WriteToStream( outputStream, Encoding.UTF8, string.Format("Content-Disposition: form-data; name=\"{0}\"{1}{1}", name, Environment.NewLine)); WriteToStream(outputStream, Encoding.UTF8, value + Environment.NewLine); return this; } public StreamUpload Add(Stream inputStream) { return Add(inputStream, "form", "file", "application/octet-stream"); } public StreamUpload Add(Stream inputStream, string formName, string fileName, string contentType) { // write content boundary start WriteBoundaryToStream(outputStream, Environment.NewLine); WriteToStream( outputStream, Encoding.UTF8, string.Format("Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"{2}", formName, fileName, Environment.NewLine)); WriteToStream(outputStream, Encoding.UTF8, string.Format("Content-Type: {0}{1}{1}", contentType, Environment.NewLine)); var buffer = new byte[inputStream.Length]; var bytesRead = 0; while ((bytesRead = inputStream.Read(buffer, 0, buffer.Length)) != 0) { outputStream.Write(buffer, 0, bytesRead); } // must include a new line before writing the end boundary WriteToStream(outputStream, Encoding.ASCII, Environment.NewLine); // make sure we end boundary now as the content is finished WriteEndBoundaryToStream(outputStream); return this; } public StreamUpload AddNameValues(NameValueCollection nameValues) { foreach (string name in nameValues.Keys) { Add(name, nameValues[name]); } return this; } public StreamUpload Clear() { outputStream.Close(); response = null; return this; } public string Response() { return (response == null) ? string.Empty : new StreamReader(response.GetResponseStream() ?? throw new InvalidOperationException("GetResponseStream null"), Encoding.UTF8).ReadToEnd(); } public StreamUpload Upload(string url) { var request = (HttpWebRequest)WebRequest.Create(url); request.ContentType = string.Format("multipart/form-data; boundary={0}", boundary); request.Method = "POST"; if (credentials != null) { var user = credentials.GetCredential(request.RequestUri, "Basic"); var auth = string.Format("{0}:{1}", user.UserName, user.Password); request.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes(auth))); } WriteToHttpStream(request, outputStream); response = request.GetResponse(); return this; } public StreamUpload WithCredentials(ICredentials credentials) { this.credentials = credentials; return this; } private void WriteBoundaryToStream(MemoryStream stream, string endDeliminator) { WriteToStream(stream, Encoding.ASCII, string.Format("--{0}{1}", boundary, endDeliminator)); } private void WriteEndBoundaryToStream(MemoryStream stream) { WriteBoundaryToStream(stream, "--"); } private void WriteNameValuesToStream(MemoryStream stream, NameValueCollection nameValues) { foreach (string name in nameValues.Keys) { WriteBoundaryToStream(stream, Environment.NewLine); WriteToStream(stream, Encoding.UTF8, string.Format("Content-Disposition: form-data; name=\"{0}\"{1}{1}", name, Environment.NewLine)); WriteToStream(stream, Encoding.UTF8, nameValues[name] + Environment.NewLine); } } private void WriteToHttpStream(HttpWebRequest request, MemoryStream outputStream) { request.ContentLength = outputStream.Length; using (var requestStream = request.GetRequestStream()) { outputStream.Position = 0; var tempBuffer = new byte[outputStream.Length]; outputStream.Read(tempBuffer, 0, tempBuffer.Length); outputStream.Close(); requestStream.Write(tempBuffer, 0, tempBuffer.Length); requestStream.Close(); } } private void WriteToStream(MemoryStream stream, Encoding encoding, string output) { var headerbytes = encoding.GetBytes(output); stream.Write(headerbytes, 0, headerbytes.Length); } } } ================================================ FILE: source/NBug_custom/Enums/LoggerCategory.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- namespace NBug.Enums { public enum LoggerCategory { /// /// This category outputs most detailed information about the internal state of the library. Every single major event /// (like /// generating a bug report, submitting a bug report, truncating internal files, etc.) is logged in this category. /// NBugTrace, /// /// This category outputs results of substantial events like the server response after submitting a bug report to the a /// server. /// NBugInfo, /// /// This category outputs warning messages from non-exceptional but important errors like a missing or inaccessable /// files. /// NBugWarning, /// /// This category outputs error messages for exceptional and critical situations. These situations generally disable /// some functionality /// of the library or halts the execution of some code path. If not in release mode, an exception is thrown for error /// messages. /// NBugError } } ================================================ FILE: source/NBug_custom/Enums/MiniDumpType.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- namespace NBug.Enums { public enum MiniDumpType { /// /// Generate no minidump at all. /// None, /// /// Generates the smallest possible minidump still with useful information. Dump size is about ~100KB compressed. /// Tiny, /// /// Generates minidump with private read write memory and data segments. This mode allows retreiving of local values /// and the stack /// variables. Dump size is about ~5MB compressed. /// Normal, /// /// Generates full application memory dump. This simply dump all memory used by the process. Dump size is about ~100MB /// compressed. /// Full } } ================================================ FILE: source/NBug_custom/Enums/StoragePath.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- namespace NBug.Enums { public enum StoragePath { /// /// %Temp% directory is the default storage. Usually set to 'C:\Documents and Settings\Username\Local Settings\Temp'. /// WindowsTemp, /// /// Initial working directory, i.e. where the executing assembly (MyProduct.exe) is located. /// CurrentDirectory, /// /// User's isolated storage store (application scope). /// IsolatedStorage, /// /// Custom path should be a full path like 'C:\Documents and Settings\MyUser\Local Settings\Temp'. /// /// Path should not have a trailing slash. If the directory doesn't exist, it is created first. Custom } } ================================================ FILE: source/NBug_custom/Enums/UIMode.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- namespace NBug.Enums { public enum UIMode { /// /// Automatic mode selection is the default setting. Mode and provider is automatically selected for different /// application types. /// Auto, /// /// No user interface is displayed at all. All the exception handling and bug reporting process is silent. In this /// mode, termination of /// of the host application can be skipped altogether via /// None, /// /// Minimal user interface is displayed. This consists of a simple message box for WinForms and WPF, and a single line /// of information /// message for console applications. /// Minimal, /// /// Normal user interface is displayed to the user, which strikes a balance between the level of details shown about /// the exception and /// being still user friendly. This closely replicates the original interface displayed by CLR in case of unhandled /// exceptions. /// Normal, /// /// Full blown user interface is displayed to the user. This interface contains as much detail about the exception and /// the application /// as possible. This is very useful for power users. /// Full } } ================================================ FILE: source/NBug_custom/Enums/UIProvider.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- namespace NBug.Enums { public enum UIProvider { /// /// Automatic provider selection is the default setting. /// Auto, /// /// Only the console is used to display the interface and interact with the user if necessary. /// Console, /// /// Windows Forms interface is used for all UI displayed to the user. /// WinForms, /// /// Windows Presentation Foundation interface is used for all UI displayed to the user. /// WPF, /// /// Custom UIProvider. /// Custom } } ================================================ FILE: source/NBug_custom/Events/CustomSubmissionEventArgs.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- using System; using System.IO; using NBug.Core.Reporting.Info; using NBug.Core.Util.Serialization; namespace NBug.Events { public class CustomSubmissionEventArgs : EventArgs { internal CustomSubmissionEventArgs(string fileName, Stream file, Report report, SerializableException exception) { FileName = fileName; File = file; Report = report; Exception = exception; Result = false; } public SerializableException Exception { get; private set; } public Stream File { get; private set; } public string FileName { get; private set; } public Report Report { get; private set; } public bool Result { get; set; } } } ================================================ FILE: source/NBug_custom/Events/CustomUIEventArgs.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- using System; using NBug.Core.Reporting.Info; using NBug.Core.UI; using NBug.Core.Util.Serialization; using NBug.Enums; namespace NBug.Events { public class CustomUIEventArgs : EventArgs { internal CustomUIEventArgs(UIMode uiMode, SerializableException exception, Report report) { UIMode = uiMode; Report = report; Exception = exception; Result = new UIDialogResult(ExecutionFlow.BreakExecution, SendReport.DoNotSend); } public SerializableException Exception { get; private set; } public Report Report { get; private set; } public UIDialogResult Result { get; set; } public UIMode UIMode { get; private set; } } } ================================================ FILE: source/NBug_custom/Exceptions.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- using System; using NBug.Core.Reporting; using NBug.Core.Util; namespace NBug { public static class Exceptions { /// /// Submits a bug report for the given exception. This function useful for submitting bug reports inside a try-catch /// block. /// Note that this function uses the NBug configuration so it will use the pre-configured UI and submission settings. /// /// The exception to submit as the bug report. public static void Report(Exception exception) { // Below never exits application by itself (by design) so execution of the application continues normally new BugReport().Report(exception, ExceptionThread.Main); } } } ================================================ FILE: source/NBug_custom/Handler.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- using System; using System.Diagnostics.Tracing; using System.Threading; using System.Windows.Forms; using Microsoft.Win32.Interop; using NBug.Core.Reporting; using NBug.Core.UI; using NBug.Core.Util; using NBug.Core.Util.Logging; using Dispatcher = NBug.Core.Submission.Dispatcher; namespace NBug { public static class Handler { static Handler() { // Submit any queued reports on a seperate thread asynchronously, while exceptions handlers are being set); if (!Settings.SkipDispatching) { new Dispatcher(Settings.DispatcherIsAsynchronous); } } // Using delegates to make sure that static constructor gets called on delegate access /// /// Used for handling WinForms exceptions bound to the UI thread. /// Handles the events in namespace. /// public static ThreadExceptionEventHandler ThreadException { get { { return ThreadExceptionHandler; } } } /// /// Used for handling general exceptions bound to the main thread. /// Handles the events in namespace. /// public static UnhandledExceptionEventHandler UnhandledException { get { return UnhandledExceptionHandler; } } /// /// Used for handling WinForms exceptions bound to the UI thread. /// Handles the events in namespace. /// /// Exception sender object. /// Real exception is in: e.Exception private static void ThreadExceptionHandler(object sender, ThreadExceptionEventArgs e) { if (HandleOutdatedWindowsCrash(e.Exception) && Settings.HandleExceptions) { Logger.Trace("Starting to handle a System.Windows.Forms.Application.ThreadException."); // WinForms UI thread exceptions do not propagate to more general handlers unless: Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException); var executionFlow = new BugReport().Report(e.Exception, ExceptionThread.UI_WinForms); if (executionFlow == ExecutionFlow.BreakExecution) { Environment.Exit(0); } } } /// /// Used for handling general exceptions bound to the main thread. /// Handles the events in namespace. /// /// Exception sender object. /// Real exception is in: ((Exception)e.ExceptionObject) private static void UnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs e) { if (HandleOutdatedWindowsCrash(e.ExceptionObject as Exception) && Settings.HandleExceptions) { Logger.Trace("Starting to handle a System.AppDomain.UnhandledException."); var executionFlow = new BugReport().Report((Exception) e.ExceptionObject, ExceptionThread.Main); if (executionFlow == ExecutionFlow.BreakExecution) { Environment.Exit(0); } } } private static bool HandleOutdatedWindowsCrash(Exception dnfe) { // DllNotFoundException, EntryPointNotFoundException, possibly others if (dnfe != null) { if (dnfe.Message.Contains(@"'api-ms-win-core-com-l1-1-0.dll'")) { MessageBox.Show("It seems like you're running an unsupported version of Windows. Please make sure you have all of the latest Windows service packs and updates installed and try again.\n\n" + "If updating didn't help you may need to use an older version of BCUninstaller. Check the README.md file for more information.", "Unsupported Windows Version", MessageBoxButtons.OK, MessageBoxIcon.Error); // Do not let NBug handle this, it only clogs up the error reports Environment.Exit((int)ResultWin32.ERROR_DLL_NOT_FOUND); return false; } } return true; } } } ================================================ FILE: source/NBug_custom/Helpers/EmailDestinationBuilder.cs ================================================ using System.Net; using System.Net.Mail; using System.Text; namespace NBug.Helpers { public class EmailDestinationBuilder { private readonly MailAddress[] _destinationAddresses; private readonly MailAddress _fromAddress; private readonly string _serverName; private MailAddress[] _blindCarbonCopyAddresses; private MailAddress[] _carbonCopyAddresses; private string _customBody; private string _fromName; private MailPriority? _mailPriority; private string _replyTo; private bool _sendAttachments; private int _smtpPort = 465; private string _smtpUserName; private string _smtpUserPassword; private string _subject; private bool _useSsl = true; public EmailDestinationBuilder(MailAddress fromAddress, MailAddress[] destinationAddresses, string serverName) { _serverName = serverName; _fromAddress = fromAddress; _destinationAddresses = destinationAddresses; _sendAttachments = false; } public EmailDestinationBuilder Bcc(MailAddress[] blindCarbonCopyAddresses) { _blindCarbonCopyAddresses = blindCarbonCopyAddresses; return this; } public EmailDestinationBuilder Body(string body) { _customBody = body; return this; } /* Type=Mail; * From=my_tracker@gmail.com; * FromName=NBug Error Reporter; * To=bugtracker@mycompany.com,someone@dummy.com,my_tracker@gmail.com; * Cc=; * Bcc=; * ReplyTo=; * UseAttachment=false; * CustomSubject=; * CustomBody=; * SmtpServer=smtp.gmail.com; * UseSSL=yes; * Port=465; * Priority=; * UseAuthentication=yes; * Username=my_tracker@gmail.com; * Password=mypassword; */ public string Build() { var sb = new StringBuilder(); sb.Append("Type=Mail;"); sb.AppendFormat("From={0};", _fromAddress.Address); if (!string.IsNullOrEmpty(_fromName)) { sb.AppendFormat("FromName={0};", _fromName); } sb.Append("To="); foreach (var address in _destinationAddresses) { sb.AppendFormat("{0},", address.Address); } sb.Length--; sb.Append(";"); if (_carbonCopyAddresses != null && _carbonCopyAddresses.Length > 0) { sb.Append("Cc="); foreach (var address in _carbonCopyAddresses) { sb.AppendFormat("{0},", address.Address); } sb.Length--; sb.Append(";"); } if (_blindCarbonCopyAddresses != null && _blindCarbonCopyAddresses.Length > 0) { sb.Append("Bcc="); foreach (var address in _blindCarbonCopyAddresses) { sb.AppendFormat("{0},", address.Address); } sb.Length--; sb.Append(";"); } if (!string.IsNullOrEmpty(_replyTo)) { sb.AppendFormat("ReplyTo={0};", _replyTo); } sb.AppendFormat("UseAttachment={0};", _sendAttachments ? "true" : "false"); if (!string.IsNullOrEmpty(_subject)) { sb.AppendFormat("CustomSubject={0};", _subject); } if (!string.IsNullOrEmpty(_customBody)) { sb.AppendFormat("CustomBody={0};", _customBody); } sb.AppendFormat("SmtpServer={0};", _serverName); sb.Append("UseSSL="); sb.Append(_useSsl ? "yes" : "no"); sb.Append(";"); sb.AppendFormat("Port={0};", _smtpPort); if (_mailPriority.HasValue) { sb.AppendFormat("Priority={0};", _mailPriority); } if (string.IsNullOrEmpty(_smtpUserName)) { sb.Append("UseAuthentication=no;"); } else { sb.Append("UseAuthentication=yes;"); sb.AppendFormat("Username={0};", _smtpUserName); sb.AppendFormat("Password={0};", _smtpUserPassword); } return sb.ToString(); } public EmailDestinationBuilder Cc(MailAddress[] carbonCopyAddresses) { _carbonCopyAddresses = carbonCopyAddresses; return this; } public EmailDestinationBuilder FromName(string fromName) { _fromName = fromName; return this; } public EmailDestinationBuilder Priority(MailPriority mailPriority) { _mailPriority = mailPriority; return this; } public EmailDestinationBuilder ReplyTo(string replyTo) { _replyTo = replyTo; return this; } public EmailDestinationBuilder SendAttachments() { _sendAttachments = true; return this; } public EmailDestinationBuilder Subject(string subject) { _subject = subject; return this; } public EmailDestinationBuilder UseServer(bool useSecureSocketLayer, int port, NetworkCredential credential) { _useSsl = useSecureSocketLayer; _smtpPort = port; if (credential != null) { _smtpUserName = credential.UserName; _smtpUserPassword = credential.Password; } return this; } public EmailDestinationBuilder UseServer(bool useSecureSocketLayer, NetworkCredential credential) { return UseServer(useSecureSocketLayer, useSecureSocketLayer ? 465 : 25, credential); } } } ================================================ FILE: source/NBug_custom/NBug.Configurator/NBug.Configurator.exe.config ================================================ ================================================ FILE: source/NBug_custom/NBug.Configurator/NBug.Examples.WinForms.exe.config ================================================ ================================================ FILE: source/NBug_custom/NBug.csproj ================================================  Library true false 1 True True Localization.resx True True Resources.resx ResXFileCodeGenerator Localization.Designer.cs ResXFileCodeGenerator Resources.Designer.cs PreserveNewest Never ================================================ FILE: source/NBug_custom/NBug_LICENSE.md ================================================ The MIT License Copyright (c) 2011 Teoman Soygul and contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: source/NBug_custom/NBug_README.md ================================================ # [![NBug](http://www.soygul.com/wp-content/uploads/2011/07/NBug_logo.png)](http://www.soygul.com/projects/nbug/) NBug is a .NET library created to automate the bug reporting process. It automatically creates and sends: * Bug reports, * Crash reports with minidump, * Error/exception reports with stack trace + ext. info. It can also be set up as a user feedback system (i.e. feature requests). ## Quickstart Read the quickstart here: http://www.soygul.com/projects/nbug/ ## Questions You can post your question on StackOverflow with NBug tag: http://stackoverflow.com/questions/tagged/nbug ## Get it on [NuGet] (https://www.nuget.org/packages/NBug/) ```powershell Install-Package NBug ``` ## CodePlex Home Old (up to v1.1.1 release) project source is hosted at CodePlex, where you can find more information about the project: http://nbug.codeplex.com/ ================================================ FILE: source/NBug_custom/Properties/AssemblyInfo.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- using System; 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("NBug")] [assembly: AssemblyDescription("NBug bug reporting library created by Teoman Soygul.")] [assembly: AssemblyCulture("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("NBug")] [assembly: AssemblyCopyright("Copyright © 2013 Teoman Soygul")] [assembly: AssemblyTrademark("")] #if DEBUG [assembly: AssemblyConfiguration("Debug")] #else [assembly: AssemblyConfiguration("Release")] #endif // 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("6c55f06b-1a75-4e10-ad9a-168604ee2d91")] // Set up for unit testing /* [assembly: InternalsVisibleTo("NBug.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100298c7bc6603288f349c24fe85cebfba2efbc6a88af29805efc852b93a86ba3c2e0a6b9979f49803b579387fcff27b2e97526b8001b3a68e0785da60352f9918a433cc4e7c3b143341289b10c0fd250d8aeddd5edecb049072d5a78c2eecb42fc5e3e5c32161cfc445bdc8dc366b0e52389cc50b07168b45d411c56e541b5bdae")] [assembly: InternalsVisibleTo("NBug.Configurator, PublicKey=0024000004800000940000000602000000240000525341310004000001000100298c7bc6603288f349c24fe85cebfba2efbc6a88af29805efc852b93a86ba3c2e0a6b9979f49803b579387fcff27b2e97526b8001b3a68e0785da60352f9918a433cc4e7c3b143341289b10c0fd250d8aeddd5edecb049072d5a78c2eecb42fc5e3e5c32161cfc445bdc8dc366b0e52389cc50b07168b45d411c56e541b5bdae")] */ /* * Basic rules to become CLS compilant is below: * 1. Unsigned types should not be part of the public interface of the class. What this means is public fields should not * have unsigned types like uint or ulong, public methods should not return unsigned types, parameters passed to public * function should not have unsigned types. However unsigned types can be part of private members. * 2. Unsafe types like pointers should not be used with public members. However they can be used with private members. * 3. Class names and member names should not differ only based on their case. For example we cannot have two methods * named MyMethod and MYMETHOD. * 4. Only properties and methods may be overloaded, Operators should not be overloaded. */ [assembly: CLSCompliant(true)] // 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.2")] // This is also assigned to 'AssemblyInformationalVersion' which is the product version // Standard Way: [major].[minor].[bugfix].[build] // .NET Convention: Third digit is the auto-incremented build version. Fourth digit is revision, which is service pack no [assembly: AssemblyFileVersion("1.2.0.0")] /* * AssemblyVersion should only be changed for major changes or breaking changes since any change to the * AssemblyVersion would force every .NET application referencing the assembly to re-compile against the * new version! * * Do not change the AssemblyVersion for a servicing release which is intended to be backwards compatible. * Do change the AssemblyVersion for a release that you know has breaking changes. * * Remember that it’s the AssemblyFileVersion that contains all the interesting servicing information * (it’s the Revision part of this version that tells you what Service Pack you’re on) */ ================================================ FILE: source/NBug_custom/Properties/Localization.Designer.cs ================================================ //------------------------------------------------------------------------------ // // This code was generated by a tool. // Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ namespace NBug.Properties { using System; /// /// A strongly-typed resource class, for looking up localized strings, etc. /// // This class was auto-generated by the StronglyTypedResourceBuilder // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Localization { private static global::System.Resources.ResourceManager resourceMan; private static global::System.Globalization.CultureInfo resourceCulture; [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] internal Localization() { } /// /// Returns the cached ResourceManager instance used by this class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("NBug.Properties.Localization", typeof(Localization).Assembly); resourceMan = temp; } return resourceMan; } } /// /// Overrides the current thread's CurrentUICulture property for all /// resource lookups using this strongly typed resource class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Globalization.CultureInfo Culture { get { return resourceCulture; } set { resourceCulture = value; } } /// /// Looks up a localized string similar to Unhandled exception occurred. Closing application.. /// internal static string UI_Console_Full_Message { get { return ResourceManager.GetString("UI_Console_Full_Message", resourceCulture); } } /// /// Looks up a localized string similar to Unhandled exception occurred. Closing application.. /// internal static string UI_Console_Minimal_Message { get { return ResourceManager.GetString("UI_Console_Minimal_Message", resourceCulture); } } /// /// Looks up a localized string similar to Unhandled exception occurred. Closing application.. /// internal static string UI_Console_Normal_Message { get { return ResourceManager.GetString("UI_Console_Normal_Message", resourceCulture); } } /// /// Looks up a localized string similar to Exception. /// internal static string UI_Dialog_Full_Exception_Tab { get { return ResourceManager.GetString("UI_Dialog_Full_Exception_Tab", resourceCulture); } } /// /// Looks up a localized string similar to General. /// internal static string UI_Dialog_Full_General_Tab { get { return ResourceManager.GetString("UI_Dialog_Full_General_Tab", resourceCulture); } } /// /// Looks up a localized string similar to Please add a brief description of how we can reproduce the error:. /// internal static string UI_Dialog_Full_How_to_Reproduce_the_Error_Notification { get { return ResourceManager.GetString("UI_Dialog_Full_How_to_Reproduce_the_Error_Notification", resourceCulture); } } /// /// Looks up a localized string similar to The application has crashed and it will now be dismissed. If you click Quit, the application will close immediately. If you click Send and Quit, the application will close and a bug report will be send.. /// internal static string UI_Dialog_Full_Message { get { return ResourceManager.GetString("UI_Dialog_Full_Message", resourceCulture); } } /// /// Looks up a localized string similar to &Quit. /// internal static string UI_Dialog_Full_Quit_Button { get { return ResourceManager.GetString("UI_Dialog_Full_Quit_Button", resourceCulture); } } /// /// Looks up a localized string similar to Report Contents. /// internal static string UI_Dialog_Full_Report_Contents_Tab { get { return ResourceManager.GetString("UI_Dialog_Full_Report_Contents_Tab", resourceCulture); } } /// /// Looks up a localized string similar to &Send and Quit. /// internal static string UI_Dialog_Full_Send_and_Quit_Button { get { return ResourceManager.GetString("UI_Dialog_Full_Send_and_Quit_Button", resourceCulture); } } /// /// Looks up a localized string similar to Error. /// internal static string UI_Dialog_Full_Title { get { return ResourceManager.GetString("UI_Dialog_Full_Title", resourceCulture); } } /// /// Looks up a localized string similar to The application has crashed and it will now be dismissed. ///A bug report has been sent to the developers. We apologize for the inconvenience.. /// internal static string UI_Dialog_Minimal_Message { get { return ResourceManager.GetString("UI_Dialog_Minimal_Message", resourceCulture); } } /// /// Looks up a localized string similar to Error. /// internal static string UI_Dialog_Minimal_Title { get { return ResourceManager.GetString("UI_Dialog_Minimal_Title", resourceCulture); } } /// /// Looks up a localized string similar to &Continue. /// internal static string UI_Dialog_Normal_Continue_Button { get { return ResourceManager.GetString("UI_Dialog_Normal_Continue_Button", resourceCulture); } } /// /// Looks up a localized string similar to Unhandled exception has occurred in your application. If you click Continue, the application will ignore this error and attempt to continue. If you click quit, the application will close immediately.. /// internal static string UI_Dialog_Normal_Message { get { return ResourceManager.GetString("UI_Dialog_Normal_Message", resourceCulture); } } /// /// Looks up a localized string similar to &Quit. /// internal static string UI_Dialog_Normal_Quit_Button { get { return ResourceManager.GetString("UI_Dialog_Normal_Quit_Button", resourceCulture); } } /// /// Looks up a localized string similar to Error. /// internal static string UI_Dialog_Normal_Title { get { return ResourceManager.GetString("UI_Dialog_Normal_Title", resourceCulture); } } } } ================================================ FILE: source/NBug_custom/Properties/Localization.ar.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 حدث استثناء غير معالج. اغلاق التطبيق. Unhandled exception occurred. Closing application. حدث استثناء غير معالج. اغلاق التطبيق. Unhandled exception occurred. Closing application. حدث استثناء غير معالج. اغلاق التطبيق. Unhandled exception occurred. Closing application. استثناء Exception عام General الرجاء اضافه وصف مختصر للطريقة التي يمكننا بها اعاده انتاج الخطا: Please add a brief description of how we can reproduce the error: وقد تحطم الطلب سيتم فصله الان. اذا قمت بالنقر فوق انهاء, سيتم اغلاق التطبيق مباشره. اذا قمت بالنقر فوق ارسال وانهاء ، سيتم اغلاق التطبيق وسيتم ارسال تقرير خطا. The application has crashed and it will now be dismissed. If you click Quit, the application will close immediately. If you click Send and Quit, the application will close and a bug report will be send. &هروب &Quit محتويات التقرير Report Contents &ارسال و انهاء &Send and Quit خطا Error تحطم الطلب سيتم فصله الان. تم ارسال تقرير خطا الى المطورين. نعتذر عن الازعاج The application has crashed and it will now be dismissed. A bug report has been sent to the developers. We apologize for the inconvenience. خطا Error &استمر &Continue حدث استثناء غير معالج في تطبيقك. اذا قمت بالنقر فوق "متابعه" ، سيتجاهل التطبيق هذا الخطا ثم محاولة المتابعة. اذا قمت بالنقر فوق انهاء, سيتم اغلاق التطبيق مباشره. . &هروب &Quit خطا Error ================================================ FILE: source/NBug_custom/Properties/Localization.cs.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Výjimka Exception Hlavní General Prosím, přidejte krátký popis, jak můžeme reprodukovat chybu: Please add a brief description of how we can reproduce the error: V aplikaci došlo k chybě a bude uzavřena. Pokud kliknete na tlačítko Zavřít, bude aplikace okamžitě uzavřen. Pokud kliknete na tlačítko Uložit a Zavřít, aplikace bude uzavřen a zpráva o chybě bude odeslána. The application has crashed and it will now be dismissed. If you click Quit, the application will close immediately. If you click Send and Quit, the application will close and a bug report will be send. &Ukončit &Quit Obsah zprávy Report Contents Odeslat a &Zavřít &Send and Quit Chyba Error V aplikaci došlo k chybě a bude uzavřena. Zpráva o chybě byla zaslána k vývojářům. Omluvám se za nepříjemnost. The application has crashed and it will now be dismissed. A bug report has been sent to the developers. We apologize for the inconvenience. Chyba Error &Pokračovat &Continue Došlo k neošetřené výjimce v žádosti. Pokud kliknete na tlačítko pokračovat, bude aplikace ignorovat chybu a pokračovat. Pokud kliknete na tlačítko Zavřít, bude vaše žádost okamžitě ukončena. . &Ukončit &Quit Chyba Error Došlo k neošetřené výjimce. Zavření aplikace. Unhandled exception occurred. Closing application. Došlo k neošetřené výjimce. Zavření aplikace. Unhandled exception occurred. Closing application. Došlo k neošetřené výjimce. Zavření aplikace. Unhandled exception occurred. Closing application. ================================================ FILE: source/NBug_custom/Properties/Localization.de.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Eine Unbehandelte Ausnahme ist aufgetreten. Die Anwendung wird beendet. Unhandled exception occurred. Closing application. Eine Unbehandelte Ausnahme ist aufgetreten. Die Anwendung wird beendet. Unhandled exception occurred. Closing application. Eine Unbehandelte Ausnahme ist aufgetreten. Die Anwendung wird beendet. Unhandled exception occurred. Closing application. Ausnahme Exception Allgemein General Bitte beschreiben Sie hier, wie der Fehler reproduziert werden kann: Please add a brief description of how we can reproduce the error: Die Awendung ist abgestürzt und wird jetzt beendet. Wenn Sie auf "Beenden" klicken, wird die Anwendung direkt geschlossen. Wenn Sie auf "Senden und beenden" klicken, wird zunächst ein Fehlerbericht and die Entwickler gesendet und die Anwendung anschließend geschlossen. The application has crashed and it will now be dismissed. If you click Quit, the application will close immediately. If you click Send and Quit, the application will close and a bug report will be send. &Beenden &Quit Fehlerberichtsinhalt Report Contents &Senden und beenden &Send and Quit Fehler Error In der Anwendung ist eine unbehandelte Ausnahme aufgetreten. Das Programm wird jetzt beendet. Es wurden Fehlerdetails an die Entwickler gesendet. The application has crashed and it will now be dismissed. A bug report has been sent to the developers. We apologize for the inconvenience. Fehler Error &Weiter &Continue Eine unbehandelte Ausnahme ist aufgetreten. Wenn Sie auf "Weiter" klicken, wird Fehler ignoriert und die Anwendung wird versuchen, weiter zu arbeiten. Wenn Sie auf "Beenden" klicken, wird die Anwendung sofort geschlossen. . &Beenden &Quit Fehler Error ================================================ FILE: source/NBug_custom/Properties/Localization.es.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Ha ocurrido un error no controlado. Se cerrará el programa. Unhandled exception occurred. Closing application. Ha ocurrido un error no controlado. Se cerrará el programa. Unhandled exception occurred. Closing application. Ha ocurrido un error no controlado. Se cerrará el programa. Unhandled exception occurred. Closing application. Excepción Exception General General Añada una breve descripción de como reproducir el error. Please add a brief description of how we can reproduce the error: El programa ha dejado de funcionar. Si presiona 'Salir', el programa se cerrará inmediatamente. Si presiona 'Enviar y Salir', el programa se cerrará y se enviará un informe de error. The application has crashed and it will now be dismissed. If you click Quit, the application will close immediately. If you click Send and Quit, the application will close and a bug report will be send. &Salir &Quit Contenido del informe Report Contents &Enviar y salir &Send and Quit Error Error La aplicación ha dejado de funcionar.Se ha enviado un informe de error a los programadores. Pedimos disculpas por los inconvenientes que esto pueda causar. The application has crashed and it will now be dismissed. A bug report has been sent to the developers. We apologize for the inconvenience. Error Error &Continuar &Continue Ha ocurrido un error no controlado. Si pulsa continuar, el programa ignorará este error y tratará de continuar. Si pulsa salir, el programa se cerrará inmediatamente, . &Salir &Quit Error Error ================================================ FILE: source/NBug_custom/Properties/Localization.fi-FI.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Tapahtui käsittelemätön poikkeus. Sovellus suljetaan. Unhandled exception occurred. Closing application. Tapahtui käsittelemätön poikkeus. Sovellus suljetaan. Unhandled exception occurred. Closing application. Tapahtui käsittelemätön poikkeus. Sovellus suljetaan. Unhandled exception occurred. Closing application. Poikkeus Exception Yleinen General Ole hyvä ja lisää lyhyt kuvaus siitä, miten voimme toistaa virheen: Please add a brief description of how we can reproduce the error: Sovellus on kaatunut ja se on nyt suljettava. Jos valitset Sulje, sovellus sulkeutuu heti. Jos napsautat Lähetä ja sulje, sovellus sulkeutuu ja vikailmoitus lähetetään. The application has crashed and it will now be dismissed. If you click Quit, the application will close immediately. If you click Send and Quit, the application will close and a bug report will be send. &Sulje &Quit Raportin sisältö Report Contents &Lähetä ja sulje &Send and Quit Virhe Error Sovellus on kaatunut ja se on nyt suljettava. Vikailmoitus on lähetetty kehittäjille. Pahoittelemme häiriötä. The application has crashed and it will now be dismissed. A bug report has been sent to the developers. We apologize for the inconvenience. Virhe Error &Jatka &Continue Ilmeni käsittelemätön poikkeus sovelluksessa. Jos valitset Jatka, sovellus ohittaa tämän virheen ja yrittää jatkaa. Jos klikkaat lopeta, sovellus sulkeutuu heti. . &Sulje &Quit Virhe Error ================================================ FILE: source/NBug_custom/Properties/Localization.fr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Exception non gérée survenue. Fermeture de l'application. Unhandled exception occurred. Closing application. Exception non gérée survenue. Fermeture de l'application. Unhandled exception occurred. Closing application. Exception non gérée survenue. Fermeture de l'application. Unhandled exception occurred. Closing application. Exception Exception Général General Merci d'ajouter une brève description sur la façon de reproduire l'erreur : Please add a brief description of how we can reproduce the error: L'application a planté et va être maintenant arrêtée. Si vous cliquez Quitter, l'application fermera immédiatement. Si vous cliquez Envoyer et Quitter, l'application fermera et un rapport d'erreur sera envoyé. The application has crashed and it will now be dismissed. If you click Quit, the application will close immediately. If you click Send and Quit, the application will close and a bug report will be send. &Quitter &Quit Contenu du rapport Report Contents &Envoyer et Quitter &Send and Quit Erreur Error L'application a planté et va être maintenant arrêtée. Un rapport d'erreur a été envoyé aux développeurs. Veuillez nous excuser pour le désagrément. The application has crashed and it will now be dismissed. A bug report has been sent to the developers. We apologize for the inconvenience. Erreur Error &Continuer &Continue Exception non gérée survenue dans votre application. Si vous cliquez Continuer, l'application ignorera cette erreur et tentera de continuer. Si vous cliquez Quitter, l'application fermera immédiatement. . &Quitter &Quit Erreur Error ================================================ FILE: source/NBug_custom/Properties/Localization.hr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Došlo je do greške. Zatvaram aplikaciju. Unhandled exception occurred. Closing application. Došlo je do greške. Zatvaram aplikaciju. Unhandled exception occurred. Closing application. Došlo je do greške. Zatvaram aplikaciju. Unhandled exception occurred. Closing application. Greška Exception Opće General Molimo dodajte kratak opis kako bi nam pomogli reproducirati grešku: Please add a brief description of how we can reproduce the error: Aplikacija je proizvela grešku i biti će zatvorena. Ako kliknete Izlaz, aplikacija će se odmah zatvoriti. Ako kliknete Pošalji i izađi, aplikacija će se zatvoriti i poslati izvještaj razvojnom timu. The application has crashed and it will now be dismissed. If you click Quit, the application will close immediately. If you click Send and Quit, the application will close and a bug report will be send. &Izlaz &Quit Sadržaj izvještaja Report Contents &Pošalji i izađi &Send and Quit Greška Error Aplikacija je proizvela grešku i biti će zatvorena. Izvještaj o grešci poslan je razvojnom timu. Ispričavamo se na neugodnosti. The application has crashed and it will now be dismissed. A bug report has been sent to the developers. We apologize for the inconvenience. Greška Error &Nastavi &Continue Došlo je do greške u aplikaciji. Ako kliknete na Nastavi, aplikacija će ignorirati ovu grešku i pokušati nastaviti sa radom. Ako kliknete Odustani aplikacija će se odmah zatvoriti. . &Odustani &Quit Greška Error ================================================ FILE: source/NBug_custom/Properties/Localization.hu.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Nem kezelt kivétel történt. Az alkalmazás bezárása. Unhandled exception occurred. Closing application. Nem kezelt kivétel történt. Az alkalmazás bezárása. Unhandled exception occurred. Closing application. Nem kezelt kivétel történt. Az alkalmazás bezárása. Unhandled exception occurred. Closing application. Kivétel Exception Általános General Kérjük adjon meg egy rövid leírást, hogy reprodukálhassuk a hibát: Please add a brief description of how we can reproduce the error: Az alkalmazás összeomlott és elvetésre került. Ha a Kilépésre kattint a program azonnal bezáródik. Ha a Küldés és kilépés lehetőséget választja, a program bezárul és hibajelentést fog küldeni. The application has crashed and it will now be dismissed. If you click Quit, the application will close immediately. If you click Send and Quit, the application will close and a bug report will be send. K&ilépés &Quit Jelentés tartalma Report Contents Kül&dés és kilépés &Send and Quit Hiba Error Az alkalmazás összeomlott és elvetésre került. A hibajelentés a fejlesztőknek elküldve. Elnézést kérünk a kellemetlenségért. The application has crashed and it will now be dismissed. A bug report has been sent to the developers. We apologize for the inconvenience. Hiba Error &Tovább &Continue Nem kezelt kivétel történt az alkalmazásban. Ha a Tovább gombra kattint, az alkalmazás kihagyja ezt a hibát, és megpróbálja folytatni. Ha a Kilépés-re kattint, az alkalmazás azonnal bezárásra kerül. . K&ilépés &Quit Hiba Error ================================================ FILE: source/NBug_custom/Properties/Localization.it.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Eccezione non gestita. Chiusura dell'applicazione. Unhandled exception occurred. Closing application. Eccezione non gestita. Chiusura dell'applicazione. Unhandled exception occurred. Closing application. Eccezione non gestita. Chiusura dell'applicazione. Unhandled exception occurred. Closing application. Eccezione Exception Generale General Ti invitiamo a scrivere una breve descrizione su come riprodurre l'errore: Please add a brief description of how we can reproduce the error: L'applicazione si è bloccata e sarà chiusa. Selezionando "Uscita" l'applicazione sarà chiusa immediatamente. Se premi "Invia ed esci" l'applicazione sarà chiusa e sarà inviato un report dell'errore avvenuto. The application has crashed and it will now be dismissed. If you click Quit, the application will close immediately. If you click Send and Quit, the application will close and a bug report will be send. &Uscita &Quit Contenuti del report Report Contents &Invia ed esci &Send and Quit Errore Error L'applicazione si è bloccata e sarà chiusa. Un report dell'errore è stato inviato allo sviluppatore. Ci scusiamo per l'inconveniente. The application has crashed and it will now be dismissed. A bug report has been sent to the developers. We apologize for the inconvenience. Errore Error &Continua &Continue Errore non gestito del tuo programma. Cliccando su "Continua" l'aplicazione ignorerà questo errore e proverà a continuare. Cliccato su "Uscita" l'applicazione sarà chiusa immediatamente. . &Uscita &Quit Errore Error ================================================ FILE: source/NBug_custom/Properties/Localization.ja.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 &終了 &Quit &送信して終了 &Send and Quit &終了 &Quit 未処理の例外が発生しました。アプリケーションを閉じます。 Unhandled exception occurred. Closing application. 未処理の例外が発生しました。アプリケーションを閉じます。 Unhandled exception occurred. Closing application. 未処理の例外が発生しました。アプリケーションを閉じます。 Unhandled exception occurred. Closing application. 例外 Exception 一般 General エラーを再現する方法についての簡単な説明を追加してください: Please add a brief description of how we can reproduce the error: アプリケーションがクラッシュし、これから終了します。 「終了」をクリックすると、アプリケーションは即座に閉じます。 「送信して終了」をクリックすると、アプリケーションは閉じ、バグレポートが送信されます。 The application has crashed and it will now be dismissed. If you click Quit, the application will close immediately. If you click Send and Quit, the application will close and a bug report will be send. レポート内容 Report Contents エラー Error アプリケーションがクラッシュし、これから終了します。 バグレポートが開発者に送信されました。ご不便をおかけして申し訳ありません。 The application has crashed and it will now be dismissed. A bug report has been sent to the developers. We apologize for the inconvenience. エラー Error &続行 &Continue アプリケーションで未処理の例外が発生しました。 「続行」をクリックすると、アプリケーションはこのエラーを無視して続行しようとします。 「終了」をクリックすると、アプリケーションは即座に閉じます。 . エラー Error ================================================ FILE: source/NBug_custom/Properties/Localization.ko-KR.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 처리되지 않은 예외가 발생했습니다. 프로그램을 종료합니다. Unhandled exception occurred. Closing application. 처리되지 않은 예외가 발생했습니다. 프로그램을 종료합니다. Unhandled exception occurred. Closing application. 처리되지 않은 예외가 발생했습니다. 프로그램을 종료합니다. Unhandled exception occurred. Closing application. 예외 Exception 일반 General 오류를 재현할 수 있도록 간단한 설명을 적어주십시오: Please add a brief description of how we can reproduce the error: 이 프로그램은 충돌이 발생하였으며 종료됩니다. '종료'를 선택하시면 프로그램이 바로 종료됩니다. '보내고 종료'를 선택하시면 프로그램이 닫히고 버그 레포트가 전송됩니다. The application has crashed and it will now be dismissed. If you click Quit, the application will close immediately. If you click Send and Quit, the application will close and a bug report will be send. 종료(&Q) &Quit 레포트 내용 Report Contents 보내고 종료(&S) &Send and Quit 오류 Error 이 프로그램은 충돌이 발생하였으며 종료됩니다. 버그 레포트가 개발자에게 보내졌습니다. 불편을 끼쳐드려 죄송합니다. The application has crashed and it will now be dismissed. A bug report has been sent to the developers. We apologize for the inconvenience. 오류 Error 계속(&C) &Continue 이 프로그램에서 처리되지 않은 예외가 발생했습니다. '계속'을 선택하시면 이 오류를 무시하고 계속 실행하도록 시도합니다. '종료'를 선택하시면 프로그램이 바로 닫힙니다. . 종료(&Q) &Quit 오류 Error ================================================ FILE: source/NBug_custom/Properties/Localization.nl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Er trad een onbehandelde uitzondering op. Het programma wordt beëindigd. Unhandled exception occurred. Closing application. Er trad een onbehandelde uitzondering op. Het programma wordt beëindigd. Unhandled exception occurred. Closing application. Er trad een onbehandelde uitzondering op. Het programma wordt beëindigd. Unhandled exception occurred. Closing application. Uitzondering Exception Algemeen General Gelieve hier de fout te beschrijven en hoe de fout gereproduceerd kan worden: Please add a brief description of how we can reproduce the error: Het programma is gecrashed en wordt nu beëindigd. Als u op "Afsluiten" klikt, wordt het programma meteen gesloten. Indien u op "Versturen en afsluiten" klikt, wordt vervolgens een foutenbericht naar de ontwikkelaar gestuurd en wordt het programma daarna afgesloten. The application has crashed and it will now be dismissed. If you click Quit, the application will close immediately. If you click Send and Quit, the application will close and a bug report will be send. &Afsluiten &Quit Inhoud foutenbericht Report Contents &Verzenden en afsluiten &Send and Quit Fout Error In het programma trad een onbehandelde uitzondering op. Het programma wordt nu beëindigd. Een foutenrapport werd naar de ontwikkelaar gestuurd. Excuses voor het ongemak. The application has crashed and it will now be dismissed. A bug report has been sent to the developers. We apologize for the inconvenience. Fout Error &Doorgaan &Continue Er trad een onbehandelde uitzondering op. Als u op "Doorgaan" klikt wordt de fout genegeerd en probeert het programma te vervolgen. Als u op "Afsluiten" klikt, wordt het programma onmiddellijk gesloten. . &Afsluiten &Quit Fout Error ================================================ FILE: source/NBug_custom/Properties/Localization.pl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Wystąpił nieobsługiwany wyjątek. Zamykanie aplikacji. Unhandled exception occurred. Closing application. Wystąpił nieobsługiwany wyjątek. Zamykanie aplikacji. Unhandled exception occurred. Closing application. Wystąpił nieobsługiwany wyjątek. Zamykanie aplikacji. Unhandled exception occurred. Closing application. Wyjątek Exception Ogólne General Proszę dodać krótki opis w jaki sposób możemy odtworzyć błąd: Please add a brief description of how we can reproduce the error: Aplikacja uległa awarii i zostanie zamknięta. Jeśli klikniesz przycisk Zamknij, aplikacja zostanie natychmiast zamknięta. Jeśli klikniesz przycisk Wyślij i Zamknij, aplikacja zostanie zamknięta i raport o błędzie zostanie wysłany. The application has crashed and it will now be dismissed. If you click Quit, the application will close immediately. If you click Send and Quit, the application will close and a bug report will be send. &Wyjdź &Quit Treść raportu Report Contents Wyślij i &Zamknij &Send and Quit Błąd Error Aplikacja uległa awarii i zostanie zamknięta. Raport błędów został wysłany do programistów. Przepraszamy za niedogodności. The application has crashed and it will now be dismissed. A bug report has been sent to the developers. We apologize for the inconvenience. Błąd Error &Kontynuuj &Continue Wystąpił nieobsługiwany wyjątek w aplikacji. Jeśli klikniesz przycisk Kontynuuj, aplikacja zignoruje błąd i spróbuje kontynuować. Jeśli klikniesz zamknij, aplikacja zostanie natychmiast zamknięta. . &Wyjdź &Quit Błąd Error ================================================ FILE: source/NBug_custom/Properties/Localization.pt-BR.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Uma exceção não tratada ocorreu. Encerrando a aplicação. Unhandled exception occurred. Closing application. Uma exceção não tratada ocorreu. Encerrando a aplicação. Unhandled exception occurred. Closing application. Uma exceção não tratada ocorreu. Encerrando a aplicação. Unhandled exception occurred. Closing application. Exceção Exception Geral General Por favor adicione uma breve descrição de como reproduzir o erro: Please add a brief description of how we can reproduce the error: A aplicação encontrou um erro e será encerrada agora. Se você clicar em "Sair", o aplicativo será fechado imediatamente. Se você clicar em "Enviar e Sair", o aplicativo será fechado e um relatório de erro será enviado. The application has crashed and it will now be dismissed. If you click Quit, the application will close immediately. If you click Send and Quit, the application will close and a bug report will be send. &Sair &Quit Conteudo do Relatório Report Contents &Enviar e Sair &Send and Quit Erro Error A aplicação deixou de funcionar e agora vai ser encerrada. Um relatorio de erro sera enviado. Desculpe qualquer inconveniente. The application has crashed and it will now be dismissed. A bug report has been sent to the developers. We apologize for the inconvenience. Erro Error &Continuar &Continue Uma exceção não tratada ocorreu na sua aplicação. Se você clicar em continuar, o aplicativo ignorará esse erro e tentará continuar. Se você clicar em sair, o aplicativo será fechado imediatamente. . &Sair &Quit Erro Error ================================================ FILE: source/NBug_custom/Properties/Localization.pt.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Ocorreu uma excepção não processada. O aplicativo vai ser encerrado. Unhandled exception occurred. Closing application. Ocorreu uma excepção não processada. O aplicativo vai ser encerrado. Unhandled exception occurred. Closing application. Ocorreu uma excepção não processada. O aplicativo vai ser encerrado. Unhandled exception occurred. Closing application. Excepção Exception Geral General Por favor adicione uma descrição breve de como popderemos reproduzir o erro: Please add a brief description of how we can reproduce the error: A aplicação deixou de funcionar e vai ser agora encerrada. Se clicar em sair, o aplicativo será fechado de imediato. Se clicar em Enviar e Sair, o aplicativo será fechado e será enviado um relatório de erro. The application has crashed and it will now be dismissed. If you click Quit, the application will close immediately. If you click Send and Quit, the application will close and a bug report will be send. &Sair &Quit Conteudo do relatorio Report Contents &Enviar e Sair &Send and Quit Erro Error A aplicação deixou de funcionar e vai ser agora encerrada. Vai ser enviado um relatório de erro. Pedimos desculpa pelo inconveniente. The application has crashed and it will now be dismissed. A bug report has been sent to the developers. We apologize for the inconvenience. Erro Error &Continuar &Continue Ocorreu uma excepção não processada. Se clicar em Continuar, o aplicativo ignorará esse erro e tentará continuar o processo. Se clicar em Sair, o aplicativo será fechado de imediato. . &Sair &Quit Erro Error ================================================ FILE: source/NBug_custom/Properties/Localization.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Unhandled exception occurred. Closing application. Unhandled exception occurred. Closing application. Unhandled exception occurred. Closing application. Unhandled exception occurred. Closing application. Unhandled exception occurred. Closing application. Unhandled exception occurred. Closing application. Exception Exception General General Please add a brief description of how we can reproduce the error: Please add a brief description of how we can reproduce the error: The application has crashed and it will now be dismissed. If you click Quit, the application will close immediately. If you click Send and Quit, the application will close and a bug report will be send. The application has crashed and it will now be dismissed. If you click Quit, the application will close immediately. If you click Send and Quit, the application will close and a bug report will be send. &Quit &Quit Report Contents Report Contents &Send and Quit &Send and Quit Error Error The application has crashed and it will now be dismissed. A bug report has been sent to the developers. We apologize for the inconvenience. The application has crashed and it will now be dismissed. A bug report has been sent to the developers. We apologize for the inconvenience. Error Error &Continue &Continue Unhandled exception has occurred in your application. If you click Continue, the application will ignore this error and attempt to continue. If you click quit, the application will close immediately. . &Quit &Quit Error Error ================================================ FILE: source/NBug_custom/Properties/Localization.ru.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Произошла ошибка. Приложение будет закрыто. Unhandled exception occurred. Closing application. Произошла ошибка. Приложение будет закрыто. Unhandled exception occurred. Closing application. Произошла ошибка. Приложение будет закрыто. Unhandled exception occurred. Closing application. Исключение Exception Общее General Пожалуйста, кратко опишите, как нам исправить ошибку: Please add a brief description of how we can reproduce the error: Произошла ошибка и приложение будет закрыто. Если Вы нажмете "Закрыть" приложение закроется. Если Вы нажмёте "Отправить", будет отправлен отчёт об ошибке и приложение будет закрыто. The application has crashed and it will now be dismissed. If you click Quit, the application will close immediately. If you click Send and Quit, the application will close and a bug report will be send. &Закрыть &Quit Содержимое отчёта Report Contents &Отправить &Send and Quit Ошибка Error Произошла ошибка и приложение будет закрыто. Отчёт об ошибке будет отправлен разработчикам. Извиняемся за доставленные неудобства. The application has crashed and it will now be dismissed. A bug report has been sent to the developers. We apologize for the inconvenience. Ошибка Error &Продолжить &Continue Произошла ошибка. Если Вы нажмёте "Продолжить", приложение проигнорирует ошибку и попытается продолжить. Если нажмёте "Закрыть", приложение будет закрыто. . Выход &Quit Ошибка Error ================================================ FILE: source/NBug_custom/Properties/Localization.sl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Prišlo je do nepričakovane, neobravnavane napake. Zapiram aplikacijo Unhandled exception occurred. Closing application. Prišlo je do nepričakovane, neobravnavane napake. Zapiram aplikacijo Unhandled exception occurred. Closing application. Prišlo je do neobravnavane izjeme. Zapiram aplikacijo. Unhandled exception occurred. Closing application. Izjema Exception Splošno General Prosimo, dodajte kratek opis, da vemo kako naj znova ponovimo napako: Please add a brief description of how we can reproduce the error: Aplikacija se je sesula in bo zdaj zavrnjena. Če kliknete na 'Končaj', se bo aplikacija takoj zaprla. Če kliknete na 'Pošlji in končaj', se bo aplikacija zaprla in bo poslano poročilo o hrošču. The application has crashed and it will now be dismissed. If you click Quit, the application will close immediately. If you click Send and Quit, the application will close and a bug report will be send. &Končaj &Quit Vsebina poročila Report Contents &Pošlji in končaj &Send and Quit Napaka Error Aplikacija se je sesula in bo zdaj zavrnjena. Poročilo o hrošču je bilo poslano razvijalcem. Opravičujemo se za nevšečnosti. The application has crashed and it will now be dismissed. A bug report has been sent to the developers. We apologize for the inconvenience. Napaka Error &Nadaljuj &Continue V vaši aplikaciji je prišlo do neobravnavane izjeme. Če kliknete na 'Naprej', bo aplikacija prezrla to napako in poskusila z nadaljevanjem. Če kliknete na 'Končaj', se bo aplikacija takoj zaprla. . &Končaj &Quit Napaka Error ================================================ FILE: source/NBug_custom/Properties/Localization.sv.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 &Avsluta &Quit Fel Error Ett ohanterat undantag inträffade. Stänger programmet. Unhandled exception occurred. Closing application. Ett ohanterat undantag inträffade. Stänger programmet. Unhandled exception occurred. Closing application. Ett ohanterat undantag inträffade. Stänger programmet. Unhandled exception occurred. Closing application. Undantag Exception Allmänt General Vänligen lägg till en kort beskrivning av hur vi kan återskapa felet: Please add a brief description of how we can reproduce the error: Programmet har kraschat och kommer nu att avslutas. Om du klickar på Avsluta stängs programmet omedelbart. Om du klickar på Skicka och Avsluta kommer programmet att stängas och en felrapport kommer att skickas. The application has crashed and it will now be dismissed. If you click Quit, the application will close immediately. If you click Send and Quit, the application will close and a bug report will be send. &Avsluta &Quit Rapportera Innehåll Report Contents &Skicka och Avsluta &Send and Quit Fel Error Programmet har kraschat och kommer nu att avslutas. En felrapport har skickats till utvecklarna. Vi ber om ursäkt för olägenheten. The application has crashed and it will now be dismissed. A bug report has been sent to the developers. We apologize for the inconvenience. Fel Error &Fortsätt &Continue Ett ohanterat undantag har inträffat i ditt program. Om du klickar på Fortsätt kommer programmet att ignorera detta fel och försöka fortsätta. Om du klickar på avsluta stängs programmet omedelbart. . ================================================ FILE: source/NBug_custom/Properties/Localization.tr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 İşlenmeyen özel durum oluştu. Uygulama kapatılıyor. Unhandled exception occurred. Closing application. İşlenmeyen özel durum oluştu. Uygulama kapatılıyor. Unhandled exception occurred. Closing application. İşlenmeyen özel durum oluştu. Uygulama kapatılıyor. Unhandled exception occurred. Closing application. İstisna Exception Genel General Lütfen hatayı nasıl yeniden oluşturabileceğimize dair kısa bir açıklama ekleyin: Please add a brief description of how we can reproduce the error: Uygulama çöktü ve şimdi görevden alınacak. Çık'ı tıklatırsanız, uygulama hemen kapanır. Gönder ve Çık'ı tıklatırsanız, uygulama kapanacak ve bir hata raporu gönderilecektir. The application has crashed and it will now be dismissed. If you click Quit, the application will close immediately. If you click Send and Quit, the application will close and a bug report will be send. &Çık &Quit Rapor İçeriği Report Contents &Gönder ve Çık &Send and Quit Hata Error Uygulama çöktü ve şimdi görevden alınacak. Geliştiricilere bir hata raporu gönderildi. Verdiğimiz rahatsızlık için özür dileriz. The application has crashed and it will now be dismissed. A bug report has been sent to the developers. We apologize for the inconvenience. Hata Error &Devam &Continue Uygulamanızda işlenmeyen özel durum oluştu. Devam'ı tıklarsanız, uygulama bu hatayı yok sayar ve devam etmeye çalışır. Çık'ı tıklarsanız, uygulama hemen kapanır. . &Çık &Quit Hata Error ================================================ FILE: source/NBug_custom/Properties/Localization.vi.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Lỗi ngoại lệ chưa được xử lý. Đang đóng ứng dụng. Unhandled exception occurred. Closing application. Lỗi ngoại lệ chưa được xử lý. Đang đóng ứng dụng. Unhandled exception occurred. Closing application. Lỗi ngoại lệ chưa được xử lý. Đang đóng ứng dụng. Unhandled exception occurred. Closing application. Ngoại lệ Exception Chung General Vui lòng cung cấp một mô tả ngắn gọn đề tái hiện lỗi: Please add a brief description of how we can reproduce the error: Ứng dụng đã gặp sự cố và sẽ tự động đóng. Nếu bạn nhấp chuột vào nút "Thoát", ứng dụng sẽ đóng ngay lập tức. Nếu bạn nhấp chuột vào nút "Gửi và Thoát", ứng dụng sẽ đóng và đồng thời gửi một báo cáo lỗi về sự cố này. The application has crashed and it will now be dismissed. If you click Quit, the application will close immediately. If you click Send and Quit, the application will close and a bug report will be send. &Thoát &Quit Nội dung báo cáo Report Contents &Gửi và thoát &Send and Quit Lỗi Error Ứng dụng đã gặp sự cố và sẽ bị đóng lại. Một báo cáo lỗi đã được gửi đến nhà phát triển. Chúng tôi chân thành xin lỗi vì sự bất tiện này. The application has crashed and it will now be dismissed. A bug report has been sent to the developers. We apologize for the inconvenience. Lỗi Error Tiế&p tục &Continue Đã xảy ra một lỗi ngoại lệ chưa được xử lý trong ứng dụng. Nếu bạn chọn "Tiếp tục", ứng dụng sẽ bỏ qua lỗi này và cố gắng tiếp tục chạy. Nếu bạn chọn "Thoát", ứng dụng sẽ đóng ngay lập tức. . &Thoát &Quit Lỗi Error ================================================ FILE: source/NBug_custom/Properties/Localization.zh-Hans.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 发生未处理的异常。正在关闭应用程序。 Unhandled exception occurred. Closing application. 发生未处理的异常。正在关闭应用程序。 Unhandled exception occurred. Closing application. 发生未处理的异常。正在关闭应用程序。 Unhandled exception occurred. Closing application. 异常 Exception 常规 General 请添加如何再现错误的简要说明: Please add a brief description of how we can reproduce the error: 应用程序已崩溃,现在将被关闭。如果单击“Quit”,应用程序将立即关闭。如果单击Send and Quit,应用程序将关闭并发送错误报告。 The application has crashed and it will now be dismissed. If you click Quit, the application will close immediately. If you click Send and Quit, the application will close and a bug report will be send. 退出 &Quit 报告内容 Report Contents 发送并退出 &Send and Quit 错误 Error 应用程序已崩溃,现在将被关闭。 错误报告已被发送给开发者。造成不便非常抱歉。 The application has crashed and it will now be dismissed. A bug report has been sent to the developers. We apologize for the inconvenience. 错误 Error 继续 &Continue 你的应用程序中发生未处理的一场。如果你点击继续,应用程序会无视此错误并试图继续。如果你点击退出,应用程序会立即关闭。 . 退出 &Quit 错误 Error ================================================ FILE: source/NBug_custom/Properties/Localization.zh-Hant.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 發生未處理的例外。正在關閉應用程式。 Unhandled exception occurred. Closing application. 發生未處理的例外。正在關閉應用程式。 Unhandled exception occurred. Closing application. 發生未處理的例外。正在關閉應用程式。 Unhandled exception occurred. Closing application. 例外 Exception 一般 General 請添加如何再現錯誤的簡要說明: Please add a brief description of how we can reproduce the error: 應用程式已當機,現在將被關閉。如果點擊"Quit",應用程式將立即關閉,如果點擊Send and Quit,應用程式將關閉並傳送錯誤報告。 The application has crashed and it will now be dismissed. If you click Quit, the application will close immediately. If you click Send and Quit, the application will close and a bug report will be send. 退出 &Quit 報告內容 Report Contents 傳送並退出 &Send and Quit Error 應用程式已當機,現在將被關閉。 錯誤報告已被傳送給開發者,造成不便非常抱歉 The application has crashed and it will now be dismissed. A bug report has been sent to the developers. We apologize for the inconvenience. 錯誤 Error 繼續 &Continue 你的應用程式中發生未處理例外。如果你點擊繼續,應用程式會忽略此錯誤並嘗試繼續。如果你點擊退出,應用程式會立即關閉。 . 退出 &Quit 錯誤 Error ================================================ FILE: source/NBug_custom/Properties/Resources.Designer.cs ================================================ //------------------------------------------------------------------------------ // // This code was generated by a tool. // Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ namespace NBug.Properties { using System; /// /// A strongly-typed resource class, for looking up localized strings, etc. /// // This class was auto-generated by the StronglyTypedResourceBuilder // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { private static global::System.Resources.ResourceManager resourceMan; private static global::System.Globalization.CultureInfo resourceCulture; [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] internal Resources() { } /// /// Returns the cached ResourceManager instance used by this class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("NBug.Properties.Resources", typeof(Resources).Assembly); resourceMan = temp; } return resourceMan; } } /// /// Overrides the current thread's CurrentUICulture property for all /// resource lookups using this strongly typed resource class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Globalization.CultureInfo Culture { get { return resourceCulture; } set { resourceCulture = value; } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap Error_16 { get { object obj = ResourceManager.GetObject("Error_16", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap Feedback { get { object obj = ResourceManager.GetObject("Feedback", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap Forum_16 { get { object obj = ResourceManager.GetObject("Forum_16", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap Help_16 { get { object obj = ResourceManager.GetObject("Help_16", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). /// internal static System.Drawing.Icon NBug_icon_16 { get { object obj = ResourceManager.GetObject("NBug_icon_16", resourceCulture); return ((System.Drawing.Icon)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). /// internal static System.Drawing.Icon NBug_icon_16_borders { get { object obj = ResourceManager.GetObject("NBug_icon_16_borders", resourceCulture); return ((System.Drawing.Icon)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap NBug_Icon_PNG_16 { get { object obj = ResourceManager.GetObject("NBug_Icon_PNG_16", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap Send { get { object obj = ResourceManager.GetObject("Send", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap VS2010_16 { get { object obj = ResourceManager.GetObject("VS2010_16", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } } } ================================================ FILE: source/NBug_custom/Properties/Resources.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAiBJREFUOE+lj19I 01EUx28EvllCBfZU+NRLJiVELxEWFA2N1qJmfwxsq9afFSrsQZr01ENIQT0sGjFqSD1s9EOXYNSEVqzm YqOGbm75Y21z7R8qOt2Ub+f8QBgRw+rCh3PvOedz7r3rAIj/WifN5lbi0j/SKtS9vZeHvV7kZmboMWtb 3MsOu+KYyXQlQ4lBjwfpQgHllZWqcA/3ssOuUHV3Xy2RlMhm4XS7lVgsl/9IZQ877IrDRuP14vIy5hYX IafTeDkyokQ+V/J7jR12xUGDwThXKiE/P68wmUjA7nIpsVqOHXbFfp3uVmFpCdP0J0amL4wGg7BJEkKy rMB7znFttY8ddsW+jo6ubLGIeD6PKD3dGw4rMRiLwepwKPC+ssa97LArmtvbe6YXFjCeTMITCikxlsko jEUiCqtnrvUMyrB+ToMddsUujcb0nSa6AwF8jccRpturcer5FE7YorB9yYFdsa2l5fYbvx/BVBa+ZAHv ojk4v/3E008p9I/+gHlYxk1nDJ0Dk9DawlBbJ2BJAKpHAezQ35PExqami3W799ytP6S636DVWXbe6LPv vfNYOvBQch+xfxhrk8Yjmrep1OmPs7Nn/OXSuQDA9EWBhi7XlKhtbBSbtQ/W1xuG6ojtRDNxlLhAmIh+ 4hkxRLwnfG0+gOPWa6/1yoAt+ldrYlOnQ9SeHfAxG86/0NMQ8VcDatRWUXP8iYXQ0xDBA34BNLyduyxX OKAAAAAASUVORK5CYII= AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAABMLAAATCwAAAAAAAAAA AADMzMz/zMzM/8zMzP/MzMz/zs3N/7Bvdf9+Fh3/gRkj/4EZI/9+Fh7/qWFp/87Mzf/MzMz/zMzM/8zM zP/MzMz/zMzM/////////////////+XQ0/9yAAr/dQMO/3UDDv91Aw7/dQMO/3IACv/fxsj///////// ////////zMzM/8zMzP/////////////////hycv/dQQP/3UED/91BA//dQQP/3UED/91BA//2r2///// /////////////8zMzP/MzMz/////////////////59PV/3UED/91BA//dQQP/3UED/91BA//dQQP/9u+ wf/////////////////MzMz/zcvL/+DGyP/bvcD/277B/8aXm/91BA//dQQP/3UED/91BRD/cgAK/3IA Cf/dwMP/7d/h//Hm5//v4uP/zMzM/7Fxd/9xAQj/dQQP/3UED/91BA//dQQP/3UED/9zAQv/nExU/8ic oP99FRz/1LC0/7qBh//JnKH/xZWa/9y/wv97Dxn/dQMO/3UED/91BA//dQQP/3UED/91BA//cwEM/6JX Xv//////9Orr//Dl5v+9hov/yJqf/8qfo/+9hov/gRkk/3UDDv91BA//dQQP/3UED/91BA//dQQP/3MB DP+hU1r/////////////////+/f4/9q8v//Npan/wIuR/4EZJP91Aw7/dQQP/3UED/91BA//dQQP/3UE D/9zAQz/oFNa//////////////////nz9P/Zur3/zaWp/7+LkP96Dhj/dQIO/3UED/91BA//dQQP/3UE D/91BA//cwEM/6JVXf//////8OPl/+vb3P+6gof/yJug/8qeov+9hov/uYCG/3ECCf91BA//dQQP/3UE D/91BA//dQQP/3QBDf+XQkv/vIeM/3kMFf/VsrX/uoGG/8iboP/ElJn/4MjK/8zLzP/n1NX/4cnL/+LK zP/LoKT/dQQP/3UED/91BA//dQQP/3IACf9wAAb/38XH//jz8//59fb/+PLz/8zMzP/MzMz///////// ////////5tLU/3UED/91BA//dQQP/3UED/91BA//dQMO/9u/wf/////////////////MzMz/zMzM//// /////////////+DIyv91BA//dQQP/3UED/91BA//dQQP/3UED//avL7/////////////////zMzM/8zM zP/////////////////m0tT/cwAL/3QDDv91Aw7/dQMO/3UDDv9yAAr/4MbJ/////////////////8zM zP/MzMz/zMzM/8zMzP/MzMz/zs3N/7d9gv9+GSD/gRkk/4EZJP9+GB//r291/87Nzf/MzMz/zMzM/8zM zP/MzMz/8A8AAPAPAADwDwAA8A8AAAAAAAAAAAAAAEAAAABwAAAAcAAAAEAAAAAAAAAAAQAA8A8AAPAP AADwDwAA8A8AAA== AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAABMLAAATCwAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAA5tXXEJM6Q7t0BAztdwcS7XcHEu10BA3tjjE7w+PQ0hYAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAIcnMTdyAAr/dQMO/3UDDv91Aw7/dQMO/3IACv+GJS5DAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABxAAg2dQQP/3UED/91BA//dQQP/3UED/91BA//cQAIQgAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdQQPLXUED/91BA//dQQP/3UED/91BA//dQQP/3IA C0EAAAAAAAAAAAAAAAAAAAAA2ry/DoIcJUByAQpCdQQPQnUED2p1BA//dQQP/3UED/91BRD/cgAK/3IA Cf+CGiRGkjlCKYQeKBx/FiAg3MHDA5U+R7xxAQj/dQQP/3UED/91BA//dQQP/3UED/9zAQv/gx4oy5hG Tol2CBDyiScxXZQ8RaWBGiVuiCcxfbFxd3N0Aw7zdQMO/3UED/91BA//dQQP/3UED/91BA//cwEM/38X IbkAAAAAt3yCKK5tdC6WQEihfxYhbostNnWWQEihdwgT7XUDDv91BA//dQQP/3UED/91BA//dQQP/3MB DP+AFyG9AAAAAAAAAAAAAAAAyJugFJE3QFaOMjtwmENMnXcIE+11Aw7/dQQP/3UED/91BA//dQQP/3UE D/9zAQz/fxchvQAAAAAAAAAAAAAAAMeZnh2PND1XjjI7cJdDS510Aw70dQIO/3UED/91BA//dQQP/3UE D/91BA//cwEM/34UHrgAAAAAtn2DNpxKUjOVPkalfhUgbYssNXWWQEihmkhQsXECCf91BA//dQQP/3UE D/91BA//dQQP/3QBDf9/FiHPkTpCm3cJEvyKKTNclDxEpYAYI26HJS59tnuBa9i5vQiHJi8zcQAKNnUE DzZ1BA9hdQQP/3UED/91BA//dQQP/3IACf9wAAb/jC03R9WztinMpakcx5ugIAAAAAAAAAAAAAAAAAAA AAAAAAAAdQQPLnUED/91BA//dQQP/3UED/91BA//dQMO/3ICCkEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAHEACTd1BA//dQQP/3UED/91BA//dQQP/3UED/9xAAhDAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAACHJi81cwAL/3QDDv91Aw7/dQMO/3UDDv9yAAr/hiQtQgAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAA7d7gDJdDS7F0Bg7sdwgT7XcIE+10BQ3skjpCuurZ2xEAAAAAAAAAAAAA AAAAAAAA8A8AAPAPAADwDwAA8A8AAAAAAAAAAAAAAEAAAABwAAAAcAAAAEAAAAAAAAAAAQAA8A8AAPAP AADwDwAA8A8AAA== iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAABYdJREFUWEftl3tM U3cUx9U5p3Mbzi3bFJXugRANbItsiYnZVHAoCZtuwnhMFKF00VjaUiuvgVUhQikFystXGSCwxbGHIwjo lMcyKS3lqVNcQBTBwcYUxZgsy9k5t/fKrbS0S2ayP/ZLPrn3/n7n8T3n97v0Mm3a/+M/1oEZ4eHhvtHR 0R0SiQQeBXK5/DLlwLpnWKt9rlgsHtHr9TB+7x6Mj4//u2BMik05MPlcawIWUNW3bt+GP27deiRQbMqB yRdYE+BCi7+Pjj5SWAEu1gQIaHFk5DeHMBiMoFDsAZFIBAUFBTAwcMMhP1aAwKaAm78Ogz0GbgxC+PYI CAj8GIKCQ2Djpg/h0OEjdv0orl0BNwaHwB59V/uZyiMiIkEojIKtW7eBUrnPrh/FnVKAVCqFa9cH7HK1 /xpIZXLYsXMX7BJLQPTpDlBlZNr1o9iUA9tvfQtosa+v3y69vX0QF5cAcrmCuUokMtBqc+36UWy7Aq78 0guOUFNTB7GxibBvXyqK+Aw6u7od8rMr4NLlK+AIer0BUlIPYus1kK7KRJ8eh/ymFCCTyaD7wqUpadYb 4avK7yBDnQNZWXmQl38E1JlayMrOg5PfV0OrqWNKf8ph8wzExMRAR9dFqzT+eB4KDh3FirMxWQG+dp/D Md1x0BWVwVG85hfqIFOTByoUdkxXgjEusFjGoxw2BSgUCmhr74Z2Ph34jGg0WnzVUiEDBWRqci1QZ+Zi F3KxK1o4mKbBP1AJGKeLifUwlMOmgLi4OGht60A6GUxEu5nBoZtw585dGHvAHbznMYb3HDhvxK0gJuLh PT5TDpsCxHtEsD9/N0gOfgLStC2QUqiAE1UV6IiCGMxBjK1EOxiMRBu0GAgTi/mZ5mmd7BgY23ZISEiY LMBb6L70nWDXAymHhdDQpYWfh0rg4mAx1HfmQHa5DHJLVXCuqZ5JbKDESAsm0GMiPSZubiFaWUygx2ea Jxs+NJeUlDRZgI/QXV56OmbQdD0frHG8LhG0JWnmqpnKzVWak2NifSucZ6F7miMR5s5M2FZVnYL4+PhR 3IKJX0NM/pGyKLC9qTcNOIAd/Ln4nFBISlXgq5eFB1IDarUaVCoVpKenQ0lpmYWAs/VNcLysAg9sBmNH V7JTKpVjvr6+SovvgXWiZbrKtpi7tT2JwMEJ4M8V1++8+7a/oBadtz1EFLZ16MzZBvip2Qg/nG2EsvIv IDQ09Gu0i+DZhuH9JsQTeYr5OV4ZsGjOB9LXT31zQQKErUFrJzrFf/lEutewJ5h+TDi89u7de/30mXqo Q6jykJCQClxfg7jx7Kjt9CVEyR9jBAhWC2b7R3tUV3REAmFr0Fqpcfuf60XLTjCOlsMZBfTXnT7HbEVw cHA5Lq9CXkBmWrG3mJrhs91Nl9uweazIFAoF1e8zcIN7pjV17abhNWFLc6wJSE5O7i8uLoWgoKB/lJxi TffyWyIS561qO2zYDBycAP5clHpli6f3wiC2fVQZhwu+21cDAgJKcO5dts1PsHbUaoI+w4npLBZ1LFjh tzgv8ct1vVxCrnLueXfR2p43/RYXotcriBMyj4erj49PLD57I68h85FnkKcR2m/6BH8SIVEkmhPyQMQs 5+VOa99Y56wTqlfqU6s2DGubNt7Padx4P+XkhuGw/W8ZPNcuLJs7f+Z69HgZWYLQgRIgrgj9oxGMBCLv ISuQRYgzQofuReR5VtQcVgR1wmLQgofL8nmJXv4ulau3uNasDnWtwc586+zmdADXqLWUjEtMQqgbBFW9 FHmVFUUCF/NEvMQKmIdX6gTXhYc1TJvFqvXAK51iSkrVCJDnEArwLAu1meb40Bytkx1BW8VtBSWejTyO TNoCvhLukJARd4D4B44COALfh38QLQ7h39hIgV/VGU6+AAAAAElFTkSuQmCC iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAddJREFUOE9jZEAD z599FIgLX7zixIkHJmzMzIwg6V9///63sFA4s2hlbISkFP8HdD0ofDOdblsuhqL/fMwlQFwKxSX/QWIg ObyaQZIcDIV2/Cyl/7FhNoYCO4IGADWaYNMMchEPa7ENhgGHD9zh0Vdvt+ZkKALZbAvEOegGAOX+szDk /3cwn+gCVK+3af0lxZVLziqBDfN2nr6Dg7EQq5N5GEv+K0k0nPF0nDpJhKfim5FmZ6yr7ZSlypKNRTpK rZX1lVtLGIBO+8zHhN3PPIzF/+VF6naALOpo2qkT7j/PyNd1xgIVqcYic93uQkeLSesYhDnK34JCG5u/ QQYAXbAH2d/LFp4WdbaeFGNl2JvtYjNlJUEDlCUaUQxYPO+kqLMVxACgd1Yy8DEBvYDHBcoSDWAvtNbv 0C7KXmcEDLMFqtJAL+j1gLywlsHLafpOXIHIDfSCpkLLGT+3Gf287CVfjDQ6Yz0dpy3SlG8pNFTvqKgp 21zCcPL4fR41uWYbYEoDRSHOaARFpZpsk5Ob3VQ1YAxIA9kyWBMVroQECmSgJZgJCd0UdoZCkCuwxgpI jmBStjbqwZmZQHIEDXj6+K2gi/WUXbwsJW9BaQSEQWxgnO8CyaEbAACgvRN7rTnSwwAAAABJRU5ErkJg gg== iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAfhJREFUOE9j/P// PwNFAGQAJZgizWDXU2I7dQwABWDo1N2+iWvOnSrZcfNawbpTCwIKK2WQA7bJaZ5fpfWsbeWWM/9XWMz6 X2Y6Y6+DfJQTWI1P14YKh8ZVrx369v3XS1j5Xzdk4X+v0o3PnRPL8q2t4vRrHBdtytGf8t+Dp/F/AF/P /yj12f/TrBb/T3KZ/1ZMzNCSwbRwwX/90jX/5Xxr//Npua8WMY1cA2LbpCz+7x67/L+v7tT/NiId//00 5v0P85rx1sI8aXagypz/UXaL/luaZVYx6Gct+y/rU/3ToXOdJchFyTM2c+p4hOWDDDFzmvvf3mT6bxf3 Rf/NHIvmgeTl1cxlQAYU+iz9H2he1cmgGTfrtmZ4y3/P0t4AmL8dy1dtMg9f+d8zZdN/69BV/w2iJmwz DOvlB8m7Rc9WsnGbcbcw/tj/QIvCagZRi9hgkG32bSf/AzWCMVhz9/H/BonTX8naVJzV9p790Txh0eTQ qv0dESnbjqUVH/mfnrj0iYqckSHYUlHL5ECQISrhHQ9sCzb/t6ne8EHCMmKaaVRToZ73BDcZxagKG/v5 /5081v308F3738q67qKgoIo3ExAgxRYjFxMTmzo7m6g1GwsvyGQ+mKSwqAMbKzOXHDenvDM7m6AlN4+s MA+fMiNYfuBTIqUuAACW+BK4EwsV5AAAAABJRU5ErkJggg== iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAppJREFUOE99k2tI k1EYx513nSBEUYH1LYqKPvchKAgKoqKoPqTVl0Ap8bLyGnTDKXlpbq6m04aXnG7vnM7FWubrzGa28rJE sWklOu/ioNLpXi/7dzbY6ytqB36cc57nnN/zvC8cnh9nHDp89EDUvv1Rq2urbm7ct3a74b93z+4puslo czgcfgDYYwFnzl1IGJ6cW5xbYDDzZ3FLZuddmPm75Bbmi1MvXrrM9wl4/gGBxxtp89TghANdthF0D45u i3XIDtv43O8xx3ysT8AP50dcb2jpWP7w7QfozgGWZrL2wY2bur9D2/L5uU8QERrOj6nQ08ybjj7Ut/VA S6BaOkHRFmgIavoLNK3d3lzDRysayFymMYrWBWHh0TL1W6aWXKo0fkK10Yz2rl4Mj9phH59A78AQSIco N7SjuslC6IBUqStgBSGhYdHCMg0j15tRpjNhxD5GchvH0qITjUQi1ZogUjUhQ6R4xgqCQkKj44TFrtRi LUrr3gFrK5sEnoDF2gdBkQqJhUrEpOUKWUEwEcRmFbuSpRQellCYnJreJHCvLqNSTyNepESSWImbGXnZ GwRxwhJXiqwOCYU1yHqlRaulB06nEwzDoH/wJ+Sks0RyUSBVI1lSs1lwJ0fuFXhavEuqZMrU6B8ahlTT jPiCKm/lZJK7RwSColrcyszndEB+YlK+wpUur0fKSwr3X1B4INd6SZTUemMsMg3SZBRuPxLnrH8CETwp VTO5qvfIfm3wIqwyIIvg23PnAnIuQ1zOCoLJizgteJo3bbD+gqrN+l90X22QKHWzp86ev8F9TJE7du7K eZwnma+oN6woKP3yVpTXGVbECuXCwSPH0knRSK7A8yzDCCcDAwOuEa5sw1Uej3eCnAvyXPAI/gFxxXIH qyUbvwAAAABJRU5ErkJggg== iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAlwSFlzAAABugAA AboB6KsBBgAAAktJREFUOE+lU1FIU1EYvnegL/owLk3wSdQXB4I+ijpFhKsP+pI++CC+6LOIL8oUhOmD oC1tw0E6Qhc1ajSKsqyMMVm2HlamK1iD6dBbc+wu56LtYffr/FeyyLkeuvBz4Zzv+/7vP+c7PACO53kN x3ECKz0rHatCX5xtfmIlM65CQI0gCKLFYnFKknTAFgt+hCEscYhLAldo4Uc6fbppMsXvi6LiEkU86OrC o95ePOnvx8OeHrg6OuDu7oZvYUFm2DRxiEsCBlLdnJhIOg0GbAwNwTM6ijczM3hvs2HXbsc7qxXbJhNe jYzg6cAAXs/NnRKHuCRwlTzbystxr70dzwYHcby3B//sLHxTU9iensZbsxkfvV68HB7G474+OFtb1TGJ ey5wTaPBnaYmfPZ4kMlk8D2RgNdoxNbkJKKhEMLhMALr67jLMDcrKi4KzHMclisrsdbQgFgkglwuh+Th Ib4wYjQaxa7fD0dLi0peKiu7RKCqCuaiIqzo9ZAZKZvNIsGchAIB2Ovr1TFJYLGkJL8AKS+WlmK5pgZf WWdFUZBKpXAQDKrOVqqrYRUEkNsLZ0CLdA5rjY0IMruxWAzfjo5wIkmQZRnhnR3Y6+owz/P5Bcg6dfes riLEDi3CbsLZ1gZXZyfi+/tg1wYf26NGeR1YtFp1w8LG2HI4cLu5WRW8XlyMW7W1+OB2w6rTnWEY9s8R 1CA9Hx9P/lL/1//F2Bib7HeQzqO8YTQe39BqlcsEqDNh/o7y/z2ms0Sqr4oeBmWb4lmoCENYDXF/ArEW LPEZBCtkAAAAAElFTkSuQmCC iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAhhJREFUOE+1U09r E0EU70fIR9iPUBQ8eMrR46IN5JhCDz2oBA8SBHEpCMFgG5GiwdJdq2Ijqe6ldo3Wrmhri0gXazW2YbMt UdNmm45ulf7R/HwzU1hLIzn54LFvhvn9eW9nOjr+R0wvBLhTXEf6bgV9w0sYLJQx/uoz2mq9c7eRn2pA L67Bq+/i29YeWLBL9Q6u5ktI6w6Kr1dbE3HwA3sT/o8mbAfQRgE1LZPXtsPgbjZxaXAG4y/Kh0m48sbP JgwbiKYAwwLYNkR4DEje5HsMFSI5l3l2kGD6/RYezzeEMgfzwzzMWSCRlV9OFk0xqhl06wNy+Tchyb2n dXxhv4TVaFLazppAJ9VKL0MySxYoVI0hkXaw5AbovjAWEmTur4qBqZoEdfbKVCgTBObqdolBUW0ocRs1 P8Cx2PWQ4PJtl6a9J+xLIB1OMHIilU2b1gSMqCZ9TdTq33FEHQgJcg8rWPF3qHcJVOKeyOyoJIioDqUk UFM2SuUqus4YIcHEzFdYji8GxIGROAc41JJHc6E1B58wRRqWhzFrEVduTR78E5mRBSz7v0l1H0AgXgsH +2DNcPBp3cep0/rhezA5V0Vfbg5ug+4CqaiaI/rmyWu+t1zdQIysDxdmW9/GiZcVnO+fgvHkI+YXV7BG 067VA9Ezt91Fyvq/wH8/lKHCW/RcfITj8Rs4evIaYmdHkBl63v4xtX1tLQ78AZ3a8qxOv4hDAAAAAElF TkSuQmCC ================================================ FILE: source/NBug_custom/Properties/Settings.Designer.cs ================================================ //------------------------------------------------------------------------------ // // This code was generated by a tool. // Runtime Version:4.0.30319.34209 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ namespace NBug.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.0.0.0")] internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); public static Settings Default { get { return defaultInstance; } } [global::System.Configuration.ApplicationScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.SpecialSettingAttribute(global::System.Configuration.SpecialSetting.ConnectionString)] public string Cipher { get { return ((string)(this["Cipher"])); } } [global::System.Configuration.ApplicationScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.SpecialSettingAttribute(global::System.Configuration.SpecialSetting.ConnectionString)] public string Destination1 { get { return ((string)(this["Destination1"])); } } [global::System.Configuration.ApplicationScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.SpecialSettingAttribute(global::System.Configuration.SpecialSetting.ConnectionString)] public string Destination2 { get { return ((string)(this["Destination2"])); } } [global::System.Configuration.ApplicationScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.SpecialSettingAttribute(global::System.Configuration.SpecialSetting.ConnectionString)] public string Destination3 { get { return ((string)(this["Destination3"])); } } [global::System.Configuration.ApplicationScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.SpecialSettingAttribute(global::System.Configuration.SpecialSetting.ConnectionString)] public string Destination4 { get { return ((string)(this["Destination4"])); } } [global::System.Configuration.ApplicationScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.SpecialSettingAttribute(global::System.Configuration.SpecialSetting.ConnectionString)] public string Destination5 { get { return ((string)(this["Destination5"])); } } [global::System.Configuration.ApplicationScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("Auto")] public global::NBug.Enums.UIMode UIMode { get { return ((global::NBug.Enums.UIMode)(this["UIMode"])); } } [global::System.Configuration.ApplicationScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("Auto")] public global::NBug.Enums.UIProvider UIProvider { get { return ((global::NBug.Enums.UIProvider)(this["UIProvider"])); } } [global::System.Configuration.ApplicationScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("10")] public int SleepBeforeSend { get { return ((int)(this["SleepBeforeSend"])); } } [global::System.Configuration.ApplicationScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("5")] public int MaxQueuedReports { get { return ((int)(this["MaxQueuedReports"])); } } [global::System.Configuration.ApplicationScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("30")] public int StopReportingAfter { get { return ((int)(this["StopReportingAfter"])); } } [global::System.Configuration.ApplicationScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("CurrentDirectory")] public string StoragePath { get { return ((string)(this["StoragePath"])); } } [global::System.Configuration.ApplicationScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("Tiny")] public global::NBug.Enums.MiniDumpType MiniDumpType { get { return ((global::NBug.Enums.MiniDumpType)(this["MiniDumpType"])); } } [global::System.Configuration.ApplicationScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("True")] public bool WriteLogToDisk { get { return ((bool)(this["WriteLogToDisk"])); } } [global::System.Configuration.ApplicationScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("True")] public bool ExitApplicationImmediately { get { return ((bool)(this["ExitApplicationImmediately"])); } } [global::System.Configuration.ApplicationScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("False")] public bool HandleProcessCorruptedStateExceptions { get { return ((bool)(this["HandleProcessCorruptedStateExceptions"])); } } [global::System.Configuration.ApplicationScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("False")] public bool ReleaseMode { get { return ((bool)(this["ReleaseMode"])); } } [global::System.Configuration.ApplicationScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("True")] public bool DeferredReporting { get { return ((bool)(this["DeferredReporting"])); } } } } ================================================ FILE: source/NBug_custom/Properties/Settings.settings ================================================  <?xml version="1.0" encoding="utf-16"?> <SerializableConnectionString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <ConnectionString /> </SerializableConnectionString> <?xml version="1.0" encoding="utf-16"?> <SerializableConnectionString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <ConnectionString /> </SerializableConnectionString> <?xml version="1.0" encoding="utf-16"?> <SerializableConnectionString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <ConnectionString /> </SerializableConnectionString> <?xml version="1.0" encoding="utf-16"?> <SerializableConnectionString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <ConnectionString /> </SerializableConnectionString> <?xml version="1.0" encoding="utf-16"?> <SerializableConnectionString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <ConnectionString /> </SerializableConnectionString> <?xml version="1.0" encoding="utf-16"?> <SerializableConnectionString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <ConnectionString /> </SerializableConnectionString> Auto Auto 10 5 30 CurrentDirectory Tiny True True False False True ================================================ FILE: source/NBug_custom/Properties/SettingsOverride.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- using System.IO; using System.Xml; using System.Xml.Linq; namespace NBug.Properties { public static class SettingsOverride { /// /// Gets or sets a value indicating whether the library settings are to be overridden. If the settings are to be /// overridden by code /// or by some other library, it shall be done before any of the static members of the /// class is accessed. /// Note that setting this to true prevents default settings from getting loaded so should be used with caution. /// internal static bool Overridden { get; set; } /// /// Loads custom settings file from the designated stream. Before calling this, you must set /// SettingsOverride.Overridden = true; /// or the default settings will be loaded as the static constructor gets called otherwise. /// /// Stream to load the settings from. public static void LoadCustomSettings(Stream settingsFile) { Overridden = true; try { NBug.Settings.LoadCustomSettings(XElement.Load(XmlReader.Create(settingsFile))); } catch (XmlException) { // Root element is missing so recreate the configuration file NBug.Settings.LoadCustomSettings( XElement.Parse("")); } } /// /// Loads custom settings file from the designated file. Before calling this, you must set /// SettingsOverride.Overridden = true; /// or the default settings will be loaded as the static constructor gets called otherwise. /// /// File to load the settings from. Used within XElement.Load(path) public static void LoadCustomSettings(string settingsFilePath) { Overridden = true; try { NBug.Settings.LoadCustomSettings(XElement.Load(settingsFilePath)); } catch (XmlException) { // Root element is missing so recreate the configuration file NBug.Settings.LoadCustomSettings( XElement.Parse("")); } } public static void SaveCustomSettings(Stream settingsFile, bool encryptConnectionStrings) { NBug.Settings.SaveCustomSettings(settingsFile, encryptConnectionStrings); } public static void SaveCustomSettings(Stream settingsFile) { NBug.Settings.SaveCustomSettings(settingsFile, false); } } } ================================================ FILE: source/NBug_custom/Settings.cs ================================================ // -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2011 - 2013 Teoman Soygul. Licensed under MIT license. // // -------------------------------------------------------------------------------------------------------------------- using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Configuration; using System.Diagnostics; using System.IO; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Security.Cryptography; using System.Text; using System.Xml; using System.Xml.Linq; using System.Xml.XPath; using NBug.Core.Reporting; using NBug.Core.Reporting.Info; using NBug.Core.Submission; using NBug.Core.Util; using NBug.Core.Util.Exceptions; using NBug.Core.Util.Logging; using NBug.Enums; using NBug.Events; using NBug.Properties; using StoragePath = NBug.Core.Util.Storage.StoragePath; namespace NBug { public static class Settings { /// /// Gets or sets an event for a CustomSubmission. /// internal static Delegate CustomSubmissionHandle; /// /// Gets or sets an event for a CustomUI. /// internal static Delegate CustomUIHandle; /// /// Lookup for quickly finding the type to instantiate for a given connection string type. /// By making this lazy we don't do the lookup until we know we have to, as /// reflection against all assemblies can be slow. /// private static Dictionary _availableProtocols; /*= new Dictionary( () => { // find all concrete implementations of IProtocolFactory var type = typeof(IProtocolFactory); return });*/ private static bool releaseMode; // False by default static Settings() { // Crucial startup settings Resources = new PublicResources(); EntryAssembly = (Assembly.GetEntryAssembly() ?? Assembly.GetExecutingAssembly()) ?? Assembly.GetCallingAssembly(); // GetEntryAssembly() is null if there is no initial GUI/CLI NBugDirectory = Path.GetDirectoryName(Assembly.GetCallingAssembly().Location) ?? Environment.CurrentDirectory; AdditionalReportFiles = new List(); // Default to developer mode settings. Settings this now so that any exception below will be handled with correct settings ReleaseMode = false; // Check to see if the settings are overriden manually. If so, don't load the settings file automatically. if (SettingsOverride.Overridden == false) { /* * Settings file search order: * 1) NBug.config (inside the same folder with 'NBug.dll') * 2) NBug.dll.config (fool proof!) (inside the same folder with 'NBug.dll') * 3) app.config (i.e. MyProduct.exe.config inside the same folder with the main executable 'MyProduct.exe') */ var path1 = Path.Combine(NBugDirectory, "NBug.config"); var path2 = Path.Combine(NBugDirectory, "NBug.dll.config"); /*string path3; // This is automatically handled by System.Configuration*/ if (File.Exists(path1) && new FileInfo(path1).Length > 0) //check if file is empty to avoid false exceptions { try { LoadCustomSettings(XElement.Load(path1)); Logger.Trace("Initialized NBug.Settings using the configuration file: " + path1); } catch (Exception exception) { // File is invalid so load default settings LoadAppconfigSettings(); Logger.Error( "Default configuration file was either corrupt or empty. Loading default app.config settings. File location: " + path1, exception); } } else if (File.Exists(path2) && new FileInfo(path2).Length > 0) //check if file is empty to avoid false exceptions { try { LoadCustomSettings(XElement.Load(path2)); Logger.Trace("Initialized NBug.Settings using the configuration file: " + path2); } catch (Exception exception) { // File is invalid so load default settings LoadAppconfigSettings(); Logger.Error( "Default configuration file was either corrupt or empty. Loading default app.config settings. File location: " + path2, exception); } } else { LoadAppconfigSettings(); } } } /// /// Gets or sets a list of additional files to be added to the report zip. The files can use * or ? in the same way as /// DOS modifiers. /// public static List AdditionalReportFiles { get; set; } public static ICollection Destinations { get; } = new Collection(); /// /// Gets or sets a value indicating whether the application will exit after handling and logging an unhandled /// exception. /// This value is disregarded for anything but UIMode.None. For UIMode.None, you can choose not to exit the application /// which will result in /// 'Windows Error Reporting' (aka Dr. Watson) window to kick in. One reason to do so would be to keep in line with /// Windows 7 Logo requirements, /// which is a corner case. This may also be helpful in using the NBug library as a simple unhandled exception logger /// facility, just to log and submit /// exceptions but not interfering with the application execution flow. Default value is true. /// public static bool ExitApplicationImmediately { get; set; } /// /// Gets or sets a value indicating whether to handle exceptions even in a corrupted process thought the /// 'HandleProcessCorruptedStateExceptions' /// flag. The default value for this is false since generating bug reports for a corrupted process may not be /// successful so use with caution. /// public static bool HandleProcessCorruptedStateExceptions { get; set; } /// /// Gets or sets the number of bug reports that can be queued for submission. Each time an unhandled exception occurs, /// the bug report is prepared to /// be send at the next application startup. If submission fails (i.e. there is no Internet connection), the queue /// grows with each additional /// unhandled exception and resulting bug reports. This limits the max no of queued reports to limit the disk space /// usage. /// Default value is 5. /// public static int MaxQueuedReports { get; set; } /// /// Gets or sets the memory dump type. Memory dumps are quite useful for replicating the exact conditions that the /// application crashed (i.e. /// getting the stack trace, local variables, etc.) but they take up a great deal of space, so choose wisely. Options /// are: /// None: No memory dump is generated. /// Tiny: Dump size ~200KB compressed. /// Normal: Dump size ~20MB compressed. /// Full: Dump size ~100MB compressed. /// Default value is Tiny. /// public static MiniDumpType MiniDumpType { get; set; } /// /// Gets or sets a value indicating whether to enable release mode for the NBug library. In release mode the internal /// developer UI is not displayed and /// unhandled exceptions are only handled if there is no debugger attached to the process. Once properly configured and /// verified to be working /// as intended, NBug release mode should be enabled to be able to properly use the Visual Studio debugger, without /// NBug trying to handle exceptions. /// before Visual Studio does. Default value is false. /// public static bool ReleaseMode { get { return releaseMode; } set { releaseMode = value; if (releaseMode) { ThrowExceptions = false; DisplayDeveloperUI = false; HandleExceptions = !Debugger.IsAttached; DispatcherIsAsynchronous = true; SkipDispatching = false; RemoveThreadSleep = false; } else { // If developer mode is on (default) ThrowExceptions = true; DisplayDeveloperUI = true; HandleExceptions = true; DispatcherIsAsynchronous = false; SkipDispatching = false; RemoveThreadSleep = true; } } } /// /// Gets or sets a public resources object which provides programmatic access to all string resources used in NBug. You /// can /// programmatically appoint new values for all the user interface texts using this property. You can also localize all /// the /// dialog text, if there is no default localization provided for your language. /// public static PublicResources Resources { get; set; } /// /// Gets or sets the time in seconds that report dispatcher waits before starting to submit queued bug reports. /// Dispatcher initializes as /// soon as the application is run but waits for given number of seconds so that it won't slow down the application /// startup. /// Default value is 10 seconds. /// public static int SleepBeforeSend { get; set; } /// /// Gets or sets the number of days that NBug will be collecting bug reports for the application. Most of the time, 30 /// to 60 days after the /// release, there will be a new release and the current one will be obsolete. Due to this, it is not logical to /// continue to create and submit /// bug reports after a given number of days. After the predefined no of days, the user will still get to see the bug /// report UI but the reports /// will not be actually submitted. Default value is 30 days. /// public static int StopReportingAfter { get; set; } /// /// Gets or sets the bug report items storage path. After and unhandled exception occurs, the bug reports are created /// and queued for submission /// on the next application startup. Until then, the reports will be stored in this location. Default value is the /// application executable directory. /// This setting can either be assigned a full path string or a value from /// enumeration. /// public static StoragePath StoragePath { get; set; } /// /// Gets or sets the UI mode. You should only change this if you read the documentation and understood it. Otherwise /// leave it to auto. /// Default value is Auto. /// public static UIMode UIMode { get; set; } /// /// Gets or sets the UI provider. You should only change this if you read the documentation and understood it. /// Otherwise leave it to auto. /// Default value is Auto. /// public static UIProvider UIProvider { get; set; } /// /// Gets or sets a value indicating whether to write "NLog.log" file to disk. Otherwise, you can subscribe to log /// events through the /// event. All the logging is done through System.Diagnostics.Trace.Write() function /// so you can also get /// the log with any trace listener. Default value is true. /// public static bool WriteLogToDisk { get; set; } /// /// Gets the Cipher text used for encrypting connection strings before saving to disk. This is automatically generated /// when the /// method method is called with encryption set to true. /// internal static byte[] Cipher { get; private set; } /// /// Gets or sets a value indicating whether the dispatcher the class deals with sending of reports to their /// destinations like mail /// address or an issue tracker, runs asynchronously (in a background worker thread as a /// ). /// By default dispatcher runs on a background thread except for debug builds, where it blocks the UI and runs in a /// synchronous manner. /// This is made so to prevent any exceptions thrown by the dispatcher from being swallowed by the CLR since background /// thread exceptions /// are ignored in most cases, which is not desirable during development (i.e. in a debug build). /// internal static bool DispatcherIsAsynchronous { get; set; } /// /// Gets or sets a value indicating whether to enable developer user interface facilities which enable easier diagnosis /// of /// configuration and other internal errors. /// internal static bool DisplayDeveloperUI { get; set; } /// /// Gets or sets a value indicating whether to enable network tracing and write the network trace log to /// "NBug.Network.log" file. /// This should only be used for diagnostics, debugging purposes as it slows down network connections considerably. /// Network tracing is disabled by default. /// internal static bool? EnableNetworkTrace { get; set; } /// /// Gets or sets the entry assembly which hosts the NBug assembly. It is used for retrieving the version and the full /// name /// of the host application. i.e. Settings.EntryAssembly.GetLoadedModules()[0].Name; @ Info\General.cs /// internal static Assembly EntryAssembly { get; set; } /// /// Gets or sets a value indicating whether the unhandled exception handlers in NBug.Handler class actually handle /// exceptions. /// Exceptions will not be handled if the application is in release mode via and a /// debugger /// is attached to the process. This enables proper debugging of normal exceptions even in the presence of NBug. /// internal static bool HandleExceptions { get; set; } /// /// Gets or sets the absolute path to the directory that NBug.dll assembly currently resides. This is used in place of /// CWD /// throughout this assembly to prevent the library from getting affected of CWD changes that happens with /// Directory.SetCurrentDirectory(). /// internal static string NBugDirectory { get; set; } /// /// Gets or sets a value indicating whether to remove all the /// statements from /// the thread executions. Some thread sleep statements are used to increase the host application performance i.e. the /// halts the execution of for a given /// number of /// seconds to let the host application initialize properly. /// internal static bool RemoveThreadSleep { get; set; } /// /// Gets or sets a value indicating whether to skip the report dispatching process altogether. /// internal static bool SkipDispatching { get; set; } /// /// Gets or sets a value indicating whether internal derived types are thrown or /// swallowed. /// Exceptions are NOT thrown by default except for debug builds. Note that exceptions are caught and re-thrown by the /// Logger.Error() method with added information so stack trace is reset. The inner exceptions should be inspected to /// get /// the actual stack trace. /// internal static bool ThrowExceptions { get; set; } /// /// Gets or sets a value indicating whether to use the deferred reporting feature. With this feature enabled, all bug /// reports are sent /// after the next application start and as a background task. This helps facilitate sending of bug reports with large /// memory dumps /// with them. When this feature is disabled, bug reports are sent as soon as an unhandled exception is caught. For the /// users, it is /// very uncomfortable to wait for bug reports to be sent after an application crash, so it is best to leave this /// feature on. /// Default value is true. /// private static bool DeferredReporting { get; set; } private static void PopulateProtocols() { if (_availableProtocols != null) return; // find all concrete implementations of IProtocolFactory var type = typeof (IProtocolFactory); _availableProtocols = AppDomain.CurrentDomain.GetAssemblies() .SelectMany(s => s.GetTypes()) .Where(type.IsAssignableFrom) .Where(t => t.IsClass) .Where(t => !t.IsAbstract) .Select(t => (IProtocolFactory) Activator.CreateInstance(t)) .ToDictionary(f => f.SupportedType); } public static event EventHandler CustomSubmissionEvent { add { CustomSubmissionHandle = Delegate.Combine(CustomSubmissionHandle, value); } remove { CustomSubmissionHandle = Delegate.Remove(CustomSubmissionHandle, value); } } public static event EventHandler CustomUIEvent { add { CustomUIHandle = Delegate.Combine(CustomUIHandle, value); } remove { CustomUIHandle = Delegate.Remove(CustomUIHandle, value); } } /// /// The internal logger write event for getting notifications for all internal NBug loggers. Using this event, you can /// attach internal NBug /// logs to your applications own logging facility (i.e. log4net, NLog, etc.). First parameters is the message string, /// second one is the log /// category (info, warning, error, etc.). /// public static event Action InternalLogWritten { add { Logger.LogWritten += value; } remove { Logger.LogWritten -= value; } } /// /// This event is fired just before any caught exception is processed, to make them into an orderly bug report. /// Parameters passed with /// this event can be inspected for some internal decision making or to add more information to the bug report. /// Supplied parameters are: /// -First parameter: : This is the actual exception object that is caught to be report /// as a bug. This object /// is processed to extract standard information from it but it can still carry some custom data that you may want to /// use so it is supplied /// as a parameter of this event for your convenience. /// -Second parameter: : This is any XML serializable object which can carry any additional /// information to be /// embedded in the actual bug report. For instance you may capture more information about the system than NBug does /// for you, so you can put /// all those new information in a user defined type and pass it here. You can also pass in any system type that is /// serializable. Make sure /// that passed objects are XML serializable or the information will not appear in the report. See the sample usage for /// proper usage if this /// event. /// /// /// A sample code demonstrating the proper use of this event: /// /// NBug.Settings.ProcessingException += (exception, report) => /// { /// report.CustomInfo = new MyCusomSystemInformation { UtcTime = DateTime.UtcNow, AdditionalData = RubyExceptionData.GetInstance(exception) }; /// }; /// /// public static event Action ProcessingException { add { BugReport.ProcessingException += value; } remove { BugReport.ProcessingException -= value; } } /// /// Adds a destination based on a connection string. /// /// Connection string. /// The protocol that was created and added. Null if empty connection string. /// /// The protocol corresponding to the Type parameter in the connection string /// was not found. /// public static IProtocol AddDestinationFromConnectionString(string connectionString) { if (string.IsNullOrEmpty(connectionString)) { return null; } var connectionStringParts = ConnectionStringParser.Parse(connectionString); var type = connectionStringParts[@"Type"]; PopulateProtocols(); if (!_availableProtocols.ContainsKey(type)) { throw new ArgumentException(string.Format("No protocol factory found for type '{0}'.", type), nameof(connectionString)); } var factory = _availableProtocols[type]; var protocol = factory.FromConnectionString(connectionString); Destinations.Add(protocol); return protocol; } public static IProtocol AddDestinationFromConnectionString(string connectionString, string cipherString) { if (string.IsNullOrEmpty(connectionString) || string.IsNullOrEmpty(cipherString)) { return null; } Cipher = Convert.FromBase64String(cipherString); return AddDestinationFromConnectionString(Decrypt(connectionString)); } /// /// This should not be used directly. Rather, should be /// preferred. /// internal static void LoadCustomSettings(XElement config) { // Read defaults first UIMode = GetDefaultEnumValue(); UIProvider = GetDefaultEnumValue(); SleepBeforeSend = Convert.ToInt32(GetDefaultValue(() => SleepBeforeSend)); MaxQueuedReports = Convert.ToInt32(GetDefaultValue(() => MaxQueuedReports)); StopReportingAfter = Convert.ToInt32(GetDefaultValue(() => StopReportingAfter)); StoragePath = GetDefaultValue(() => StoragePath); MiniDumpType = GetDefaultEnumValue(); WriteLogToDisk = Convert.ToBoolean(GetDefaultValue(() => WriteLogToDisk)); ExitApplicationImmediately = Convert.ToBoolean(GetDefaultValue(() => ExitApplicationImmediately)); HandleProcessCorruptedStateExceptions = Convert.ToBoolean(GetDefaultValue(() => HandleProcessCorruptedStateExceptions)); ReleaseMode = Convert.ToBoolean(GetDefaultValue(() => ReleaseMode)); DeferredReporting = Convert.ToBoolean(GetDefaultValue(() => DeferredReporting)); if (config.XPathSelectElement("system.diagnostics") != null && config.XPathSelectElement("system.diagnostics/sharedListeners") != null) { var traceLog = from networkTrace in config.XPathSelectElements("system.diagnostics/sharedListeners/add") where networkTrace.Attribute("initializeData") != null && networkTrace.Attribute("initializeData").Value == "NBug.Network.log" select networkTrace; if (traceLog.Any()) { EnableNetworkTrace = true; } } // Read application settings var applicationSettings = from element in config.Elements("applicationSettings").Elements("NBug.Properties.Settings").Elements("setting") where element.Attribute("name") != null && element.Element("value") != null select element; foreach (var applicationSetting in applicationSettings) { var property = applicationSetting.Attribute("name").Value; var value = applicationSetting.Element("value").Value; if (property == GetPropertyName(() => UIMode)) { UIMode = (UIMode) Enum.Parse(typeof (UIMode), value); } else if (property == GetPropertyName(() => UIProvider)) { UIProvider = (UIProvider) Enum.Parse(typeof (UIProvider), value); } else if (property == GetPropertyName(() => SleepBeforeSend)) { SleepBeforeSend = Convert.ToInt32(value); } else if (property == GetPropertyName(() => MaxQueuedReports)) { MaxQueuedReports = Convert.ToInt32(value); } else if (property == GetPropertyName(() => StopReportingAfter)) { StopReportingAfter = Convert.ToInt32(value); } else if (property == GetPropertyName(() => StoragePath)) { StoragePath = value; } else if (property == GetPropertyName(() => MiniDumpType)) { MiniDumpType = (MiniDumpType) Enum.Parse(typeof (MiniDumpType), value); } else if (property == GetPropertyName(() => WriteLogToDisk)) { WriteLogToDisk = Convert.ToBoolean(value); } else if (property == GetPropertyName(() => ExitApplicationImmediately)) { ExitApplicationImmediately = Convert.ToBoolean(value); } else if (property == GetPropertyName(() => HandleProcessCorruptedStateExceptions)) { HandleProcessCorruptedStateExceptions = Convert.ToBoolean(value); } else if (property == GetPropertyName(() => ReleaseMode)) { ReleaseMode = Convert.ToBoolean(value); } else if (property == GetPropertyName(() => DeferredReporting)) { DeferredReporting = Convert.ToBoolean(value); } else { Logger.Error( string.Format( "There is a problem with the 'applicationSettings' section of the configuration file. The property read from the file '{0}' is undefined. This is probably a refactoring problem, or a malformed config file.", property)); } } // Read connection strings var connectionStrings = from element in config.Elements("connectionStrings").Elements("add") where element.Attribute("name") != null && element.Attribute("connectionString") != null select element; foreach (var connectionString in connectionStrings) { var property = connectionString.Attribute("name").Value; var value = connectionString.Attribute("connectionString").Value; var prefix = "NBug.Properties.Settings."; if (property == prefix + GetPropertyName(() => Cipher)) { Cipher = Convert.FromBase64String(value); } else if (property.StartsWith(prefix)) { var decodedConnectionString = Decrypt(value); try { AddDestinationFromConnectionString(decodedConnectionString); } catch (ArgumentException e) { Logger.Error(e.Message); } } else { Logger.Error( "There is a problem with the 'connectionStrings' section of the configuration file. The property read from the file '" + property + "' is undefined. This is probably a refactoring problem, or malformed config file."); } } PopulateProtocols(); var x = _availableProtocols; } /// /// This should not be used directly. Rather should be /// preferred. /// internal static void SaveCustomSettings(Stream settingsFile, bool encryptConnectionStrings) { XDocument config; try { config = XDocument.Load(XmlReader.Create(settingsFile)); } catch (XmlException) { // Root element is missing so recreate the configuration file config = XDocument.Parse(""); } // Restructure the configuration file if (config.Root == null || config.Root.Name != "configuration") { config = XDocument.Parse( "
"); } else { if (config.Root.Element("configSections") == null) { config.Root.AddFirst( XElement.Parse( "
")); } else { var sectionGroup = from setting in config.Root.Element("configSections").Elements() where setting.Attribute("name") != null && setting.Attribute("name").Value == "applicationSettings" select setting; if (!sectionGroup.Any()) { config.Root.Element("configSections") .Add( XElement.Parse( "
")); } else { var nbugSection = from section in sectionGroup.Elements() where section.Attribute("name") != null && section.Attribute("name").Value == "NBug.Properties.Settings" select section; if (!nbugSection.Any()) { sectionGroup.First() .Add( XElement.Parse( "
")); } } } if (config.Root.Element("connectionStrings") == null) { config.Root.Add(XElement.Parse("")); } if (config.Root.Element("applicationSettings") == null) { config.Root.Add( XElement.Parse( "")); } else if (config.Root.Element("applicationSettings").Element("NBug.Properties.Settings") == null) { config.Root.Element("applicationSettings") .Add(XElement.Parse("")); } } if (EnableNetworkTrace.HasValue) { if (EnableNetworkTrace.Value) { if (config.Root.XPathSelectElement("system.diagnostics") != null) { config.Root.XPathSelectElement("system.diagnostics").Remove(); } config.Root.Add( XElement.Parse( "")); } else { if (config.Root.XPathSelectElement("system.diagnostics") != null) { config.Root.XPathSelectElement("system.diagnostics").Remove(); } } } // Replace connection strings var prefix = "NBug.Properties.Settings."; var connectionStrings = from connString in config.Root.Element("connectionStrings").Elements() where connString.Attribute("name") != null && connString.Attribute("name").Value.StartsWith(prefix) select connString; connectionStrings.Remove(); if (encryptConnectionStrings) { if (Cipher == null || Cipher.Length == 0) { Cipher = GenerateKey(); } config.Root.Element("connectionStrings") .Add( new XElement( "add", new XAttribute("name", "NBug.Properties.Settings." + GetPropertyName(() => Cipher)), new XAttribute("connectionString", Convert.ToBase64String(Cipher)))); } else { Cipher = null; } var i = 1; foreach (var destination in Destinations) { AddConnectionString(config, destination.ConnectionString, i); i++; } // Replace application setting var applicationSettings = from appSetting in config.Root.Element("applicationSettings").Element("NBug.Properties.Settings").Elements() where appSetting.Attribute("name") != null && (appSetting.Attribute("name").Value == GetPropertyName(() => UIMode) || appSetting.Attribute("name").Value == GetPropertyName(() => UIProvider) || appSetting.Attribute("name").Value == GetPropertyName(() => SleepBeforeSend) || appSetting.Attribute("name").Value == GetPropertyName(() => MaxQueuedReports) || appSetting.Attribute("name").Value == GetPropertyName(() => StopReportingAfter) || appSetting.Attribute("name").Value == GetPropertyName(() => StoragePath) || appSetting.Attribute("name").Value == GetPropertyName(() => MiniDumpType) || appSetting.Attribute("name").Value == GetPropertyName(() => WriteLogToDisk) || appSetting.Attribute("name").Value == GetPropertyName(() => ExitApplicationImmediately) || appSetting.Attribute("name").Value == GetPropertyName(() => HandleProcessCorruptedStateExceptions) || appSetting.Attribute("name").Value == GetPropertyName(() => ReleaseMode) || appSetting.Attribute("name").Value == GetPropertyName(() => DeferredReporting)) select appSetting; applicationSettings.Remove(); AddApplicationSetting(config, UIMode, () => UIMode); AddApplicationSetting(config, UIProvider, () => UIProvider); AddApplicationSetting(config, SleepBeforeSend, () => SleepBeforeSend); AddApplicationSetting(config, MaxQueuedReports, () => MaxQueuedReports); AddApplicationSetting(config, StopReportingAfter, () => StopReportingAfter); AddApplicationSetting(config, MiniDumpType, () => MiniDumpType); AddApplicationSetting(config, WriteLogToDisk, () => WriteLogToDisk); AddApplicationSetting(config, ExitApplicationImmediately, () => ExitApplicationImmediately); AddApplicationSetting(config, HandleProcessCorruptedStateExceptions, () => HandleProcessCorruptedStateExceptions); AddApplicationSetting(config, ReleaseMode, () => ReleaseMode); AddApplicationSetting(config, DeferredReporting, () => DeferredReporting); if (StoragePath == Enums.StoragePath.Custom) { AddApplicationSetting(config, (string) StoragePath, () => StoragePath); } else { AddApplicationSetting(config, (Enums.StoragePath) StoragePath, () => StoragePath); } settingsFile.SetLength(0); settingsFile.Flush(); config.Save(XmlWriter.Create(settingsFile)); settingsFile.Flush(); } private static void AddApplicationSetting(XDocument document, object content, Expression> propertyExpression) { document.Root.Element("applicationSettings") .Element("NBug.Properties.Settings") .Add( new XElement( "setting", new XAttribute("name", GetPropertyName(propertyExpression)), new XAttribute("serializeAs", "String"), new XElement("value", content))); } private static void AddConnectionString(XDocument document, string content, int number) { if (!string.IsNullOrEmpty(content)) { document.Root.Element("connectionStrings") .Add( new XElement( "add", new XAttribute("name", "NBug.Properties.Settings.Connection" + number), new XAttribute("connectionString", Encrypt(content)))); } } private static string Decrypt(string connectionString) { if (Cipher == null || Cipher.Length == 0) { return connectionString; } // Preserve FIPS compliance SHA512 hashProvider; if (Environment.OSVersion.Version.Major > 5 || (Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor >= 2)) { hashProvider = new SHA512CryptoServiceProvider(); } else { hashProvider = new SHA512Managed(); } using (var hash = hashProvider) //using (var cipher = new Rfc2898DeriveBytes(Cipher, hash.ComputeHash(Cipher), 3)) using (var decryptor = new AesCryptoServiceProvider()) { var cipher = new Rfc2898DeriveBytes(Cipher, hash.ComputeHash(Cipher), 3); var key = cipher.GetBytes(decryptor.KeySize/8); var iv = cipher.GetBytes(decryptor.BlockSize/8); var dec = decryptor.CreateDecryptor(key, iv); var connectionStringBytes = Convert.FromBase64String(connectionString); // Reading from config file is always in Base64 var decryptedBytes = dec.TransformFinalBlock(connectionStringBytes, 0, connectionStringBytes.Length); return Encoding.UTF8.GetString(decryptedBytes); } } private static string Encrypt(string connectionString) { if (Cipher == null || Cipher.Length == 0) { return connectionString; } // Preserve FIPS compliance via using xxxCryptoServiceProvider classes where possible SHA512 hashProvider; if (Environment.OSVersion.Version.Major > 5 || (Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor >= 2)) { hashProvider = new SHA512CryptoServiceProvider(); } else { hashProvider = new SHA512Managed(); } using (var hash = hashProvider) //using (var cipher = new Rfc2898DeriveBytes(Cipher, hash.ComputeHash(Cipher), 3)) using (var encryptor = new AesCryptoServiceProvider()) { var cipher = new Rfc2898DeriveBytes(Cipher, hash.ComputeHash(Cipher), 3); var key = cipher.GetBytes(encryptor.KeySize/8); var iv = cipher.GetBytes(encryptor.BlockSize/8); var enc = encryptor.CreateEncryptor(key, iv); var connectionStringBytes = Encoding.UTF8.GetBytes(connectionString); var encryptedBytes = enc.TransformFinalBlock(connectionStringBytes, 0, connectionStringBytes.Length); return Convert.ToBase64String(encryptedBytes); // Writing to config file is always in Base64 } } private static byte[] GenerateKey() { using (var encryptor = new AesCryptoServiceProvider()) { encryptor.GenerateKey(); return encryptor.Key; } } private static T GetDefaultEnumValue() { var defaultSetting = typeof (Properties.Settings).GetProperty(typeof (T).Name) .GetCustomAttributes(typeof (DefaultSettingValueAttribute), false)[0] as DefaultSettingValueAttribute; try { return (T) Enum.Parse(typeof (T), defaultSetting.Value); } catch (Exception exception) { throw new NBugRuntimeException( "There is no internal default value supplied for '" + typeof (T).Name + "' or the supplied value is invalid. See the inner exception for details.", exception); } } /// /// Replicate the behavior of normal Properties.Settings class via getting default values for null settings. /// Use this like GetDefaultValue(() => SleepBeforeSend); /// /// /// The . /// private static string GetDefaultValue(Expression> propertyExpression) { if (typeof(Properties.Settings).GetProperty(((MemberExpression) propertyExpression.Body).Member.Name) .GetCustomAttributes(typeof(DefaultSettingValueAttribute), false)[0] is DefaultSettingValueAttribute defaultSetting) return defaultSetting.Value; return null; } private static string GetPropertyName(Expression> propertyExpression) { return ((MemberExpression) propertyExpression.Body).Member.Name; } private static void LoadAppconfigSettings() { // Application settings UIMode = Properties.Settings.Default.UIMode; UIProvider = Properties.Settings.Default.UIProvider; SleepBeforeSend = Properties.Settings.Default.SleepBeforeSend; MaxQueuedReports = Properties.Settings.Default.MaxQueuedReports; StopReportingAfter = Properties.Settings.Default.StopReportingAfter; StoragePath = Properties.Settings.Default.StoragePath; MiniDumpType = Properties.Settings.Default.MiniDumpType; WriteLogToDisk = Properties.Settings.Default.WriteLogToDisk; ExitApplicationImmediately = Properties.Settings.Default.ExitApplicationImmediately; HandleProcessCorruptedStateExceptions = Properties.Settings.Default.HandleProcessCorruptedStateExceptions; ReleaseMode = Properties.Settings.Default.ReleaseMode; DeferredReporting = Properties.Settings.Default.DeferredReporting; // Connection strings Cipher = Convert.FromBase64String(Properties.Settings.Default.Cipher); AddDestinationFromConnectionString(Decrypt(Properties.Settings.Default.Destination1)); AddDestinationFromConnectionString(Decrypt(Properties.Settings.Default.Destination2)); AddDestinationFromConnectionString(Decrypt(Properties.Settings.Default.Destination3)); AddDestinationFromConnectionString(Decrypt(Properties.Settings.Default.Destination4)); AddDestinationFromConnectionString(Decrypt(Properties.Settings.Default.Destination5)); } } } ================================================ FILE: source/NetSettingBinder/ISettingChangedHandlerEntry.cs ================================================ namespace Klocman.Binding.Settings { internal interface ISettingChangedHandlerEntry { object Tag { get; set; } void SendEvent(object value); } } ================================================ FILE: source/NetSettingBinder/LockedList.cs ================================================ using System; using System.Collections; using System.Collections.Generic; using System.Linq; namespace Klocman.Binding.Settings { internal class LockedList : IList { private readonly List _list; public LockedList() { _list = new List(); } public IEnumerator GetEnumerator() { lock (_list) return _list.ToList().GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { lock (_list) return ((IEnumerable)_list.ToList()).GetEnumerator(); } public void Add(T item) { lock (_list) _list.Add(item); } public void Clear() { lock (_list) _list.Clear(); } public bool Contains(T item) { lock (_list) return _list.Contains(item); } public void CopyTo(T[] array, int arrayIndex) { lock (_list) _list.CopyTo(array, arrayIndex); } public bool Remove(T item) { lock (_list) return _list.Remove(item); } public int Count { get { lock (_list) return _list.Count; } } public bool IsReadOnly => false; public int IndexOf(T item) { lock (_list) return _list.IndexOf(item); } public void Insert(int index, T item) { lock (_list) _list.Insert(index, item); } public void RemoveAt(int index) { lock (_list) _list.RemoveAt(index); } public int RemoveAll(Predicate match) { lock (_list) return _list.RemoveAll(match); } public T this[int index] { get { lock (_list) return _list[index]; } set { lock (_list) _list[index] = value; } } } } ================================================ FILE: source/NetSettingBinder/NetSettingBinder.csproj ================================================  Library Klocman.Binding.Settings false ================================================ FILE: source/NetSettingBinder/Properties/AssemblyInfo.cs ================================================ using System.Reflection; 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("NetSettingBinder")] [assembly: AssemblyDescription("A tool for binding controls, variables and typed event handlers to custom Settings classes.")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Marcin Szeniak")] [assembly: AssemblyProduct("NetSettingBinder")] [assembly: AssemblyCopyright("Copyright © 2016")] [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("c28a3493-8fca-4571-8f9e-27b8420c0720")] [assembly: AssemblyVersion("1.1.1")] ================================================ FILE: source/NetSettingBinder/ReflectionTools.cs ================================================ using System; using System.Linq.Expressions; using System.Reflection; namespace Klocman.Binding.Settings { internal static class ReflectionTools { /// /// Get the name of a static or instance property from a property access lambda. /// /// Type of the property /// Type of a class that contains the property /// You must pass a lambda formed like this 'x => x.Property' or this 'x => class.Property' /// The name of the property public static string GetPropertyName(Expression> memberLamda) { return GetPropertyInfo(memberLamda).Name; } /// /// Get the PropertyInfo of a static or instance property from a property access lambda. /// /// Type of the property /// Type of a class that contains the property /// You must pass a lambda formed like this 'x => x.Property' or this 'x => class.Property' /// The name of the property public static PropertyInfo GetPropertyInfo(Expression> memberLamda) { if (memberLamda == null) throw new ArgumentNullException(nameof(memberLamda)); if (memberLamda.Body is not MemberExpression memberSelectorExpression) throw new ArgumentException( "You must pass a lambda of the form: 'x => x.Property' or 'x => class.Property'", nameof(memberLamda)); var property = memberSelectorExpression.Member as PropertyInfo; if (property == null) throw new ArgumentException( "You must pass a lambda of the form: 'x => x.Property' or 'x => class.Property'", nameof(memberLamda)); return property; } /// /// Try to set specified property to the supplied object. Ignores setter access protection. /// Will throw an exception if the setter doesn't exist or any of the parameters is invalid. /// /// Type of a class that contains the property /// Instance of the class that contains the property /// You must pass a lambda formed like this 'x => x.Property' or this 'x => class.Property' /// Value to set the property to. public static void SetPropertyValue(TClass classInstance, Expression> memberLamda, object value) { var memberSelectorExpression = memberLamda.Body as MemberExpression; var property = memberSelectorExpression?.Member as PropertyInfo; property?.SetValue(classInstance, value, null); } } } ================================================ FILE: source/NetSettingBinder/SettingBinder.Forms.cs ================================================ using System; using System.Configuration; using System.Linq.Expressions; using System.Windows.Forms; namespace Klocman.Binding.Settings { public partial class SettingBinder where TSettingClass : ApplicationSettingsBase { /// /// Control will update any changes to the settings store and receive updates to change accordingly. /// Best to tag using the parent form. /// /// Control to bind the setting to /// Lambda of style 'x => x.Property' or 'x => class.Property' /// Tag used for grouping /// Adds an event handler to ToolStripMenuItem.Click that will flip its Checked property automatically. /// Invalid lambda format public void BindControl(ToolStripMenuItem sourceControl, Expression> targetSetting, object tag, bool clickingChangesChecked = true) { Bind(x => sourceControl.Checked = x, () => sourceControl.Checked, eh => sourceControl.CheckedChanged += eh, eh => sourceControl.CheckedChanged -= eh, targetSetting, tag); sourceControl.Click += (x, y) => sourceControl.Checked = !sourceControl.Checked; } /// /// Control will update any changes to the settings store and receive updates to change accordingly. /// Best to tag using the parent form. /// /// Control to bind the setting to /// Lambda of style 'x => x.Property' or 'x => class.Property' /// Tag used for grouping /// Invalid lambda format public void BindControl(ToolStripButton sourceControl, Expression> targetSetting, object tag) { Bind(x => sourceControl.Checked = x, () => sourceControl.Checked, eh => sourceControl.CheckedChanged += eh, eh => sourceControl.CheckedChanged -= eh, targetSetting, tag); } /// /// Control will update any changes to the settings store and receive updates to change accordingly. /// Best to tag using the parent form. /// /// Control to bind the setting to /// Lambda of style 'x => x.Property' or 'x => class.Property' /// Tag used for grouping /// Invalid lambda format public void BindControl(TextBox sourceControl, Expression> targetSetting, object tag) { Bind(x => sourceControl.Text = x, () => sourceControl.Text, eh => sourceControl.TextChanged += eh, eh => sourceControl.TextChanged -= eh, targetSetting, tag); } /// /// Control will update any changes to the settings store and receive updates to change accordingly. /// Best to tag using the parent form. /// /// Control to bind the setting to /// Lambda of style 'x => x.Property' or 'x => class.Property' /// Tag used for grouping /// Invalid lambda format public void BindControl(CheckBox sourceControl, Expression> targetSetting, object tag) { Bind(x => sourceControl.Checked = x, () => sourceControl.Checked, eh => sourceControl.CheckedChanged += eh, eh => sourceControl.CheckedChanged -= eh, targetSetting, tag); } /// /// Control will update any changes to the settings store and receive updates to change accordingly. /// Best to tag using the parent form. /// Clicking the ToolStripMenuItem will automatically change it's Checked property. /// /// Control to bind the setting to /// Lambda of style 'x => x.Property' or 'x => class.Property' /// Tag used for grouping /// Invalid lambda format public void BindControl(NumericUpDown sourceControl, Expression> targetSetting, object tag) { Bind(x => sourceControl.Value = x, () => sourceControl.Value, eh => sourceControl.ValueChanged += eh, eh => sourceControl.ValueChanged -= eh, targetSetting, tag); } } } ================================================ FILE: source/NetSettingBinder/SettingBinder.cs ================================================ using System; using System.Collections.Generic; using System.ComponentModel; using System.Configuration; using System.Linq.Expressions; using System.Reflection; namespace Klocman.Binding.Settings { /// /// Binding helper used for binding controls, variables and typed event handlers to custom Settings classes. /// It is realized using generics and does not require any boxing or string literals. /// /// Type of your custom Settings class, it must inherit from ApplicationSettingsBase public partial class SettingBinder where TSettingClass : ApplicationSettingsBase { private readonly LockedList> _eventEntries; /// /// Create a new SettingBinder and hook into the specified class /// /// Custom Settings class this binder is hooked into public SettingBinder(TSettingClass settingSet) { _eventEntries = new LockedList>(); Settings = settingSet ?? throw new ArgumentNullException(nameof(settingSet)); Settings.PropertyChanged += PropertyChangedCallback; } /// /// Custom Settings class this manager is hooked into /// public TSettingClass Settings { get; } /// /// Bind specified property inside of targetClass to the specified setting. /// Use event handler specified by eventHandlerName to get notifications of property changes. /// /// Type of the property /// Type of the class containing specified property /// Lambda of style 'x => x.Property' or 'x => class.Property' /// Name of the event handler /// Instance of the target class /// Lambda of style 'x => x.Property' or 'x => class.Property' /// Tag used for grouping public void BindProperty(TPropertyClass targetClass, Expression> targetProperty, string eventHandlerName, Expression> selectedSetting, object tag) where TPropertyClass : class { var propertyInfo = ReflectionTools.GetPropertyInfo(targetProperty); var eventInfo = typeof(TPropertyClass).GetEvent(eventHandlerName, BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static); if (eventInfo == null) throw new ArgumentException(@"Event name is invalid or the event is not public", nameof(eventHandlerName)); Bind(x => propertyInfo.SetValue(targetClass, x, null), () => (TProperty)propertyInfo.GetValue(targetClass, null), handler => eventInfo.AddEventHandler(targetClass, handler), handler => eventInfo.RemoveEventHandler(targetClass, handler), selectedSetting, tag); } /// /// Bind specified property inside of targetClass to the specified setting. /// Use INotifyPropertyChanged.PropertyChanged event to get notifications of property changes. /// /// Type of the property /// Type of the class containing specified property /// Lambda of style 'x => x.Property' or 'x => class.Property' /// Instance of the target class implementing INotifyPropertyChanged /// Lambda of style 'x => x.Property' or 'x => class.Property' /// Tag used for grouping public void BindProperty(TPropertyClass targetClass, Expression> targetProperty, Expression> selectedSetting, object tag) where TPropertyClass : class, INotifyPropertyChanged { var propertyInfo = ReflectionTools.GetPropertyInfo(targetProperty); var propertyName = propertyInfo.Name; var eventInterface = (INotifyPropertyChanged)targetClass; EventHandler handlerCallback = null; void PropertyChangedHandler(object sender, PropertyChangedEventArgs args) { if (propertyName.Equals(args.PropertyName)) handlerCallback?.Invoke(sender, args); } Bind(x => propertyInfo.SetValue(targetClass, x, null), () => (TProperty)propertyInfo.GetValue(targetClass, null), handler => { handlerCallback = handler; eventInterface.PropertyChanged += PropertyChangedHandler; }, handler => { eventInterface.PropertyChanged -= PropertyChangedHandler; }, selectedSetting, tag); } /// /// Manually bind to a setting /// /// Bound value type /// Delegate used to set value of the external property /// Delegate used to get value of the external property /// Delegate used to register to the notifying event of the external property /// Delegate used to unregister from the notifying event of the external property /// Lambda of style 'x => x.Property' or 'x => class.Property' /// Tag used for grouping public void Bind(Action setter, Func getter, Action registerEvent, Action unregisterEvent, Expression> targetSetting, object tag) { var property = ReflectionTools.GetPropertyInfo(targetSetting); void CheckedChanged(object x, EventArgs y) { property.SetValue(Settings, getter(), null); } registerEvent(CheckedChanged); void SettingChanged(object x, SettingChangedEventArgs y) { var remoteValue = getter(); if ((remoteValue != null && !remoteValue.Equals(y.NewValue)) || (remoteValue == null && y.NewValue != null)) { unregisterEvent(CheckedChanged); setter(y.NewValue); registerEvent(CheckedChanged); } } Subscribe(SettingChanged, targetSetting, tag); } /// /// Create event handler that will automatically update target property in target class when the specified setting /// changes. /// /// Type of the property /// Type of the class containing specified property /// /// The property to be updated when setting changes. Lambda of style 'x => x.Property' or 'x /// => class.Property' /// /// Instance of the class with the property to be updated /// Lambda of style 'x => x.Property' or 'x => class.Property' /// Tag used for grouping public void Subscribe(TPropertyClass targetClass, Expression> targetProperty, Expression> selectedSetting, object tag) { var property = ReflectionTools.GetPropertyInfo(targetProperty); Subscribe((sender, args) => property.SetValue(targetClass, args.NewValue, null), selectedSetting, tag); } /// /// Register event handler for the chosen property and tag it. /// /// Type of the property /// Handler to register /// Lambda of style 'x => x.Property' or 'x => class.Property' /// Tag used for grouping public void Subscribe(SettingChangedEventHandler handler, Expression> selectedSetting, object tag) { var name = ReflectionTools.GetPropertyName(selectedSetting); _eventEntries.Add(new KeyValuePair(name, new SettingChangedHandlerEntry(handler, tag))); } /// /// Remove all handlers with the specified tag /// /// Tag used by group to remove public void RemoveHandlers(object groupTag) { _eventEntries.RemoveAll(pair => Equals(pair.Value.Tag, groupTag)); } /// /// Send property changed events to all registered handlers /// Warning: Do not rely on this firing xyzChanged events as controls and such /// might not fire them if the value doesn't actually change. /// change. /// public void SendUpdates() { foreach (var entry in _eventEntries) { entry.Value.SendEvent(Settings[entry.Key]); } } /// /// Send property changed events to the whole group. /// Warning: Do not rely on this firing xyzChanged events as controls and such /// might not fire them if the value doesn't actually change. /// /// Tag used by group to update public void SendUpdates(object groupTag) { foreach (var entry in _eventEntries) { if (Equals(entry.Value.Tag, groupTag)) { entry.Value.SendEvent(Settings[entry.Key]); } } } /// /// Event handler registered to the custom Settings class /// private void PropertyChangedCallback(object sender, PropertyChangedEventArgs e) { foreach (var entry in _eventEntries) { if (entry.Key.Equals(e.PropertyName)) { entry.Value.SendEvent(Settings[e.PropertyName]); } } } } } ================================================ FILE: source/NetSettingBinder/SettingChangedEventArgs.cs ================================================ using System; namespace Klocman.Binding.Settings { /// /// EventArgs used by the SettingBinder to announce setting changes /// /// Type of the setting that was changed public class SettingChangedEventArgs : EventArgs { internal SettingChangedEventArgs(T value) { if (value == null) throw new ArgumentNullException(nameof(value)); NewValue = value; } /// /// New value of the changed setting /// public T NewValue { get; } } } ================================================ FILE: source/NetSettingBinder/SettingChangedEventHandler.cs ================================================ namespace Klocman.Binding.Settings { public delegate void SettingChangedEventHandler( object sender, SettingChangedEventArgs args); } ================================================ FILE: source/NetSettingBinder/SettingChangedHandlerEntry.cs ================================================ using System; namespace Klocman.Binding.Settings { /// /// This class contains the information required to send the event back to the subscriber /// internal sealed class SettingChangedHandlerEntry : ISettingChangedHandlerEntry { internal SettingChangedHandlerEntry(SettingChangedEventHandler handler, object tag) { Handler = handler ?? throw new ArgumentNullException(nameof(handler)); Tag = tag ?? throw new ArgumentNullException(nameof(tag)); } private SettingChangedEventHandler Handler { get; } public object Tag { get; set; } /// /// Implemented explicitly to hide it from outside access /// void ISettingChangedHandlerEntry.SendEvent(object value) { Handler(this, new SettingChangedEventArgs((T) value)); } } } ================================================ FILE: source/ObjectListView/CellEditing/CellEditKeyEngine.cs ================================================ /* * CellEditKeyEngine - A engine that allows the behaviour of arbitrary keys to be configured * * Author: Phillip Piper * Date: 3-March-2011 10:53 pm * * Change log: * v2.8 * 2014-05-30 JPP - When a row is disabled, skip over it when looking for another cell to edit * v2.5 * 2012-04-14 JPP - Fixed bug where, on a OLV with only a single editable column, tabbing * to change rows would edit the cell above rather than the cell below * the cell being edited. * 2.5 * 2011-03-03 JPP - First version * * Copyright (C) 2011-2014 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System; using System.Collections.Generic; using System.Windows.Forms; namespace BrightIdeasSoftware { /// /// Indicates the behavior of a key when a cell "on the edge" is being edited. /// and the normal behavior of that key would exceed the edge. For example, /// for a key that normally moves one column to the left, the "edge" would be /// the left most column, since the normal action of the key cannot be taken /// (since there are no more columns to the left). /// public enum CellEditAtEdgeBehaviour { /// /// The key press will be ignored /// Ignore, /// /// The key press will result in the cell editing wrapping to the /// cell on the opposite edge. /// Wrap, /// /// The key press will wrap, but the column will be changed to the /// appropiate adjacent column. This only makes sense for keys where /// the normal action is ChangeRow. /// ChangeColumn, /// /// The key press will wrap, but the row will be changed to the /// appropiate adjacent row. This only makes sense for keys where /// the normal action is ChangeColumn. /// ChangeRow, /// /// The key will result in the current edit operation being ended. /// EndEdit }; /// /// Indicates the normal behaviour of a key when used during a cell edit /// operation. /// public enum CellEditCharacterBehaviour { /// /// The key press will be ignored /// Ignore, /// /// The key press will end the current edit and begin an edit /// operation on the next editable cell to the left. /// ChangeColumnLeft, /// /// The key press will end the current edit and begin an edit /// operation on the next editable cell to the right. /// ChangeColumnRight, /// /// The key press will end the current edit and begin an edit /// operation on the row above. /// ChangeRowUp, /// /// The key press will end the current edit and begin an edit /// operation on the row below /// ChangeRowDown, /// /// The key press will cancel the current edit /// CancelEdit, /// /// The key press will finish the current edit operation /// EndEdit, /// /// Custom verb that can be used for specialized actions. /// CustomVerb1, /// /// Custom verb that can be used for specialized actions. /// CustomVerb2, /// /// Custom verb that can be used for specialized actions. /// CustomVerb3, /// /// Custom verb that can be used for specialized actions. /// CustomVerb4, /// /// Custom verb that can be used for specialized actions. /// CustomVerb5, /// /// Custom verb that can be used for specialized actions. /// CustomVerb6, /// /// Custom verb that can be used for specialized actions. /// CustomVerb7, /// /// Custom verb that can be used for specialized actions. /// CustomVerb8, /// /// Custom verb that can be used for specialized actions. /// CustomVerb9, /// /// Custom verb that can be used for specialized actions. /// CustomVerb10, }; /// /// Instances of this class handle key presses during a cell edit operation. /// public class CellEditKeyEngine { #region Public interface /// /// Sets the behaviour of a given key /// /// /// /// public virtual void SetKeyBehaviour(Keys key, CellEditCharacterBehaviour normalBehaviour, CellEditAtEdgeBehaviour atEdgeBehaviour) { CellEditKeyMap[key] = normalBehaviour; CellEditKeyAtEdgeBehaviourMap[key] = atEdgeBehaviour; } /// /// Handle a key press /// /// /// /// True if the key was completely handled. public virtual bool HandleKey(ObjectListView olv, Keys keyData) { if (olv == null) throw new ArgumentNullException("olv"); CellEditCharacterBehaviour behaviour; if (!CellEditKeyMap.TryGetValue(keyData, out behaviour)) return false; ListView = olv; switch (behaviour) { case CellEditCharacterBehaviour.Ignore: break; case CellEditCharacterBehaviour.CancelEdit: HandleCancelEdit(); break; case CellEditCharacterBehaviour.EndEdit: HandleEndEdit(); break; case CellEditCharacterBehaviour.ChangeColumnLeft: case CellEditCharacterBehaviour.ChangeColumnRight: HandleColumnChange(keyData, behaviour); break; case CellEditCharacterBehaviour.ChangeRowDown: case CellEditCharacterBehaviour.ChangeRowUp: HandleRowChange(keyData, behaviour); break; default: return HandleCustomVerb(keyData, behaviour); } return true; } #endregion #region Implementation properties /// /// Gets or sets the ObjectListView on which the current key is being handled. /// This cannot be null. /// protected ObjectListView ListView { get { return listView; } set { listView = value; } } private ObjectListView listView; /// /// Gets the row of the cell that is currently being edited /// protected OLVListItem ItemBeingEdited { get { return (ListView == null || ListView.CellEditEventArgs == null) ? null : ListView.CellEditEventArgs.ListViewItem; } } /// /// Gets the index of the column of the cell that is being edited /// protected int SubItemIndexBeingEdited { get { return (ListView == null || ListView.CellEditEventArgs == null) ? -1 : ListView.CellEditEventArgs.SubItemIndex; } } /// /// Gets or sets the map that remembers the normal behaviour of keys /// protected IDictionary CellEditKeyMap { get { if (cellEditKeyMap == null) InitializeCellEditKeyMaps(); return cellEditKeyMap; } set { cellEditKeyMap = value; } } private IDictionary cellEditKeyMap; /// /// Gets or sets the map that remembers the desired behaviour of keys /// on edge cases. /// protected IDictionary CellEditKeyAtEdgeBehaviourMap { get { if (cellEditKeyAtEdgeBehaviourMap == null) InitializeCellEditKeyMaps(); return cellEditKeyAtEdgeBehaviourMap; } set { cellEditKeyAtEdgeBehaviourMap = value; } } private IDictionary cellEditKeyAtEdgeBehaviourMap; #endregion #region Initialization /// /// Setup the default key mapping /// protected virtual void InitializeCellEditKeyMaps() { cellEditKeyMap = new Dictionary(); cellEditKeyMap[Keys.Escape] = CellEditCharacterBehaviour.CancelEdit; cellEditKeyMap[Keys.Return] = CellEditCharacterBehaviour.EndEdit; cellEditKeyMap[Keys.Enter] = CellEditCharacterBehaviour.EndEdit; cellEditKeyMap[Keys.Tab] = CellEditCharacterBehaviour.ChangeColumnRight; cellEditKeyMap[Keys.Tab | Keys.Shift] = CellEditCharacterBehaviour.ChangeColumnLeft; cellEditKeyMap[Keys.Left | Keys.Alt] = CellEditCharacterBehaviour.ChangeColumnLeft; cellEditKeyMap[Keys.Right | Keys.Alt] = CellEditCharacterBehaviour.ChangeColumnRight; cellEditKeyMap[Keys.Up | Keys.Alt] = CellEditCharacterBehaviour.ChangeRowUp; cellEditKeyMap[Keys.Down | Keys.Alt] = CellEditCharacterBehaviour.ChangeRowDown; cellEditKeyAtEdgeBehaviourMap = new Dictionary(); cellEditKeyAtEdgeBehaviourMap[Keys.Tab] = CellEditAtEdgeBehaviour.Wrap; cellEditKeyAtEdgeBehaviourMap[Keys.Tab | Keys.Shift] = CellEditAtEdgeBehaviour.Wrap; cellEditKeyAtEdgeBehaviourMap[Keys.Left | Keys.Alt] = CellEditAtEdgeBehaviour.Wrap; cellEditKeyAtEdgeBehaviourMap[Keys.Right | Keys.Alt] = CellEditAtEdgeBehaviour.Wrap; cellEditKeyAtEdgeBehaviourMap[Keys.Up | Keys.Alt] = CellEditAtEdgeBehaviour.ChangeColumn; cellEditKeyAtEdgeBehaviourMap[Keys.Down | Keys.Alt] = CellEditAtEdgeBehaviour.ChangeColumn; } #endregion #region Command handling /// /// Handle the end edit command /// protected virtual void HandleEndEdit() { ListView.PossibleFinishCellEditing(); } /// /// Handle the cancel edit command /// protected virtual void HandleCancelEdit() { ListView.CancelCellEdit(); } /// /// Placeholder that subclasses can override to handle any custom verbs /// /// /// /// protected virtual bool HandleCustomVerb(Keys keyData, CellEditCharacterBehaviour behaviour) { return false; } /// /// Handle a change row command /// /// /// protected virtual void HandleRowChange(Keys keyData, CellEditCharacterBehaviour behaviour) { // If we couldn't finish editing the current cell, don't try to move it if (!ListView.PossibleFinishCellEditing()) return; OLVListItem olvi = ItemBeingEdited; int subItemIndex = SubItemIndexBeingEdited; bool isGoingUp = behaviour == CellEditCharacterBehaviour.ChangeRowUp; // Try to find a row above (or below) the currently edited cell // If we find one, start editing it and we're done. OLVListItem adjacentOlvi = GetAdjacentItemOrNull(olvi, isGoingUp); if (adjacentOlvi != null) { StartCellEditIfDifferent(adjacentOlvi, subItemIndex); return; } // There is no adjacent row in the direction we want, so we must be on an edge. CellEditAtEdgeBehaviour atEdgeBehaviour; if (!CellEditKeyAtEdgeBehaviourMap.TryGetValue(keyData, out atEdgeBehaviour)) atEdgeBehaviour = CellEditAtEdgeBehaviour.Wrap; switch (atEdgeBehaviour) { case CellEditAtEdgeBehaviour.Ignore: break; case CellEditAtEdgeBehaviour.EndEdit: ListView.PossibleFinishCellEditing(); break; case CellEditAtEdgeBehaviour.Wrap: adjacentOlvi = GetAdjacentItemOrNull(null, isGoingUp); StartCellEditIfDifferent(adjacentOlvi, subItemIndex); break; case CellEditAtEdgeBehaviour.ChangeColumn: // Figure out the next editable column List editableColumnsInDisplayOrder = EditableColumnsInDisplayOrder; int displayIndex = Math.Max(0, editableColumnsInDisplayOrder.IndexOf(ListView.GetColumn(subItemIndex))); if (isGoingUp) displayIndex = (editableColumnsInDisplayOrder.Count + displayIndex - 1) % editableColumnsInDisplayOrder.Count; else displayIndex = (displayIndex + 1) % editableColumnsInDisplayOrder.Count; subItemIndex = editableColumnsInDisplayOrder[displayIndex].Index; // Wrap to the next row and start the cell edit adjacentOlvi = GetAdjacentItemOrNull(null, isGoingUp); StartCellEditIfDifferent(adjacentOlvi, subItemIndex); break; } } /// /// Handle a change column command /// /// /// protected virtual void HandleColumnChange(Keys keyData, CellEditCharacterBehaviour behaviour) { // If we couldn't finish editing the current cell, don't try to move it if (!ListView.PossibleFinishCellEditing()) return; // Changing columns only works in details mode if (ListView.View != View.Details) return; List editableColumns = EditableColumnsInDisplayOrder; OLVListItem olvi = ItemBeingEdited; int displayIndex = Math.Max(0, editableColumns.IndexOf(ListView.GetColumn(SubItemIndexBeingEdited))); bool isGoingLeft = behaviour == CellEditCharacterBehaviour.ChangeColumnLeft; // Are we trying to continue past one of the edges? if ((isGoingLeft && displayIndex == 0) || (!isGoingLeft && displayIndex == editableColumns.Count - 1)) { // Yes, so figure out our at edge behaviour CellEditAtEdgeBehaviour atEdgeBehaviour; if (!CellEditKeyAtEdgeBehaviourMap.TryGetValue(keyData, out atEdgeBehaviour)) atEdgeBehaviour = CellEditAtEdgeBehaviour.Wrap; switch (atEdgeBehaviour) { case CellEditAtEdgeBehaviour.Ignore: return; case CellEditAtEdgeBehaviour.EndEdit: HandleEndEdit(); return; case CellEditAtEdgeBehaviour.ChangeRow: case CellEditAtEdgeBehaviour.Wrap: if (atEdgeBehaviour == CellEditAtEdgeBehaviour.ChangeRow) olvi = GetAdjacentItem(olvi, isGoingLeft && displayIndex == 0); if (isGoingLeft) displayIndex = editableColumns.Count - 1; else displayIndex = 0; break; } } else { if (isGoingLeft) displayIndex -= 1; else displayIndex += 1; } int subItemIndex = editableColumns[displayIndex].Index; StartCellEditIfDifferent(olvi, subItemIndex); } #endregion #region Utilities /// /// Start editing the indicated cell if that cell is not already being edited /// /// The row to edit /// The cell within that row to edit protected void StartCellEditIfDifferent(OLVListItem olvi, int subItemIndex) { if (ItemBeingEdited == olvi && SubItemIndexBeingEdited == subItemIndex) return; ListView.EnsureVisible(olvi.Index); ListView.StartCellEdit(olvi, subItemIndex); } /// /// Gets the adjacent item to the given item in the given direction. /// If that item is disabled, continue in that direction until an enabled item is found. /// /// The row whose neighbour is sought /// The direction of the adjacentness /// An OLVListView adjacent to the given item, or null if there are no more enabled items in that direction. protected OLVListItem GetAdjacentItemOrNull(OLVListItem olvi, bool up) { OLVListItem item = up ? ListView.GetPreviousItem(olvi) : ListView.GetNextItem(olvi); while (item != null && !item.Enabled) item = up ? ListView.GetPreviousItem(item) : ListView.GetNextItem(item); return item; } /// /// Gets the adjacent item to the given item in the given direction, wrapping if needed. /// /// The row whose neighbour is sought /// The direction of the adjacentness /// An OLVListView adjacent to the given item, or null if there are no more items in that direction. protected OLVListItem GetAdjacentItem(OLVListItem olvi, bool up) { return GetAdjacentItemOrNull(olvi, up) ?? GetAdjacentItemOrNull(null, up); } /// /// Gets a collection of columns that are editable in the order they are shown to the user /// protected List EditableColumnsInDisplayOrder { get { List editableColumnsInDisplayOrder = new List(); foreach (OLVColumn x in ListView.ColumnsInDisplayOrder) if (x.IsEditable) editableColumnsInDisplayOrder.Add(x); return editableColumnsInDisplayOrder; } } #endregion } } ================================================ FILE: source/ObjectListView/CellEditing/CellEditors.cs ================================================ /* * CellEditors - Several slightly modified controls that are used as celleditors within ObjectListView. * * Author: Phillip Piper * Date: 20/10/2008 5:15 PM * * Change log: * v2.6 * 2012-08-02 JPP - Make most editors public so they can be reused/subclassed * v2.3 * 2009-08-13 JPP - Standardized code formatting * v2.2.1 * 2008-01-18 JPP - Added special handling for enums * 2008-01-16 JPP - Added EditorRegistry * v2.0.1 * 2008-10-20 JPP - Separated from ObjectListView.cs * * Copyright (C) 2006-2014 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Windows.Forms; namespace BrightIdeasSoftware { /// /// These items allow combo boxes to remember a value and its description. /// public class ComboBoxItem { /// /// /// /// /// public ComboBoxItem(Object key, String description) { this.key = key; this.description = description; } private readonly String description; /// /// /// public Object Key { get { return key; } } private readonly Object key; /// /// Returns a string that represents the current object. /// /// /// A string that represents the current object. /// /// 2 public override string ToString() { return description; } } //----------------------------------------------------------------------- // Cell editors // These classes are simple cell editors that make it easier to get and set // the value that the control is showing. // In many cases, you can intercept the CellEditStarting event to // change the characteristics of the editor. For example, changing // the acceptable range for a numeric editor or changing the strings // that respresent true and false values for a boolean editor. /// /// This editor shows and auto completes values from the given listview column. /// [ToolboxItem(false)] public class AutoCompleteCellEditor : ComboBox { /// /// Create an AutoCompleteCellEditor /// /// /// public AutoCompleteCellEditor(ObjectListView lv, OLVColumn column) { DropDownStyle = ComboBoxStyle.DropDown; Dictionary alreadySeen = new Dictionary(); for (int i = 0; i < Math.Min(lv.GetItemCount(), 1000); i++) { String str = column.GetStringValue(lv.GetModelObject(i)); if (!alreadySeen.ContainsKey(str)) { Items.Add(str); alreadySeen[str] = true; } } Sorted = true; AutoCompleteSource = AutoCompleteSource.ListItems; AutoCompleteMode = AutoCompleteMode.Append; } } /// /// This combo box is specialised to allow editing of an enum. /// [ToolboxItem(false)] public class EnumCellEditor : ComboBox { /// /// /// /// public EnumCellEditor(Type type) { DropDownStyle = ComboBoxStyle.DropDownList; ValueMember = "Key"; ArrayList values = new ArrayList(); foreach (object value in Enum.GetValues(type)) values.Add(new ComboBoxItem(value, Enum.GetName(type, value))); DataSource = values; } } /// /// This editor simply shows and edits integer values. /// [ToolboxItem(false)] public class IntUpDown : NumericUpDown { /// /// /// public IntUpDown() { DecimalPlaces = 0; Minimum = -9999999; Maximum = 9999999; } /// /// Gets or sets the value shown by this editor /// [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] new public int Value { get { return Decimal.ToInt32(base.Value); } set { base.Value = new Decimal(value); } } } /// /// This editor simply shows and edits unsigned integer values. /// /// This class can't be made public because unsigned int is not a /// CLS-compliant type. If you want to use, just copy the code to this class /// into your project and use it from there. [ToolboxItem(false)] internal class UintUpDown : NumericUpDown { public UintUpDown() { DecimalPlaces = 0; Minimum = 0; Maximum = 9999999; } [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] new public uint Value { get { return Decimal.ToUInt32(base.Value); } set { base.Value = new Decimal(value); } } } /// /// This editor simply shows and edits boolean values. /// [ToolboxItem(false)] public class BooleanCellEditor : ComboBox { /// /// /// public BooleanCellEditor() { DropDownStyle = ComboBoxStyle.DropDownList; ValueMember = "Key"; ArrayList values = new ArrayList(); values.Add(new ComboBoxItem(false, "False")); values.Add(new ComboBoxItem(true, "True")); DataSource = values; } } /// /// This editor simply shows and edits boolean values using a checkbox /// [ToolboxItem(false)] public class BooleanCellEditor2 : CheckBox { /// /// Gets or sets the value shown by this editor /// [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public bool? Value { get { switch (CheckState) { case CheckState.Checked: return true; case CheckState.Indeterminate: return null; case CheckState.Unchecked: default: return false; } } set { if (value.HasValue) CheckState = value.Value ? CheckState.Checked : CheckState.Unchecked; else CheckState = CheckState.Indeterminate; } } /// /// Gets or sets how the checkbox will be aligned /// [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public new HorizontalAlignment TextAlign { get { switch (CheckAlign) { case ContentAlignment.MiddleRight: return HorizontalAlignment.Right; case ContentAlignment.MiddleCenter: return HorizontalAlignment.Center; case ContentAlignment.MiddleLeft: default: return HorizontalAlignment.Left; } } set { switch (value) { case HorizontalAlignment.Left: CheckAlign = ContentAlignment.MiddleLeft; break; case HorizontalAlignment.Center: CheckAlign = ContentAlignment.MiddleCenter; break; case HorizontalAlignment.Right: CheckAlign = ContentAlignment.MiddleRight; break; } } } } /// /// This editor simply shows and edits floating point values. /// /// You can intercept the CellEditStarting event if you want /// to change the characteristics of the editor. For example, by increasing /// the number of decimal places. [ToolboxItem(false)] public class FloatCellEditor : NumericUpDown { /// /// /// public FloatCellEditor() { DecimalPlaces = 2; Minimum = -9999999; Maximum = 9999999; } /// /// Gets or sets the value shown by this editor /// [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] new public double Value { get { return Convert.ToDouble(base.Value); } set { base.Value = Convert.ToDecimal(value); } } } } ================================================ FILE: source/ObjectListView/CellEditing/EditorRegistry.cs ================================================ /* * EditorRegistry - A registry mapping types to cell editors. * * Author: Phillip Piper * Date: 6-March-2011 7:53 am * * Change log: * 2011-03-31 JPP - Use OLVColumn.DataType if the value to be edited is null * 2011-03-06 JPP - Separated from CellEditors.cs * * Copyright (C) 2011-2014 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System; using System.Collections.Generic; using System.Windows.Forms; using System.Reflection; namespace BrightIdeasSoftware { /// /// A delegate that creates an editor for the given value /// /// The model from which that value came /// The column for which the editor is being created /// A representative value of the type to be edited. This value may not be the exact /// value for the column/model combination. It could be simply representative of /// the appropriate type of value. /// A control which can edit the given value public delegate Control EditorCreatorDelegate(Object model, OLVColumn column, Object value); /// /// An editor registry gives a way to decide what cell editor should be used to edit /// the value of a cell. Programmers can register non-standard types and the control that /// should be used to edit instances of that type. /// /// /// All ObjectListViews share the same editor registry. /// public class EditorRegistry { #region Initializing /// /// Create an EditorRegistry /// public EditorRegistry() { InitializeStandardTypes(); } private void InitializeStandardTypes() { Register(typeof(Boolean), typeof(BooleanCellEditor)); Register(typeof(Int16), typeof(IntUpDown)); Register(typeof(Int32), typeof(IntUpDown)); Register(typeof(Int64), typeof(IntUpDown)); Register(typeof(UInt16), typeof(UintUpDown)); Register(typeof(UInt32), typeof(UintUpDown)); Register(typeof(UInt64), typeof(UintUpDown)); Register(typeof(Single), typeof(FloatCellEditor)); Register(typeof(Double), typeof(FloatCellEditor)); Register(typeof(DateTime), delegate(Object model, OLVColumn column, Object value) { DateTimePicker c = new DateTimePicker(); c.Format = DateTimePickerFormat.Short; return c; }); Register(typeof(Boolean), delegate(Object model, OLVColumn column, Object value) { CheckBox c = new BooleanCellEditor2(); c.ThreeState = column.TriStateCheckBoxes; return c; }); } #endregion #region Registering /// /// Register that values of 'type' should be edited by instances of 'controlType'. /// /// The type of value to be edited /// The type of the Control that will edit values of 'type' /// /// ObjectListView.EditorRegistry.Register(typeof(Color), typeof(MySpecialColorEditor)); /// public void Register(Type type, Type controlType) { Register(type, delegate(Object model, OLVColumn column, Object value) { return controlType.InvokeMember("", BindingFlags.CreateInstance, null, null, null) as Control; }); } /// /// Register the given delegate so that it is called to create editors /// for values of the given type /// /// The type of value to be edited /// The delegate that will create a control that can edit values of 'type' /// /// ObjectListView.EditorRegistry.Register(typeof(Color), CreateColorEditor); /// ... /// public Control CreateColorEditor(Object model, OLVColumn column, Object value) /// { /// return new MySpecialColorEditor(); /// } /// public void Register(Type type, EditorCreatorDelegate creator) { creatorMap[type] = creator; } /// /// Register a delegate that will be called to create an editor for values /// that have not been handled. /// /// The delegate that will create a editor for all other types public void RegisterDefault(EditorCreatorDelegate creator) { defaultCreator = creator; } /// /// Register a delegate that will be given a chance to create a control /// before any other option is considered. /// /// The delegate that will create a control public void RegisterFirstChance(EditorCreatorDelegate creator) { firstChanceCreator = creator; } /// /// Remove the registered handler for the given type /// /// Does nothing if the given type doesn't exist /// The type whose registration is to be removed public void Unregister(Type type) { if (creatorMap.ContainsKey(type)) creatorMap.Remove(type); } #endregion #region Accessing /// /// Create and return an editor that is appropriate for the given value. /// Return null if no appropriate editor can be found. /// /// The model involved /// The column to be edited /// The value to be edited. This value may not be the exact /// value for the column/model combination. It could be simply representative of /// the appropriate type of value. /// A Control that can edit the given type of values public Control GetEditor(Object model, OLVColumn column, Object value) { Control editor; // Give the first chance delegate a chance to decide if (firstChanceCreator != null) { editor = firstChanceCreator(model, column, value); if (editor != null) return editor; } // Try to find a creator based on the type of the value (or the column) Type type = value == null ? column.DataType : value.GetType(); if (type != null && creatorMap.ContainsKey(type)) { editor = creatorMap[type](model, column, value); if (editor != null) return editor; } // Enums without other processing get a special editor if (value != null && value.GetType().IsEnum) return CreateEnumEditor(value.GetType()); // Give any default creator a final chance if (defaultCreator != null) return defaultCreator(model, column, value); return null; } /// /// Create and return an editor that will edit values of the given type /// /// A enum type protected Control CreateEnumEditor(Type type) { return new EnumCellEditor(type); } #endregion #region Private variables private EditorCreatorDelegate firstChanceCreator; private EditorCreatorDelegate defaultCreator; private Dictionary creatorMap = new(); #endregion } } ================================================ FILE: source/ObjectListView/CustomDictionary.xml ================================================  br Canceled Center Color Colors f fmt g gdi hti i lightbox lv lvi lvsi m multi Munger n olv olvi p parms r Renderer s SubItem Unapply Unpause x y ComPlus OLV ================================================ FILE: source/ObjectListView/DataListView.cs ================================================ /* * DataListView - A data-bindable listview * * Author: Phillip Piper * Date: 27/09/2008 9:15 AM * * Change log: * 2015-02-02 JPP - Made Unfreezing more efficient by removing a redundant BuildList() call * v2.6 * 2011-02-27 JPP - Moved most of the logic to DataSourceAdapter (where it * can be used by FastDataListView too) * v2.3 * 2009-01-18 JPP - Boolean columns are now handled as checkboxes * - Auto-generated columns would fail if the data source was * reseated, even to the same data source * v2.0.1 * 2009-01-07 JPP - Made all public and protected methods virtual * 2008-10-03 JPP - Separated from ObjectListView.cs * * Copyright (C) 2006-2015 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System; using System.Collections; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.Drawing.Design; using System.Windows.Forms; namespace BrightIdeasSoftware { /// /// A DataListView is a ListView that can be bound to a datasource (which would normally be a DataTable or DataView). /// /// /// This listview keeps itself in sync with its source datatable by listening for change events. /// The DataListView will automatically create columns to show all of the data source's columns/properties, if there is not already /// a column showing that property. This allows you to define one or two columns in the designer and then have the others generated automatically. /// If you don't want any column to be auto generated, set to false. /// These generated columns will be only the simplest view of the world, and would look more interesting with a few delegates installed. /// This listview will also automatically generate missing aspect getters to fetch the values from the data view. /// Changing data sources is possible, but error prone. Before changing data sources, the programmer is responsible for modifying/resetting /// the column collection to be valid for the new data source. /// Internally, a CurrencyManager controls keeping the data source in-sync with other users of the data source (as per normal .NET /// behavior). This means that the model objects in the DataListView are DataRowView objects. If you write your own AspectGetters/Setters, /// they will be given DataRowView objects. /// public class DataListView : ObjectListView { #region Life and death /// /// Make a DataListView /// public DataListView() { Adapter = new DataSourceAdapter(this); } protected override void Dispose(bool disposing) { Adapter.Dispose(); base.Dispose(disposing); } #endregion #region Public Properties /// /// Gets or sets whether or not columns will be automatically generated to show the /// columns when the DataSource is set. /// /// This must be set before the DataSource is set. It has no effect afterwards. [Category("Data"), Description("Should the control automatically generate columns from the DataSource"), DefaultValue(true)] public bool AutoGenerateColumns { get { return Adapter.AutoGenerateColumns; } set { Adapter.AutoGenerateColumns = value; } } /// /// Get or set the DataSource that will be displayed in this list view. /// /// The DataSource should implement either , , /// or . Some common examples are the following types of objects: /// /// /// /// /// /// /// /// When binding to a list container (i.e. one that implements the /// interface, such as ) /// you must also set the property in order /// to identify which particular list you would like to display. You /// may also set the property even when /// DataSource refers to a list, since can /// also be used to navigate relations between lists. /// When a DataSource is set, the control will create OLVColumns to show any /// data source columns that are not already shown. /// If the DataSource is changed, you will have to remove any previously /// created columns, since they will be configured for the previous DataSource. /// . /// [Category("Data"), TypeConverter("System.Windows.Forms.Design.DataSourceConverter, System.Design")] [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public virtual Object DataSource { get { return Adapter.DataSource; } set { Adapter.DataSource = value; } } /// /// Gets or sets the name of the list or table in the data source for which the DataListView is displaying data. /// /// If the data source is not a DataSet or DataViewManager, this property has no effect [Category("Data"), Editor("System.Windows.Forms.Design.DataMemberListEditor, System.Design", typeof(UITypeEditor)), DefaultValue("")] [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public virtual string DataMember { get { return Adapter.DataMember; } set { Adapter.DataMember = value; } } #endregion #region Implementation properties /// /// Gets or sets the DataSourceAdaptor that does the bulk of the work needed /// for data binding. /// /// /// Adaptors cannot be shared between controls. Each DataListView needs its own adapter. /// protected DataSourceAdapter Adapter { get { Debug.Assert(adapter != null, "Data adapter should not be null"); return adapter; } set { adapter = value; } } private DataSourceAdapter adapter; #endregion #region Object manipulations /// /// Add the given collection of model objects to this control. /// /// A collection of model objects /// This is a no-op for data lists, since the data /// is controlled by the DataSource. Manipulate the data source /// rather than this view of the data source. public override void AddObjects(ICollection modelObjects) { } /// /// Insert the given collection of objects before the given position /// /// Where to insert the objects /// The objects to be inserted /// This is a no-op for data lists, since the data /// is controlled by the DataSource. Manipulate the data source /// rather than this view of the data source. public override void InsertObjects(int index, ICollection modelObjects) { } /// /// Remove the given collection of model objects from this control. /// /// This is a no-op for data lists, since the data /// is controlled by the DataSource. Manipulate the data source /// rather than this view of the data source. public override void RemoveObjects(ICollection modelObjects) { } #endregion #region Event Handlers /// /// Change the Unfreeze behaviour /// protected override void DoUnfreeze() { // Copied from base method, but we don't need to BuildList() since we know that our // data adaptor is going to do that immediately after this method exits. EndUpdate(); ResizeFreeSpaceFillingColumns(); // this.BuildList(); } /// /// Handles parent binding context changes /// /// Unused EventArgs. protected override void OnParentBindingContextChanged(EventArgs e) { base.OnParentBindingContextChanged(e); // BindingContext is an ambient property - by default it simply picks // up the parent control's context (unless something has explicitly // given us our own). So we must respond to changes in our parent's // binding context in the same way we would changes to our own // binding context. // THINK: Do we need to forward this to the adapter? } #endregion } } ================================================ FILE: source/ObjectListView/DataTreeListView.cs ================================================ /* * DataTreeListView - A data bindable TreeListView * * Author: Phillip Piper * Date: 05/05/2012 3:26 PM * * Change log: * 2012-05-05 JPP Initial version * * TO DO: * * Copyright (C) 2012 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System; using System.Collections; using System.ComponentModel; using System.Data; using System.Drawing.Design; using System.Windows.Forms; namespace BrightIdeasSoftware { /// /// A DataTreeListView is a TreeListView that calculates its hierarchy based on /// information in the data source. /// /// /// Like a , a DataTreeListView sources all its information /// from a combination of and . /// can be a DataTable, DataSet, /// or anything that implements . /// /// /// To function properly, the DataTreeListView requires: /// /// the table to have a column which holds a unique for the row. The name of this column must be set in . /// the table to have a column which holds id of the hierarchical parent of the row. The name of this column must be set in . /// a value which identifies which rows are the roots of the tree (). /// /// The hierarchy structure is determined finding all the rows where the parent key is equal to . These rows /// become the root objects of the hierarchy. /// /// Like a TreeListView, the hierarchy must not contain cycles. Bad things will happen if the data is cyclic. /// public partial class DataTreeListView : TreeListView { #region Public Properties /// /// Gets or sets whether or not columns will be automatically generated to show the /// columns when the DataSource is set. /// /// This must be set before the DataSource is set. It has no effect afterwards. [Category("Data"), Description("Should the control automatically generate columns from the DataSource"), DefaultValue(true)] public bool AutoGenerateColumns { get { return Adapter.AutoGenerateColumns; } set { Adapter.AutoGenerateColumns = value; } } /// /// Get or set the DataSource that will be displayed in this list view. /// /// The DataSource should implement either , , /// or . Some common examples are the following types of objects: /// /// /// /// /// /// /// /// When binding to a list container (i.e. one that implements the /// interface, such as ) /// you must also set the property in order /// to identify which particular list you would like to display. You /// may also set the property even when /// DataSource refers to a list, since can /// also be used to navigate relations between lists. /// [Category("Data"), TypeConverter("System.Windows.Forms.Design.DataSourceConverter, System.Design")] [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public virtual Object DataSource { get { return Adapter.DataSource; } set { Adapter.DataSource = value; } } /// /// Gets or sets the name of the list or table in the data source for which the DataListView is displaying data. /// /// If the data source is not a DataSet or DataViewManager, this property has no effect [Category("Data"), Editor("System.Windows.Forms.Design.DataMemberListEditor, System.Design", typeof(UITypeEditor)), DefaultValue("")] public virtual string DataMember { get { return Adapter.DataMember; } set { Adapter.DataMember = value; } } /// /// Gets or sets the name of the property/column that uniquely identifies each row. /// /// /// /// The value contained by this column must be unique across all rows /// in the data source. Odd and unpredictable things will happen if two /// rows have the same id. /// /// Null cannot be a valid key value. /// [Category("Data"), Description("The name of the property/column that holds the key of a row"), DefaultValue(null)] public virtual string KeyAspectName { get { return Adapter.KeyAspectName; } set { Adapter.KeyAspectName = value; } } /// /// Gets or sets the name of the property/column that contains the key of /// the parent of a row. /// /// /// /// The test condition for deciding if one row is the parent of another is functionally /// equivilent to this: /// /// Object.Equals(candidateParentRow[this.KeyAspectName], row[this.ParentKeyAspectName]) /// /// /// Unlike key value, parent keys can be null but a null parent key can only be used /// to identify root objects. /// [Category("Data"), Description("The name of the property/column that holds the key of the parent of a row"), DefaultValue(null)] public virtual string ParentKeyAspectName { get { return Adapter.ParentKeyAspectName; } set { Adapter.ParentKeyAspectName = value; } } /// /// Gets or sets the value that identifies a row as a root object. /// When the ParentKey of a row equals the RootKeyValue, that row will /// be treated as root of the TreeListView. /// /// /// /// The test condition for deciding a root object is functionally /// equivilent to this: /// /// Object.Equals(candidateRow[this.ParentKeyAspectName], this.RootKeyValue) /// /// /// The RootKeyValue can be null. Actually, it can be any value that can /// be compared for equality against a basic type. /// If this is set to the wrong value (i.e. to a value that no row /// has in the parent id column), the list will be empty. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual object RootKeyValue { get { return Adapter.RootKeyValue; } set { Adapter.RootKeyValue = value; } } /// /// Gets or sets the value that identifies a row as a root object. /// . The RootKeyValue can be of any type, /// but the IDE cannot sensibly represent a value of any type, /// so this is a typed wrapper around that property. /// /// /// If you want the root value to be something other than a string, /// you will have set it yourself. /// [Category("Data"), Description("The parent id value that identifies a row as a root object"), DefaultValue(null)] public virtual string RootKeyValueString { get { return Convert.ToString(Adapter.RootKeyValue); } set { Adapter.RootKeyValue = value; } } /// /// Gets or sets whether or not the key columns (id and parent id) should /// be shown to the user. /// /// This must be set before the DataSource is set. It has no effect /// afterwards. [Category("Data"), Description("Should the keys columns (id and parent id) be shown to the user?"), DefaultValue(true)] public virtual bool ShowKeyColumns { get { return Adapter.ShowKeyColumns; } set { Adapter.ShowKeyColumns = value; } } #endregion #region Implementation properties /// /// Gets or sets the DataSourceAdaptor that does the bulk of the work needed /// for data binding. /// protected TreeDataSourceAdapter Adapter { get { if (adapter == null) adapter = new TreeDataSourceAdapter(this); return adapter; } set { adapter = value; } } private TreeDataSourceAdapter adapter; #endregion } } ================================================ FILE: source/ObjectListView/DragDrop/DragSource.cs ================================================ /* * DragSource.cs - Add drag source functionality to an ObjectListView * * Author: Phillip Piper * Date: 2009-03-17 5:15 PM * * Change log: * 2011-03-29 JPP - Separate OLVDataObject.cs * v2.3 * 2009-07-06 JPP - Make sure Link is acceptable as an drop effect by default * (since MS didn't make it part of the 'All' value) * v2.2 * 2009-04-15 JPP - Separated DragSource.cs into DropSink.cs * 2009-03-17 JPP - Initial version * * Copyright (C) 2009-2014 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System; using System.Windows.Forms; namespace BrightIdeasSoftware { /// /// An IDragSource controls how drag out from the ObjectListView will behave /// public interface IDragSource { /// /// A drag operation is beginning. Return the data object that will be used /// for data transfer. Return null to prevent the drag from starting. The data /// object will normally include all the selected objects. /// /// /// The returned object is later passed to the GetAllowedEffect() and EndDrag() /// methods. /// /// What ObjectListView is being dragged from. /// Which mouse button is down? /// What item was directly dragged by the user? There may be more than just this /// item selected. /// The data object that will be used for data transfer. This will often be a subclass /// of DataObject, but does not need to be. Object StartDrag(ObjectListView olv, MouseButtons button, OLVListItem item); /// /// What operations are possible for this drag? This controls the icon shown during the drag /// /// The data object returned by StartDrag() /// A combination of DragDropEffects flags DragDropEffects GetAllowedEffects(Object dragObject); /// /// The drag operation is complete. Do whatever is necessary to complete the action. /// /// The data object returned by StartDrag() /// The value returned from GetAllowedEffects() void EndDrag(Object dragObject, DragDropEffects effect); } /// /// A do-nothing implementation of IDragSource that can be safely subclassed. /// public class AbstractDragSource : IDragSource { #region IDragSource Members /// /// See IDragSource documentation /// /// /// /// /// public virtual Object StartDrag(ObjectListView olv, MouseButtons button, OLVListItem item) { return null; } /// /// See IDragSource documentation /// /// /// public virtual DragDropEffects GetAllowedEffects(Object data) { return DragDropEffects.None; } /// /// See IDragSource documentation /// /// /// public virtual void EndDrag(Object dragObject, DragDropEffects effect) { } #endregion } /// /// A reasonable implementation of IDragSource that provides normal /// drag source functionality. It creates a data object that supports /// inter-application dragging of text and HTML representation of /// the dragged rows. It can optionally force a refresh of all dragged /// rows when the drag is complete. /// /// Subclasses can override GetDataObject() to add new /// data formats to the data transfer object. public class SimpleDragSource : IDragSource { #region Constructors /// /// Construct a SimpleDragSource /// public SimpleDragSource() { } /// /// Construct a SimpleDragSource that refreshes the dragged rows when /// the drag is complete /// /// public SimpleDragSource(bool refreshAfterDrop) { RefreshAfterDrop = refreshAfterDrop; } #endregion #region Public properties /// /// Gets or sets whether the dragged rows should be refreshed when the /// drag operation is complete. /// public bool RefreshAfterDrop { get { return refreshAfterDrop; } set { refreshAfterDrop = value; } } private bool refreshAfterDrop; #endregion #region IDragSource Members /// /// Create a DataObject when the user does a left mouse drag operation. /// See IDragSource for further information. /// /// /// /// /// public virtual Object StartDrag(ObjectListView olv, MouseButtons button, OLVListItem item) { // We only drag on left mouse if (button != MouseButtons.Left) return null; return CreateDataObject(olv); } /// /// Which operations are allowed in the operation? By default, all operations are supported. /// /// /// All opertions are supported public virtual DragDropEffects GetAllowedEffects(Object data) { return DragDropEffects.All | DragDropEffects.Link; // why didn't MS include 'Link' in 'All'?? } /// /// The drag operation is finished. Refreshe the dragged rows if so configured. /// /// /// public virtual void EndDrag(Object dragObject, DragDropEffects effect) { if (dragObject is not OLVDataObject data) return; if (RefreshAfterDrop) data.ListView.RefreshObjects(data.ModelObjects); } /// /// Create a data object that will be used to as the data object /// for the drag operation. /// /// /// Subclasses can override this method add new formats to the data object. /// /// The ObjectListView that is the source of the drag /// A data object for the drag protected virtual object CreateDataObject(ObjectListView olv) { return new OLVDataObject(olv); } #endregion } } ================================================ FILE: source/ObjectListView/DragDrop/DropSink.cs ================================================ /* * DropSink.cs - Add drop sink ability to an ObjectListView * * Author: Phillip Piper * Date: 2009-03-17 5:15 PM * * Change log: * v2.9 * 2015-07-08 JPP - Added SimpleDropSink.EnableFeedback to allow all the pretty and helpful * user feedback during drags to be turned off * v2.7 * 2011-04-20 JPP - Rewrote how ModelDropEventArgs.RefreshObjects() works on TreeListViews * v2.4.1 * 2010-08-24 JPP - Moved AcceptExternal property up to SimpleDragSource. * v2.3 * 2009-09-01 JPP - Correctly handle case where RefreshObjects() is called for * objects that were children but are now roots. * 2009-08-27 JPP - Added ModelDropEventArgs.RefreshObjects() to simplify updating after * a drag-drop operation * 2009-08-19 JPP - Changed to use OlvHitTest() * v2.2.1 * 2007-07-06 JPP - Added StandardDropActionFromKeys property to OlvDropEventArgs * v2.2 * 2009-05-17 JPP - Added a Handled flag to OlvDropEventArgs * - Tweaked the appearance of the drop-on-background feedback * 2009-04-15 JPP - Separated DragDrop.cs into DropSink.cs * 2009-03-17 JPP - Initial version * * Copyright (C) 2009-2014 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System; using System.Collections; using System.Drawing; using System.Drawing.Drawing2D; using System.Windows.Forms; namespace BrightIdeasSoftware { /// /// Objects that implement this interface can acts as the receiver for drop /// operation for an ObjectListView. /// public interface IDropSink { /// /// Gets or sets the ObjectListView that is the drop sink /// ObjectListView ListView { get; set; } /// /// Draw any feedback that is appropriate to the current drop state. /// /// /// Any drawing is done over the top of the ListView. This operation should disturb /// the Graphic as little as possible. Specifically, do not erase the area into which /// you draw. /// /// A Graphic for drawing /// The contents bounds of the ListView (not including any header) void DrawFeedback(Graphics g, Rectangle bounds); /// /// The user has released the drop over this control /// /// /// Implementators should set args.Effect to the appropriate DragDropEffects. This value is returned /// to the originator of the drag. /// /// void Drop(DragEventArgs args); /// /// A drag has entered this control. /// /// Implementators should set args.Effect to the appropriate DragDropEffects. /// void Enter(DragEventArgs args); /// /// Change the cursor to reflect the current drag operation. /// /// void GiveFeedback(GiveFeedbackEventArgs args); /// /// The drag has left the bounds of this control /// void Leave(); /// /// The drag is moving over this control. /// /// This is where any drop target should be calculated. /// Implementators should set args.Effect to the appropriate DragDropEffects. /// /// void Over(DragEventArgs args); /// /// Should the drag be allowed to continue? /// /// void QueryContinue(QueryContinueDragEventArgs args); } /// /// This is a do-nothing implementation of IDropSink that is a useful /// base class for more sophisticated implementations. /// public class AbstractDropSink : IDropSink { #region IDropSink Members /// /// Gets or sets the ObjectListView that is the drop sink /// public virtual ObjectListView ListView { get { return listView; } set { listView = value; } } private ObjectListView listView; /// /// Draw any feedback that is appropriate to the current drop state. /// /// /// Any drawing is done over the top of the ListView. This operation should disturb /// the Graphic as little as possible. Specifically, do not erase the area into which /// you draw. /// /// A Graphic for drawing /// The contents bounds of the ListView (not including any header) public virtual void DrawFeedback(Graphics g, Rectangle bounds) { } /// /// The user has released the drop over this control /// /// /// Implementators should set args.Effect to the appropriate DragDropEffects. This value is returned /// to the originator of the drag. /// /// public virtual void Drop(DragEventArgs args) { Cleanup(); } /// /// A drag has entered this control. /// /// Implementators should set args.Effect to the appropriate DragDropEffects. /// public virtual void Enter(DragEventArgs args) { } /// /// The drag has left the bounds of this control /// public virtual void Leave() { Cleanup(); } /// /// The drag is moving over this control. /// /// This is where any drop target should be calculated. /// Implementators should set args.Effect to the appropriate DragDropEffects. /// /// public virtual void Over(DragEventArgs args) { } /// /// Change the cursor to reflect the current drag operation. /// /// You only need to override this if you want non-standard cursors. /// The standard cursors are supplied automatically. /// public virtual void GiveFeedback(GiveFeedbackEventArgs args) { args.UseDefaultCursors = true; } /// /// Should the drag be allowed to continue? /// /// /// You only need to override this if you want the user to be able /// to end the drop in some non-standard way, e.g. dragging to a /// certain point even without releasing the mouse, or going outside /// the bounds of the application. /// /// public virtual void QueryContinue(QueryContinueDragEventArgs args) { } #endregion #region Commands /// /// This is called when the mouse leaves the drop region and after the /// drop has completed. /// protected virtual void Cleanup() { } #endregion } /// /// The enum indicates which target has been found for a drop operation /// [Flags] public enum DropTargetLocation { /// /// No applicable target has been found /// None = 0, /// /// The list itself is the target of the drop /// Background = 0x01, /// /// An item is the target /// Item = 0x02, /// /// Between two items (or above the top item or below the bottom item) /// can be the target. This is not actually ever a target, only a value indicate /// that it is valid to drop between items /// BetweenItems = 0x04, /// /// Above an item is the target /// AboveItem = 0x08, /// /// Below an item is the target /// BelowItem = 0x10, /// /// A subitem is the target of the drop /// SubItem = 0x20, /// /// On the right of an item is the target (not currently used) /// RightOfItem = 0x40, /// /// On the left of an item is the target (not currently used) /// LeftOfItem = 0x80 } /// /// This class represents a simple implementation of a drop sink. /// /// /// Actually, it should be called CleverDropSink -- it's far from simple and can do quite a lot in its own right. /// public class SimpleDropSink : AbstractDropSink { #region Life and death /// /// Make a new drop sink /// public SimpleDropSink() { timer = new Timer(); timer.Interval = 250; timer.Tick += new EventHandler(timer_Tick); CanDropOnItem = true; //this.CanDropOnSubItem = true; //this.CanDropOnBackground = true; //this.CanDropBetween = true; FeedbackColor = Color.FromArgb(180, Color.MediumBlue); billboard = new BillboardOverlay(); } #endregion #region Public properties /// /// Get or set the locations where a drop is allowed to occur (OR-ed together) /// public DropTargetLocation AcceptableLocations { get { return acceptableLocations; } set { acceptableLocations = value; } } private DropTargetLocation acceptableLocations; /// /// Gets or sets whether this sink allows model objects to be dragged from other lists. Defaults to true. /// public bool AcceptExternal { get { return acceptExternal; } set { acceptExternal = value; } } private bool acceptExternal = true; /// /// Gets or sets whether the ObjectListView should scroll when the user drags /// something near to the top or bottom rows. Defaults to true. /// /// AutoScroll does not scroll horizontally. public bool AutoScroll { get { return autoScroll; } set { autoScroll = value; } } private bool autoScroll = true; /// /// Gets the billboard overlay that will be used to display feedback /// messages during a drag operation. /// /// Set this to null to stop the feedback. public BillboardOverlay Billboard { get { return billboard; } set { billboard = value; } } private BillboardOverlay billboard; /// /// Get or set whether a drop can occur between items of the list /// public bool CanDropBetween { get { return (AcceptableLocations & DropTargetLocation.BetweenItems) == DropTargetLocation.BetweenItems; } set { if (value) AcceptableLocations |= DropTargetLocation.BetweenItems; else AcceptableLocations &= ~DropTargetLocation.BetweenItems; } } /// /// Get or set whether a drop can occur on the listview itself /// public bool CanDropOnBackground { get { return (AcceptableLocations & DropTargetLocation.Background) == DropTargetLocation.Background; } set { if (value) AcceptableLocations |= DropTargetLocation.Background; else AcceptableLocations &= ~DropTargetLocation.Background; } } /// /// Get or set whether a drop can occur on items in the list /// public bool CanDropOnItem { get { return (AcceptableLocations & DropTargetLocation.Item) == DropTargetLocation.Item; } set { if (value) AcceptableLocations |= DropTargetLocation.Item; else AcceptableLocations &= ~DropTargetLocation.Item; } } /// /// Get or set whether a drop can occur on a subitem in the list /// public bool CanDropOnSubItem { get { return (AcceptableLocations & DropTargetLocation.SubItem) == DropTargetLocation.SubItem; } set { if (value) AcceptableLocations |= DropTargetLocation.SubItem; else AcceptableLocations &= ~DropTargetLocation.SubItem; } } /// /// Gets or sets whether the drop sink should draw feedback onto the given list /// during the drag operation. Defaults to true. /// /// If this is false, you will have to give the user feedback in some /// other fashion, like cursor changes public bool EnableFeedback { get { return enableFeedback; } set { enableFeedback = value; } } private bool enableFeedback = true; /// /// Get or set the index of the item that is the target of the drop /// public int DropTargetIndex { get { return dropTargetIndex; } set { if (dropTargetIndex != value) { dropTargetIndex = value; ListView.Invalidate(); } } } private int dropTargetIndex = -1; /// /// Get the item that is the target of the drop /// public OLVListItem DropTargetItem { get { return ListView.GetItem(DropTargetIndex); } } /// /// Get or set the location of the target of the drop /// public DropTargetLocation DropTargetLocation { get { return dropTargetLocation; } set { if (dropTargetLocation != value) { dropTargetLocation = value; ListView.Invalidate(); } } } private DropTargetLocation dropTargetLocation; /// /// Get or set the index of the subitem that is the target of the drop /// public int DropTargetSubItemIndex { get { return dropTargetSubItemIndex; } set { if (dropTargetSubItemIndex != value) { dropTargetSubItemIndex = value; ListView.Invalidate(); } } } private int dropTargetSubItemIndex = -1; /// /// Get or set the color that will be used to provide drop feedback /// public Color FeedbackColor { get { return feedbackColor; } set { feedbackColor = value; } } private Color feedbackColor; /// /// Get whether the alt key was down during this drop event /// public bool IsAltDown { get { return (KeyState & 32) == 32; } } /// /// Get whether any modifier key was down during this drop event /// public bool IsAnyModifierDown { get { return (KeyState & (4 + 8 + 32)) != 0; } } /// /// Get whether the control key was down during this drop event /// public bool IsControlDown { get { return (KeyState & 8) == 8; } } /// /// Get whether the left mouse button was down during this drop event /// public bool IsLeftMouseButtonDown { get { return (KeyState & 1) == 1; } } /// /// Get whether the right mouse button was down during this drop event /// public bool IsMiddleMouseButtonDown { get { return (KeyState & 16) == 16; } } /// /// Get whether the right mouse button was down during this drop event /// public bool IsRightMouseButtonDown { get { return (KeyState & 2) == 2; } } /// /// Get whether the shift key was down during this drop event /// public bool IsShiftDown { get { return (KeyState & 4) == 4; } } /// /// Get or set the state of the keys during this drop event /// public int KeyState { get { return keyState; } set { keyState = value; } } private int keyState; /// /// Gets or sets whether the drop sink will automatically use cursors /// based on the drop effect. By default, this is true. If this is /// set to false, you must set the Cursor yourself. /// public bool UseDefaultCursors { get { return useDefaultCursors; } set { useDefaultCursors = value; } } private bool useDefaultCursors = true; #endregion #region Events /// /// Triggered when the sink needs to know if a drop can occur. /// /// /// Handlers should set Effect to indicate what is possible. /// Handlers can change any of the DropTarget* setttings to change /// the target of the drop. /// public event EventHandler CanDrop; /// /// Triggered when the drop is made. /// public event EventHandler Dropped; /// /// Triggered when the sink needs to know if a drop can occur /// AND the source is an ObjectListView /// /// /// Handlers should set Effect to indicate what is possible. /// Handlers can change any of the DropTarget* setttings to change /// the target of the drop. /// public event EventHandler ModelCanDrop; /// /// Triggered when the drop is made. /// AND the source is an ObjectListView /// public event EventHandler ModelDropped; #endregion #region DropSink Interface /// /// Cleanup the drop sink when the mouse has left the control or /// the drag has finished. /// protected override void Cleanup() { DropTargetLocation = DropTargetLocation.None; ListView.FullRowSelect = originalFullRowSelect; Billboard.Text = null; } /// /// Draw any feedback that is appropriate to the current drop state. /// /// /// Any drawing is done over the top of the ListView. This operation should disturb /// the Graphic as little as possible. Specifically, do not erase the area into which /// you draw. /// /// A Graphic for drawing /// The contents bounds of the ListView (not including any header) public override void DrawFeedback(Graphics g, Rectangle bounds) { g.SmoothingMode = ObjectListView.SmoothingMode; if (EnableFeedback) { switch (DropTargetLocation) { case DropTargetLocation.Background: DrawFeedbackBackgroundTarget(g, bounds); break; case DropTargetLocation.Item: DrawFeedbackItemTarget(g, bounds); break; case DropTargetLocation.AboveItem: DrawFeedbackAboveItemTarget(g, bounds); break; case DropTargetLocation.BelowItem: DrawFeedbackBelowItemTarget(g, bounds); break; } } if (Billboard != null) { Billboard.Draw(ListView, g, bounds); } } /// /// The user has released the drop over this control /// /// public override void Drop(DragEventArgs args) { dropEventArgs.DragEventArgs = args; TriggerDroppedEvent(args); timer.Stop(); Cleanup(); } /// /// A drag has entered this control. /// /// Implementators should set args.Effect to the appropriate DragDropEffects. /// public override void Enter(DragEventArgs args) { //System.Diagnostics.Debug.WriteLine("Enter"); /* * When FullRowSelect is true, we have two problems: * 1) GetItemRect(ItemOnly) returns the whole row rather than just the icon/text, which messes * up our calculation of the drop rectangle. * 2) during the drag, the Timer events will not fire! This is the major problem, since without * those events we can't autoscroll. * * The first problem we can solve through coding, but the second is more difficult. * We avoid both problems by turning off FullRowSelect during the drop operation. */ originalFullRowSelect = ListView.FullRowSelect; ListView.FullRowSelect = false; // Setup our drop event args block dropEventArgs = new ModelDropEventArgs(); dropEventArgs.DropSink = this; dropEventArgs.ListView = ListView; dropEventArgs.DragEventArgs = args; dropEventArgs.DataObject = args.Data; if (args.Data is OLVDataObject olvData) { dropEventArgs.SourceListView = olvData.ListView; dropEventArgs.SourceModels = olvData.ModelObjects; } Over(args); } /// /// Change the cursor to reflect the current drag operation. /// /// public override void GiveFeedback(GiveFeedbackEventArgs args) { args.UseDefaultCursors = UseDefaultCursors; } /// /// The drag is moving over this control. /// /// public override void Over(DragEventArgs args) { //System.Diagnostics.Debug.WriteLine("Over"); dropEventArgs.DragEventArgs = args; KeyState = args.KeyState; Point pt = ListView.PointToClient(new Point(args.X, args.Y)); args.Effect = CalculateDropAction(args, pt); CheckScrolling(pt); } #endregion #region Events /// /// Trigger the Dropped events /// /// protected virtual void TriggerDroppedEvent(DragEventArgs args) { dropEventArgs.Handled = false; // If the source is an ObjectListView, trigger the ModelDropped event if (dropEventArgs.SourceListView != null) OnModelDropped(dropEventArgs); if (!dropEventArgs.Handled) OnDropped(dropEventArgs); } /// /// Trigger CanDrop /// /// protected virtual void OnCanDrop(OlvDropEventArgs args) { if (CanDrop != null) CanDrop(this, args); } /// /// Trigger Dropped /// /// protected virtual void OnDropped(OlvDropEventArgs args) { if (Dropped != null) Dropped(this, args); } /// /// Trigger ModelCanDrop /// /// protected virtual void OnModelCanDrop(ModelDropEventArgs args) { // Don't allow drops from other list, if that's what's configured if (!AcceptExternal && args.SourceListView != null && args.SourceListView != ListView) { args.Effect = DragDropEffects.None; args.DropTargetLocation = DropTargetLocation.None; args.InfoMessage = "This list doesn't accept drops from other lists"; return; } if (ModelCanDrop != null) ModelCanDrop(this, args); } /// /// Trigger ModelDropped /// /// protected virtual void OnModelDropped(ModelDropEventArgs args) { if (ModelDropped != null) ModelDropped(this, args); } #endregion #region Implementation private void timer_Tick(object sender, EventArgs e) { HandleTimerTick(); } /// /// Handle the timer tick event, which is sent when the listview should /// scroll /// protected virtual void HandleTimerTick() { // If the mouse has been released, stop scrolling. // This is only necessary if the mouse is released outside of the control. // If the mouse is released inside the control, we would receive a Drop event. if ((IsLeftMouseButtonDown && (Control.MouseButtons & MouseButtons.Left) != MouseButtons.Left) || (IsMiddleMouseButtonDown && (Control.MouseButtons & MouseButtons.Middle) != MouseButtons.Middle) || (IsRightMouseButtonDown && (Control.MouseButtons & MouseButtons.Right) != MouseButtons.Right)) { timer.Stop(); Cleanup(); return; } // Auto scrolling will continune while the mouse is close to the ListView const int GRACE_PERIMETER = 30; Point pt = ListView.PointToClient(Cursor.Position); Rectangle r2 = ListView.ClientRectangle; r2.Inflate(GRACE_PERIMETER, GRACE_PERIMETER); if (r2.Contains(pt)) { ListView.LowLevelScroll(0, scrollAmount); } } /// /// When the mouse is at the given point, what should the target of the drop be? /// /// This method should update the DropTarget* members of the given arg block /// /// The mouse point, in client co-ordinates protected virtual void CalculateDropTarget(OlvDropEventArgs args, Point pt) { const int SMALL_VALUE = 3; DropTargetLocation location = DropTargetLocation.None; int targetIndex = -1; int targetSubIndex = 0; if (CanDropOnBackground) location = DropTargetLocation.Background; // Which item is the mouse over? // If it is not over any item, it's over the background. //ListViewHitTestInfo info = this.ListView.HitTest(pt.X, pt.Y); OlvListViewHitTestInfo info = ListView.OlvHitTest(pt.X, pt.Y); if (info.Item != null && CanDropOnItem) { location = DropTargetLocation.Item; targetIndex = info.Item.Index; if (info.SubItem != null && CanDropOnSubItem) targetSubIndex = info.Item.SubItems.IndexOf(info.SubItem); } // Check to see if the mouse is "between" rows. // ("between" is somewhat loosely defined) if (CanDropBetween && ListView.GetItemCount() > 0) { // If the mouse is over an item, check to see if it is near the top or bottom if (location == DropTargetLocation.Item) { if (pt.Y - SMALL_VALUE <= info.Item.Bounds.Top) location = DropTargetLocation.AboveItem; if (pt.Y + SMALL_VALUE >= info.Item.Bounds.Bottom) location = DropTargetLocation.BelowItem; } else { // Is there an item a little below the mouse? // If so, we say the drop point is above that row info = ListView.OlvHitTest(pt.X, pt.Y + SMALL_VALUE); if (info.Item != null) { targetIndex = info.Item.Index; location = DropTargetLocation.AboveItem; } else { // Is there an item a little above the mouse? info = ListView.OlvHitTest(pt.X, pt.Y - SMALL_VALUE); if (info.Item != null) { targetIndex = info.Item.Index; location = DropTargetLocation.BelowItem; } } } } args.DropTargetLocation = location; args.DropTargetIndex = targetIndex; args.DropTargetSubItemIndex = targetSubIndex; } /// /// What sort of action is possible when the mouse is at the given point? /// /// /// /// /// /// public virtual DragDropEffects CalculateDropAction(DragEventArgs args, Point pt) { CalculateDropTarget(dropEventArgs, pt); dropEventArgs.MouseLocation = pt; dropEventArgs.InfoMessage = null; dropEventArgs.Handled = false; if (dropEventArgs.SourceListView != null) { dropEventArgs.TargetModel = ListView.GetModelObject(dropEventArgs.DropTargetIndex); OnModelCanDrop(dropEventArgs); } if (!dropEventArgs.Handled) OnCanDrop(dropEventArgs); UpdateAfterCanDropEvent(dropEventArgs); return dropEventArgs.Effect; } /// /// Based solely on the state of the modifier keys, what drop operation should /// be used? /// /// The drop operation that matches the state of the keys public DragDropEffects CalculateStandardDropActionFromKeys() { if (IsControlDown) { if (IsShiftDown) return DragDropEffects.Link; else return DragDropEffects.Copy; } else { return DragDropEffects.Move; } } /// /// Should the listview be made to scroll when the mouse is at the given point? /// /// protected virtual void CheckScrolling(Point pt) { if (!AutoScroll) return; Rectangle r = ListView.ContentRectangle; int rowHeight = ListView.RowHeightEffective; int close = rowHeight; // In Tile view, using the whole row height is too much if (ListView.View == View.Tile) close /= 2; if (pt.Y <= (r.Top + close)) { // Scroll faster if the mouse is closer to the top timer.Interval = ((pt.Y <= (r.Top + close / 2)) ? 100 : 350); timer.Start(); scrollAmount = -rowHeight; } else { if (pt.Y >= (r.Bottom - close)) { timer.Interval = ((pt.Y >= (r.Bottom - close / 2)) ? 100 : 350); timer.Start(); scrollAmount = rowHeight; } else { timer.Stop(); } } } /// /// Update the state of our sink to reflect the information that /// may have been written into the drop event args. /// /// protected virtual void UpdateAfterCanDropEvent(OlvDropEventArgs args) { DropTargetIndex = args.DropTargetIndex; DropTargetLocation = args.DropTargetLocation; DropTargetSubItemIndex = args.DropTargetSubItemIndex; if (Billboard != null) { Point pt = args.MouseLocation; pt.Offset(5, 5); if (Billboard.Text != dropEventArgs.InfoMessage || Billboard.Location != pt) { Billboard.Text = dropEventArgs.InfoMessage; Billboard.Location = pt; ListView.Invalidate(); } } } #endregion #region Rendering /// /// Draw the feedback that shows that the background is the target /// /// /// protected virtual void DrawFeedbackBackgroundTarget(Graphics g, Rectangle bounds) { float penWidth = 12.0f; Rectangle r = bounds; r.Inflate((int)-penWidth / 2, (int)-penWidth / 2); using (Pen p = new Pen(Color.FromArgb(128, FeedbackColor), penWidth)) { using (GraphicsPath path = GetRoundedRect(r, 30.0f)) { g.DrawPath(p, path); } } } /// /// Draw the feedback that shows that an item (or a subitem) is the target /// /// /// /// /// DropTargetItem and DropTargetSubItemIndex tells what is the target /// protected virtual void DrawFeedbackItemTarget(Graphics g, Rectangle bounds) { if (DropTargetItem == null) return; Rectangle r = CalculateDropTargetRectangle(DropTargetItem, DropTargetSubItemIndex); r.Inflate(1, 1); float diameter = r.Height / 3; using (GraphicsPath path = GetRoundedRect(r, diameter)) { using (SolidBrush b = new SolidBrush(Color.FromArgb(48, FeedbackColor))) { g.FillPath(b, path); } using (Pen p = new Pen(FeedbackColor, 3.0f)) { g.DrawPath(p, path); } } } /// /// Draw the feedback that shows the drop will occur before target /// /// /// protected virtual void DrawFeedbackAboveItemTarget(Graphics g, Rectangle bounds) { if (DropTargetItem == null) return; Rectangle r = CalculateDropTargetRectangle(DropTargetItem, DropTargetSubItemIndex); DrawBetweenLine(g, r.Left, r.Top, r.Right, r.Top); } /// /// Draw the feedback that shows the drop will occur after target /// /// /// protected virtual void DrawFeedbackBelowItemTarget(Graphics g, Rectangle bounds) { if (DropTargetItem == null) return; Rectangle r = CalculateDropTargetRectangle(DropTargetItem, DropTargetSubItemIndex); DrawBetweenLine(g, r.Left, r.Bottom, r.Right, r.Bottom); } /// /// Return a GraphicPath that is round corner rectangle. /// /// /// /// protected GraphicsPath GetRoundedRect(Rectangle rect, float diameter) { GraphicsPath path = new GraphicsPath(); RectangleF arc = new RectangleF(rect.X, rect.Y, diameter, diameter); path.AddArc(arc, 180, 90); arc.X = rect.Right - diameter; path.AddArc(arc, 270, 90); arc.Y = rect.Bottom - diameter; path.AddArc(arc, 0, 90); arc.X = rect.Left; path.AddArc(arc, 90, 90); path.CloseFigure(); return path; } /// /// Calculate the target rectangle when the given item (and possible subitem) /// is the target of the drop. /// /// /// /// protected virtual Rectangle CalculateDropTargetRectangle(OLVListItem item, int subItem) { if (subItem > 0) return item.SubItems[subItem].Bounds; Rectangle r = ListView.CalculateCellTextBounds(item, subItem); // Allow for indent if (item.IndentCount > 0) { int indentWidth = ListView.SmallImageSize.Width; r.X += (indentWidth * item.IndentCount); r.Width -= (indentWidth * item.IndentCount); } return r; } /// /// Draw a "between items" line at the given co-ordinates /// /// /// /// /// /// protected virtual void DrawBetweenLine(Graphics g, int x1, int y1, int x2, int y2) { using (Brush b = new SolidBrush(FeedbackColor)) { int x = x1; int y = y1; using (GraphicsPath gp = new GraphicsPath()) { gp.AddLine( x, y + 5, x, y - 5); gp.AddBezier( x, y - 6, x + 3, y - 2, x + 6, y - 1, x + 11, y); gp.AddBezier( x + 11, y, x + 6, y + 1, x + 3, y + 2, x, y + 6); gp.CloseFigure(); g.FillPath(b, gp); } x = x2; y = y2; using (GraphicsPath gp = new GraphicsPath()) { gp.AddLine( x, y + 6, x, y - 6); gp.AddBezier( x, y - 7, x - 3, y - 2, x - 6, y - 1, x - 11, y); gp.AddBezier( x - 11, y, x - 6, y + 1, x - 3, y + 2, x, y + 7); gp.CloseFigure(); g.FillPath(b, gp); } } using (Pen p = new Pen(FeedbackColor, 3.0f)) { g.DrawLine(p, x1, y1, x2, y2); } } #endregion private Timer timer; private int scrollAmount; private bool originalFullRowSelect; private ModelDropEventArgs dropEventArgs; } /// /// This drop sink allows items within the same list to be rearranged, /// as well as allowing items to be dropped from other lists. /// /// /// /// This class can only be used on plain ObjectListViews and FastObjectListViews. /// The other flavours have no way to implement the insert operation that is required. /// /// /// This class does not work with grouping. /// /// /// This class works when the OLV is sorted, but it is up to the programmer /// to decide what rearranging such lists "means". Example: if the control is sorting /// students by academic grade, and the user drags a "Fail" grade student up amonst the "A+" /// students, it is the responsibility of the programmer to makes the appropriate changes /// to the model and redraw/rebuild the control so that the users action makes sense. /// /// /// Users of this class should listen for the CanDrop event to decide /// if models from another OLV can be moved to OLV under this sink. /// /// public class RearrangingDropSink : SimpleDropSink { /// /// Create a RearrangingDropSink /// public RearrangingDropSink() { CanDropBetween = true; CanDropOnBackground = true; CanDropOnItem = false; } /// /// Create a RearrangingDropSink /// /// public RearrangingDropSink(bool acceptDropsFromOtherLists) : this() { AcceptExternal = acceptDropsFromOtherLists; } /// /// Trigger OnModelCanDrop /// /// protected override void OnModelCanDrop(ModelDropEventArgs args) { base.OnModelCanDrop(args); if (args.Handled) return; args.Effect = DragDropEffects.Move; // Don't allow drops from other list, if that's what's configured if (!AcceptExternal && args.SourceListView != ListView) { args.Effect = DragDropEffects.None; args.DropTargetLocation = DropTargetLocation.None; args.InfoMessage = "This list doesn't accept drops from other lists"; } // If we are rearranging a list, don't allow drops on the background if (args.DropTargetLocation == DropTargetLocation.Background && args.SourceListView == ListView) { args.Effect = DragDropEffects.None; args.DropTargetLocation = DropTargetLocation.None; } } /// /// Trigger OnModelDropped /// /// protected override void OnModelDropped(ModelDropEventArgs args) { base.OnModelDropped(args); if (!args.Handled) RearrangeModels(args); } /// /// Do the work of processing the dropped items /// /// public virtual void RearrangeModels(ModelDropEventArgs args) { switch (args.DropTargetLocation) { case DropTargetLocation.AboveItem: ListView.MoveObjects(args.DropTargetIndex, args.SourceModels); break; case DropTargetLocation.BelowItem: ListView.MoveObjects(args.DropTargetIndex + 1, args.SourceModels); break; case DropTargetLocation.Background: ListView.AddObjects(args.SourceModels); break; default: return; } if (args.SourceListView != ListView) { args.SourceListView.RemoveObjects(args.SourceModels); } } } /// /// When a drop sink needs to know if something can be dropped, or /// to notify that a drop has occured, it uses an instance of this class. /// public class OlvDropEventArgs : EventArgs { /// /// Create a OlvDropEventArgs /// public OlvDropEventArgs() { } #region Data Properties /// /// Get the original drag-drop event args /// public DragEventArgs DragEventArgs { get { return dragEventArgs; } internal set { dragEventArgs = value; } } private DragEventArgs dragEventArgs; /// /// Get the data object that is being dragged /// public object DataObject { get { return dataObject; } internal set { dataObject = value; } } private object dataObject; /// /// Get the drop sink that originated this event /// public SimpleDropSink DropSink { get { return dropSink; } internal set { dropSink = value; } } private SimpleDropSink dropSink; /// /// Get or set the index of the item that is the target of the drop /// public int DropTargetIndex { get { return dropTargetIndex; } set { dropTargetIndex = value; } } private int dropTargetIndex = -1; /// /// Get or set the location of the target of the drop /// public DropTargetLocation DropTargetLocation { get { return dropTargetLocation; } set { dropTargetLocation = value; } } private DropTargetLocation dropTargetLocation; /// /// Get or set the index of the subitem that is the target of the drop /// public int DropTargetSubItemIndex { get { return dropTargetSubItemIndex; } set { dropTargetSubItemIndex = value; } } private int dropTargetSubItemIndex = -1; /// /// Get the item that is the target of the drop /// public OLVListItem DropTargetItem { get { return ListView.GetItem(DropTargetIndex); } set { if (value == null) DropTargetIndex = -1; else DropTargetIndex = value.Index; } } /// /// Get or set the drag effect that should be used for this operation /// public DragDropEffects Effect { get { return effect; } set { effect = value; } } private DragDropEffects effect; /// /// Get or set if this event was handled. No further processing will be done for a handled event. /// public bool Handled { get { return handled; } set { handled = value; } } private bool handled; /// /// Get or set the feedback message for this operation /// /// /// If this is not null, it will be displayed as a feedback message /// during the drag. /// public string InfoMessage { get { return infoMessage; } set { infoMessage = value; } } private string infoMessage; /// /// Get the ObjectListView that is being dropped on /// public ObjectListView ListView { get { return listView; } internal set { listView = value; } } private ObjectListView listView; /// /// Get the location of the mouse (in target ListView co-ords) /// public Point MouseLocation { get { return mouseLocation; } internal set { mouseLocation = value; } } private Point mouseLocation; /// /// Get the drop action indicated solely by the state of the modifier keys /// public DragDropEffects StandardDropActionFromKeys { get { return DropSink.CalculateStandardDropActionFromKeys(); } } #endregion } /// /// These events are triggered when the drag source is an ObjectListView. /// public class ModelDropEventArgs : OlvDropEventArgs { /// /// Create a ModelDropEventArgs /// public ModelDropEventArgs() { } /// /// Gets the model objects that are being dragged. /// public IList SourceModels { get { return dragModels; } internal set { dragModels = value; if (SourceListView is TreeListView tlv) { foreach (object model in SourceModels) { object parent = tlv.GetParent(model); if (!toBeRefreshed.Contains(parent)) toBeRefreshed.Add(parent); } } } } private IList dragModels; private ArrayList toBeRefreshed = new(); /// /// Gets the ObjectListView that is the source of the dragged objects. /// public ObjectListView SourceListView { get { return sourceListView; } internal set { sourceListView = value; } } private ObjectListView sourceListView; /// /// Get the model object that is being dropped upon. /// /// This is only value for TargetLocation == Item public object TargetModel { get { return targetModel; } internal set { targetModel = value; } } private object targetModel; /// /// Refresh all the objects involved in the operation /// public void RefreshObjects() { toBeRefreshed.AddRange(SourceModels); if (SourceListView is not TreeListView tlv) SourceListView.RefreshObjects(toBeRefreshed); else tlv.RebuildAll(true); if (ListView is not TreeListView tlv2) ListView.RefreshObject(TargetModel); else tlv2.RebuildAll(true); } } } ================================================ FILE: source/ObjectListView/DragDrop/OLVDataObject.cs ================================================ /* * OLVDataObject.cs - An OLE DataObject that knows how to convert rows of an OLV to text and HTML * * Author: Phillip Piper * Date: 2011-03-29 3:34PM * * Change log: * v2.8 * 2014-05-02 JPP - When the listview is completely empty, don't try to set CSV text in the clipboard. * v2.6 * 2012-08-08 JPP - Changed to use OLVExporter. * - Added CSV to formats exported to Clipboard * v2.4 * 2011-03-29 JPP - Initial version * * Copyright (C) 2011-2014 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System; using System.Collections; using System.Windows.Forms; namespace BrightIdeasSoftware { /// /// A data transfer object that knows how to transform a list of model /// objects into a text and HTML representation. /// public class OLVDataObject : DataObject { #region Life and death /// /// Create a data object from the selected objects in the given ObjectListView /// /// The source of the data object public OLVDataObject(ObjectListView olv) : this(olv, olv.SelectedObjects) { } /// /// Create a data object which operates on the given model objects /// in the given ObjectListView /// /// The source of the data object /// The model objects to be put into the data object public OLVDataObject(ObjectListView olv, IList modelObjects) { objectListView = olv; this.modelObjects = modelObjects; includeHiddenColumns = olv.IncludeHiddenColumnsInDataTransfer; includeColumnHeaders = olv.IncludeColumnHeadersInCopy; CreateTextFormats(); } #endregion #region Properties /// /// Gets or sets whether hidden columns will also be included in the text /// and HTML representation. If this is false, only visible columns will /// be included. /// public bool IncludeHiddenColumns { get { return includeHiddenColumns; } } private readonly bool includeHiddenColumns; /// /// Gets or sets whether column headers will also be included in the text /// and HTML representation. /// public bool IncludeColumnHeaders { get { return includeColumnHeaders; } } private readonly bool includeColumnHeaders; /// /// Gets the ObjectListView that is being used as the source of the data /// public ObjectListView ListView { get { return objectListView; } } private readonly ObjectListView objectListView; /// /// Gets the model objects that are to be placed in the data object /// public IList ModelObjects { get { return modelObjects; } } private readonly IList modelObjects; #endregion /// /// Put a text and HTML representation of our model objects /// into the data object. /// public void CreateTextFormats() { OLVExporter exporter = CreateExporter(); // Put both the text and html versions onto the clipboard. // For some reason, SetText() with UnicodeText doesn't set the basic CF_TEXT format, // but using SetData() does. //this.SetText(sbText.ToString(), TextDataFormat.UnicodeText); SetData(exporter.ExportTo(OLVExporter.ExportFormat.TabSeparated)); string exportTo = exporter.ExportTo(OLVExporter.ExportFormat.CSV); if (!String.IsNullOrEmpty(exportTo)) SetText(exportTo, TextDataFormat.CommaSeparatedValue); SetText(ConvertToHtmlFragment(exporter.ExportTo(OLVExporter.ExportFormat.HTML)), TextDataFormat.Html); } /// /// Create an exporter for the data contained in this object /// /// protected OLVExporter CreateExporter() { OLVExporter exporter = new OLVExporter(ListView); exporter.IncludeColumnHeaders = IncludeColumnHeaders; exporter.IncludeHiddenColumns = IncludeHiddenColumns; exporter.ModelObjects = ModelObjects; return exporter; } /// /// Make a HTML representation of our model objects /// [Obsolete("Use OLVExporter directly instead", false)] public string CreateHtml() { OLVExporter exporter = CreateExporter(); return exporter.ExportTo(OLVExporter.ExportFormat.HTML); } /// /// Convert the fragment of HTML into the Clipboards HTML format. /// /// The HTML format is found here http://msdn2.microsoft.com/en-us/library/aa767917.aspx /// /// The HTML to put onto the clipboard. It must be valid HTML! /// A string that can be put onto the clipboard and will be recognized as HTML private string ConvertToHtmlFragment(string fragment) { // Minimal implementation of HTML clipboard format const string SOURCE = "http://www.codeproject.com/Articles/16009/A-Much-Easier-to-Use-ListView"; const String MARKER_BLOCK = "Version:1.0\r\n" + "StartHTML:{0,8}\r\n" + "EndHTML:{1,8}\r\n" + "StartFragment:{2,8}\r\n" + "EndFragment:{3,8}\r\n" + "StartSelection:{2,8}\r\n" + "EndSelection:{3,8}\r\n" + "SourceURL:{4}\r\n" + "{5}"; int prefixLength = String.Format(MARKER_BLOCK, 0, 0, 0, 0, SOURCE, "").Length; const String DEFAULT_HTML_BODY = "" + "{0}"; string html = String.Format(DEFAULT_HTML_BODY, fragment); int startFragment = prefixLength + html.IndexOf(fragment, StringComparison.Ordinal); int endFragment = startFragment + fragment.Length; return String.Format(MARKER_BLOCK, prefixLength, prefixLength + html.Length, startFragment, endFragment, SOURCE, html); } } } ================================================ FILE: source/ObjectListView/FastDataListView.cs ================================================ /* * FastDataListView - A data bindable listview that has the speed of a virtual list * * Author: Phillip Piper * Date: 22/09/2010 8:11 AM * * Change log: * 2015-02-02 JPP - Made Unfreezing more efficient by removing a redundant BuildList() call * v2.6 * 2010-09-22 JPP - Initial version * * Copyright (C) 2006-2015 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System; using System.Collections; using System.Data; using System.ComponentModel; using System.Windows.Forms; using System.Drawing.Design; namespace BrightIdeasSoftware { /// /// A FastDataListView virtualizes the display of data from a DataSource. It operates on /// DataSets and DataTables in the same way as a DataListView, but does so much more efficiently. /// /// /// /// A FastDataListView still has to load all its data from the DataSource. If you have SQL statement /// that returns 1 million rows, all 1 million rows will still need to read from the database. /// However, once the rows are loaded, the FastDataListView will only build rows as they are displayed. /// /// public class FastDataListView : FastObjectListView { protected override void Dispose(bool disposing) { if (adapter != null) { adapter.Dispose(); adapter = null; } base.Dispose(disposing); } #region Public Properties /// /// Gets or sets whether or not columns will be automatically generated to show the /// columns when the DataSource is set. /// /// This must be set before the DataSource is set. It has no effect afterwards. [Category("Data"), Description("Should the control automatically generate columns from the DataSource"), DefaultValue(true)] public bool AutoGenerateColumns { get { return Adapter.AutoGenerateColumns; } set { Adapter.AutoGenerateColumns = value; } } /// /// Get or set the VirtualListDataSource that will be displayed in this list view. /// /// The VirtualListDataSource should implement either , , /// or . Some common examples are the following types of objects: /// /// /// /// /// /// /// /// When binding to a list container (i.e. one that implements the /// interface, such as ) /// you must also set the property in order /// to identify which particular list you would like to display. You /// may also set the property even when /// VirtualListDataSource refers to a list, since can /// also be used to navigate relations between lists. /// [Category("Data"), TypeConverter("System.Windows.Forms.Design.DataSourceConverter, System.Design")] [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public virtual Object DataSource { get { return Adapter.DataSource; } set { Adapter.DataSource = value; } } /// /// Gets or sets the name of the list or table in the data source for which the DataListView is displaying data. /// /// If the data source is not a DataSet or DataViewManager, this property has no effect [Category("Data"), Editor("System.Windows.Forms.Design.DataMemberListEditor, System.Design", typeof(UITypeEditor)), DefaultValue("")] [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public virtual string DataMember { get { return Adapter.DataMember; } set { Adapter.DataMember = value; } } #endregion #region Implementation properties /// /// Gets or sets the DataSourceAdaptor that does the bulk of the work needed /// for data binding. /// protected DataSourceAdapter Adapter { get { if (adapter == null) adapter = CreateDataSourceAdapter(); return adapter; } set { adapter = value; } } private DataSourceAdapter adapter; #endregion #region Implementation /// /// Create the DataSourceAdapter that this control will use. /// /// A DataSourceAdapter configured for this list /// Subclasses should override this to create their /// own specialized adapters protected virtual DataSourceAdapter CreateDataSourceAdapter() { return new DataSourceAdapter(this); } /// /// Change the Unfreeze behaviour /// protected override void DoUnfreeze() { // Copied from base method, but we don't need to BuildList() since we know that our // data adaptor is going to do that immediately after this method exits. EndUpdate(); ResizeFreeSpaceFillingColumns(); // this.BuildList(); } #endregion } } ================================================ FILE: source/ObjectListView/FastObjectListView.cs ================================================ /* * FastObjectListView - A listview that behaves like an ObjectListView but has the speed of a virtual list * * Author: Phillip Piper * Date: 27/09/2008 9:15 AM * * Change log: * 2014-10-15 JPP - Fire Filter event when applying filters * v2.8 * 2012-06-11 JPP - Added more efficient version of FilteredObjects * v2.5.1 * 2011-04-25 JPP - Fixed problem with removing objects from filtered or sorted list * v2.4 * 2010-04-05 JPP - Added filtering * v2.3 * 2009-08-27 JPP - Added GroupingStrategy * - Added optimized Objects property * v2.2.1 * 2009-01-07 JPP - Made all public and protected methods virtual * 2008-09-27 JPP - Separated from ObjectListView.cs * * Copyright (C) 2006-2014 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Windows.Forms; namespace BrightIdeasSoftware { /// /// A FastObjectListView trades function for speed. /// /// /// On my mid-range laptop, this view builds a list of 10,000 objects in 0.1 seconds, /// as opposed to a normal ObjectListView which takes 10-15 seconds. Lists of up to 50,000 items should be /// able to be handled with sub-second response times even on low end machines. /// /// A FastObjectListView is implemented as a virtual list with many of the virtual modes limits (e.g. no sorting) /// fixed through coding. There are some functions that simply cannot be provided. Specifically, a FastObjectListView cannot: /// /// use Tile view /// show groups on XP /// /// /// public class FastObjectListView : VirtualObjectListView { /// /// Make a FastObjectListView /// public FastObjectListView() { VirtualListDataSource = new FastObjectListDataSource(this); GroupingStrategy = new FastListGroupingStrategy(); } /// /// Gets the collection of objects that survive any filtering that may be in place. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public override IEnumerable FilteredObjects { get { // This is much faster than the base method return ((FastObjectListDataSource)VirtualListDataSource).FilteredObjectList; } } /// /// Get/set the collection of objects that this list will show /// /// /// /// The contents of the control will be updated immediately after setting this property. /// /// This method preserves selection, if possible. Use SetObjects() if /// you do not want to preserve the selection. Preserving selection is the slowest part of this /// code and performance is O(n) where n is the number of selected rows. /// This method is not thread safe. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public override IEnumerable Objects { get { // This is much faster than the base method return ((FastObjectListDataSource)VirtualListDataSource).ObjectList; } set { base.Objects = value; } } /// /// Move the given collection of objects to the given index. /// /// This operation only makes sense on non-grouped ObjectListViews. /// /// public override void MoveObjects(int index, ICollection modelObjects) { if (InvokeRequired) { Invoke((MethodInvoker)delegate() { MoveObjects(index, modelObjects); }); return; } // If any object that is going to be moved is before the point where the insertion // will occur, then we have to reduce the location of our insertion point int displacedObjectCount = 0; foreach (object modelObject in modelObjects) { int i = IndexOf(modelObject); if (i >= 0 && i <= index) displacedObjectCount++; } index -= displacedObjectCount; BeginUpdate(); try { RemoveObjects(modelObjects); InsertObjects(index, modelObjects); } finally { EndUpdate(); } } /// /// Remove any sorting and revert to the given order of the model objects /// /// To be really honest, Unsort() doesn't work on FastObjectListViews since /// the original ordering of model objects is lost when Sort() is called. So this method /// effectively just turns off sorting. public override void Unsort() { ShowGroups = false; PrimarySortColumn = null; PrimarySortOrder = SortOrder.None; SetObjects(Objects); } } /// /// Provide a data source for a FastObjectListView /// /// /// This class isn't intended to be used directly, but it is left as a public /// class just in case someone wants to subclass it. /// public class FastObjectListDataSource : AbstractVirtualListDataSource { /// /// Create a FastObjectListDataSource /// /// public FastObjectListDataSource(FastObjectListView listView) : base(listView) { } #region IVirtualListDataSource Members /// /// Get n'th object /// /// /// public override object GetNthObject(int n) { if (n >= 0 && n < filteredObjectList.Count) return filteredObjectList[n]; return null; } /// /// How many items are in the data source /// /// public override int GetObjectCount() { return filteredObjectList.Count; } /// /// Get the index of the given model /// /// /// public override int GetObjectIndex(object model) { int index; if (model != null && objectsToIndexMap.TryGetValue(model, out index)) return index; return -1; } /// /// /// /// /// /// /// /// public override int SearchText(string text, int first, int last, OLVColumn column) { if (first <= last) { for (int i = first; i <= last; i++) { string data = column.GetStringValue(listView.GetNthItemInDisplayOrder(i).RowObject); if (data.StartsWith(text, StringComparison.CurrentCultureIgnoreCase)) return i; } } else { for (int i = first; i >= last; i--) { string data = column.GetStringValue(listView.GetNthItemInDisplayOrder(i).RowObject); if (data.StartsWith(text, StringComparison.CurrentCultureIgnoreCase)) return i; } } return -1; } /// /// /// /// /// public override void Sort(OLVColumn column, SortOrder sortOrder) { if (sortOrder != SortOrder.None) { ModelObjectComparer comparer = new ModelObjectComparer(column, sortOrder, listView.SecondarySortColumn, listView.SecondarySortOrder); fullObjectList.Sort(comparer); filteredObjectList.Sort(comparer); } RebuildIndexMap(); } /// /// /// /// public override void AddObjects(ICollection modelObjects) { foreach (object modelObject in modelObjects) { if (modelObject != null) fullObjectList.Add(modelObject); } FilterObjects(); RebuildIndexMap(); } /// /// /// /// /// public override void InsertObjects(int index, ICollection modelObjects) { fullObjectList.InsertRange(index, modelObjects); FilterObjects(); RebuildIndexMap(); } /// /// Remove the given collection of models from this source. /// /// public override void RemoveObjects(ICollection modelObjects) { // We have to unselect any object that is about to be deleted List indicesToRemove = new List(); foreach (object modelObject in modelObjects) { int i = GetObjectIndex(modelObject); if (i >= 0) indicesToRemove.Add(i); } // Sort the indices from highest to lowest so that we // remove latter ones before earlier ones. In this way, the // indices of the rows doesn't change after the deletes. indicesToRemove.Sort(); indicesToRemove.Reverse(); foreach (int i in indicesToRemove) listView.SelectedIndices.Remove(i); // Remove the objects from the unfiltered list foreach (object modelObject in modelObjects) fullObjectList.Remove(modelObject); FilterObjects(); RebuildIndexMap(); } /// /// /// /// public override void SetObjects(IEnumerable collection) { ArrayList newObjects = ObjectListView.EnumerableToArray(collection, true); fullObjectList = newObjects; FilterObjects(); RebuildIndexMap(); } /// /// Update/replace the nth object with the given object /// /// /// public override void UpdateObject(int index, object modelObject) { if (index < 0 || index >= filteredObjectList.Count) return; int i = fullObjectList.IndexOf(filteredObjectList[index]); if (i < 0) return; if (ReferenceEquals(fullObjectList[i], modelObject)) return; fullObjectList[i] = modelObject; filteredObjectList[index] = modelObject; objectsToIndexMap[modelObject] = index; } private ArrayList fullObjectList = new(); private ArrayList filteredObjectList = new(); private IModelFilter modelFilter; private IListFilter listFilter; #endregion #region IFilterableDataSource Members /// /// Apply the given filters to this data source. One or both may be null. /// /// /// public override void ApplyFilters(IModelFilter iModelFilter, IListFilter iListFilter) { modelFilter = iModelFilter; listFilter = iListFilter; SetObjects(fullObjectList); } #endregion #region Implementation /// /// Gets the full list of objects being used for this fast list. /// This list is unfiltered. /// public ArrayList ObjectList { get { return fullObjectList; } } /// /// Gets the list of objects from ObjectList which survive any installed filters. /// public ArrayList FilteredObjectList { get { return filteredObjectList; } } /// /// Rebuild the map that remembers which model object is displayed at which line /// protected void RebuildIndexMap() { objectsToIndexMap.Clear(); for (int i = 0; i < filteredObjectList.Count; i++) objectsToIndexMap[filteredObjectList[i]] = i; } readonly Dictionary objectsToIndexMap = new(); /// /// Build our filtered list from our full list. /// protected void FilterObjects() { // If this list isn't filtered, we don't need to do anything else if (!listView.UseFiltering) { filteredObjectList = new ArrayList(fullObjectList); return; } // Tell the world to filter the objects. If they do so, don't do anything else // ReSharper disable PossibleMultipleEnumeration FilterEventArgs args = new FilterEventArgs(fullObjectList); listView.OnFilter(args); if (args.FilteredObjects != null) { filteredObjectList = ObjectListView.EnumerableToArray(args.FilteredObjects, false); return; } IEnumerable objects = (listFilter == null) ? fullObjectList : listFilter.Filter(fullObjectList); // Apply the object filter if there is one if (modelFilter == null) { filteredObjectList = ObjectListView.EnumerableToArray(objects, false); } else { filteredObjectList = new ArrayList(); foreach (object model in objects) { if (modelFilter.Filter(model)) filteredObjectList.Add(model); } } } #endregion } } ================================================ FILE: source/ObjectListView/Filtering/Cluster.cs ================================================ /* * Cluster - Implements a simple cluster * * Author: Phillip Piper * Date: 3-March-2011 10:53 pm * * Change log: * 2011-03-03 JPP - First version * * Copyright (C) 2011-2014 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System; namespace BrightIdeasSoftware { /// /// Concrete implementation of the ICluster interface. /// public class Cluster : ICluster { #region Life and death /// /// Create a cluster /// /// The key for the cluster public Cluster(object key) { Count = 1; ClusterKey = key; } #endregion #region Public overrides /// /// Return a string representation of this cluster /// /// public override string ToString() { return DisplayLabel ?? "[empty]"; } #endregion #region Implementation of ICluster /// /// Gets or sets how many items belong to this cluster /// public int Count { get { return count; } set { count = value; } } private int count; /// /// Gets or sets the label that will be shown to the user to represent /// this cluster /// public string DisplayLabel { get { return displayLabel; } set { displayLabel = value; } } private string displayLabel; /// /// Gets or sets the actual data object that all members of this cluster /// have commonly returned. /// public object ClusterKey { get { return clusterKey; } set { clusterKey = value; } } private object clusterKey; #endregion #region Implementation of IComparable /// /// Return an indication of the ordering between this object and the given one /// /// /// public int CompareTo(object other) { if (other == null || other == DBNull.Value) return 1; if (other is not ICluster otherCluster) return 1; if (ClusterKey is string keyAsString) return String.Compare(keyAsString, otherCluster.ClusterKey as string, StringComparison.CurrentCultureIgnoreCase); if (ClusterKey is IComparable keyAsComparable) return keyAsComparable.CompareTo(otherCluster.ClusterKey); return -1; } #endregion } } ================================================ FILE: source/ObjectListView/Filtering/ClusteringStrategy.cs ================================================ /* * ClusteringStrategy - Implements a simple clustering strategy * * Author: Phillip Piper * Date: 3-March-2011 10:53 pm * * Change log: * 2011-03-03 JPP - First version * * Copyright (C) 2011-2014 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System; using System.Collections; namespace BrightIdeasSoftware { /// /// This class provides a useful base implemention of a clustering /// strategy where the clusters are grouped around the value of a given column. /// public class ClusteringStrategy : IClusteringStrategy { #region Static properties /// /// This field is the text that will be shown to the user when a cluster /// key is null. It is exposed so it can be localized. /// static public string NULL_LABEL = "[null]"; /// /// This field is the text that will be shown to the user when a cluster /// key is empty (i.e. a string of zero length). It is exposed so it can be localized. /// static public string EMPTY_LABEL = "[empty]"; /// /// Gets or sets the format that will be used by default for clusters that only /// contain 1 item. The format string must accept two placeholders: /// - {0} is the cluster key converted to a string /// - {1} is the number of items in the cluster (always 1 in this case) /// static public string DefaultDisplayLabelFormatSingular { get { return defaultDisplayLabelFormatSingular; } set { defaultDisplayLabelFormatSingular = value; } } static private string defaultDisplayLabelFormatSingular = "{0} ({1} item)"; /// /// Gets or sets the format that will be used by default for clusters that /// contain 0 or two or more items. The format string must accept two placeholders: /// - {0} is the cluster key converted to a string /// - {1} is the number of items in the cluster /// static public string DefaultDisplayLabelFormatPlural { get { return defaultDisplayLabelFormatPural; } set { defaultDisplayLabelFormatPural = value; } } static private string defaultDisplayLabelFormatPural = "{0} ({1} items)"; #endregion #region Life and death /// /// Create a clustering strategy /// public ClusteringStrategy() { DisplayLabelFormatSingular = DefaultDisplayLabelFormatSingular; DisplayLabelFormatPlural = DefaultDisplayLabelFormatPlural; } #endregion #region Public properties /// /// Gets or sets the column upon which this strategy is operating /// public OLVColumn Column { get { return column; } set { column = value; } } private OLVColumn column; /// /// Gets or sets the format that will be used when the cluster /// contains only 1 item. The format string must accept two placeholders: /// - {0} is the cluster key converted to a string /// - {1} is the number of items in the cluster (always 1 in this case) /// /// If this is not set, the value from /// ClusteringStrategy.DefaultDisplayLabelFormatSingular will be used public string DisplayLabelFormatSingular { get { return displayLabelFormatSingular; } set { displayLabelFormatSingular = value; } } private string displayLabelFormatSingular; /// /// Gets or sets the format that will be used when the cluster /// contains 0 or two or more items. The format string must accept two placeholders: /// - {0} is the cluster key converted to a string /// - {1} is the number of items in the cluster /// /// If this is not set, the value from /// ClusteringStrategy.DefaultDisplayLabelFormatPlural will be used public string DisplayLabelFormatPlural { get { return displayLabelFormatPural; } set { displayLabelFormatPural = value; } } private string displayLabelFormatPural; #endregion #region ICluster implementation /// /// Get the cluster key by which the given model will be partitioned by this strategy /// /// /// virtual public object GetClusterKey(object model) { return Column.GetValue(model); } /// /// Create a cluster to hold the given cluster key /// /// /// virtual public ICluster CreateCluster(object clusterKey) { return new Cluster(clusterKey); } /// /// Gets the display label that the given cluster should use /// /// /// virtual public string GetClusterDisplayLabel(ICluster cluster) { string s = Column.ValueToString(cluster.ClusterKey) ?? NULL_LABEL; if (String.IsNullOrEmpty(s)) s = EMPTY_LABEL; return ApplyDisplayFormat(cluster, s); } /// /// Create a filter that will include only model objects that /// match one or more of the given values. /// /// /// virtual public IModelFilter CreateFilter(IList valuesChosenForFiltering) { return new OneOfFilter(GetClusterKey, valuesChosenForFiltering); } /// /// Create a label that combines the string representation of the cluster /// key with a format string that holds an "X [N items in cluster]" type layout. /// /// /// /// virtual protected string ApplyDisplayFormat(ICluster cluster, string s) { string format = (cluster.Count == 1) ? DisplayLabelFormatSingular : DisplayLabelFormatPlural; return String.IsNullOrEmpty(format) ? s : String.Format(format, s, cluster.Count); } #endregion } } ================================================ FILE: source/ObjectListView/Filtering/ClustersFromGroupsStrategy.cs ================================================ /* * ClusteringStrategy - Implements a simple clustering strategy * * Author: Phillip Piper * Date: 1-April-2011 8:12am * * Change log: * 2011-04-01 JPP - First version * * Copyright (C) 2011-2014 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System; namespace BrightIdeasSoftware { /// /// This class calculates clusters from the groups that the column uses. /// /// /// /// This is the default strategy for all non-date, filterable columns. /// /// /// This class does not strictly mimic the groups created by the given column. /// In particular, if the programmer changes the default grouping technique /// by listening for grouping events, this class will not mimic that behaviour. /// /// public class ClustersFromGroupsStrategy : ClusteringStrategy { /// /// Get the cluster key by which the given model will be partitioned by this strategy /// /// /// public override object GetClusterKey(object model) { return Column.GetGroupKey(model); } /// /// Gets the display label that the given cluster should use /// /// /// public override string GetClusterDisplayLabel(ICluster cluster) { string s = Column.ConvertGroupKeyToTitle(cluster.ClusterKey); if (String.IsNullOrEmpty(s)) s = EMPTY_LABEL; return ApplyDisplayFormat(cluster, s); } } } ================================================ FILE: source/ObjectListView/Filtering/DateTimeClusteringStrategy.cs ================================================ /* * DateTimeClusteringStrategy - A strategy to cluster objects by a date time * * Author: Phillip Piper * Date: 30-March-2011 9:40am * * Change log: * 2011-03-30 JPP - First version * * Copyright (C) 2011-2014 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System; using System.Globalization; namespace BrightIdeasSoftware { /// /// This enum is used to indicate various portions of a datetime /// [Flags] public enum DateTimePortion { /// /// Year /// Year = 0x01, /// /// Month /// Month = 0x02, /// /// Day of the month /// Day = 0x04, /// /// Hour /// Hour = 0x08, /// /// Minute /// Minute = 0x10, /// /// Second /// Second = 0x20 } /// /// This class implements a strategy where the model objects are clustered /// according to some portion of the datetime value in the configured column. /// /// To create a strategy that grouped people who were born in /// the same month, you would create a strategy that extracted just /// the month, and formatted it to show just the month's name. Like this: /// /// /// someColumn.ClusteringStrategy = new DateTimeClusteringStrategy(DateTimePortion.Month, "MMMM"); /// public class DateTimeClusteringStrategy : ClusteringStrategy { #region Life and death /// /// Create a strategy that clusters by month/year /// public DateTimeClusteringStrategy() : this(DateTimePortion.Year | DateTimePortion.Month, "MMMM yyyy") { } /// /// Create a strategy that clusters around the given parts /// /// /// public DateTimeClusteringStrategy(DateTimePortion portions, string format) { Portions = portions; Format = format; } #endregion #region Properties /// /// Gets or sets the format string will will be used to create a user-presentable /// version of the cluster key. /// /// The format should use the date/time format strings, as documented /// in the Windows SDK. Both standard formats and custom format will work. /// "D" - long date pattern /// "MMMM, yyyy" - "January, 1999" public string Format { get { return format; } set { format = value; } } private string format; /// /// Gets or sets the parts of the DateTime that will be extracted when /// determining the clustering key for an object. /// public DateTimePortion Portions { get { return portions; } set { portions = value; } } private DateTimePortion portions = DateTimePortion.Year | DateTimePortion.Month; #endregion #region IClusterStrategy implementation /// /// Get the cluster key by which the given model will be partitioned by this strategy /// /// /// public override object GetClusterKey(object model) { // Get the data attribute we want from the given model // Make sure the returned value is a DateTime if (Column.GetValue(model) is not DateTime dateTime) return null; // Extract the parts of the datetime that we are intereted in. // Even if we aren't interested in a particular portion, we still have to give it a reasonable default // otherwise we won't be able to build a DateTime object for it int year = ((Portions & DateTimePortion.Year) == DateTimePortion.Year) ? dateTime.Year : 1; int month = ((Portions & DateTimePortion.Month) == DateTimePortion.Month) ? dateTime.Month : 1; int day = ((Portions & DateTimePortion.Day) == DateTimePortion.Day) ? dateTime.Day : 1; int hour = ((Portions & DateTimePortion.Hour) == DateTimePortion.Hour) ? dateTime.Hour : 0; int minute = ((Portions & DateTimePortion.Minute) == DateTimePortion.Minute) ? dateTime.Minute : 0; int second = ((Portions & DateTimePortion.Second) == DateTimePortion.Second) ? dateTime.Second : 0; return new DateTime(year, month, day, hour, minute, second); } /// /// Gets the display label that the given cluster should use /// /// /// public override string GetClusterDisplayLabel(ICluster cluster) { DateTime? dateTime = cluster.ClusterKey as DateTime?; return ApplyDisplayFormat(cluster, dateTime.HasValue ? DateToString(dateTime.Value) : NULL_LABEL); } /// /// Convert the given date into a user presentable string /// /// /// protected virtual string DateToString(DateTime dateTime) { if (String.IsNullOrEmpty(Format)) return dateTime.ToString(CultureInfo.CurrentUICulture); try { return dateTime.ToString(Format); } catch (FormatException) { return String.Format("Bad format string '{0}' for value '{1}'", Format, dateTime); } } #endregion } } ================================================ FILE: source/ObjectListView/Filtering/FilterMenuBuilder.cs ================================================ /* * FilterMenuBuilder - Responsible for creating a Filter menu * * Author: Phillip Piper * Date: 4-March-2011 11:59 pm * * Change log: * 2012-05-20 JPP - Allow the same model object to be in multiple clusters * Useful for xor'ed flag fields, and multi-value strings * (e.g. hobbies that are stored as comma separated values). * v2.5.1 * 2012-04-14 JPP - Fixed rare bug with clustering an empty list (SF #3445118) * v2.5 * 2011-04-12 JPP - Added some images to menu * 2011-03-04 JPP - First version * * Copyright (C) 2011-2014 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System; using System.Collections.Generic; using System.Windows.Forms; using System.Collections; using System.Drawing; namespace BrightIdeasSoftware { /// /// Instances of this class know how to build a Filter menu. /// It is responsible for clustering the values in the target column, /// build a menu that shows those clusters, and then constructing /// a filter that will enact the users choices. /// /// /// Almost all of the methods in this class are declared as "virtual protected" /// so that subclasses can provide alternative behaviours. /// public class FilterMenuBuilder { #region Static properties /// /// Gets or sets the string that labels the Apply button. /// Exposed so it can be localized. /// static public string APPLY_LABEL = "Apply"; /// /// Gets or sets the string that labels the Clear All menu item. /// Exposed so it can be localized. /// static public string CLEAR_ALL_FILTERS_LABEL = "Clear All Filters"; /// /// Gets or sets the string that labels the Filtering menu as a whole.. /// Exposed so it can be localized. /// static public string FILTERING_LABEL = "Filtering"; /// /// Gets or sets the string that represents Select All values. /// If this is set to null or empty, no Select All option will be included. /// Exposed so it can be localized. /// static public string SELECT_ALL_LABEL = "Select All"; /// /// Gets or sets the image that will be placed next to the Clear Filtering menu item /// static public Bitmap ClearFilteringImage = Properties.Resources.ClearFiltering; /// /// Gets or sets the image that will be placed next to all "Apply" menu items on the filtering menu /// static public Bitmap FilteringImage = Properties.Resources.Filtering; #endregion #region Public properties /// /// Gets or sets whether null should be considered as a valid data value. /// If this is true (the default), then a cluster will null as a key will be allow. /// If this is false, object that return a cluster key of null will ignored. /// public bool TreatNullAsDataValue { get { return treatNullAsDataValue; } set { treatNullAsDataValue = value; } } private bool treatNullAsDataValue = true; /// /// Gets or sets the maximum number of objects that the clustering strategy /// will consider. This should be large enough to collect all unique clusters, /// but small enough to finish in a reasonable time. /// /// The default value is 10,000. This should be perfectly /// acceptable for almost all lists. public int MaxObjectsToConsider { get { return maxObjectsToConsider; } set { maxObjectsToConsider = value; } } private int maxObjectsToConsider = 10000; #endregion /// /// Create a Filter menu on the given tool tip for the given column in the given ObjectListView. /// /// This is the main entry point into this class. /// /// /// /// The strip that should be shown to the user virtual public ToolStripDropDown MakeFilterMenu(ToolStripDropDown strip, ObjectListView listView, OLVColumn column) { if (strip == null) throw new ArgumentNullException("strip"); if (listView == null) throw new ArgumentNullException("listView"); if (column == null) throw new ArgumentNullException("column"); if (!column.UseFiltering || column.ClusteringStrategy == null || listView.Objects == null) return strip; List clusters = Cluster(column.ClusteringStrategy, listView, column); if (clusters.Count > 0) { SortClusters(column.ClusteringStrategy, clusters); strip.Items.Add(CreateFilteringMenuItem(column, clusters)); } return strip; } /// /// Create a collection of clusters that should be presented to the user /// /// /// /// /// virtual protected List Cluster(IClusteringStrategy strategy, ObjectListView listView, OLVColumn column) { // Build a map that correlates cluster key to clusters NullableDictionary map = new NullableDictionary(); int count = 0; foreach (object model in listView.ObjectsForClustering) { ClusterOneModel(strategy, map, model); if (count++ > MaxObjectsToConsider) break; } // Now that we know exactly how many items are in each cluster, create a label for it foreach (ICluster cluster in map.Values) cluster.DisplayLabel = strategy.GetClusterDisplayLabel(cluster); return new List(map.Values); } private void ClusterOneModel(IClusteringStrategy strategy, NullableDictionary map, object model) { object clusterKey = strategy.GetClusterKey(model); // If the returned value is an IEnumerable, that means the given model can belong to more than one cluster if (clusterKey is string || clusterKey is not IEnumerable keyEnumerable) keyEnumerable = new object[] {clusterKey}; // Deal with nulls and DBNulls ArrayList nullCorrected = new ArrayList(); foreach (object key in keyEnumerable) { if (key == null || key == DBNull.Value) { if (TreatNullAsDataValue) nullCorrected.Add(null); } else nullCorrected.Add(key); } // Group by key foreach (object key in nullCorrected) { if (map.ContainsKey(key)) map[key].Count += 1; else map[key] = strategy.CreateCluster(key); } } /// /// Order the given list of clusters in the manner in which they should be presented to the user. /// /// /// virtual protected void SortClusters(IClusteringStrategy strategy, List clusters) { clusters.Sort(); } /// /// Do the work of making a menu that shows the clusters to the users /// /// /// /// virtual protected ToolStripMenuItem CreateFilteringMenuItem(OLVColumn column, List clusters) { ToolStripCheckedListBox checkedList = new ToolStripCheckedListBox(); checkedList.Tag = column; foreach (ICluster cluster in clusters) checkedList.AddItem(cluster, column.ValuesChosenForFiltering.Contains(cluster.ClusterKey)); if (!String.IsNullOrEmpty(SELECT_ALL_LABEL)) { int checkedCount = checkedList.CheckedItems.Count; if (checkedCount == 0) checkedList.AddItem(SELECT_ALL_LABEL, CheckState.Unchecked); else checkedList.AddItem(SELECT_ALL_LABEL, checkedCount == clusters.Count ? CheckState.Checked : CheckState.Indeterminate); } checkedList.ItemCheck += new ItemCheckEventHandler(HandleItemCheckedWrapped); ToolStripMenuItem clearAll = new ToolStripMenuItem(CLEAR_ALL_FILTERS_LABEL, ClearFilteringImage, delegate(object sender, EventArgs args) { ClearAllFilters(column); }); ToolStripMenuItem apply = new ToolStripMenuItem(APPLY_LABEL, FilteringImage, delegate(object sender, EventArgs args) { EnactFilter(checkedList, column); }); ToolStripMenuItem subMenu = new ToolStripMenuItem(FILTERING_LABEL, null, new ToolStripItem[] { clearAll, new ToolStripSeparator(), checkedList, apply }); return subMenu; } /// /// Wrap a protected section around the real HandleItemChecked method, so that if /// that method tries to change a "checkedness" of an item, we don't get a recursive /// stack error. Effectively, this ensure that HandleItemChecked is only called /// in response to a user action. /// /// /// private void HandleItemCheckedWrapped(object sender, ItemCheckEventArgs e) { if (alreadyInHandleItemChecked) return; try { alreadyInHandleItemChecked = true; HandleItemChecked(sender, e); } finally { alreadyInHandleItemChecked = false; } } bool alreadyInHandleItemChecked = false; /// /// Handle a user-generated ItemCheck event /// /// /// virtual protected void HandleItemChecked(object sender, ItemCheckEventArgs e) { if (sender is not ToolStripCheckedListBox checkedList) return; if (checkedList.Tag is not OLVColumn column) return; if (column.ListView is not ObjectListView listView) return; // Deal with the "Select All" item if there is one int selectAllIndex = checkedList.Items.IndexOf(SELECT_ALL_LABEL); if (selectAllIndex >= 0) HandleSelectAllItem(e, checkedList, selectAllIndex); } /// /// Handle any checking/unchecking of the Select All option, and keep /// its checkedness in sync with everything else that is checked. /// /// /// /// virtual protected void HandleSelectAllItem(ItemCheckEventArgs e, ToolStripCheckedListBox checkedList, int selectAllIndex) { // Did they check/uncheck the "Select All"? if (e.Index == selectAllIndex) { if (e.NewValue == CheckState.Checked) checkedList.CheckAll(); if (e.NewValue == CheckState.Unchecked) checkedList.UncheckAll(); return; } // OK. The user didn't check/uncheck SelectAll. Now we have to update it's // checkedness to reflect the state of everything else // If all clusters are checked, we check the Select All. // If no clusters are checked, the uncheck the Select All. // For everything else, Select All is set to indeterminate. // How many items are currenty checked? int count = checkedList.CheckedItems.Count; // First complication. // The value of the Select All itself doesn't count if (checkedList.GetItemCheckState(selectAllIndex) != CheckState.Unchecked) count -= 1; // Another complication. // CheckedItems does not yet know about the item the user has just // clicked, so we have to adjust the count of checked items to what // it is going to be if (e.NewValue != e.CurrentValue) { if (e.NewValue == CheckState.Checked) count += 1; else count -= 1; } // Update the state of the Select All item if (count == 0) checkedList.SetItemState(selectAllIndex, CheckState.Unchecked); else if (count == checkedList.Items.Count - 1) checkedList.SetItemState(selectAllIndex, CheckState.Checked); else checkedList.SetItemState(selectAllIndex, CheckState.Indeterminate); } /// /// Clear all the filters that are applied to the given column /// /// The column from which filters are to be removed virtual protected void ClearAllFilters(OLVColumn column) { if (column.ListView is not ObjectListView olv || olv.IsDisposed) return; olv.ResetColumnFiltering(); } /// /// Apply the selected values from the given list as a filter on the given column /// /// A list in which the checked items should be used as filters /// The column for which a filter should be generated virtual protected void EnactFilter(ToolStripCheckedListBox checkedList, OLVColumn column) { if (column.ListView is not ObjectListView olv || olv.IsDisposed) return; // Collect all the checked values ArrayList chosenValues = new ArrayList(); foreach (object x in checkedList.CheckedItems) { if (x is ICluster cluster) { chosenValues.Add(cluster.ClusterKey); } } column.ValuesChosenForFiltering = chosenValues; olv.UpdateColumnFiltering(); } } } ================================================ FILE: source/ObjectListView/Filtering/Filters.cs ================================================ /* * Filters - Filtering on ObjectListViews * * Author: Phillip Piper * Date: 03/03/2010 17:00 * * Change log: * 2011-03-01 JPP Added CompositeAllFilter, CompositeAnyFilter and OneOfFilter * v2.4.1 * 2010-06-23 JPP Extended TextMatchFilter to handle regular expressions and string prefix matching. * v2.4 * 2010-03-03 JPP Initial version * * TO DO: * * Copyright (C) 2010-2014 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System; using System.Collections; using System.Collections.Generic; namespace BrightIdeasSoftware { /// /// Interface for model-by-model filtering /// public interface IModelFilter { /// /// Should the given model be included when this filter is installed /// /// The model object to consider /// Returns true if the model will be included by the filter bool Filter(object modelObject); } /// /// Interface for whole list filtering /// public interface IListFilter { /// /// Return a subset of the given list of model objects as the new /// contents of the ObjectListView /// /// The collection of model objects that the list will possibly display /// The filtered collection that holds the model objects that will be displayed. IEnumerable Filter(IEnumerable modelObjects); } /// /// Base class for model-by-model filters /// public class AbstractModelFilter : IModelFilter { /// /// Should the given model be included when this filter is installed /// /// The model object to consider /// Returns true if the model will be included by the filter virtual public bool Filter(object modelObject) { return true; } } /// /// This filter calls a given Predicate to decide if a model object should be included /// public class ModelFilter : IModelFilter { /// /// Create a filter based on the given predicate /// /// The function that will filter objects public ModelFilter(Predicate predicate) { Predicate = predicate; } /// /// Gets or sets the predicate used to filter model objects /// protected Predicate Predicate { get { return predicate; } set { predicate = value; } } private Predicate predicate; /// /// Should the given model object be included? /// /// /// virtual public bool Filter(object modelObject) { return Predicate == null ? true : Predicate(modelObject); } } /// /// A CompositeFilter joins several other filters together. /// If there are no filters, all model objects are included /// abstract public class CompositeFilter : IModelFilter { /// /// Create an empty filter /// public CompositeFilter() { } /// /// Create a composite filter from the given list of filters /// /// A list of filters public CompositeFilter(IEnumerable filters) { foreach (IModelFilter filter in filters) { if (filter != null) Filters.Add(filter); } } /// /// Gets or sets the filters used by this composite /// public IList Filters { get { return filters; } set { filters = value; } } private IList filters = new List(); /// /// Get the sub filters that are text match filters /// public IEnumerable TextFilters { get { foreach (IModelFilter filter in Filters) { if (filter is TextMatchFilter textFilter) yield return textFilter; } } } /// /// Decide whether or not the given model should be included by the filter /// /// /// True if the object is included by the filter virtual public bool Filter(object modelObject) { if (Filters == null || Filters.Count == 0) return true; return FilterObject(modelObject); } /// /// Decide whether or not the given model should be included by the filter /// /// Filters is guaranteed to be non-empty when this method is called /// The model object under consideration /// True if the object is included by the filter abstract public bool FilterObject(object modelObject); } /// /// A CompositeAllFilter joins several other filters together. /// A model object must satisfy all filters to be included. /// If there are no filters, all model objects are included /// public class CompositeAllFilter : CompositeFilter { /// /// Create a filter /// /// public CompositeAllFilter(List filters) : base(filters) { } /// /// Decide whether or not the given model should be included by the filter /// /// Filters is guaranteed to be non-empty when this method is called /// The model object under consideration /// True if the object is included by the filter override public bool FilterObject(object modelObject) { foreach (IModelFilter filter in Filters) if (!filter.Filter(modelObject)) return false; return true; } } /// /// A CompositeAllFilter joins several other filters together. /// A model object must only satisfy one of the filters to be included. /// If there are no filters, all model objects are included /// public class CompositeAnyFilter : CompositeFilter { /// /// Create a filter from the given filters /// /// public CompositeAnyFilter(List filters) : base(filters) { } /// /// Decide whether or not the given model should be included by the filter /// /// Filters is guaranteed to be non-empty when this method is called /// The model object under consideration /// True if the object is included by the filter override public bool FilterObject(object modelObject) { foreach (IModelFilter filter in Filters) if (filter.Filter(modelObject)) return true; return false; } } /// /// Instances of this class extract a value from the model object /// and compare that value to a list of fixed values. The model /// object is included if the extracted value is in the list /// /// If there is no delegate installed or there are /// no values to match, no model objects will be matched public class OneOfFilter : IModelFilter { /// /// Create a filter that will use the given delegate to extract values /// /// public OneOfFilter(AspectGetterDelegate valueGetter) : this(valueGetter, new ArrayList()) { } /// /// Create a filter that will extract values using the given delegate /// and compare them to the values in the given list. /// /// /// public OneOfFilter(AspectGetterDelegate valueGetter, ICollection possibleValues) { ValueGetter = valueGetter; PossibleValues = new ArrayList(possibleValues); } /// /// Gets or sets the delegate that will be used to extract values /// from model objects /// virtual public AspectGetterDelegate ValueGetter { get { return valueGetter; } set { valueGetter = value; } } private AspectGetterDelegate valueGetter; /// /// Gets or sets the list of values that the value extracted from /// the model object must match in order to be included. /// virtual public IList PossibleValues { get { return possibleValues; } set { possibleValues = value; } } private IList possibleValues; /// /// Should the given model object be included? /// /// /// public virtual bool Filter(object modelObject) { if (ValueGetter == null || PossibleValues == null || PossibleValues.Count == 0) return false; object result = ValueGetter(modelObject); if (result is string || result is not IEnumerable enumerable) return DoesValueMatch(result); foreach (object x in enumerable) { if (DoesValueMatch(x)) return true; } return false; } /// /// Decides if the given property is a match for the values in the PossibleValues collection /// /// /// protected virtual bool DoesValueMatch(object result) { return PossibleValues.Contains(result); } } /// /// Instances of this class match a property of a model objects against /// a list of bit flags. The property should be an xor-ed collection /// of bits flags. /// /// Both the property compared and the list of possible values /// must be convertible to ulongs. public class FlagBitSetFilter : OneOfFilter { /// /// Create an instance /// /// /// public FlagBitSetFilter(AspectGetterDelegate valueGetter, ICollection possibleValues) : base(valueGetter, possibleValues) { ConvertPossibleValues(); } /// /// Gets or sets the collection of values that will be matched. /// These must be ulongs (or convertible to ulongs). /// public override IList PossibleValues { get { return base.PossibleValues; } set { base.PossibleValues = value; ConvertPossibleValues(); } } private void ConvertPossibleValues() { possibleValuesAsUlongs = new List(); foreach (object x in PossibleValues) possibleValuesAsUlongs.Add(Convert.ToUInt64(x)); } /// /// Decides if the given property is a match for the values in the PossibleValues collection /// /// /// protected override bool DoesValueMatch(object result) { try { UInt64 value = Convert.ToUInt64(result); foreach (ulong flag in possibleValuesAsUlongs) { if ((value & flag) == flag) return true; } return false; } catch (InvalidCastException) { return false; } catch (FormatException) { return false; } } private List possibleValuesAsUlongs = new(); } /// /// Base class for whole list filters /// public class AbstractListFilter : IListFilter { /// /// Return a subset of the given list of model objects as the new /// contents of the ObjectListView /// /// The collection of model objects that the list will possibly display /// The filtered collection that holds the model objects that will be displayed. virtual public IEnumerable Filter(IEnumerable modelObjects) { return modelObjects; } } /// /// Instance of this class implement delegate based whole list filtering /// public class ListFilter : AbstractListFilter { /// /// A delegate that filters on a whole list /// /// /// public delegate IEnumerable ListFilterDelegate(IEnumerable rowObjects); /// /// Create a ListFilter /// /// public ListFilter(ListFilterDelegate function) { Function = function; } /// /// Gets or sets the delegate that will filter the list /// public ListFilterDelegate Function { get { return function; } set { function = value; } } private ListFilterDelegate function; /// /// Do the actual work of filtering /// /// /// public override IEnumerable Filter(IEnumerable modelObjects) { if (Function == null) return modelObjects; return Function(modelObjects); } } /// /// Filter the list so only the last N entries are displayed /// public class TailFilter : AbstractListFilter { /// /// Create a no-op tail filter /// public TailFilter() { } /// /// Create a filter that includes on the last N model objects /// /// public TailFilter(int numberOfObjects) { Count = numberOfObjects; } /// /// Gets or sets the number of model objects that will be /// returned from the tail of the list /// public int Count { get { return count; } set { count = value; } } private int count; /// /// Return the last N subset of the model objects /// /// /// public override IEnumerable Filter(IEnumerable modelObjects) { if (Count <= 0) return modelObjects; ArrayList list = ObjectListView.EnumerableToArray(modelObjects, false); if (Count > list.Count) return list; object[] tail = new object[Count]; list.CopyTo(list.Count - Count, tail, 0, Count); return new ArrayList(tail); } } } ================================================ FILE: source/ObjectListView/Filtering/FlagClusteringStrategy.cs ================================================ /* * FlagClusteringStrategy - Implements a clustering strategy for a field which is a single integer * containing an XOR'ed collection of bit flags * * Author: Phillip Piper * Date: 23-March-2012 8:33 am * * Change log: * 2012-03-23 JPP - First version * * Copyright (C) 2012 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System; using System.Collections; using System.Collections.Generic; using System.Globalization; namespace BrightIdeasSoftware { /// /// Instances of this class cluster model objects on the basis of a /// property that holds an xor-ed collection of bit flags. /// public class FlagClusteringStrategy : ClusteringStrategy { #region Life and death /// /// Create a clustering strategy that operates on the flags of the given enum /// /// public FlagClusteringStrategy(Type enumType) { if (enumType == null) throw new ArgumentNullException("enumType"); if (!enumType.IsEnum) throw new ArgumentException("Type must be enum", "enumType"); if (enumType.GetCustomAttributes(typeof(FlagsAttribute), false) == null) throw new ArgumentException("Type must have [Flags] attribute", "enumType"); List flags = new List(); foreach (object x in Enum.GetValues(enumType)) flags.Add(Convert.ToInt64(x)); List flagLabels = new List(); foreach (string x in Enum.GetNames(enumType)) flagLabels.Add(x); SetValues(flags.ToArray(), flagLabels.ToArray()); } /// /// Create a clustering strategy around the given collections of flags and their display labels. /// There must be the same number of elements in both collections. /// /// The list of flags. /// public FlagClusteringStrategy(long[] values, string[] labels) { SetValues(values, labels); } #endregion #region Implementation /// /// Gets the value that will be xor-ed to test for the presence of a particular value. /// public long[] Values { get { return values; } private set { values = value; } } private long[] values; /// /// Gets the labels that will be used when the corresponding Value is XOR present in the data. /// public string[] Labels { get { return labels; } private set { labels = value; } } private string[] labels; private void SetValues(long[] flags, string[] flagLabels) { if (flags == null || flags.Length == 0) throw new ArgumentNullException("flags"); if (flagLabels == null || flagLabels.Length == 0) throw new ArgumentNullException("flagLabels"); if (flags.Length != flagLabels.Length) throw new ArgumentException("values and labels must have the same number of entries", "flags"); Values = flags; Labels = flagLabels; } #endregion #region Implementation of IClusteringStrategy /// /// Get the cluster key by which the given model will be partitioned by this strategy /// /// /// public override object GetClusterKey(object model) { List flags = new List(); try { long modelValue = Convert.ToInt64(Column.GetValue(model)); foreach (long x in Values) { if ((x & modelValue) == x) flags.Add(x); } return flags; } catch (InvalidCastException ex) { System.Diagnostics.Debug.Write(ex); return flags; } catch (FormatException ex) { System.Diagnostics.Debug.Write(ex); return flags; } } /// /// Gets the display label that the given cluster should use /// /// /// public override string GetClusterDisplayLabel(ICluster cluster) { long clusterKeyAsUlong = Convert.ToInt64(cluster.ClusterKey); for (int i = 0; i < Values.Length; i++ ) { if (clusterKeyAsUlong == Values[i]) return ApplyDisplayFormat(cluster, Labels[i]); } return ApplyDisplayFormat(cluster, clusterKeyAsUlong.ToString(CultureInfo.CurrentUICulture)); } /// /// Create a filter that will include only model objects that /// match one or more of the given values. /// /// /// public override IModelFilter CreateFilter(IList valuesChosenForFiltering) { return new FlagBitSetFilter(GetClusterKey, valuesChosenForFiltering); } #endregion } } ================================================ FILE: source/ObjectListView/Filtering/ICluster.cs ================================================ /* * ICluster - A cluster is a group of objects that can be included or excluded as a whole * * Author: Phillip Piper * Date: 4-March-2011 11:59 pm * * Change log: * 2011-03-04 JPP - First version * * Copyright (C) 2011-2014 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System; namespace BrightIdeasSoftware { /// /// A cluster is a like collection of objects that can be usefully filtered /// as whole using the filtering UI provided by the ObjectListView. /// public interface ICluster : IComparable { /// /// Gets or sets how many items belong to this cluster /// int Count { get; set; } /// /// Gets or sets the label that will be shown to the user to represent /// this cluster /// string DisplayLabel { get; set; } /// /// Gets or sets the actual data object that all members of this cluster /// have commonly returned. /// object ClusterKey { get; set; } } } ================================================ FILE: source/ObjectListView/Filtering/IClusteringStrategy.cs ================================================ /* * IClusterStrategy - Encapsulates the ability to create a list of clusters from an ObjectListView * * Author: Phillip Piper * Date: 4-March-2011 11:59 pm * * Change log: * 2012-05-23 JPP - Added CreateFilter() method to interface to allow the strategy * to control the actual model filter that is created. * v2.5 * 2011-03-04 JPP - First version * * Copyright (C) 2011-2014 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System.Collections; namespace BrightIdeasSoftware{ /// /// Implementation of this interface control the selecting of cluster keys /// and how those clusters will be presented to the user /// public interface IClusteringStrategy { /// /// Gets or sets the column upon which this strategy will operate /// OLVColumn Column { get; set; } /// /// Get the cluster key by which the given model will be partitioned by this strategy /// /// If the returned value is an IEnumerable, the given model is considered /// to belong to multiple clusters /// /// object GetClusterKey(object model); /// /// Create a cluster to hold the given cluster key /// /// /// ICluster CreateCluster(object clusterKey); /// /// Gets the display label that the given cluster should use /// /// /// string GetClusterDisplayLabel(ICluster cluster); /// /// Create a filter that will include only model objects that /// match one or more of the given values. /// /// /// IModelFilter CreateFilter(IList valuesChosenForFiltering); } } ================================================ FILE: source/ObjectListView/Filtering/TextMatchFilter.cs ================================================ /* * TextMatchFilter - Text based filtering on ObjectListViews * * Author: Phillip Piper * Date: 31/05/2011 7:45am * * Change log: * v2.6 * 2012-10-13 JPP Allow filtering to consider additional columns * v2.5.1 * 2011-06-22 JPP Handle searching for empty strings * v2.5.0 * 2011-05-31 JPP Initial version * * TO DO: * * Copyright (C) 2011-2014 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System; using System.Collections.Generic; using System.Text.RegularExpressions; using System.Drawing; namespace BrightIdeasSoftware { /// /// Instances of this class include only those rows of the listview /// that match one or more given strings. /// /// This class can match strings by prefix, regex, or simple containment. /// There are factory methods for each of these matching strategies. public class TextMatchFilter : AbstractModelFilter { #region Life and death /// /// Create a text filter that will include rows where any cell matches /// any of the given regex expressions. /// /// /// /// /// Any string that is not a valid regex expression will be ignored. public static TextMatchFilter Regex(ObjectListView olv, params string[] texts) { TextMatchFilter filter = new TextMatchFilter(olv); filter.RegexStrings = texts; return filter; } /// /// Create a text filter that includes rows where any cell begins with one of the given strings /// /// /// /// public static TextMatchFilter Prefix(ObjectListView olv, params string[] texts) { TextMatchFilter filter = new TextMatchFilter(olv); filter.PrefixStrings = texts; return filter; } /// /// Create a text filter that includes rows where any cell contains any of the given strings. /// /// /// /// public static TextMatchFilter Contains(ObjectListView olv, params string[] texts) { TextMatchFilter filter = new TextMatchFilter(olv); filter.ContainsStrings = texts; return filter; } /// /// Create a TextFilter /// /// public TextMatchFilter(ObjectListView olv) { ListView = olv; } /// /// Create a TextFilter that finds the given string /// /// /// public TextMatchFilter(ObjectListView olv, string text) { ListView = olv; ContainsStrings = new string[] { text }; } /// /// Create a TextFilter that finds the given string using the given comparison /// /// /// /// public TextMatchFilter(ObjectListView olv, string text, StringComparison comparison) { ListView = olv; ContainsStrings = new string[] { text }; StringComparison = comparison; } #endregion #region Public properties /// /// Gets or sets which columns will be used for the comparisons? If this is null, all columns will be used /// public OLVColumn[] Columns { get { return columns; } set { columns = value; } } private OLVColumn[] columns; /// /// Gets or sets additional columns which will be used in the comparison. These will be used /// in addition to either the Columns property or to all columns taken from the control. /// public OLVColumn[] AdditionalColumns { get { return additionalColumns; } set { additionalColumns = value; } } private OLVColumn[] additionalColumns; /// /// Gets or sets the collection of strings that will be used for /// contains matching. Setting this replaces all previous texts /// of any kind. /// public IEnumerable ContainsStrings { get { foreach (TextMatchingStrategy component in MatchingStrategies) yield return component.Text; } set { MatchingStrategies = new List(); if (value != null) { foreach (string text in value) MatchingStrategies.Add(new TextContainsMatchingStrategy(this, text)); } } } /// /// Gets whether or not this filter has any search criteria /// public bool HasComponents { get { return MatchingStrategies.Count > 0; } } /// /// Gets or set the ObjectListView upon which this filter will work /// /// /// You cannot really rebase a filter after it is created, so do not change this value. /// It is included so that it can be set in an object initializer. /// public ObjectListView ListView { get { return listView; } set { listView = value; } } private ObjectListView listView; /// /// Gets or sets the collection of strings that will be used for /// prefix matching. Setting this replaces all previous texts /// of any kind. /// public IEnumerable PrefixStrings { get { foreach (TextMatchingStrategy component in MatchingStrategies) yield return component.Text; } set { MatchingStrategies = new List(); if (value != null) { foreach (string text in value) MatchingStrategies.Add(new TextBeginsMatchingStrategy(this, text)); } } } /// /// Gets or sets the options that will be used when compiling the regular expression. /// /// /// This is only used when doing Regex matching (obviously). /// If this is not set specifically, the appropriate options are chosen to match the /// StringComparison setting (culture invariant, case sensitive). /// public RegexOptions RegexOptions { get { if (!regexOptions.HasValue) { switch (StringComparison) { case StringComparison.CurrentCulture: regexOptions = RegexOptions.None; break; case StringComparison.CurrentCultureIgnoreCase: regexOptions = RegexOptions.IgnoreCase; break; case StringComparison.Ordinal: case StringComparison.InvariantCulture: regexOptions = RegexOptions.CultureInvariant; break; case StringComparison.OrdinalIgnoreCase: case StringComparison.InvariantCultureIgnoreCase: regexOptions = RegexOptions.CultureInvariant | RegexOptions.IgnoreCase; break; default: regexOptions = RegexOptions.None; break; } } return regexOptions.Value; } set { regexOptions = value; } } private RegexOptions? regexOptions; /// /// Gets or sets the collection of strings that will be used for /// regex pattern matching. Setting this replaces all previous texts /// of any kind. /// public IEnumerable RegexStrings { get { foreach (TextMatchingStrategy component in MatchingStrategies) yield return component.Text; } set { MatchingStrategies = new List(); if (value != null) { foreach (string text in value) MatchingStrategies.Add(new TextRegexMatchingStrategy(this, text)); } } } /// /// Gets or sets how the filter will match text /// public StringComparison StringComparison { get { return stringComparison; } set { stringComparison = value; } } private StringComparison stringComparison = StringComparison.InvariantCultureIgnoreCase; #endregion #region Implementation /// /// Loop over the columns that are being considering by the filter /// /// protected virtual IEnumerable IterateColumns() { if (Columns == null) { foreach (OLVColumn column in ListView.Columns) yield return column; } else { foreach (OLVColumn column in Columns) yield return column; } if (AdditionalColumns != null) { foreach (OLVColumn column in AdditionalColumns) yield return column; } } #endregion #region Public interface /// /// Do the actual work of filtering /// /// /// public override bool Filter(object modelObject) { if (ListView == null || !HasComponents) return true; foreach (OLVColumn column in IterateColumns()) { if (column.IsVisible && column.Searchable) { string[] cellTexts = column.GetSearchValues(modelObject); if (cellTexts != null && cellTexts.Length > 0) { foreach (TextMatchingStrategy filter in MatchingStrategies) { if (String.IsNullOrEmpty(filter.Text)) return true; foreach (string cellText in cellTexts) { if (filter.MatchesText(cellText)) return true; } } } } } return false; } /// /// Find all the ways in which this filter matches the given string. /// /// This is used by the renderer to decide which bits of /// the string should be highlighted /// /// A list of character ranges indicating the matched substrings public IEnumerable FindAllMatchedRanges(string cellText) { List ranges = new List(); foreach (TextMatchingStrategy filter in MatchingStrategies) { if (!String.IsNullOrEmpty(filter.Text)) ranges.AddRange(filter.FindAllMatchedRanges(cellText)); } return ranges; } /// /// Is the given column one of the columns being used by this filter? /// /// /// public bool IsIncluded(OLVColumn column) { if (Columns == null) { return column.ListView == ListView; } foreach (OLVColumn x in Columns) { if (x == column) return true; } return false; } #endregion #region Implementation members private List MatchingStrategies = new(); #endregion #region Components /// /// Base class for the various types of string matching that TextMatchFilter provides /// abstract protected class TextMatchingStrategy { /// /// Gets how the filter will match text /// public StringComparison StringComparison { get { return TextFilter.StringComparison; } } /// /// Gets the text filter to which this component belongs /// public TextMatchFilter TextFilter { get { return textFilter; } set { textFilter = value; } } private TextMatchFilter textFilter; /// /// Gets or sets the text that will be matched /// public string Text { get { return text; } set { text = value; } } private string text; /// /// Find all the ways in which this filter matches the given string. /// /// /// /// This is used by the renderer to decide which bits of /// the string should be highlighted. /// /// this.Text will not be null or empty when this is called. /// /// The text of the cell we want to search /// A list of character ranges indicating the matched substrings abstract public IEnumerable FindAllMatchedRanges(string cellText); /// /// Does the given text match the filter /// /// /// this.Text will not be null or empty when this is called. /// /// The text of the cell we want to search /// Return true if the given cellText matches our strategy abstract public bool MatchesText(string cellText); } /// /// This component provides text contains matching strategy. /// protected class TextContainsMatchingStrategy : TextMatchingStrategy { /// /// Create a text contains strategy /// /// /// public TextContainsMatchingStrategy(TextMatchFilter filter, string text) { TextFilter = filter; Text = text; } /// /// Does the given text match the filter /// /// /// this.Text will not be null or empty when this is called. /// /// The text of the cell we want to search /// Return true if the given cellText matches our strategy override public bool MatchesText(string cellText) { return cellText.IndexOf(Text, StringComparison) != -1; } /// /// Find all the ways in which this filter matches the given string. /// /// /// /// This is used by the renderer to decide which bits of /// the string should be highlighted. /// /// this.Text will not be null or empty when this is called. /// /// The text of the cell we want to search /// A list of character ranges indicating the matched substrings override public IEnumerable FindAllMatchedRanges(string cellText) { List ranges = new List(); int matchIndex = cellText.IndexOf(Text, StringComparison); while (matchIndex != -1) { ranges.Add(new CharacterRange(matchIndex, Text.Length)); matchIndex = cellText.IndexOf(Text, matchIndex + Text.Length, StringComparison); } return ranges; } } /// /// This component provides text begins with matching strategy. /// protected class TextBeginsMatchingStrategy : TextMatchingStrategy { /// /// Create a text begins strategy /// /// /// public TextBeginsMatchingStrategy(TextMatchFilter filter, string text) { TextFilter = filter; Text = text; } /// /// Does the given text match the filter /// /// /// this.Text will not be null or empty when this is called. /// /// The text of the cell we want to search /// Return true if the given cellText matches our strategy override public bool MatchesText(string cellText) { return cellText.StartsWith(Text, StringComparison); } /// /// Find all the ways in which this filter matches the given string. /// /// /// /// This is used by the renderer to decide which bits of /// the string should be highlighted. /// /// this.Text will not be null or empty when this is called. /// /// The text of the cell we want to search /// A list of character ranges indicating the matched substrings override public IEnumerable FindAllMatchedRanges(string cellText) { List ranges = new List(); if (cellText.StartsWith(Text, StringComparison)) ranges.Add(new CharacterRange(0, Text.Length)); return ranges; } } /// /// This component provides regex matching strategy. /// protected class TextRegexMatchingStrategy : TextMatchingStrategy { /// /// Creates a regex strategy /// /// /// public TextRegexMatchingStrategy(TextMatchFilter filter, string text) { TextFilter = filter; Text = text; } /// /// Gets or sets the options that will be used when compiling the regular expression. /// public RegexOptions RegexOptions { get { return TextFilter.RegexOptions; } } /// /// Gets or sets a compilex regular expression, based on our current Text and RegexOptions. /// /// /// If Text fails to compile as a regular expression, this will return a Regex object /// that will match all strings. /// protected Regex Regex { get { if (regex == null) { try { regex = new Regex(Text, RegexOptions); } catch (ArgumentException) { regex = InvalidRegexMarker; } } return regex; } set { regex = value; } } private Regex regex; /// /// Gets whether or not our current regular expression is a valid regex /// protected bool IsRegexInvalid { get { return Regex == InvalidRegexMarker; } } static private Regex InvalidRegexMarker = new(".*"); /// /// Does the given text match the filter /// /// /// this.Text will not be null or empty when this is called. /// /// The text of the cell we want to search /// Return true if the given cellText matches our strategy public override bool MatchesText(string cellText) { if (IsRegexInvalid) return true; return Regex.Match(cellText).Success; } /// /// Find all the ways in which this filter matches the given string. /// /// /// /// This is used by the renderer to decide which bits of /// the string should be highlighted. /// /// this.Text will not be null or empty when this is called. /// /// The text of the cell we want to search /// A list of character ranges indicating the matched substrings override public IEnumerable FindAllMatchedRanges(string cellText) { List ranges = new List(); if (!IsRegexInvalid) { foreach (Match match in Regex.Matches(cellText)) { if (match.Length > 0) ranges.Add(new CharacterRange(match.Index, match.Length)); } } return ranges; } } #endregion } } ================================================ FILE: source/ObjectListView/FullClassDiagram.cd ================================================  AQCABIAAAIAhAACgAAAAAIAMAAAECAAggAIAIIAAAEA= CellEditing\CellEditKeyEngine.cs AAAAAAAAAAAAAAQEIAAEAAAAAAAAAAAAAAAAAAAAAAA= CellEditing\CellEditors.cs AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= CellEditing\CellEditors.cs AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= CellEditing\CellEditors.cs AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAA= CellEditing\CellEditors.cs AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAA= CellEditing\CellEditors.cs AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= CellEditing\CellEditors.cs AAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAgAAAAAAA= CellEditing\CellEditors.cs AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAA= CellEditing\CellEditors.cs AAAAAAQIAAABAQAAQAAgAAAAAAABAIAAAAQAAAAAAAA= CellEditing\EditorRegistry.cs ABgAAAAAAAAAAgIhAAACAAAEAAAAAAAAAAAAAAAAAAA= DataListView.cs BAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAQAA= DragDrop\DragSource.cs BAAAAAAAAAAAAAAAAQAAAAAQAAAQEAAAAAAAAAAAQAA= DragDrop\DragSource.cs AAAAAAAAAAAQQAAAAAIAEAAAAAEFAAAAgAAAAMAAAAA= DragDrop\DropSink.cs ZS0gAiQEBAoQDA8YQBMAMCAFgwQHBALcAEBEiEAAAQA= DragDrop\DropSink.cs BYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= DragDrop\DropSink.cs IACgGiAAIBoAAAAAAAAAAAAAAALAAAAKgAQECIAEgAA= DragDrop\DropSink.cs BAEAAAAAAAAAAAAAAAEQAAAAAAAAAAIAAAAAgAQAAEA= DragDrop\DropSink.cs AQAAEAEABAAAAAAAEAAAAAAAAAIAAgACgAAAAAAAQBA= DragDrop\OLVDataObject.cs AAAAAAAAAAAAAgIAAAACAAAEQAAAAAAAAAAAAAAAAAA= FastDataListView.cs AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEQAAAAAAAAAAA= FastObjectListView.cs ABAAAAgAQAQAABAgAAASQ4AQAAIEAAAAAAAAAEIAgAA= FastObjectListView.cs AAAAAAAQAAAAEAQEBAAAAAQAgAAAAIAAAAAAAAAAAAA= Filtering\Cluster.cs AAAAAAAEAAAAAAAAAhBABAgAQAAIKAQBAQAAAAAAoIA= Filtering\ClusteringStrategy.cs AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQBAAAAAAAAAAA= Filtering\ClustersFromGroupsStrategy.cs AAAAAAIAAAACAAAAAAAACAAAAQgAAAQBAAAAAAAAAAA= Filtering\DateTimeClusteringStrategy.cs SAEAADAQgEEAAQAIAAgQIAAAAFQAAAAAAAAAoAAAAAE= Filtering\FilterMenuBuilder.cs AAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAA= Filtering\Filters.cs AAAAAAAAAEAAAABAAAAAAAAAABAAAAAAAAAAAAAAAAA= Filtering\Filters.cs AAAAAAAAAAgAAAAAAIAAAACAABAAAAAAAAAAAAAAAAA= Filtering\Filters.cs AAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= Filtering\Filters.cs AAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= Filtering\Filters.cs AAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAA= Filtering\Filters.cs AAAAAAAAAAAAAAAAAgAAAAIAABAAAAAAAAAAAAAAAAA= Filtering\Filters.cs AAAAAAAAAAAAAAAABAAAAAQAABAAAAAAAAAAAAAAAAA= Filtering\Filters.cs AAAgAAACAAAABAAABAAgAQACABABAAAAyEIAAIgSgAA= Filtering\TextMatchFilter.cs EgAAQTAAZAEgWGAASFwIIEYECGBGAQKAQEEGAQJAAEE= Implementation\Attributes.cs AAIAAAAAAAQAAAAAAAAAAAAAQAAAAAAAAABQAAAAAAA= Implementation\Comparers.cs AAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAA= Implementation\Comparers.cs AAIAAAAAAAQAAAAAAAAAAAAAQAAAAAAAAABQAAAAAAA= Implementation\Comparers.cs AZggAAAwAGAAAgACQAYCBCAEICACACUEhAEAQKBAgQg= Implementation\DataSourceAdapter.cs 5/7+//3///fX/+//+///f/3//f/37N////+//7+///8= Implementation\Enums.cs ASgQyXBAABICBAAAAIAAACCEMAKBQAOAABDAgAUpAQA= Implementation\Events.cs ABEAEAAFQAAAABAABABQEAQAQAAAECAAAAAgAAAAAAA= Implementation\Events.cs AAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAA= Implementation\Events.cs AAAABAAAIAAAAAAAAAEAAAQAAAAABAAAAAAAABAAIAA= Implementation\Events.cs AAQABAAAAAQQAAAAAAEAAAQAAAAABAAAAAAgABQAIAE= Implementation\Events.cs AAAAAAAAAAAAAAAAAEAAAAAAAAAAAAEAAAAAAAAAAAA= Implementation\Events.cs AAAEAAAAAAAAAAAAAAAEAAAQAAAAAAAAAAAAAAAQAAA= Implementation\Events.cs AAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAA= Implementation\Events.cs AAAAAAAAAAAgAAAAIAAAAAAAAAAAAgAAAAAAAAAAAAA= Implementation\Events.cs AAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= Implementation\Events.cs AAAAQAAAIAEAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAEA= Implementation\Events.cs AAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAQAAAAA= Implementation\Events.cs AAAAAAAAMABAAAAQgAZAFAAGUARAAAAAgAgAAIAIAAA= Implementation\Events.cs AAAAAAAAAAAAAAAAAIAAAACAAAAAAAAAAAAAAAAAAAA= Implementation\Events.cs AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAA= Implementation\Events.cs AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= Implementation\Events.cs CAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAA= Implementation\Events.cs AAAAAQAAAAAAAEGAAAAAAAAAAAgAACAIAAAACAAHAAA= Implementation\Events.cs AAAgAAAAMAAAAAAAgARABAAEUAQIAAAAiAgAAIAIAAA= Implementation\Events.cs AAAAAAAAAAAAAAAAAABAAAAAQAAAAAAIiAgACIAIAAA= Implementation\Events.cs AEAAAAAAAAAAAAAAgAQAAAAEAAAAAQAAgAkEAIAAAAA= Implementation\Events.cs AAAAAAAAEAAAAAAAAABABAAAUAQAAAAAAAgAAAAAAAA= Implementation\Events.cs AAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAACAAAAAAAAAA= Implementation\Events.cs AAIgAAAGJACRCAAEEABEAAAAJACBAAAAAAgIAAAAAAA= Implementation\Events.cs QAAAEAAAAAAAABAABABQEAQAQAAAEAAAAAAAAEAAAAA= Implementation\Events.cs QAAAAEAAAAAAAAAAgAAAAIAAAAAAAAAAAIAAAACAAAA= Implementation\Events.cs QAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= Implementation\Events.cs QAAAgEAACggAgAAIAAAAAEAAAIAAAAAAAAAAAAAAAII= Implementation\Events.cs AAAAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAgAAAAIAAA= Implementation\Events.cs AAAAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAgAAAAIAAA= Implementation\Events.cs AAAAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAgAAAAIAAA= Implementation\Events.cs AAAAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAgAAAAIAAA= Implementation\Events.cs AAAAAAAAIMAAAACBEAEAoQAAAKAACAAUhAAgRIQAIAE= Implementation\GroupingParameters.cs bEYChOwmAAQgiCQEQBgEAMwAEAAMAEQMgEFAFODAGhM= Implementation\Groups.cs AAAAgAAAJAAAAAQEABCAAAAAhAAAAACAAAAAAAIAAAE= Implementation\Munger.cs AAAIACAAJAAAgAAEACAAAAAABAAAIAAAAAEAAAAAEAA= Implementation\Munger.cs AAEAAAAAAAAAAAAAIAAAACAAAAAAAAAAAAAAAAABAAA= Implementation\Munger.cs cChxFKmMjlNGI/LfZWKToPLMK45gioYxDANnzL7yfN4= Implementation\NativeMethods.cs AAEAAAAAAAAEAAAACAAAAAAAQAAAAAAAAAAAAAAAAAA= Implementation\NullableDictionary.cs ABAAAAAAAABEAACAAAAAAAAQABAAEgAQAAIAASAAAgE= Implementation\OLVListItem.cs AAAAAAAAAAAEAAAAAAAAAAAAABAIAAAQCAgACSAAAAk= Implementation\OLVListSubItem.cs AAAAgEAAEAgAAABEAAZABAAGAAQAEAAAgAAAAAAIAAA= Implementation\OlvListViewHitTestInfo.cs AAAAAAAAAAAAAACAAAAEAAAAAAAAAAAEAAAACAAAAAA= Implementation\VirtualGroups.cs AAAAABAAAAAAAACAAAAAAAAAAAAAAAAEAAAACAAAAAA= Implementation\VirtualGroups.cs AIAAAAAAAAAAAAAAAAAAAgAIAAAQAAAAAAAEAEACAAA= Implementation\VirtualGroups.cs ABAAAAAAgAAAAAAgAAASQgAQAAAEAAAAAAAAAIAAgAA= Implementation\VirtualListDataSource.cs AABAAAAAAAAAAAAAAABCAAAAAAAEAAAAAAAAAAAAAAA= Implementation\VirtualListDataSource.cs MgARTxAAJEcEWCbkoNwJbE6WTnSOEnOKQhSWGDJgsFk= OLVColumn.cs AACgAIAABAAAAIABACCiAIAgAACAAgAAABAIAAAAgAE= Rendering\Adornments.cs ABAAAAAAAIAAAAAAAEAAAAAAEAAAABAAAEABAAAAAAA= Rendering\Adornments.cs QAIggAAEIAAgBIAIAAIASEACIABAACIIAAMACCADAsA= Rendering\Adornments.cs AAEAAAAAAAABAgAAAQAABAAAAAQBAAAAAAAAAAAAAAA= Rendering\Decorations.cs AgAAAAAAEAAAAgAAAAAAAAAAAAAAAAAAAAAQAAIAAAA= Rendering\Decorations.cs YAgAgCABAAAgA4AAAAIAgAAAAAAAAAAAAAIAACBIgAA= Rendering\Decorations.cs AAAAgAAgAAAAIAAAAAAAAAAAAAAAAAAAAAAAAABAAIA= Rendering\Decorations.cs AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAA= Rendering\Decorations.cs QAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAEAAAAA= Rendering\Decorations.cs AAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= Rendering\Decorations.cs AAAAAAAAAAABAgAAAQAABAAAAAQAAAAAAAAAAAAAAAA= Rendering\Decorations.cs AAAAAAAAAAABAgAAAQAABAAAAAQAAAAAAAAAAAAAAAA= Rendering\Decorations.cs AAAAAAAAAAAAAgAAAAAAAIAAAACAAAAAAAAAAAAAAAA= Rendering\Overlays.cs AAAAAAAAAAAAAgAAAAAAABAAAAAQAAAAAAAAAAAAAAA= Rendering\Overlays.cs AAAAAAAAAIAAAgAAAAAAABAAAAAQAAAAAAAAAAAAAAA= Rendering\Overlays.cs AAAAAAAAAAAAAgAAAAIAAAACAAAAAAAAAAAAAAAAAAA= Rendering\Overlays.cs AAAAAQAAAABAAAAAABAAAAAAAAAAABAAAAAAAAAAAAA= Rendering\Renderers.cs AAABAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= Rendering\Renderers.cs AxLAQSEQZQhhAmA5IRBAASSQUhQgkFAAgJDGAAMDE8I= Rendering\Renderers.cs QAggCAEAAEAAAIAwAAKAEAIQABAAEAAAAAAAAAAKAAA= Rendering\Renderers.cs AAIAEBAAAQAAAAgAABAAEAAAAAAAAAAAABAAAAAAAAA= Rendering\Renderers.cs AAAAAAQBIAAAAAAAAAAAAAAAAAAAAAAACBAAAAIAAAA= Rendering\Renderers.cs AAAgAAAAAAAAAAAAAIAAAAAgIAAAAABBABAAAAAEIAA= Rendering\Renderers.cs AAIAAQAAAAEAAgAAEAIAABAAAAAAAAAAIAEAACADAAA= Rendering\Styles.cs AAIAAQAAAAEAAgAAAAIAAAAAAAAAAAAAAAEAAAADAAA= Rendering\Styles.cs AAAAAAAAQAiAAAAAgAIAAAAAAAAIBAAgAAAAAAAAAAA= Rendering\Styles.cs AAIAAQAAAAEAAAAAAAAAAAACACAAAgAgAAEAAAADAAA= Rendering\Styles.cs AAAAAAAQAAgAAAAAAAAAAICAAIAIAAAABAAAAQAEAAA= Rendering\Styles.cs BgCkgAAARAoAAEAyEAAAAAIAAAAIAhCAAQIERAgAASA= SubControls\GlassPanelForm.cs MAAIOQAUABAAAACQiBQCKRgAACECAAoAwAAQxJAACaE= SubControls\HeaderControl.cs AkAACAgAACCACAAAAAAAAIAAwAAIAAQCAAAAAAAAAAA= SubControls\ToolStripCheckedListBox.cs CkoAByAwQQAggEvSAAIQiIWIBELAYOIpiAKQUIQDqEA= SubControls\ToolTipControl.cs AAAAAEAAFDAAQTAUAACIBAoWEAAAAAAoAAAAAIEAAgA= Utilities\ColumnSelectionForm.cs AAABAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAACAAAAAA= Utilities\Generator.cs AAAAwABEAAAAAACIAIAQEAABEAAAAAEEggAAAAACQAA= Utilities\TypedObjectListView.cs AAAACAAAAEAEAABAAEAQCAAAQAAEAEAAAAgAAAAAAAA= Utilities\TypedObjectListView.cs AVkQQAAAAGIEAQAkKkHAEAgRH4gBgAGOCCEigAAgIAQ= VirtualObjectListView.cs AAEAAAABACAEAQAEAAAAAAAgAQCAAAAAAAMIQAABEAA= ObjectListView.DesignTime.cs AAAAAAAAAAAAAABAAAABAAAAAAAAQAAAAAAAAAAAAAA= ObjectListView.DesignTime.cs AAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAIAAAAAAAA= ObjectListView.DesignTime.cs AAAAAAAAAAAAAAIAAAABEAAAgQAAAAAAAAAAQAIAAIg= AAAAAAAAAAAAAgIAAAACAAEGAAAAAEAAAAAAABAAQAA= DataTreeListView.cs BAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAQAA= DragDrop\DragSource.cs AAAAAAAAAAAQQAAAAAIAEAAAAAEFAAAAgAAAAAAAAAA= DragDrop\DropSink.cs AAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAA= Filtering\Filters.cs AAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAA= Filtering\Filters.cs AAAAAAAQAAAAAAAAAAAAAAQAgAAAAAAAAAAAAAAAAAA= Filtering\ICluster.cs AAAAAAAAAAAAAAAAABBAAAAAAAAAAAQBAQAAAAAAAAA= Filtering\IClusteringStrategy.cs AAAAAAAAAAAAAACAAAAEAAAAAAAAAAAEAAAACAAAAAA= Implementation\VirtualGroups.cs AIAAAAAAAAAAAAAAAAAAAgAIAAAQAAAAAAAEAEAAAAA= Implementation\VirtualGroups.cs ABAAAAAAAAAAAAAgAAASAgAQAAAEAAAAAAAAAAAAgAA= Implementation\VirtualListDataSource.cs AAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAA= Implementation\VirtualListDataSource.cs AAAAAAAAAAAAAAAAAQAAAAAAAAQAAAAAAAAAAAAAAAA= Rendering\Decorations.cs AAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= Rendering\Overlays.cs AAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAA= Rendering\Overlays.cs AAAAAQAAAABAAAAAABAAAAAAAAAAABAAAAAAAAAAAAA= Rendering\Renderers.cs AAAAAQAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAADAAA= Rendering\Styles.cs AAAgAAAACAAAAAAAAAAAAAAAAAAQAAAAAAAAAEAAAAA= CellEditing\CellEditKeyEngine.cs gAEAAAAQCAIAAAAAAIAAAAAAAUAQIABAAEAgAAAgACA= CellEditing\CellEditKeyEngine.cs AAAAAQAAAAABAAAAAAAAAAAEAAQBBAAAAAIgAAEAAAA= DragDrop\DropSink.cs AAAAAAAAJAAAAAAAAAAAAAIAAAAAACIEAAAAAAAAAAA= Filtering\DateTimeClusteringStrategy.cs AEAAAAAAAAAAABAAEAQAARAAIQAAAAQAAAAAAEAAAAA= Implementation\Groups.cs AgAAgAAAwABAAAAAAAUAAAIAgQAAAAAEACAgAAAFAAA= Implementation\Groups.cs AAAAAAQAAAAAAAAAAAAAAQAAAAAAEAAAAIAAAAAAAAA= Implementation\Groups.cs ASAAEEAAAAAAAAQAEAAAAAAAAAAAABAAAAAACAAAEAA= Implementation\OlvListViewHitTestInfo.cs AAAEAAAAAAAAAAAAAAAAAAAQAAAABAAAAAAAAAAAAAA= CellEditing\EditorRegistry.cs AAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAA= Implementation\Delegates.cs AAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAgA= Implementation\Delegates.cs AAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAA= Implementation\Delegates.cs AAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgA= Implementation\Delegates.cs AAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAA= Implementation\Delegates.cs AAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAA= Implementation\Delegates.cs AAAAAAAAAAAAAAAAAAAAAAAQAAQAAAAAAAAAAAAAAAA= Implementation\Delegates.cs AAAAAAAAgAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAA= Implementation\Delegates.cs AAAAAAAAAAAAAAAAAAAEAAAQAAAAAAAAAAAAAAAAAAA= Implementation\Delegates.cs AAAAAQABgAAAAACAQAAAAAAAAAAAAAAAAAAAAAAgAAA= Implementation\Delegates.cs AAAAAAAAAAAAAAAAAAAAAAAAABAAAACAAAAAAAAAAAA= Implementation\Delegates.cs AAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAA= Implementation\Delegates.cs AAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAA= Implementation\Delegates.cs AAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= Implementation\Delegates.cs AAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAA= Implementation\Delegates.cs AAAAAAAAABAAAAAAgACAAAAACAAAAAAAAAAAAAAAAAA= Implementation\Delegates.cs AAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAA= Implementation\Delegates.cs AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAA= Implementation\Delegates.cs AAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAA= Implementation\Delegates.cs AAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAABAAAAAAAAAA= Implementation\Events.cs ================================================ FILE: source/ObjectListView/GlobalSuppressions.cs ================================================ // This file is used by Code Analysis to maintain SuppressMessage // attributes that are applied to this project. // Project-level suppressions either have no target or are given // a specific target and scoped to a namespace, type, member, etc. using System.Diagnostics.CodeAnalysis; [assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~M:BrightIdeasSoftware.ObjectListView.HandleChar(System.Windows.Forms.Message@)~System.Boolean")] ================================================ FILE: source/ObjectListView/Implementation/Attributes.cs ================================================ /* * Attributes - Attributes that can be attached to properties of models to allow columns to be * built from them directly * * Author: Phillip Piper * Date: 15/08/2009 22:01 * * Change log: * v2.6 * 2012-08-16 JPP - Added [OLVChildren] and [OLVIgnore] * - OLV attributes can now only be set on properties * v2.4 * 2010-04-14 JPP - Allow Name property to be set * * v2.3 * 2009-08-15 JPP - Initial version * * To do: * * Copyright (C) 2009-2014 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System; using System.Windows.Forms; namespace BrightIdeasSoftware { /// /// This attribute is used to mark a property of a model /// class that should be noticed by Generator class. /// /// /// All the attributes of this class match their equivilent properties on OLVColumn. /// [AttributeUsage(AttributeTargets.Property)] public class OLVColumnAttribute : Attribute { #region Constructor // There are several property where we actually want nullable value (bool?, int?), // but it seems attribute properties can't be nullable types. // So we explicitly track if those properties have been set. /// /// Create a new OLVColumnAttribute /// public OLVColumnAttribute() { } /// /// Create a new OLVColumnAttribute with the given title /// /// The title of the column public OLVColumnAttribute(string title) { Title = title; } #endregion #region Public properties /// /// /// public string AspectToStringFormat { get { return aspectToStringFormat; } set { aspectToStringFormat = value; } } private string aspectToStringFormat; /// /// /// public bool CheckBoxes { get { return checkBoxes; } set { checkBoxes = value; IsCheckBoxesSet = true; } } private bool checkBoxes; internal bool IsCheckBoxesSet = false; /// /// /// public int DisplayIndex { get { return displayIndex; } set { displayIndex = value; } } private int displayIndex = -1; /// /// /// public bool FillsFreeSpace { get { return fillsFreeSpace; } set { fillsFreeSpace = value; } } private bool fillsFreeSpace; /// /// /// public int FreeSpaceProportion { get { return freeSpaceProportion; } set { freeSpaceProportion = value; IsFreeSpaceProportionSet = true; } } private int freeSpaceProportion; internal bool IsFreeSpaceProportionSet = false; /// /// An array of IComparables that mark the cutoff points for values when /// grouping on this column. /// public object[] GroupCutoffs { get { return groupCutoffs; } set { groupCutoffs = value; } } private object[] groupCutoffs; /// /// /// public string[] GroupDescriptions { get { return groupDescriptions; } set { groupDescriptions = value; } } private string[] groupDescriptions; /// /// /// public string GroupWithItemCountFormat { get { return groupWithItemCountFormat; } set { groupWithItemCountFormat = value; } } private string groupWithItemCountFormat; /// /// /// public string GroupWithItemCountSingularFormat { get { return groupWithItemCountSingularFormat; } set { groupWithItemCountSingularFormat = value; } } private string groupWithItemCountSingularFormat; /// /// /// public bool Hyperlink { get { return hyperlink; } set { hyperlink = value; } } private bool hyperlink; /// /// /// public string ImageAspectName { get { return imageAspectName; } set { imageAspectName = value; } } private string imageAspectName; /// /// /// public bool IsEditable { get { return isEditable; } set { isEditable = value; IsEditableSet = true; } } private bool isEditable = true; internal bool IsEditableSet = false; /// /// /// public bool IsVisible { get { return isVisible; } set { isVisible = value; } } private bool isVisible = true; /// /// /// public bool IsTileViewColumn { get { return isTileViewColumn; } set { isTileViewColumn = value; } } private bool isTileViewColumn; /// /// /// public int MaximumWidth { get { return maximumWidth; } set { maximumWidth = value; } } private int maximumWidth = -1; /// /// /// public int MinimumWidth { get { return minimumWidth; } set { minimumWidth = value; } } private int minimumWidth = -1; /// /// /// public String Name { get { return name; } set { name = value; } } private String name; /// /// /// public HorizontalAlignment TextAlign { get { return textAlign; } set { textAlign = value; IsTextAlignSet = true; } } private HorizontalAlignment textAlign = HorizontalAlignment.Left; internal bool IsTextAlignSet = false; /// /// /// public String Tag { get { return tag; } set { tag = value; } } private String tag; /// /// /// public String Title { get { return title; } set { title = value; } } private String title; /// /// /// public String ToolTipText { get { return toolTipText; } set { toolTipText = value; } } private String toolTipText; /// /// /// public bool TriStateCheckBoxes { get { return triStateCheckBoxes; } set { triStateCheckBoxes = value; IsTriStateCheckBoxesSet = true; } } private bool triStateCheckBoxes; internal bool IsTriStateCheckBoxesSet = false; /// /// /// public bool UseInitialLetterForGroup { get { return useInitialLetterForGroup; } set { useInitialLetterForGroup = value; } } private bool useInitialLetterForGroup; /// /// /// public int Width { get { return width; } set { width = value; } } private int width = 150; #endregion } /// /// Properties marked with [OLVChildren] will be used as the children source in a TreeListView. /// [AttributeUsage(AttributeTargets.Property)] public class OLVChildrenAttribute : Attribute { } /// /// Properties marked with [OLVIgnore] will not have columns generated for them. /// [AttributeUsage(AttributeTargets.Property)] public class OLVIgnoreAttribute : Attribute { } } ================================================ FILE: source/ObjectListView/Implementation/Comparers.cs ================================================ /* * Comparers - Various Comparer classes used within ObjectListView * * Author: Phillip Piper * Date: 25/11/2008 17:15 * * Change log: * v2.8.1 * 2014-12-03 JPP - Added StringComparer * v2.3 * 2009-08-24 JPP - Added OLVGroupComparer * 2009-06-01 JPP - ModelObjectComparer would crash if secondary sort column was null. * 2008-12-20 JPP - Fixed bug with group comparisons when a group key was null (SF#2445761) * 2008-11-25 JPP Initial version * * TO DO: * * Copyright (C) 2006-2014 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System; using System.Collections; using System.Collections.Generic; using System.Windows.Forms; namespace BrightIdeasSoftware { /// /// ColumnComparer is the workhorse for all comparison between two values of a particular column. /// If the column has a specific comparer, use that to compare the values. Otherwise, do /// a case insensitive string compare of the string representations of the values. /// /// This class inherits from both IComparer and its generic counterpart /// so that it can be used on untyped and typed collections. /// This is used by normal (non-virtual) ObjectListViews. Virtual lists use /// ModelObjectComparer /// public class ColumnComparer : IComparer, IComparer { /// /// Gets or sets the method that will be used to compare two strings. /// The default is to compare on the current culture, case-insensitive /// public static StringCompareDelegate StringComparer { get { return stringComparer; } set { stringComparer = value; } } private static StringCompareDelegate stringComparer; /// /// Create a ColumnComparer that will order the rows in a list view according /// to the values in a given column /// /// The column whose values will be compared /// The ordering for column values public ColumnComparer(OLVColumn col, SortOrder order) { column = col; sortOrder = order; } /// /// Create a ColumnComparer that will order the rows in a list view according /// to the values in a given column, and by a secondary column if the primary /// column is equal. /// /// The column whose values will be compared /// The ordering for column values /// The column whose values will be compared for secondary sorting /// The ordering for secondary column values public ColumnComparer(OLVColumn col, SortOrder order, OLVColumn col2, SortOrder order2) : this(col, order) { // There is no point in secondary sorting on the same column if (col != col2) secondComparer = new ColumnComparer(col2, order2); } /// /// Compare two rows /// /// row1 /// row2 /// An ordering indication: -1, 0, 1 public int Compare(object x, object y) { return Compare((OLVListItem)x, (OLVListItem)y); } /// /// Compare two rows /// /// row1 /// row2 /// An ordering indication: -1, 0, 1 public int Compare(OLVListItem x, OLVListItem y) { if (sortOrder == SortOrder.None) return 0; int result = 0; object x1 = column.GetValue(x.RowObject); object y1 = column.GetValue(y.RowObject); // Handle nulls. Null values come last bool xIsNull = (x1 == null || x1 == DBNull.Value); bool yIsNull = (y1 == null || y1 == DBNull.Value); if (xIsNull || yIsNull) { if (xIsNull && yIsNull) result = 0; else result = (xIsNull ? -1 : 1); } else { result = CompareValues(x1, y1); } if (sortOrder == SortOrder.Descending) result = 0 - result; // If the result was equality, use the secondary comparer to resolve it if (result == 0 && secondComparer != null) result = secondComparer.Compare(x, y); return result; } /// /// Compare the actual values to be used for sorting /// /// The aspect extracted from the first row /// The aspect extracted from the second row /// An ordering indication: -1, 0, 1 public int CompareValues(object x, object y) { // Force case insensitive compares on strings if (x is string xAsString) return CompareStrings(xAsString, y as String); return x is IComparable comparable ? comparable.CompareTo(y) : 0; } private static int CompareStrings(string x, string y) { if (StringComparer == null) return String.Compare(x, y, StringComparison.CurrentCultureIgnoreCase); else return StringComparer(x, y); } private OLVColumn column; private SortOrder sortOrder; private ColumnComparer secondComparer; } /// /// This comparer sort list view groups. OLVGroups have a "SortValue" property, /// which is used if present. Otherwise, the titles of the groups will be compared. /// public class OLVGroupComparer : IComparer { /// /// Create a group comparer /// /// The ordering for column values public OLVGroupComparer(SortOrder order) { sortOrder = order; } /// /// Compare the two groups. OLVGroups have a "SortValue" property, /// which is used if present. Otherwise, the titles of the groups will be compared. /// /// group1 /// group2 /// An ordering indication: -1, 0, 1 public int Compare(OLVGroup x, OLVGroup y) { // If we can compare the sort values, do that. // Otherwise do a case insensitive compare on the group header. int result; if (x.SortValue != null && y.SortValue != null) result = x.SortValue.CompareTo(y.SortValue); else result = String.Compare(x.Header, y.Header, StringComparison.CurrentCultureIgnoreCase); if (sortOrder == SortOrder.Descending) result = 0 - result; return result; } private SortOrder sortOrder; } /// /// This comparer can be used to sort a collection of model objects by a given column /// /// /// This is used by virtual ObjectListViews. Non-virtual lists use /// ColumnComparer /// public class ModelObjectComparer : IComparer, IComparer { /// /// Gets or sets the method that will be used to compare two strings. /// The default is to compare on the current culture, case-insensitive /// public static StringCompareDelegate StringComparer { get { return stringComparer; } set { stringComparer = value; } } private static StringCompareDelegate stringComparer; /// /// Create a model object comparer /// /// /// public ModelObjectComparer(OLVColumn col, SortOrder order) { column = col; sortOrder = order; } /// /// Create a model object comparer with a secondary sorting column /// /// /// /// /// public ModelObjectComparer(OLVColumn col, SortOrder order, OLVColumn col2, SortOrder order2) : this(col, order) { // There is no point in secondary sorting on the same column if (col != col2 && col2 != null && order2 != SortOrder.None) secondComparer = new ModelObjectComparer(col2, order2); } /// /// Compare the two model objects /// /// /// /// public int Compare(object x, object y) { int result = 0; object x1 = column.GetValue(x); object y1 = column.GetValue(y); if (sortOrder == SortOrder.None) return 0; // Handle nulls. Null values come last bool xIsNull = (x1 == null || x1 == DBNull.Value); bool yIsNull = (y1 == null || y1 == DBNull.Value); if (xIsNull || yIsNull) { if (xIsNull && yIsNull) result = 0; else result = (xIsNull ? -1 : 1); } else { result = CompareValues(x1, y1); } if (sortOrder == SortOrder.Descending) result = 0 - result; // If the result was equality, use the secondary comparer to resolve it if (result == 0 && secondComparer != null) result = secondComparer.Compare(x, y); return result; } /// /// Compare the actual values /// /// /// /// public int CompareValues(object x, object y) { // Force case insensitive compares on strings if (x is string xStr) return CompareStrings(xStr, y as String); return x is IComparable comparable ? comparable.CompareTo(y) : 0; } private static int CompareStrings(string x, string y) { if (StringComparer == null) return String.Compare(x, y, StringComparison.CurrentCultureIgnoreCase); else return StringComparer(x, y); } private OLVColumn column; private SortOrder sortOrder; private ModelObjectComparer secondComparer; #region IComparer Members #endregion } } ================================================ FILE: source/ObjectListView/Implementation/DataSourceAdapter.cs ================================================ /* * DataSourceAdapter - A helper class that translates DataSource events for an ObjectListView * * Author: Phillip Piper * Date: 20/09/2010 7:42 AM * * Change log: * v2.9 * 2015-10-31 JPP - Put back sanity check on upper limit of source items * 2015-02-02 JPP - Made CreateColumnsFromSource() only rebuild columns when new ones were added * v2.8.1 * 2014-11-23 JPP - Honour initial CurrencyManager.Position when setting DataSource. * 2014-10-27 JPP - Fix issue where SelectedObject was not sync'ed with CurrencyManager.Position (SF #129) * v2.6 * 2012-08-16 JPP - Unify common column creation functionality with Generator when possible * * 2010-09-20 JPP - Initial version * * Copyright (C) 2010-2014 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System; using System.ComponentModel; using System.Data; using System.Windows.Forms; using System.Diagnostics; namespace BrightIdeasSoftware { /// /// A helper class that translates DataSource events for an ObjectListView /// public class DataSourceAdapter : IDisposable { #region Life and death /// /// Make a DataSourceAdapter /// public DataSourceAdapter(ObjectListView olv) { ListView = olv ?? throw new ArgumentNullException("olv"); // ReSharper disable once DoNotCallOverridableMethodsInConstructor BindListView(ListView); } /// /// Finalize this object /// ~DataSourceAdapter() { Dispose(false); } /// /// Release all the resources used by this instance /// public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } /// /// Release all the resources used by this instance /// public virtual void Dispose(bool fromUser) { UnbindListView(ListView); UnbindDataSource(); } #endregion #region Public Properties /// /// Gets or sets whether or not columns will be automatically generated to show the /// columns when the DataSource is set. /// /// This must be set before the DataSource is set. It has no effect afterwards. public bool AutoGenerateColumns { get { return autoGenerateColumns; } set { autoGenerateColumns = value; } } private bool autoGenerateColumns = true; /// /// Get or set the DataSource that will be displayed in this list view. /// public virtual Object DataSource { get { return dataSource; } set { dataSource = value; RebindDataSource(true); } } private Object dataSource; /// /// Gets or sets the name of the list or table in the data source for which the DataListView is displaying data. /// /// If the data source is not a DataSet or DataViewManager, this property has no effect public virtual string DataMember { get { return dataMember; } set { if (dataMember != value) { dataMember = value; RebindDataSource(); } } } private string dataMember = ""; /// /// Gets the ObjectListView upon which this adaptor will operate /// public ObjectListView ListView { get { return listView; } internal set { listView = value; } } private ObjectListView listView; #endregion #region Implementation properties /// /// Gets or sets the currency manager which is handling our binding context /// protected CurrencyManager CurrencyManager { get { return currencyManager; } set { currencyManager = value; } } private CurrencyManager currencyManager; #endregion #region Binding and unbinding /// /// /// /// protected virtual void BindListView(ObjectListView olv) { if (olv == null) return; olv.Freezing += new EventHandler(HandleListViewFreezing); olv.SelectionChanged += new EventHandler(HandleListViewSelectionChanged); olv.BindingContextChanged += new EventHandler(HandleListViewBindingContextChanged); } /// /// /// /// protected virtual void UnbindListView(ObjectListView olv) { if (olv == null) return; olv.Freezing -= new EventHandler(HandleListViewFreezing); olv.SelectionChanged -= new EventHandler(HandleListViewSelectionChanged); olv.BindingContextChanged -= new EventHandler(HandleListViewBindingContextChanged); } /// /// /// protected virtual void BindDataSource() { if (CurrencyManager == null) return; CurrencyManager.MetaDataChanged += new EventHandler(HandleCurrencyManagerMetaDataChanged); CurrencyManager.PositionChanged += new EventHandler(HandleCurrencyManagerPositionChanged); CurrencyManager.ListChanged += new ListChangedEventHandler(CurrencyManagerListChanged); } /// /// /// protected virtual void UnbindDataSource() { if (CurrencyManager == null) return; CurrencyManager.MetaDataChanged -= new EventHandler(HandleCurrencyManagerMetaDataChanged); CurrencyManager.PositionChanged -= new EventHandler(HandleCurrencyManagerPositionChanged); CurrencyManager.ListChanged -= new ListChangedEventHandler(CurrencyManagerListChanged); } #endregion #region Initialization /// /// Our data source has changed. Figure out how to handle the new source /// protected virtual void RebindDataSource() { RebindDataSource(false); } /// /// Our data source has changed. Figure out how to handle the new source /// protected virtual void RebindDataSource(bool forceDataInitialization) { CurrencyManager tempCurrencyManager = null; if (ListView != null && ListView.BindingContext != null && DataSource != null) { tempCurrencyManager = ListView.BindingContext[DataSource, DataMember] as CurrencyManager; } // Has our currency manager changed? if (CurrencyManager != tempCurrencyManager) { UnbindDataSource(); CurrencyManager = tempCurrencyManager; BindDataSource(); // Our currency manager has changed so we have to initialize a new data source forceDataInitialization = true; } if (forceDataInitialization) InitializeDataSource(); } /// /// The data source for this control has changed. Reconfigure the control for the new source /// protected virtual void InitializeDataSource() { if (ListView.Frozen || CurrencyManager == null) return; CreateColumnsFromSource(); CreateMissingAspectGettersAndPutters(); SetListContents(); ListView.AutoSizeColumns(); // Fake a position change event so that the control matches any initial Position HandleCurrencyManagerPositionChanged(null, null); } /// /// Take the contents of the currently bound list and put them into the control /// protected virtual void SetListContents() { ListView.Objects = CurrencyManager.List; } /// /// Create columns for the listview based on what properties are available in the data source /// /// /// This method will create columns if there is not already a column displaying that property. /// protected virtual void CreateColumnsFromSource() { if (CurrencyManager == null) return; // Don't generate any columns in design mode. If we do, the user will see them, // but the Designer won't know about them and won't persist them, which is very confusing if (ListView.IsDesignMode) return; // Don't create columns if we've been told not to if (!AutoGenerateColumns) return; // Use a Generator to create columns Generator generator = Generator.Instance as Generator ?? new Generator(); PropertyDescriptorCollection properties = CurrencyManager.GetItemProperties(); if (properties.Count == 0) return; bool wereColumnsAdded = false; foreach (PropertyDescriptor property in properties) { if (!ShouldCreateColumn(property)) continue; // Create a column OLVColumn column = generator.MakeColumnFromPropertyDescriptor(property); ConfigureColumn(column, property); // Add it to our list ListView.AllColumns.Add(column); wereColumnsAdded = true; } if (wereColumnsAdded) generator.PostCreateColumns(ListView); } /// /// Decide if a new column should be added to the control to display /// the given property /// /// /// protected virtual bool ShouldCreateColumn(PropertyDescriptor property) { // Is there a column that already shows this property? If so, we don't show it again if (ListView.AllColumns.Exists(delegate(OLVColumn x) { return x.AspectName == property.Name; })) return false; // Relationships to other tables turn up as IBindibleLists. Don't make columns to show them. // CHECK: Is this always true? What other things could be here? Constraints? Triggers? if (property.PropertyType == typeof(IBindingList)) return false; // Ignore anything marked with [OLVIgnore] return property.Attributes[typeof(OLVIgnoreAttribute)] == null; } /// /// Configure the given column to show the given property. /// The title and aspect name of the column are already filled in. /// /// /// protected virtual void ConfigureColumn(OLVColumn column, PropertyDescriptor property) { column.LastDisplayIndex = ListView.AllColumns.Count; // If our column is a BLOB, it could be an image, so assign a renderer to draw it. // CONSIDER: Is this a common enough case to warrant this code? if (property.PropertyType == typeof(Byte[])) column.Renderer = new ImageRenderer(); } /// /// Generate aspect getters and putters for any columns that are missing them (and for which we have /// enough information to actually generate a getter) /// protected virtual void CreateMissingAspectGettersAndPutters() { foreach (OLVColumn x in ListView.AllColumns) { OLVColumn column = x; // stack based variable accessible from closures if (column.AspectGetter == null && !String.IsNullOrEmpty(column.AspectName)) { column.AspectGetter = delegate(object row) { // In most cases, rows will be DataRowView objects if (row is not DataRowView drv) return column.GetAspectByName(row); return (drv.Row.RowState == DataRowState.Detached) ? null : drv[column.AspectName]; }; } if (column.IsEditable && column.AspectPutter == null && !String.IsNullOrEmpty(column.AspectName)) { column.AspectPutter = delegate(object row, object newValue) { // In most cases, rows will be DataRowView objects if (row is not DataRowView drv) column.PutAspectByName(row, newValue); else { if (drv.Row.RowState != DataRowState.Detached) drv[column.AspectName] = newValue; } }; } } } #endregion #region Event Handlers /// /// CurrencyManager ListChanged event handler. /// Deals with fine-grained changes to list items. /// /// /// It's actually difficult to deal with these changes in a fine-grained manner. /// If our listview is grouped, then any change may make a new group appear or /// an old group disappear. It is rarely enough to simply update the affected row. /// /// /// protected virtual void CurrencyManagerListChanged(object sender, ListChangedEventArgs e) { Debug.Assert(sender == CurrencyManager); // Ignore changes make while frozen, since we will do a complete rebuild when we unfreeze if (ListView.Frozen) return; //System.Diagnostics.Debug.WriteLine(e.ListChangedType); Stopwatch sw = Stopwatch.StartNew(); switch (e.ListChangedType) { case ListChangedType.Reset: HandleListChangedReset(e); break; case ListChangedType.ItemChanged: HandleListChangedItemChanged(e); break; case ListChangedType.ItemAdded: HandleListChangedItemAdded(e); break; // An item has gone away. case ListChangedType.ItemDeleted: HandleListChangedItemDeleted(e); break; // An item has changed its index. case ListChangedType.ItemMoved: HandleListChangedItemMoved(e); break; // Something has changed in the metadata. // CHECK: When are these events actually fired? case ListChangedType.PropertyDescriptorAdded: case ListChangedType.PropertyDescriptorChanged: case ListChangedType.PropertyDescriptorDeleted: HandleListChangedMetadataChanged(e); break; } sw.Stop(); Debug.WriteLine(String.Format("PERF - Processing {0} event on {1} rows took {2}ms", e.ListChangedType, ListView.GetItemCount(), sw.ElapsedMilliseconds)); } /// /// Handle PropertyDescriptor* events /// /// protected virtual void HandleListChangedMetadataChanged(ListChangedEventArgs e) { InitializeDataSource(); } /// /// Handle ItemMoved event /// /// protected virtual void HandleListChangedItemMoved(ListChangedEventArgs e) { // When is this actually triggered? InitializeDataSource(); } /// /// Handle the ItemDeleted event /// /// protected virtual void HandleListChangedItemDeleted(ListChangedEventArgs e) { InitializeDataSource(); } /// /// Handle an ItemAdded event. /// /// protected virtual void HandleListChangedItemAdded(ListChangedEventArgs e) { // We get this event twice if certain grid controls are used to add a new row to a // datatable: once when the editing of a new row begins, and once again when that // editing commits. (If the user cancels the creation of the new row, we never see // the second creation.) We detect this by seeing if this is a view on a row in a // DataTable, and if it is, testing to see if it's a new row under creation. Object newRow = CurrencyManager.List[e.NewIndex]; if (newRow is not DataRowView drv || !drv.IsNew) { // Either we're not dealing with a view on a data table, or this is the commit // notification. Either way, this is the final notification, so we want to // handle the new row now! InitializeDataSource(); } } /// /// Handle the Reset event /// /// protected virtual void HandleListChangedReset(ListChangedEventArgs e) { // The whole list has changed utterly, so reload it. InitializeDataSource(); } /// /// Handle ItemChanged event. This is triggered when a single item /// has changed, so just refresh that one item. /// /// /// Even in this simple case, we should probably rebuild the list. /// For example, the change could put the item into its own new group. protected virtual void HandleListChangedItemChanged(ListChangedEventArgs e) { // A single item has changed, so just refresh that. //System.Diagnostics.Debug.WriteLine(String.Format("HandleListChangedItemChanged: {0}, {1}", e.NewIndex, e.PropertyDescriptor.Name)); Object changedRow = CurrencyManager.List[e.NewIndex]; ListView.RefreshObject(changedRow); } /// /// The CurrencyManager calls this if the data source looks /// different. We just reload everything. /// /// /// /// /// CHECK: Do we need this if we are handle ListChanged metadata events? /// protected virtual void HandleCurrencyManagerMetaDataChanged(object sender, EventArgs e) { InitializeDataSource(); } /// /// Called by the CurrencyManager when the currently selected item /// changes. We update the ListView selection so that we stay in sync /// with any other controls bound to the same source. /// /// /// protected virtual void HandleCurrencyManagerPositionChanged(object sender, EventArgs e) { int index = CurrencyManager.Position; // Make sure the index is sane (-1 pops up from time to time) if (index < 0 || index >= ListView.GetItemCount()) return; // Avoid recursion. If we are currently changing the index, don't // start the process again. if (isChangingIndex) return; try { isChangingIndex = true; ChangePosition(index); } finally { isChangingIndex = false; } } private bool isChangingIndex = false; /// /// Change the control's position (which is it's currently selected row) /// to the nth row in the dataset /// /// The index of the row to be selected protected virtual void ChangePosition(int index) { // We can't use the index directly, since our listview may be sorted ListView.SelectedObject = CurrencyManager.List[index]; // THINK: Do we always want to bring it into view? if (ListView.SelectedIndices.Count > 0) ListView.EnsureVisible(ListView.SelectedIndices[0]); } #endregion #region ObjectListView event handlers /// /// Handle the selection changing in our ListView. /// We need to tell our currency manager about the new position. /// /// /// protected virtual void HandleListViewSelectionChanged(object sender, EventArgs e) { // Prevent recursion if (isChangingIndex) return; // Sanity if (CurrencyManager == null) return; // If only one item is selected, tell the currency manager which item is selected. // CurrencyManager can't handle multiple selection so there's nothing we can do // if more than one row is selected. if (ListView.SelectedIndices.Count != 1) return; try { isChangingIndex = true; // We can't use the selectedIndex directly, since our listview may be sorted and/or filtered // So we have to find the index of the selected object within the original list. CurrencyManager.Position = CurrencyManager.List.IndexOf(ListView.SelectedObject); } finally { isChangingIndex = false; } } /// /// Handle the frozenness of our ListView changing. /// /// /// protected virtual void HandleListViewFreezing(object sender, FreezeEventArgs e) { if (!alreadyFreezing && e.FreezeLevel == 0) { try { alreadyFreezing = true; RebindDataSource(true); } finally { alreadyFreezing = false; } } } private bool alreadyFreezing = false; /// /// Handle a change to the BindingContext of our ListView. /// /// /// protected virtual void HandleListViewBindingContextChanged(object sender, EventArgs e) { RebindDataSource(false); } #endregion } } ================================================ FILE: source/ObjectListView/Implementation/Delegates.cs ================================================ /* * Delegates - All delegate definitions used in ObjectListView * * Author: Phillip Piper * Date: 31-March-2011 5:53 pm * * Change log: * v2.10 * 2015-12-30 JPP - Added CellRendererGetterDelegate * v2.? * 2011-03-31 JPP - Split into its own file * * Copyright (C) 2011-2015 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System; using System.Windows.Forms; using System.Drawing; namespace BrightIdeasSoftware { #region Delegate declarations /// /// These delegates are used to extract an aspect from a row object /// public delegate Object AspectGetterDelegate(Object rowObject); /// /// These delegates are used to put a changed value back into a model object /// public delegate void AspectPutterDelegate(Object rowObject, Object newValue); /// /// These delegates can be used to convert an aspect value to a display string, /// instead of using the default ToString() /// public delegate string AspectToStringConverterDelegate(Object value); /// /// These delegates are used to get the tooltip for a cell /// public delegate String CellToolTipGetterDelegate(OLVColumn column, Object modelObject); /// /// These delegates are used to the state of the checkbox for a row object. /// /// /// For reasons known only to someone in Microsoft, we can only set /// a boolean on the ListViewItem to indicate it's "checked-ness", but when /// we receive update events, we have to use a tristate CheckState. So we can /// be told about an indeterminate state, but we can't set it ourselves. /// /// As of version 2.0, we can now return indeterminate state. /// public delegate CheckState CheckStateGetterDelegate(Object rowObject); /// /// These delegates are used to get the state of the checkbox for a row object. /// /// /// public delegate bool BooleanCheckStateGetterDelegate(Object rowObject); /// /// These delegates are used to put a changed check state back into a model object /// public delegate CheckState CheckStatePutterDelegate(Object rowObject, CheckState newValue); /// /// These delegates are used to put a changed check state back into a model object /// /// /// /// public delegate bool BooleanCheckStatePutterDelegate(Object rowObject, bool newValue); /// /// These delegates are used to get the renderer for a particular cell /// public delegate IRenderer CellRendererGetterDelegate(Object rowObject, OLVColumn column); /// /// The callbacks for RightColumnClick events /// public delegate void ColumnRightClickEventHandler(object sender, ColumnClickEventArgs e); /// /// This delegate will be used to own draw header column. /// public delegate bool HeaderDrawingDelegate(Graphics g, Rectangle r, int columnIndex, OLVColumn column, bool isPressed, HeaderStateStyle stateStyle); /// /// This delegate is called when a group has been created but not yet made /// into a real ListViewGroup. The user can take this opportunity to fill /// in lots of other details about the group. /// public delegate void GroupFormatterDelegate(OLVGroup group, GroupingParameters parms); /// /// These delegates are used to retrieve the object that is the key of the group to which the given row belongs. /// public delegate Object GroupKeyGetterDelegate(Object rowObject); /// /// These delegates are used to convert a group key into a title for the group /// public delegate string GroupKeyToTitleConverterDelegate(Object groupKey); /// /// These delegates are used to get the tooltip for a column header /// public delegate String HeaderToolTipGetterDelegate(OLVColumn column); /// /// These delegates are used to fetch the image selector that should be used /// to choose an image for this column. /// public delegate Object ImageGetterDelegate(Object rowObject); /// /// These delegates are used to draw a cell /// public delegate bool RenderDelegate(EventArgs e, Graphics g, Rectangle r, Object rowObject); /// /// These delegates are used to fetch a row object for virtual lists /// public delegate Object RowGetterDelegate(int rowIndex); /// /// These delegates are used to format a listviewitem before it is added to the control. /// public delegate void RowFormatterDelegate(OLVListItem olvItem); /// /// These delegates can be used to return the array of texts that should be searched for text filtering /// public delegate string[] SearchValueGetterDelegate(Object value); /// /// These delegates are used to sort the listview in some custom fashion /// public delegate void SortDelegate(OLVColumn column, SortOrder sortOrder); /// /// These delegates are used to order two strings. /// x cannot be null. y can be null. /// public delegate int StringCompareDelegate(string x, string y); #endregion } ================================================ FILE: source/ObjectListView/Implementation/DragSource.cs ================================================ /* * DragSource.cs - Add drag source functionality to an ObjectListView * * UNFINISHED * * Author: Phillip Piper * Date: 2009-03-17 5:15 PM * * Change log: * v2.3 * 2009-07-06 JPP - Make sure Link is acceptable as an drop effect by default * (since MS didn't make it part of the 'All' value) * v2.2 * 2009-04-15 JPP - Separated DragSource.cs into DropSink.cs * 2009-03-17 JPP - Initial version * * Copyright (C) 2009 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip_piper@bigfoot.com. */ using System; using System.Collections; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Drawing; using System.Drawing.Drawing2D; namespace BrightIdeasSoftware { /// /// An IDragSource controls how drag out from the ObjectListView will behave /// public interface IDragSource { /// /// A drag operation is beginning. Return the data object that will be used /// for data transfer. Return null to prevent the drag from starting. /// /// /// The returned object is later passed to the GetAllowedEffect() and EndDrag() /// methods. /// /// What ObjectListView is being dragged from. /// Which mouse button is down? /// What item was directly dragged by the user? There may be more than just this /// item selected. /// The data object that will be used for data transfer. This will often be a subclass /// of DataObject, but does not need to be. Object StartDrag(ObjectListView olv, MouseButtons button, OLVListItem item); /// /// What operations are possible for this drag? This controls the icon shown during the drag /// /// The data object returned by StartDrag() /// A combination of DragDropEffects flags DragDropEffects GetAllowedEffects(Object dragObject); /// /// The drag operation is complete. Do whatever is necessary to complete the action. /// /// The data object returned by StartDrag() /// The value returned from GetAllowedEffects() void EndDrag(Object dragObject, DragDropEffects effect); } /// /// A do-nothing implementation of IDragSource that can be safely subclassed. /// public class AbstractDragSource : IDragSource { #region IDragSource Members /// /// See IDragSource documentation /// /// /// /// /// public virtual Object StartDrag(ObjectListView olv, MouseButtons button, OLVListItem item) { return null; } /// /// See IDragSource documentation /// /// /// public virtual DragDropEffects GetAllowedEffects(Object data) { return DragDropEffects.None; } /// /// See IDragSource documentation /// /// /// public virtual void EndDrag(Object dragObject, DragDropEffects effect) { } #endregion } /// /// A reasonable implementation of IDragSource that provides normal /// drag source functionality. It creates a data object that supports /// inter-application dragging of text and HTML representation of /// the dragged rows. It can optionally force a refresh of all dragged /// rows when the drag is complete. /// /// Subclasses can override GetDataObject() to add new /// data formats to the data transfer object. public class SimpleDragSource : IDragSource { #region Constructors /// /// Construct a SimpleDragSource /// public SimpleDragSource() { } /// /// Construct a SimpleDragSource that refreshes the dragged rows when /// the drag is complete /// /// public SimpleDragSource(bool refreshAfterDrop) { this.RefreshAfterDrop = refreshAfterDrop; } #endregion #region Public properties /// /// Gets or sets whether the dragged rows should be refreshed when the /// drag operation is complete. /// public bool RefreshAfterDrop { get { return refreshAfterDrop; } set { refreshAfterDrop = value; } } private bool refreshAfterDrop; #endregion #region IDragSource Members /// /// Create a DataObject when the user does a left mouse drag operation. /// See IDragSource for further information. /// /// /// /// /// public virtual Object StartDrag(ObjectListView olv, MouseButtons button, OLVListItem item) { // We only drag on left mouse if (button != MouseButtons.Left) return null; return this.CreateDataObject(olv); } /// /// Which operations are allowed in the operation? By default, all operations are supported. /// /// /// All opertions are supported public virtual DragDropEffects GetAllowedEffects(Object data) { return DragDropEffects.All | DragDropEffects.Link; // why didn't MS include 'Link' in 'All'?? } /// /// The drag operation is finished. Refreshe the dragged rows if so configured. /// /// /// public virtual void EndDrag(Object dragObject, DragDropEffects effect) { OLVDataObject data = dragObject as OLVDataObject; if (data == null) return; if (this.RefreshAfterDrop) data.ListView.RefreshObjects(data.ModelObjects); } /// /// Create a data object that will be used to as the data object /// for the drag operation. /// /// /// Subclasses can override this method add new formats to the data object. /// /// The ObjectListView that is the source of the drag /// A data object for the drag protected virtual object CreateDataObject(ObjectListView olv) { OLVDataObject data = new OLVDataObject(olv); data.CreateTextFormats(); return data; } #endregion } /// /// A data transfer object that knows how to transform a list of model /// objects into a text and HTML representation. /// public class OLVDataObject : DataObject { #region Life and death /// /// Create a data object from the selected objects in the given ObjectListView /// /// The source of the data object public OLVDataObject(ObjectListView olv) : this(olv, olv.SelectedObjects) { } /// /// Create a data object which operates on the given model objects /// in the given ObjectListView /// /// The source of the data object /// The model objects to be put into the data object public OLVDataObject(ObjectListView olv, IList modelObjects) { this.objectListView = olv; this.modelObjects = modelObjects; this.includeHiddenColumns = olv.IncludeHiddenColumnsInDataTransfer; this.includeColumnHeaders = olv.IncludeColumnHeadersInCopy; } #endregion #region Properties /// /// Gets or sets whether hidden columns will also be included in the text /// and HTML representation. If this is false, only visible columns will /// be included. /// public bool IncludeHiddenColumns { get { return includeHiddenColumns; } } private bool includeHiddenColumns; /// /// Gets or sets whether column headers will also be included in the text /// and HTML representation. /// public bool IncludeColumnHeaders { get { return includeColumnHeaders; } } private bool includeColumnHeaders; /// /// Gets the ObjectListView that is being used as the source of the data /// public ObjectListView ListView { get { return objectListView; } } private ObjectListView objectListView; /// /// Gets the model objects that are to be placed in the data object /// public IList ModelObjects { get { return modelObjects; } } private IList modelObjects = new ArrayList(); #endregion /// /// Put a text and HTML representation of our model objects /// into the data object. /// public void CreateTextFormats() { IList columns = this.IncludeHiddenColumns ? this.ListView.AllColumns : this.ListView.ColumnsInDisplayOrder; // Build text and html versions of the selection StringBuilder sbText = new StringBuilder(); StringBuilder sbHtml = new StringBuilder(""); // Include column headers if (includeColumnHeaders) { sbHtml.Append(""); } foreach (object modelObject in this.ModelObjects) { sbHtml.Append(""); } sbHtml.AppendLine("
"); foreach (OLVColumn col in columns) { if (col != columns[0]) { sbText.Append("\t"); sbHtml.Append(""); } string strValue = col.Text; sbText.Append(strValue); sbHtml.Append(strValue); //TODO: Should encode the string value } sbText.AppendLine(); sbHtml.AppendLine("
"); foreach (OLVColumn col in columns) { if (col != columns[0]) { sbText.Append("\t"); sbHtml.Append(""); } string strValue = col.GetStringValue(modelObject); sbText.Append(strValue); sbHtml.Append(strValue); //TODO: Should encode the string value } sbText.AppendLine(); sbHtml.AppendLine("
"); // Put both the text and html versions onto the clipboard. // For some reason, SetText() with UnicodeText doesn't set the basic CF_TEXT format, // but using SetData() does. //this.SetText(sbText.ToString(), TextDataFormat.UnicodeText); this.SetData(sbText.ToString()); this.SetText(ConvertToHtmlFragment(sbHtml.ToString()), TextDataFormat.Html); } /// /// Make a HTML representation of our model objects /// public string CreateHtml() { IList columns = this.ListView.ColumnsInDisplayOrder; // Build html version of the selection StringBuilder sbHtml = new StringBuilder(""); foreach (object modelObject in this.ModelObjects) { sbHtml.Append(""); } sbHtml.AppendLine("
"); foreach (OLVColumn col in columns) { if (col != columns[0]) { sbHtml.Append(""); } string strValue = col.GetStringValue(modelObject); sbHtml.Append(strValue); //TODO: Should encode the string value } sbHtml.AppendLine("
"); return sbHtml.ToString(); } /// /// Convert the fragment of HTML into the Clipboards HTML format. /// /// The HTML format is found here http://msdn2.microsoft.com/en-us/library/aa767917.aspx /// /// The HTML to put onto the clipboard. It must be valid HTML! /// A string that can be put onto the clipboard and will be recognized as HTML private string ConvertToHtmlFragment(string fragment) { // Minimal implementation of HTML clipboard format string source = "http://www.codeproject.com/KB/list/ObjectListView.aspx"; const String MARKER_BLOCK = "Version:1.0\r\n" + "StartHTML:{0,8}\r\n" + "EndHTML:{1,8}\r\n" + "StartFragment:{2,8}\r\n" + "EndFragment:{3,8}\r\n" + "StartSelection:{2,8}\r\n" + "EndSelection:{3,8}\r\n" + "SourceURL:{4}\r\n" + "{5}"; int prefixLength = String.Format(MARKER_BLOCK, 0, 0, 0, 0, source, "").Length; const String DEFAULT_HTML_BODY = "" + "{0}"; string html = String.Format(DEFAULT_HTML_BODY, fragment); int startFragment = prefixLength + html.IndexOf(fragment); int endFragment = startFragment + fragment.Length; return String.Format(MARKER_BLOCK, prefixLength, prefixLength + html.Length, startFragment, endFragment, source, html); } } } ================================================ FILE: source/ObjectListView/Implementation/DropSink.cs ================================================ /* * DropSink.cs - Add drop sink ability to an ObjectListView * * Author: Phillip Piper * Date: 2009-03-17 5:15 PM * * Change log: * 2010-08-24 JPP - Moved AcceptExternal property up to SimpleDragSource. * v2.3 * 2009-09-01 JPP - Correctly handle case where RefreshObjects() is called for * objects that were children but are now roots. * 2009-08-27 JPP - Added ModelDropEventArgs.RefreshObjects() to simplify updating after * a drag-drop operation * 2009-08-19 JPP - Changed to use OlvHitTest() * v2.2.1 * 2007-07-06 JPP - Added StandardDropActionFromKeys property to OlvDropEventArgs * v2.2 * 2009-05-17 JPP - Added a Handled flag to OlvDropEventArgs * - Tweaked the appearance of the drop-on-background feedback * 2009-04-15 JPP - Separated DragDrop.cs into DropSink.cs * 2009-03-17 JPP - Initial version * * Copyright (C) 2009-2010 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip_piper@bigfoot.com. */ using System; using System.Collections; using System.Drawing; using System.Drawing.Drawing2D; using System.Windows.Forms; namespace BrightIdeasSoftware { /// /// Objects that implement this interface can acts as the receiver for drop /// operation for an ObjectListView. /// public interface IDropSink { /// /// Gets or sets the ObjectListView that is the drop sink /// ObjectListView ListView { get; set; } /// /// Draw any feedback that is appropriate to the current drop state. /// /// /// Any drawing is done over the top of the ListView. This operation should disturb /// the Graphic as little as possible. Specifically, do not erase the area into which /// you draw. /// /// A Graphic for drawing /// The contents bounds of the ListView (not including any header) void DrawFeedback(Graphics g, Rectangle bounds); /// /// The user has released the drop over this control /// /// /// Implementators should set args.Effect to the appropriate DragDropEffects. This value is returned /// to the originator of the drag. /// /// void Drop(DragEventArgs args); /// /// A drag has entered this control. /// /// Implementators should set args.Effect to the appropriate DragDropEffects. /// void Enter(DragEventArgs args); /// /// Change the cursor to reflect the current drag operation. /// /// void GiveFeedback(GiveFeedbackEventArgs args); /// /// The drag has left the bounds of this control /// void Leave(); /// /// The drag is moving over this control. /// /// This is where any drop target should be calculated. /// Implementators should set args.Effect to the appropriate DragDropEffects. /// /// void Over(DragEventArgs args); /// /// Should the drag be allowed to continue? /// /// void QueryContinue(QueryContinueDragEventArgs args); } /// /// This is a do-nothing implementation of IDropSink that is a useful /// base class for more sophisticated implementations. /// public class AbstractDropSink : IDropSink { #region IDropSink Members /// /// Gets or sets the ObjectListView that is the drop sink /// public virtual ObjectListView ListView { get { return listView; } set { this.listView = value; } } private ObjectListView listView; /// /// Draw any feedback that is appropriate to the current drop state. /// /// /// Any drawing is done over the top of the ListView. This operation should disturb /// the Graphic as little as possible. Specifically, do not erase the area into which /// you draw. /// /// A Graphic for drawing /// The contents bounds of the ListView (not including any header) public virtual void DrawFeedback(Graphics g, Rectangle bounds) { } /// /// The user has released the drop over this control /// /// /// Implementators should set args.Effect to the appropriate DragDropEffects. This value is returned /// to the originator of the drag. /// /// public virtual void Drop(DragEventArgs args) { this.Cleanup(); } /// /// A drag has entered this control. /// /// Implementators should set args.Effect to the appropriate DragDropEffects. /// public virtual void Enter(DragEventArgs args) { } /// /// The drag has left the bounds of this control /// public virtual void Leave() { this.Cleanup(); } /// /// The drag is moving over this control. /// /// This is where any drop target should be calculated. /// Implementators should set args.Effect to the appropriate DragDropEffects. /// /// public virtual void Over(DragEventArgs args) { } /// /// Change the cursor to reflect the current drag operation. /// /// You only need to override this if you want non-standard cursors. /// The standard cursors are supplied automatically. /// public virtual void GiveFeedback(GiveFeedbackEventArgs args) { args.UseDefaultCursors = true; } /// /// Should the drag be allowed to continue? /// /// /// You only need to override this if you want the user to be able /// to end the drop in some non-standard way, e.g. dragging to a /// certain point even without releasing the mouse, or going outside /// the bounds of the application. /// /// public virtual void QueryContinue(QueryContinueDragEventArgs args) { } #endregion #region Commands /// /// This is called when the mouse leaves the drop region and after the /// drop has completed. /// protected virtual void Cleanup() { } #endregion } /// /// The enum indicates which target has been found for a drop operation /// [Flags] public enum DropTargetLocation { /// /// No applicable target has been found /// None = 0, /// /// The list itself is the target of the drop /// Background = 0x01, /// /// An item is the target /// Item = 0x02, /// /// Between two items (or above the top item or below the bottom item) /// can be the target. This is not actually ever a target, only a value indicate /// that it is valid to drop between items /// BetweenItems = 0x04, /// /// Above an item is the target /// AboveItem = 0x08, /// /// Below an item is the target /// BelowItem = 0x10, /// /// A subitem is the target of the drop /// SubItem = 0x20, /// /// On the right of an item is the target (not currently used) /// RightOfItem = 0x40, /// /// On the left of an item is the target (not currently used) /// LeftOfItem = 0x80 } /// /// This class represents a simple implementation of a drop sink. /// /// /// Actually, it's far from simple and can do quite a lot in its own right. /// public class SimpleDropSink : AbstractDropSink { #region Life and death /// /// Make a new drop sink /// public SimpleDropSink() { this.timer = new Timer(); this.timer.Interval = 250; this.timer.Tick += new EventHandler(this.timer_Tick); this.CanDropOnItem = true; //this.CanDropOnSubItem = true; //this.CanDropOnBackground = true; //this.CanDropBetween = true; this.FeedbackColor = Color.FromArgb(180, Color.MediumBlue); this.billboard = new BillboardOverlay(); } #endregion #region Public properties /// /// Get or set the locations where a drop is allowed to occur (OR-ed together) /// public DropTargetLocation AcceptableLocations { get { return this.acceptableLocations; } set { this.acceptableLocations = value; } } private DropTargetLocation acceptableLocations; /// /// Gets or sets whether this sink allows model objects to be dragged from other lists /// public bool AcceptExternal { get { return this.acceptExternal; } set { this.acceptExternal = value; } } private bool acceptExternal = true; /// /// Gets or sets whether the ObjectListView should scroll when the user drags /// something near to the top or bottom rows. /// public bool AutoScroll { get { return this.autoScroll; } set { this.autoScroll = value; } } private bool autoScroll = true; /// /// Gets the billboard overlay that will be used to display feedback /// messages during a drag operation. /// /// Set this to null to stop the feedback. public BillboardOverlay Billboard { get { return this.billboard; } set { this.billboard = value; } } private BillboardOverlay billboard; /// /// Get or set whether a drop can occur between items of the list /// public bool CanDropBetween { get { return (this.AcceptableLocations & DropTargetLocation.BetweenItems) == DropTargetLocation.BetweenItems; } set { if (value) this.AcceptableLocations |= DropTargetLocation.BetweenItems; else this.AcceptableLocations &= ~DropTargetLocation.BetweenItems; } } /// /// Get or set whether a drop can occur on the listview itself /// public bool CanDropOnBackground { get { return (this.AcceptableLocations & DropTargetLocation.Background) == DropTargetLocation.Background; } set { if (value) this.AcceptableLocations |= DropTargetLocation.Background; else this.AcceptableLocations &= ~DropTargetLocation.Background; } } /// /// Get or set whether a drop can occur on items in the list /// public bool CanDropOnItem { get { return (this.AcceptableLocations & DropTargetLocation.Item) == DropTargetLocation.Item; } set { if (value) this.AcceptableLocations |= DropTargetLocation.Item; else this.AcceptableLocations &= ~DropTargetLocation.Item; } } /// /// Get or set whether a drop can occur on a subitem in the list /// public bool CanDropOnSubItem { get { return (this.AcceptableLocations & DropTargetLocation.SubItem) == DropTargetLocation.SubItem; } set { if (value) this.AcceptableLocations |= DropTargetLocation.SubItem; else this.AcceptableLocations &= ~DropTargetLocation.SubItem; } } /// /// Get or set the index of the item that is the target of the drop /// public int DropTargetIndex { get { return dropTargetIndex; } set { if (this.dropTargetIndex != value) { this.dropTargetIndex = value; this.ListView.Invalidate(); } } } private int dropTargetIndex = -1; /// /// Get the item that is the target of the drop /// public OLVListItem DropTargetItem { get { return this.ListView.GetItem(this.DropTargetIndex); } } /// /// Get or set the location of the target of the drop /// public DropTargetLocation DropTargetLocation { get { return dropTargetLocation; } set { if (this.dropTargetLocation != value) { this.dropTargetLocation = value; this.ListView.Invalidate(); } } } private DropTargetLocation dropTargetLocation; /// /// Get or set the index of the subitem that is the target of the drop /// public int DropTargetSubItemIndex { get { return dropTargetSubItemIndex; } set { if (this.dropTargetSubItemIndex != value) { this.dropTargetSubItemIndex = value; this.ListView.Invalidate(); } } } private int dropTargetSubItemIndex = -1; /// /// Get or set the color that will be used to provide drop feedback /// public Color FeedbackColor { get { return this.feedbackColor; } set { this.feedbackColor = value; } } private Color feedbackColor; /// /// Get whether the alt key was down during this drop event /// public bool IsAltDown { get { return (this.KeyState & 32) == 32; } } /// /// Get whether any modifier key was down during this drop event /// public bool IsAnyModifierDown { get { return (this.KeyState & (4 + 8 + 32)) != 0; } } /// /// Get whether the control key was down during this drop event /// public bool IsControlDown { get { return (this.KeyState & 8) == 8; } } /// /// Get whether the left mouse button was down during this drop event /// public bool IsLeftMouseButtonDown { get { return (this.KeyState & 1) == 1; } } /// /// Get whether the right mouse button was down during this drop event /// public bool IsMiddleMouseButtonDown { get { return (this.KeyState & 16) == 16; } } /// /// Get whether the right mouse button was down during this drop event /// public bool IsRightMouseButtonDown { get { return (this.KeyState & 2) == 2; } } /// /// Get whether the shift key was down during this drop event /// public bool IsShiftDown { get { return (this.KeyState & 4) == 4; } } /// /// Get or set the state of the keys during this drop event /// public int KeyState { get { return this.keyState; } set { this.keyState = value; } } private int keyState; #endregion #region Events /// /// Triggered when the sink needs to know if a drop can occur. /// /// /// Handlers should set Effect to indicate what is possible. /// Handlers can change any of the DropTarget* setttings to change /// the target of the drop. /// public event EventHandler CanDrop; /// /// Triggered when the drop is made. /// public event EventHandler Dropped; /// /// Triggered when the sink needs to know if a drop can occur /// AND the source is an ObjectListView /// /// /// Handlers should set Effect to indicate what is possible. /// Handlers can change any of the DropTarget* setttings to change /// the target of the drop. /// public event EventHandler ModelCanDrop; /// /// Triggered when the drop is made. /// AND the source is an ObjectListView /// public event EventHandler ModelDropped; #endregion #region DropSink Interface /// /// Cleanup the drop sink when the mouse has left the control or /// the drag has finished. /// protected override void Cleanup() { this.DropTargetLocation = DropTargetLocation.None; this.ListView.FullRowSelect = this.originalFullRowSelect; this.Billboard.Text = null; } /// /// Draw any feedback that is appropriate to the current drop state. /// /// /// Any drawing is done over the top of the ListView. This operation should disturb /// the Graphic as little as possible. Specifically, do not erase the area into which /// you draw. /// /// A Graphic for drawing /// The contents bounds of the ListView (not including any header) public override void DrawFeedback(Graphics g, Rectangle bounds) { g.SmoothingMode = ObjectListView.SmoothingMode; switch (this.DropTargetLocation) { case DropTargetLocation.Background: this.DrawFeedbackBackgroundTarget(g, bounds); break; case DropTargetLocation.Item: this.DrawFeedbackItemTarget(g, bounds); break; case DropTargetLocation.AboveItem: this.DrawFeedbackAboveItemTarget(g, bounds); break; case DropTargetLocation.BelowItem: this.DrawFeedbackBelowItemTarget(g, bounds); break; } if (this.Billboard != null) { this.Billboard.Draw(this.ListView, g, bounds); } } /// /// The user has released the drop over this control /// /// public override void Drop(DragEventArgs args) { this.TriggerDroppedEvent(args); this.timer.Stop(); this.Cleanup(); } /// /// A drag has entered this control. /// /// Implementators should set args.Effect to the appropriate DragDropEffects. /// public override void Enter(DragEventArgs args) { //System.Diagnostics.Debug.WriteLine("Enter"); /* * When FullRowSelect is true, we have two problems: * 1) GetItemRect(ItemOnly) returns the whole row rather than just the icon/text, which messes * up our calculation of the drop rectangle. * 2) during the drag, the Timer events will not fire! This is the major problem, since without * those events we can't autoscroll. * * The first problem we can solve through coding, but the second is more difficult. * We avoid both problems by turning off FullRowSelect during the drop operation. */ this.originalFullRowSelect = this.ListView.FullRowSelect; this.ListView.FullRowSelect = false; // Setup our drop event args block this.dropEventArgs = new ModelDropEventArgs(); this.dropEventArgs.DropSink = this; this.dropEventArgs.ListView = this.ListView; this.dropEventArgs.DataObject = args.Data; OLVDataObject olvData = args.Data as OLVDataObject; if (olvData != null) { this.dropEventArgs.SourceListView = olvData.ListView; this.dropEventArgs.SourceModels = olvData.ModelObjects; } this.Over(args); } /// /// The drag is moving over this control. /// /// public override void Over(DragEventArgs args) { //System.Diagnostics.Debug.WriteLine("Over"); this.KeyState = args.KeyState; Point pt = this.ListView.PointToClient(new Point(args.X, args.Y)); args.Effect = this.CalculateDropAction(args, pt); this.CheckScrolling(pt); } #endregion #region Events /// /// Trigger the Dropped events /// /// protected virtual void TriggerDroppedEvent(DragEventArgs args) { this.dropEventArgs.Handled = false; // If the source is an ObjectListView, trigger the ModelDropped event if (this.dropEventArgs.SourceListView != null) this.OnModelDropped(this.dropEventArgs); if (!this.dropEventArgs.Handled) this.OnDropped(this.dropEventArgs); } /// /// Trigger CanDrop /// /// protected virtual void OnCanDrop(OlvDropEventArgs args) { if (this.CanDrop != null) this.CanDrop(this, args); } /// /// Trigger Dropped /// /// protected virtual void OnDropped(OlvDropEventArgs args) { if (this.Dropped != null) this.Dropped(this, args); } /// /// Trigger ModelCanDrop /// /// protected virtual void OnModelCanDrop(ModelDropEventArgs args) { // Don't allow drops from other list, if that's what's configured if (!this.AcceptExternal && args.SourceListView != null && args.SourceListView != this.ListView) { args.Effect = DragDropEffects.None; args.DropTargetLocation = DropTargetLocation.None; args.InfoMessage = "This list doesn't accept drops from other lists"; return; } if (this.ModelCanDrop != null) this.ModelCanDrop(this, args); } /// /// Trigger ModelDropped /// /// protected virtual void OnModelDropped(ModelDropEventArgs args) { if (this.ModelDropped != null) this.ModelDropped(this, args); } #endregion #region Implementation private void timer_Tick(object sender, EventArgs e) { this.HandleTimerTick(); } /// /// Handle the timer tick event, which is sent when the listview should /// scroll /// protected virtual void HandleTimerTick() { // If the mouse has been released, stop scrolling. // This is only necessary if the mouse is released outside of the control. // If the mouse is released inside the control, we would receive a Drop event. if ((this.IsLeftMouseButtonDown && (Control.MouseButtons & MouseButtons.Left) != MouseButtons.Left) || (this.IsMiddleMouseButtonDown && (Control.MouseButtons & MouseButtons.Middle) != MouseButtons.Middle) || (this.IsRightMouseButtonDown && (Control.MouseButtons & MouseButtons.Right) != MouseButtons.Right)) { this.timer.Stop(); this.Cleanup(); return; } // Auto scrolling will continune while the mouse is close to the ListView const int GRACE_PERIMETER = 30; Point pt = this.ListView.PointToClient(Cursor.Position); Rectangle r2 = this.ListView.ClientRectangle; r2.Inflate(GRACE_PERIMETER, GRACE_PERIMETER); if (r2.Contains(pt)) { this.ListView.LowLevelScroll(0, this.scrollAmount); } } /// /// When the mouse is at the given point, what should the target of the drop be? /// /// This method should update the DropTarget* members of the given arg block /// /// The mouse point, in client co-ordinates protected virtual void CalculateDropTarget(OlvDropEventArgs args, Point pt) { const int SMALL_VALUE = 3; DropTargetLocation location = DropTargetLocation.None; int targetIndex = -1; int targetSubIndex = 0; if (this.CanDropOnBackground) location = DropTargetLocation.Background; // Which item is the mouse over? // If it is not over any item, it's over the background. //ListViewHitTestInfo info = this.ListView.HitTest(pt.X, pt.Y); OlvListViewHitTestInfo info = this.ListView.OlvHitTest(pt.X, pt.Y); if (info.Item != null && this.CanDropOnItem) { location = DropTargetLocation.Item; targetIndex = info.Item.Index; if (info.SubItem != null && this.CanDropOnSubItem) targetSubIndex = info.Item.SubItems.IndexOf(info.SubItem); } // Check to see if the mouse is "between" rows. // ("between" is somewhat loosely defined) if (this.CanDropBetween && this.ListView.GetItemCount() > 0) { // If the mouse is over an item, check to see if it is near the top or bottom if (location == DropTargetLocation.Item) { if (pt.Y - SMALL_VALUE <= info.Item.Bounds.Top) location = DropTargetLocation.AboveItem; if (pt.Y + SMALL_VALUE >= info.Item.Bounds.Bottom) location = DropTargetLocation.BelowItem; } else { // Is there an item a little below the mouse? // If so, we say the drop point is above that row info = this.ListView.OlvHitTest(pt.X, pt.Y + SMALL_VALUE); if (info.Item != null) { targetIndex = info.Item.Index; location = DropTargetLocation.AboveItem; } else { // Is there an item a little above the mouse? info = this.ListView.OlvHitTest(pt.X, pt.Y - SMALL_VALUE); if (info.Item != null) { targetIndex = info.Item.Index; location = DropTargetLocation.BelowItem; } } } } args.DropTargetLocation = location; args.DropTargetIndex = targetIndex; args.DropTargetSubItemIndex = targetSubIndex; } /// /// What sort of action is possible when the mouse is at the given point? /// /// /// /// /// /// public virtual DragDropEffects CalculateDropAction(DragEventArgs args, Point pt) { this.CalculateDropTarget(this.dropEventArgs, pt); this.dropEventArgs.MouseLocation = pt; this.dropEventArgs.InfoMessage = null; this.dropEventArgs.Handled = false; if (this.dropEventArgs.SourceListView != null) { this.dropEventArgs.TargetModel = this.ListView.GetModelObject(this.dropEventArgs.DropTargetIndex); this.OnModelCanDrop(this.dropEventArgs); } if (!this.dropEventArgs.Handled) this.OnCanDrop(this.dropEventArgs); this.UpdateAfterCanDropEvent(this.dropEventArgs); return this.dropEventArgs.Effect; } /// /// Based solely on the state of the modifier keys, what drop operation should /// be used? /// /// The drop operation that matches the state of the keys public DragDropEffects CalculateStandardDropActionFromKeys() { if (this.IsControlDown) { if (this.IsShiftDown) return DragDropEffects.Link; else return DragDropEffects.Copy; } else { return DragDropEffects.Move; } } /// /// Should the listview be made to scroll when the mouse is at the given point? /// /// protected virtual void CheckScrolling(Point pt) { if (!this.AutoScroll) return; Rectangle r = this.ListView.ContentRectangle; int rowHeight = this.ListView.RowHeightEffective; int close = rowHeight; // In Tile view, using the whole row height is too much if (this.ListView.View == View.Tile) close /= 2; if (pt.Y <= (r.Top + close)) { // Scroll faster if the mouse is closer to the top this.timer.Interval = ((pt.Y <= (r.Top + close / 2)) ? 100 : 350); this.timer.Start(); this.scrollAmount = -rowHeight; } else { if (pt.Y >= (r.Bottom - close)) { this.timer.Interval = ((pt.Y >= (r.Bottom - close / 2)) ? 100 : 350); this.timer.Start(); this.scrollAmount = rowHeight; } else { this.timer.Stop(); } } } /// /// Update the state of our sink to reflect the information that /// may have been written into the drop event args. /// /// protected virtual void UpdateAfterCanDropEvent(OlvDropEventArgs args) { this.DropTargetIndex = args.DropTargetIndex; this.DropTargetLocation = args.DropTargetLocation; this.DropTargetSubItemIndex = args.DropTargetSubItemIndex; if (this.Billboard != null) { Point pt = args.MouseLocation; pt.Offset(5, 5); if (this.Billboard.Text != this.dropEventArgs.InfoMessage || this.Billboard.Location != pt) { this.Billboard.Text = this.dropEventArgs.InfoMessage; this.Billboard.Location = pt; this.ListView.Invalidate(); } } } #endregion #region Rendering /// /// Draw the feedback that shows that the background is the target /// /// /// protected virtual void DrawFeedbackBackgroundTarget(Graphics g, Rectangle bounds) { float penWidth = 12.0f; Rectangle r = bounds; r.Inflate((int)-penWidth / 2, (int)-penWidth / 2); using (Pen p = new Pen(Color.FromArgb(128, this.FeedbackColor), penWidth)) { using (GraphicsPath path = this.GetRoundedRect(r, 30.0f)) { g.DrawPath(p, path); } } } /// /// Draw the feedback that shows that an item (or a subitem) is the target /// /// /// /// /// DropTargetItem and DropTargetSubItemIndex tells what is the target /// protected virtual void DrawFeedbackItemTarget(Graphics g, Rectangle bounds) { if (this.DropTargetItem == null) return; Rectangle r = this.CalculateDropTargetRectangle(this.DropTargetItem, this.DropTargetSubItemIndex); r.Inflate(1, 1); float diameter = r.Height / 3; using (GraphicsPath path = this.GetRoundedRect(r, diameter)) { using (SolidBrush b = new SolidBrush(Color.FromArgb(48, this.FeedbackColor))) { g.FillPath(b, path); } using (Pen p = new Pen(this.FeedbackColor, 3.0f)) { g.DrawPath(p, path); } } } /// /// Draw the feedback that shows the drop will occur before target /// /// /// protected virtual void DrawFeedbackAboveItemTarget(Graphics g, Rectangle bounds) { if (this.DropTargetItem == null) return; Rectangle r = this.CalculateDropTargetRectangle(this.DropTargetItem, this.DropTargetSubItemIndex); this.DrawBetweenLine(g, r.Left, r.Top, r.Right, r.Top); } /// /// Draw the feedback that shows the drop will occur after target /// /// /// protected virtual void DrawFeedbackBelowItemTarget(Graphics g, Rectangle bounds) { if (this.DropTargetItem == null) return; Rectangle r = this.CalculateDropTargetRectangle(this.DropTargetItem, this.DropTargetSubItemIndex); this.DrawBetweenLine(g, r.Left, r.Bottom, r.Right, r.Bottom); } /// /// Return a GraphicPath that is round corner rectangle. /// /// /// /// protected GraphicsPath GetRoundedRect(Rectangle rect, float diameter) { GraphicsPath path = new GraphicsPath(); RectangleF arc = new RectangleF(rect.X, rect.Y, diameter, diameter); path.AddArc(arc, 180, 90); arc.X = rect.Right - diameter; path.AddArc(arc, 270, 90); arc.Y = rect.Bottom - diameter; path.AddArc(arc, 0, 90); arc.X = rect.Left; path.AddArc(arc, 90, 90); path.CloseFigure(); return path; } /// /// Calculate the target rectangle when the given item (and possible subitem) /// is the target of the drop. /// /// /// /// protected virtual Rectangle CalculateDropTargetRectangle(OLVListItem item, int subItem) { if (subItem > 0) return item.SubItems[subItem].Bounds; Rectangle r = this.ListView.CalculateCellTextBounds(item, subItem); // Allow for indent if (item.IndentCount > 0) { int indentWidth = this.ListView.SmallImageSize.Width; r.X += (indentWidth * item.IndentCount); r.Width -= (indentWidth * item.IndentCount); } return r; } /// /// Draw a "between items" line at the given co-ordinates /// /// /// /// /// /// protected virtual void DrawBetweenLine(Graphics g, int x1, int y1, int x2, int y2) { using (Brush b = new SolidBrush(this.FeedbackColor)) { int x = x1; int y = y1; using (GraphicsPath gp = new GraphicsPath()) { gp.AddLine( x, y + 5, x, y - 5); gp.AddBezier( x, y - 6, x + 3, y - 2, x + 6, y - 1, x + 11, y); gp.AddBezier( x + 11, y, x + 6, y + 1, x + 3, y + 2, x, y + 6); gp.CloseFigure(); g.FillPath(b, gp); } x = x2; y = y2; using (GraphicsPath gp = new GraphicsPath()) { gp.AddLine( x, y + 6, x, y - 6); gp.AddBezier( x, y - 7, x - 3, y - 2, x - 6, y - 1, x - 11, y); gp.AddBezier( x - 11, y, x - 6, y + 1, x - 3, y + 2, x, y + 7); gp.CloseFigure(); g.FillPath(b, gp); } } using (Pen p = new Pen(this.FeedbackColor, 3.0f)) { g.DrawLine(p, x1, y1, x2, y2); } } #endregion private Timer timer; private int scrollAmount; private bool originalFullRowSelect; private ModelDropEventArgs dropEventArgs; } /// /// This drop sink allows items within the same list to be rearranged, /// as well as allowing items to be dropped from other lists. /// /// /// /// This class can only be used on plain ObjectListViews and FastObjectListViews. /// The other flavours have no way to implement the insert operation that is required. /// /// /// This class does not work with grouping. /// /// /// This class works when the OLV is sorted, but it is up to the programmer /// to decide what rearranging such lists "means". Example: if the control is sorting /// students by academic grade, and the user drags a "Fail" grade student up amonst the "A+" /// students, it is the responsibility of the programmer to makes the appropriate changes /// to the model and redraw/rebuild the control so that the users action makes sense. /// /// /// Users of this class should listen for the CanDrop event to decide /// if models from another OLV can be moved to OLV under this sink. /// /// public class RearrangingDropSink : SimpleDropSink { /// /// Create a RearrangingDropSink /// public RearrangingDropSink() { this.CanDropBetween = true; this.CanDropOnBackground = true; this.CanDropOnItem = false; } /// /// Create a RearrangingDropSink /// /// public RearrangingDropSink(bool acceptDropsFromOtherLists) : this() { this.AcceptExternal = acceptDropsFromOtherLists; } /// /// Trigger OnModelCanDrop /// /// protected override void OnModelCanDrop(ModelDropEventArgs args) { base.OnModelCanDrop(args); if (args.Handled) return; args.Effect = DragDropEffects.Move; // Don't allow drops from other list, if that's what's configured if (!this.AcceptExternal && args.SourceListView != this.ListView) { args.Effect = DragDropEffects.None; args.DropTargetLocation = DropTargetLocation.None; args.InfoMessage = "This list doesn't accept drops from other lists"; } // If we are rearranging a list, don't allow drops on the background if (args.DropTargetLocation == DropTargetLocation.Background && args.SourceListView == this.ListView) { args.Effect = DragDropEffects.None; args.DropTargetLocation = DropTargetLocation.None; } } /// /// Trigger OnModelDropped /// /// protected override void OnModelDropped(ModelDropEventArgs args) { base.OnModelDropped(args); if (!args.Handled) this.RearrangeModels(args); } /// /// Do the work of processing the dropped items /// /// public virtual void RearrangeModels(ModelDropEventArgs args) { switch (args.DropTargetLocation) { case DropTargetLocation.AboveItem: this.ListView.MoveObjects(args.DropTargetIndex, args.SourceModels); break; case DropTargetLocation.BelowItem: this.ListView.MoveObjects(args.DropTargetIndex + 1, args.SourceModels); break; case DropTargetLocation.Background: this.ListView.AddObjects(args.SourceModels); break; default: return; } if (args.SourceListView != this.ListView) { args.SourceListView.RemoveObjects(args.SourceModels); } } } /// /// When a drop sink needs to know if something can be dropped, or /// to notify that a drop has occured, it uses an instance of this class. /// public class OlvDropEventArgs : EventArgs { /// /// Create a OlvDropEventArgs /// public OlvDropEventArgs() { } #region Data Properties /// /// Get the data object that is being dragged /// public object DataObject { get { return this.dataObject; } internal set { this.dataObject = value; } } private object dataObject; /// /// Get the drop sink that originated this event /// public SimpleDropSink DropSink { get { return this.dropSink; } internal set { this.dropSink = value; } } private SimpleDropSink dropSink; /// /// Get or set the index of the item that is the target of the drop /// public int DropTargetIndex { get { return dropTargetIndex; } set { this.dropTargetIndex = value; } } private int dropTargetIndex = -1; /// /// Get or set the location of the target of the drop /// public DropTargetLocation DropTargetLocation { get { return dropTargetLocation; } set { this.dropTargetLocation = value; } } private DropTargetLocation dropTargetLocation; /// /// Get or set the index of the subitem that is the target of the drop /// public int DropTargetSubItemIndex { get { return dropTargetSubItemIndex; } set { this.dropTargetSubItemIndex = value; } } private int dropTargetSubItemIndex = -1; /// /// Get the item that is the target of the drop /// public OLVListItem DropTargetItem { get { return this.ListView.GetItem(this.DropTargetIndex); } set { if (value == null) this.DropTargetIndex = -1; else this.DropTargetIndex = value.Index; } } /// /// Get or set the drag effect that should be used for this operation /// public DragDropEffects Effect { get { return this.effect; } set { this.effect = value; } } private DragDropEffects effect; /// /// Get or set if this event was handled. No further processing will be done for a handled event. /// public bool Handled { get { return this.handled; } set { this.handled = value; } } private bool handled; /// /// Get or set the feedback message for this operation /// /// /// If this is not null, it will be displayed as a feedback message /// during the drag. /// public string InfoMessage { get { return this.infoMessage; } set { this.infoMessage = value; } } private string infoMessage; /// /// Get the ObjectListView that is being dropped on /// public ObjectListView ListView { get { return this.listView; } internal set { this.listView = value; } } private ObjectListView listView; /// /// Get the location of the mouse (in target ListView co-ords) /// public Point MouseLocation { get { return this.mouseLocation; } internal set { this.mouseLocation = value; } } private Point mouseLocation; /// /// Get the drop action indicated solely by the state of the modifier keys /// public DragDropEffects StandardDropActionFromKeys { get { return this.DropSink.CalculateStandardDropActionFromKeys(); } } #endregion } /// /// These events are triggered when the drag source is an ObjectListView. /// public class ModelDropEventArgs : OlvDropEventArgs { /// /// Create a ModelDropEventArgs /// public ModelDropEventArgs() { } /// /// Gets the model objects that are being dragged. /// public IList SourceModels { get { return this.dragModels; } internal set { this.dragModels = value; TreeListView tlv = this.SourceListView as TreeListView; if (tlv != null) { foreach (object model in this.SourceModels) { object parent = tlv.GetParent(model); if (!toBeRefreshed.Contains(parent)) toBeRefreshed.Add(parent); } } } } private IList dragModels; private ArrayList toBeRefreshed = new ArrayList(); /// /// Gets the ObjectListView that is the source of the dragged objects. /// public ObjectListView SourceListView { get { return this.sourceListView; } internal set { this.sourceListView = value; } } private ObjectListView sourceListView; /// /// Get the model object that is being dropped upon. /// /// This is only value for TargetLocation == Item public object TargetModel { get { return this.targetModel; } internal set { this.targetModel = value; } } private object targetModel; /// /// Refresh all the objects involved in the operation /// public void RefreshObjects() { TreeListView tlv = this.SourceListView as TreeListView; if (tlv != null) { foreach (object model in this.SourceModels) { object parent = tlv.GetParent(model); if (!toBeRefreshed.Contains(parent)) toBeRefreshed.Add(parent); } } toBeRefreshed.AddRange(this.SourceModels); if (this.ListView == this.SourceListView) { toBeRefreshed.Add(this.TargetModel); this.ListView.RefreshObjects(toBeRefreshed); } else { this.SourceListView.RefreshObjects(toBeRefreshed); this.ListView.RefreshObject(this.TargetModel); } } } } ================================================ FILE: source/ObjectListView/Implementation/Enums.cs ================================================ /* * Enums - All enum definitions used in ObjectListView * * Author: Phillip Piper * Date: 31-March-2011 5:53 pm * * Change log: * 2011-03-31 JPP - Split into its own file * * Copyright (C) 2011-2014 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ namespace BrightIdeasSoftware { public partial class ObjectListView { /// /// How does a user indicate that they want to edit cells? /// public enum CellEditActivateMode { /// /// This list cannot be edited. F2 does nothing. /// None = 0, /// /// A single click on a subitem will edit the value. Single clicking the primary column, /// selects the row just like normal. The user must press F2 to edit the primary column. /// SingleClick = 1, /// /// Double clicking a subitem or the primary column will edit that cell. /// F2 will edit the primary column. /// DoubleClick = 2, /// /// Pressing F2 is the only way to edit the cells. Once the primary column is being edited, /// the other cells in the row can be edited by pressing Tab. /// F2Only = 3, /// /// A single click on a any cell will edit the value, even the primary column. /// SingleClickAlways = 4, } /// /// These values specify how column selection will be presented to the user /// public enum ColumnSelectBehaviour { /// /// No column selection will be presented /// None, /// /// The columns will be show in the main menu /// InlineMenu, /// /// The columns will be shown in a submenu /// Submenu, /// /// A model dialog will be presented to allow the user to choose columns /// ModelDialog, /* * NonModelDialog is just a little bit tricky since the OLV can change views while the dialog is showing * So, just comment this out for the time being. /// /// A non-model dialog will be presented to allow the user to choose columns /// NonModelDialog * */ } } } ================================================ FILE: source/ObjectListView/Implementation/Events.cs ================================================ /* * Events - All the events that can be triggered within an ObjectListView. * * Author: Phillip Piper * Date: 17/10/2008 9:15 PM * * Change log: * v2.8.0 * 2014-05-20 JPP - Added IsHyperlinkEventArgs.IsHyperlink * v2.6 * 2012-04-17 JPP - Added group state change and group expansion events * v2.5 * 2010-08-08 JPP - CellEdit validation and finish events now have NewValue property. * v2.4 * 2010-03-04 JPP - Added filtering events * v2.3 * 2009-08-16 JPP - Added group events * 2009-08-08 JPP - Added HotItem event * 2009-07-24 JPP - Added Hyperlink events * - Added Formatting events * v2.2.1 * 2009-06-13 JPP - Added Cell events * - Moved all event parameter blocks to this file. * - Added Handled property to AfterSearchEventArgs * v2.2 * 2009-06-01 JPP - Added ColumnToGroupBy and GroupByOrder to sorting events - Gave all event descriptions * 2009-04-23 JPP - Added drag drop events * v2.1 * 2009-01-18 JPP - Moved SelectionChanged event to this file * v2.0 * 2008-12-06 JPP - Added searching events * 2008-12-01 JPP - Added secondary sort information to Before/AfterSorting events * 2008-10-17 JPP - Separated from ObjectListView.cs * * Copyright (C) 2006-2014 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Windows.Forms; namespace BrightIdeasSoftware { /// /// The callbacks for CellEditing events /// /// this /// We could replace this with EventHandler<CellEditEventArgs> but that would break all /// cell editing event code from v1.x. /// public delegate void CellEditEventHandler(object sender, CellEditEventArgs e); public partial class ObjectListView { //----------------------------------------------------------------------------------- #region Events /// /// Triggered after a ObjectListView has been searched by the user typing into the list /// [Category("ObjectListView"), Description("This event is triggered after the control has done a search-by-typing action.")] public event EventHandler AfterSearching; /// /// Triggered after a ObjectListView has been sorted /// [Category("ObjectListView"), Description("This event is triggered after the items in the list have been sorted.")] public event EventHandler AfterSorting; /// /// Triggered before a ObjectListView is searched by the user typing into the list /// /// /// Set Cancelled to true to prevent the searching from taking place. /// Changing StringToFind or StartSearchFrom will change the subsequent search. /// [Category("ObjectListView"), Description("This event is triggered before the control does a search-by-typing action.")] public event EventHandler BeforeSearching; /// /// Triggered before a ObjectListView is sorted /// /// /// Set Cancelled to true to prevent the sort from taking place. /// Changing ColumnToSort or SortOrder will change the subsequent sort. /// [Category("ObjectListView"), Description("This event is triggered before the items in the list are sorted.")] public event EventHandler BeforeSorting; /// /// Triggered after a ObjectListView has created groups /// [Category("ObjectListView"), Description("This event is triggered after the groups are created.")] public event EventHandler AfterCreatingGroups; /// /// Triggered before a ObjectListView begins to create groups /// /// /// Set Groups to prevent the default group creation process /// [Category("ObjectListView"), Description("This event is triggered before the groups are created.")] public event EventHandler BeforeCreatingGroups; /// /// Triggered just before a ObjectListView creates groups /// /// /// You can make changes to the groups, which have been created, before those /// groups are created within the listview. /// [Category("ObjectListView"), Description("This event is triggered when the groups are just about to be created.")] public event EventHandler AboutToCreateGroups; /// /// Triggered when a button in a cell is left clicked. /// [Category("ObjectListView"), Description("This event is triggered when the user left clicks a button.")] public event EventHandler ButtonClick; /// /// This event is triggered when the user moves a drag over an ObjectListView that /// has a SimpleDropSink installed as the drop handler. /// /// /// Handlers for this event should set the Effect argument and optionally the /// InfoMsg property. They can also change any of the DropTarget* setttings to change /// the target of the drop. /// [Category("ObjectListView"), Description("Can the user drop the currently dragged items at the current mouse location?")] public event EventHandler CanDrop; /// /// Triggered when a cell has finished being edited. /// [Category("ObjectListView"), Description("This event is triggered cell edit operation has completely finished")] public event CellEditEventHandler CellEditFinished; /// /// Triggered when a cell is about to finish being edited. /// /// If Cancel is already true, the user is cancelling the edit operation. /// Set Cancel to true to prevent the value from the cell being written into the model. /// You cannot prevent the editing from finishing within this event -- you need /// the CellEditValidating event for that. [Category("ObjectListView"), Description("This event is triggered cell edit operation is finishing.")] public event CellEditEventHandler CellEditFinishing; /// /// Triggered when a cell is about to be edited. /// /// Set Cancel to true to prevent the cell being edited. /// You can change the the Control to be something completely different. [Category("ObjectListView"), Description("This event is triggered when cell edit is about to begin.")] public event CellEditEventHandler CellEditStarting; /// /// Triggered when a cell editor needs to be validated /// /// /// If this event is cancelled, focus will remain on the cell editor. /// [Category("ObjectListView"), Description("This event is triggered when a cell editor is about to lose focus and its new contents need to be validated.")] public event CellEditEventHandler CellEditValidating; /// /// Triggered when a cell is left clicked. /// [Category("ObjectListView"), Description("This event is triggered when the user left clicks a cell.")] public event EventHandler CellClick; /// /// Triggered when the mouse is above a cell. /// [Category("ObjectListView"), Description("This event is triggered when the mouse is over a cell.")] public event EventHandler CellOver; /// /// Triggered when a cell is right clicked. /// [Category("ObjectListView"), Description("This event is triggered when the user right clicks a cell.")] public event EventHandler CellRightClick; /// /// This event is triggered when a cell needs a tool tip. /// [Category("ObjectListView"), Description("This event is triggered when a cell needs a tool tip.")] public event EventHandler CellToolTipShowing; /// /// This event is triggered when a checkbox is checked/unchecked on a subitem /// [Category("ObjectListView"), Description("This event is triggered when a checkbox is checked/unchecked on a subitem.")] public event EventHandler SubItemChecking; /// /// Triggered when a column header is right clicked. /// [Category("ObjectListView"), Description("This event is triggered when the user right clicks a column header.")] public event ColumnRightClickEventHandler ColumnRightClick; /// /// This event is triggered when the user releases a drag over an ObjectListView that /// has a SimpleDropSink installed as the drop handler. /// [Category("ObjectListView"), Description("This event is triggered when the user dropped items onto the control.")] public event EventHandler Dropped; /// /// This event is triggered when the control needs to filter its collection of objects. /// [Category("ObjectListView"), Description("This event is triggered when the control needs to filter its collection of objects.")] public event EventHandler Filter; /// /// This event is triggered when a cell needs to be formatted. /// [Category("ObjectListView"), Description("This event is triggered when a cell needs to be formatted.")] public event EventHandler FormatCell; /// /// This event is triggered when the frozeness of the control changes. /// [Category("ObjectListView"), Description("This event is triggered when frozeness of the control changes.")] public event EventHandler Freezing; /// /// This event is triggered when a row needs to be formatted. /// [Category("ObjectListView"), Description("This event is triggered when a row needs to be formatted.")] public event EventHandler FormatRow; /// /// This event is triggered when a group is about to collapse or expand. /// This can be cancelled to prevent the expansion. /// [Category("ObjectListView"), Description("This event is triggered when a group is about to collapse or expand.")] public event EventHandler GroupExpandingCollapsing; /// /// This event is triggered when a group changes state. /// [Category("ObjectListView"), Description("This event is triggered when a group changes state.")] public event EventHandler GroupStateChanged; /// /// This event is triggered when a header checkbox is changing value /// [Category("ObjectListView"), Description("This event is triggered when a header checkbox changes value.")] public event EventHandler HeaderCheckBoxChanging; /// /// This event is triggered when a header needs a tool tip. /// [Category("ObjectListView"), Description("This event is triggered when a header needs a tool tip.")] public event EventHandler HeaderToolTipShowing; /// /// Triggered when the "hot" item changes /// [Category("ObjectListView"), Description("This event is triggered when the hot item changed.")] public event EventHandler HotItemChanged; /// /// Triggered when a hyperlink cell is clicked. /// [Category("ObjectListView"), Description("This event is triggered when a hyperlink cell is clicked.")] public event EventHandler HyperlinkClicked; /// /// Triggered when the task text of a group is clicked. /// [Category("ObjectListView"), Description("This event is triggered when the task text of a group is clicked.")] public event EventHandler GroupTaskClicked; /// /// Is the value in the given cell a hyperlink. /// [Category("ObjectListView"), Description("This event is triggered when the control needs to know if a given cell contains a hyperlink.")] public event EventHandler IsHyperlink; /// /// Some new objects are about to be added to an ObjectListView. /// [Category("ObjectListView"), Description("This event is triggered when objects are about to be added to the control")] public event EventHandler ItemsAdding; /// /// The contents of the ObjectListView has changed. /// [Category("ObjectListView"), Description("This event is triggered when the contents of the control have changed.")] public event EventHandler ItemsChanged; /// /// The contents of the ObjectListView is about to change via a SetObjects call /// /// /// Set Cancelled to true to prevent the contents of the list changing. This does not work with virtual lists. /// [Category("ObjectListView"), Description("This event is triggered when the contents of the control changes.")] public event EventHandler ItemsChanging; /// /// Some objects are about to be removed from an ObjectListView. /// [Category("ObjectListView"), Description("This event is triggered when objects are removed from the control.")] public event EventHandler ItemsRemoving; /// /// This event is triggered when the user moves a drag over an ObjectListView that /// has a SimpleDropSink installed as the drop handler, and when the source control /// for the drag was an ObjectListView. /// /// /// Handlers for this event should set the Effect argument and optionally the /// InfoMsg property. They can also change any of the DropTarget* setttings to change /// the target of the drop. /// [Category("ObjectListView"), Description("Can the dragged collection of model objects be dropped at the current mouse location")] public event EventHandler ModelCanDrop; /// /// This event is triggered when the user releases a drag over an ObjectListView that /// has a SimpleDropSink installed as the drop handler and when the source control /// for the drag was an ObjectListView. /// [Category("ObjectListView"), Description("A collection of model objects from a ObjectListView has been dropped on this control")] public event EventHandler ModelDropped; /// /// This event is triggered once per user action that changes the selection state /// of one or more rows. /// [Category("ObjectListView"), Description("This event is triggered once per user action that changes the selection state of one or more rows.")] public event EventHandler SelectionChanged; /// /// This event is triggered when the contents of the ObjectListView has scrolled. /// [Category("ObjectListView"), Description("This event is triggered when the contents of the ObjectListView has scrolled.")] public event EventHandler Scroll; #endregion //----------------------------------------------------------------------------------- #region OnEvents /// /// /// /// protected virtual void OnAboutToCreateGroups(CreateGroupsEventArgs e) { if (AboutToCreateGroups != null) AboutToCreateGroups(this, e); } /// /// /// /// protected virtual void OnBeforeCreatingGroups(CreateGroupsEventArgs e) { if (BeforeCreatingGroups != null) BeforeCreatingGroups(this, e); } /// /// /// /// protected virtual void OnAfterCreatingGroups(CreateGroupsEventArgs e) { if (AfterCreatingGroups != null) AfterCreatingGroups(this, e); } /// /// /// /// protected virtual void OnAfterSearching(AfterSearchingEventArgs e) { if (AfterSearching != null) AfterSearching(this, e); } /// /// /// /// protected virtual void OnAfterSorting(AfterSortingEventArgs e) { if (AfterSorting != null) AfterSorting(this, e); } /// /// /// /// protected virtual void OnBeforeSearching(BeforeSearchingEventArgs e) { if (BeforeSearching != null) BeforeSearching(this, e); } /// /// /// /// protected virtual void OnBeforeSorting(BeforeSortingEventArgs e) { if (BeforeSorting != null) BeforeSorting(this, e); } /// /// /// /// protected virtual void OnButtonClick(CellClickEventArgs args) { if (ButtonClick != null) ButtonClick(this, args); } /// /// /// /// protected virtual void OnCanDrop(OlvDropEventArgs args) { if (CanDrop != null) CanDrop(this, args); } /// /// /// /// protected virtual void OnCellClick(CellClickEventArgs args) { if (CellClick != null) CellClick(this, args); } /// /// /// /// protected virtual void OnCellOver(CellOverEventArgs args) { if (CellOver != null) CellOver(this, args); } /// /// /// /// protected virtual void OnCellRightClick(CellRightClickEventArgs args) { if (CellRightClick != null) CellRightClick(this, args); } /// /// /// /// protected virtual void OnCellToolTip(ToolTipShowingEventArgs args) { if (CellToolTipShowing != null) CellToolTipShowing(this, args); } /// /// /// /// protected virtual void OnSubItemChecking(SubItemCheckingEventArgs args) { if (SubItemChecking != null) SubItemChecking(this, args); } /// /// /// /// protected virtual void OnColumnRightClick(ColumnClickEventArgs e) { if (ColumnRightClick != null) ColumnRightClick(this, e); } /// /// /// /// protected virtual void OnDropped(OlvDropEventArgs args) { if (Dropped != null) Dropped(this, args); } /// /// /// /// internal protected virtual void OnFilter(FilterEventArgs e) { if (Filter != null) Filter(this, e); } /// /// /// /// protected virtual void OnFormatCell(FormatCellEventArgs args) { if (FormatCell != null) FormatCell(this, args); } /// /// /// /// protected virtual void OnFormatRow(FormatRowEventArgs args) { if (FormatRow != null) FormatRow(this, args); } /// /// /// /// protected virtual void OnFreezing(FreezeEventArgs args) { if (Freezing != null) Freezing(this, args); } /// /// /// /// protected virtual void OnGroupExpandingCollapsing(GroupExpandingCollapsingEventArgs args) { if (GroupExpandingCollapsing != null) GroupExpandingCollapsing(this, args); } /// /// /// /// protected virtual void OnGroupStateChanged(GroupStateChangedEventArgs args) { if (GroupStateChanged != null) GroupStateChanged(this, args); } /// /// /// /// protected virtual void OnHeaderCheckBoxChanging(HeaderCheckBoxChangingEventArgs args) { if (HeaderCheckBoxChanging != null) HeaderCheckBoxChanging(this, args); } /// /// /// /// protected virtual void OnHeaderToolTip(ToolTipShowingEventArgs args) { if (HeaderToolTipShowing != null) HeaderToolTipShowing(this, args); } /// /// /// /// protected virtual void OnHotItemChanged(HotItemChangedEventArgs e) { if (HotItemChanged != null) HotItemChanged(this, e); } /// /// /// /// protected virtual void OnHyperlinkClicked(HyperlinkClickedEventArgs e) { if (HyperlinkClicked != null) HyperlinkClicked(this, e); } /// /// /// /// protected virtual void OnGroupTaskClicked(GroupTaskClickedEventArgs e) { if (GroupTaskClicked != null) GroupTaskClicked(this, e); } /// /// /// /// protected virtual void OnIsHyperlink(IsHyperlinkEventArgs e) { if (IsHyperlink != null) IsHyperlink(this, e); } /// /// /// /// protected virtual void OnItemsAdding(ItemsAddingEventArgs e) { if (ItemsAdding != null) ItemsAdding(this, e); } /// /// /// /// protected virtual void OnItemsChanged(ItemsChangedEventArgs e) { if (ItemsChanged != null) ItemsChanged(this, e); } /// /// /// /// protected virtual void OnItemsChanging(ItemsChangingEventArgs e) { if (ItemsChanging != null) ItemsChanging(this, e); } /// /// /// /// protected virtual void OnItemsRemoving(ItemsRemovingEventArgs e) { if (ItemsRemoving != null) ItemsRemoving(this, e); } /// /// /// /// protected virtual void OnModelCanDrop(ModelDropEventArgs args) { if (ModelCanDrop != null) ModelCanDrop(this, args); } /// /// /// /// protected virtual void OnModelDropped(ModelDropEventArgs args) { if (ModelDropped != null) ModelDropped(this, args); } /// /// /// /// protected virtual void OnSelectionChanged(EventArgs e) { if (SelectionChanged != null) SelectionChanged(this, e); } /// /// /// /// protected virtual void OnScroll(ScrollEventArgs e) { if (Scroll != null) Scroll(this, e); } /// /// Tell the world when a cell is about to be edited. /// protected virtual void OnCellEditStarting(CellEditEventArgs e) { if (CellEditStarting != null) CellEditStarting(this, e); } /// /// Tell the world when a cell is about to finish being edited. /// protected virtual void OnCellEditorValidating(CellEditEventArgs e) { // Hack. ListView is an imperfect control container. It does not manage validation // perfectly. If the ListView is part of a TabControl, and the cell editor loses // focus by the user clicking on another tab, the TabControl processes the click // and switches tabs, even if this Validating event cancels. This results in the // strange situation where the cell editor is active, but isn't visible. When the // user switches back to the tab with the ListView, composite controls like spin // controls, DateTimePicker and ComboBoxes do not work properly. Specifically, // keyboard input still works fine, but the controls do not respond to mouse // input. SO, if the validation fails, we have to specifically give focus back to // the cell editor. (this is the Select() call in the code below). // But (there is always a 'but'), doing that changes the focus so the cell editor // triggers another Validating event -- which fails again. From the user's point // of view, they click away from the cell editor, and the validating code // complains twice. So we only trigger a Validating event if more than 0.1 seconds // has elapsed since the last validate event. // I know it's a hack. I'm very open to hear a neater solution. // Also, this timed response stops us from sending a series of validation events // if the user clicks and holds on the OLV scroll bar. //System.Diagnostics.Debug.WriteLine(Environment.TickCount - lastValidatingEvent); if ((Environment.TickCount - lastValidatingEvent) < 100) { e.Cancel = true; } else { lastValidatingEvent = Environment.TickCount; if (CellEditValidating != null) CellEditValidating(this, e); } lastValidatingEvent = Environment.TickCount; } private int lastValidatingEvent = 0; /// /// Tell the world when a cell is about to finish being edited. /// protected virtual void OnCellEditFinishing(CellEditEventArgs e) { if (CellEditFinishing != null) CellEditFinishing(this, e); } /// /// Tell the world when a cell has finished being edited. /// protected virtual void OnCellEditFinished(CellEditEventArgs e) { if (CellEditFinished != null) CellEditFinished(this, e); } #endregion } public partial class TreeListView { #region Events /// /// This event is triggered when user input requests the expansion of a list item. /// [Category("ObjectListView"), Description("This event is triggered when a branch is about to expand.")] public event EventHandler Expanding; /// /// This event is triggered when user input requests the collapse of a list item. /// [Category("ObjectListView"), Description("This event is triggered when a branch is about to collapsed.")] public event EventHandler Collapsing; /// /// This event is triggered after the expansion of a list item due to user input. /// [Category("ObjectListView"), Description("This event is triggered when a branch has been expanded.")] public event EventHandler Expanded; /// /// This event is triggered after the collapse of a list item due to user input. /// [Category("ObjectListView"), Description("This event is triggered when a branch has been collapsed.")] public event EventHandler Collapsed; #endregion #region OnEvents /// /// Trigger the expanding event /// /// protected virtual void OnExpanding(TreeBranchExpandingEventArgs e) { if (Expanding != null) Expanding(this, e); } /// /// Trigger the collapsing event /// /// protected virtual void OnCollapsing(TreeBranchCollapsingEventArgs e) { if (Collapsing != null) Collapsing(this, e); } /// /// Trigger the expanded event /// /// protected virtual void OnExpanded(TreeBranchExpandedEventArgs e) { if (Expanded != null) Expanded(this, e); } /// /// Trigger the collapsed event /// /// protected virtual void OnCollapsed(TreeBranchCollapsedEventArgs e) { if (Collapsed != null) Collapsed(this, e); } #endregion } //----------------------------------------------------------------------------------- #region Event Parameter Blocks /// /// Let the world know that a cell edit operation is beginning or ending /// public class CellEditEventArgs : EventArgs { /// /// Create an event args /// /// /// /// /// /// public CellEditEventArgs(OLVColumn column, Control control, Rectangle cellBounds, OLVListItem item, int subItemIndex) { Control = control; this.column = column; this.cellBounds = cellBounds; listViewItem = item; rowObject = item.RowObject; this.subItemIndex = subItemIndex; value = column.GetValue(item.RowObject); } /// /// Change this to true to cancel the cell editing operation. /// /// /// During the CellEditStarting event, setting this to true will prevent the cell from being edited. /// During the CellEditFinishing event, if this value is already true, this indicates that the user has /// cancelled the edit operation and that the handler should perform cleanup only. Setting this to true, /// will prevent the ObjectListView from trying to write the new value into the model object. /// public bool Cancel; /// /// During the CellEditStarting event, this can be modified to be the control that you want /// to edit the value. You must fully configure the control before returning from the event, /// including its bounds and the value it is showing. /// During the CellEditFinishing event, you can use this to get the value that the user /// entered and commit that value to the model. Changing the control during the finishing /// event has no effect. /// public Control Control; /// /// The column of the cell that is going to be or has been edited. /// public OLVColumn Column { get { return column; } } private OLVColumn column; /// /// The model object of the row of the cell that is going to be or has been edited. /// public Object RowObject { get { return rowObject; } } private Object rowObject; /// /// The listview item of the cell that is going to be or has been edited. /// public OLVListItem ListViewItem { get { return listViewItem; } } private OLVListItem listViewItem; /// /// The data value of the cell as it stands in the control. /// /// Only validate during Validating and Finishing events. public Object NewValue { get { return newValue; } set { newValue = value; } } private Object newValue; /// /// The index of the cell that is going to be or has been edited. /// public int SubItemIndex { get { return subItemIndex; } } private int subItemIndex; /// /// The data value of the cell before the edit operation began. /// public Object Value { get { return value; } } private Object value; /// /// The bounds of the cell that is going to be or has been edited. /// public Rectangle CellBounds { get { return cellBounds; } } private Rectangle cellBounds; /// /// Gets or sets whether the control used for editing should be auto matically disposed /// when the cell edit operation finishes. Defaults to true /// /// If the control is expensive to create, you might want to cache it and reuse for /// for various cells. If so, you don't want ObjectListView to dispose of the control automatically public bool AutoDispose { get { return autoDispose; } set { autoDispose = value; } } private bool autoDispose = true; } /// /// Event blocks for events that can be cancelled /// public class CancellableEventArgs : EventArgs { /// /// Has this event been cancelled by the event handler? /// public bool Canceled; } /// /// BeforeSorting /// public class BeforeSortingEventArgs : CancellableEventArgs { /// /// Create BeforeSortingEventArgs /// /// /// /// /// public BeforeSortingEventArgs(OLVColumn column, SortOrder order, OLVColumn column2, SortOrder order2) { ColumnToGroupBy = column; GroupByOrder = order; ColumnToSort = column; SortOrder = order; SecondaryColumnToSort = column2; SecondarySortOrder = order2; } /// /// Create BeforeSortingEventArgs /// /// /// /// /// /// /// public BeforeSortingEventArgs(OLVColumn groupColumn, SortOrder groupOrder, OLVColumn column, SortOrder order, OLVColumn column2, SortOrder order2) { ColumnToGroupBy = groupColumn; GroupByOrder = groupOrder; ColumnToSort = column; SortOrder = order; SecondaryColumnToSort = column2; SecondarySortOrder = order2; } /// /// Did the event handler already do the sorting for us? /// public bool Handled; /// /// What column will be used for grouping /// public OLVColumn ColumnToGroupBy; /// /// How will groups be ordered /// public SortOrder GroupByOrder; /// /// What column will be used for sorting /// public OLVColumn ColumnToSort; /// /// What order will be used for sorting. None means no sorting. /// public SortOrder SortOrder; /// /// What column will be used for secondary sorting? /// public OLVColumn SecondaryColumnToSort; /// /// What order will be used for secondary sorting? /// public SortOrder SecondarySortOrder; } /// /// Sorting has just occurred. /// public class AfterSortingEventArgs : EventArgs { /// /// Create a AfterSortingEventArgs /// /// /// /// /// /// /// public AfterSortingEventArgs(OLVColumn groupColumn, SortOrder groupOrder, OLVColumn column, SortOrder order, OLVColumn column2, SortOrder order2) { columnToGroupBy = groupColumn; groupByOrder = groupOrder; columnToSort = column; sortOrder = order; secondaryColumnToSort = column2; secondarySortOrder = order2; } /// /// Create a AfterSortingEventArgs /// /// public AfterSortingEventArgs(BeforeSortingEventArgs args) { columnToGroupBy = args.ColumnToGroupBy; groupByOrder = args.GroupByOrder; columnToSort = args.ColumnToSort; sortOrder = args.SortOrder; secondaryColumnToSort = args.SecondaryColumnToSort; secondarySortOrder = args.SecondarySortOrder; } /// /// What column was used for grouping? /// public OLVColumn ColumnToGroupBy { get { return columnToGroupBy; } } private OLVColumn columnToGroupBy; /// /// What ordering was used for grouping? /// public SortOrder GroupByOrder { get { return groupByOrder; } } private SortOrder groupByOrder; /// /// What column was used for sorting? /// public OLVColumn ColumnToSort { get { return columnToSort; } } private OLVColumn columnToSort; /// /// What ordering was used for sorting? /// public SortOrder SortOrder { get { return sortOrder; } } private SortOrder sortOrder; /// /// What column was used for secondary sorting? /// public OLVColumn SecondaryColumnToSort { get { return secondaryColumnToSort; } } private OLVColumn secondaryColumnToSort; /// /// What order was used for secondary sorting? /// public SortOrder SecondarySortOrder { get { return secondarySortOrder; } } private SortOrder secondarySortOrder; } /// /// This event is triggered when the contents of a list have changed /// and we want the world to have a chance to filter the list. /// public class FilterEventArgs : EventArgs { /// /// Create a FilterEventArgs /// /// public FilterEventArgs(IEnumerable objects) { Objects = objects; } /// /// Gets or sets what objects are being filtered /// public IEnumerable Objects; /// /// Gets or sets what objects survived the filtering /// public IEnumerable FilteredObjects; } /// /// This event is triggered after the items in the list have been changed, /// either through SetObjects, AddObjects or RemoveObjects. /// public class ItemsChangedEventArgs : EventArgs { /// /// Create a ItemsChangedEventArgs /// public ItemsChangedEventArgs() { } /// /// Constructor for this event when used by a virtual list /// /// /// public ItemsChangedEventArgs(int oldObjectCount, int newObjectCount) { this.oldObjectCount = oldObjectCount; this.newObjectCount = newObjectCount; } /// /// Gets how many items were in the list before it changed /// public int OldObjectCount { get { return oldObjectCount; } } private int oldObjectCount; /// /// Gets how many objects are in the list after the change. /// public int NewObjectCount { get { return newObjectCount; } } private int newObjectCount; } /// /// This event is triggered by AddObjects before any change has been made to the list. /// public class ItemsAddingEventArgs : CancellableEventArgs { /// /// Create an ItemsAddingEventArgs /// /// public ItemsAddingEventArgs(ICollection objectsToAdd) { ObjectsToAdd = objectsToAdd; } /// /// Create an ItemsAddingEventArgs /// /// /// public ItemsAddingEventArgs(int index, ICollection objectsToAdd) { Index = index; ObjectsToAdd = objectsToAdd; } /// /// Gets or sets where the collection is going to be inserted. /// public int Index; /// /// Gets or sets the objects to be added to the list /// public ICollection ObjectsToAdd; } /// /// This event is triggered by SetObjects before any change has been made to the list. /// /// /// When used with a virtual list, OldObjects will always be null. /// public class ItemsChangingEventArgs : CancellableEventArgs { /// /// Create ItemsChangingEventArgs /// /// /// public ItemsChangingEventArgs(IEnumerable oldObjects, IEnumerable newObjects) { this.oldObjects = oldObjects; NewObjects = newObjects; } /// /// Gets the objects that were in the list before it change. /// For virtual lists, this will always be null. /// public IEnumerable OldObjects { get { return oldObjects; } } private IEnumerable oldObjects; /// /// Gets or sets the objects that will be in the list after it changes. /// public IEnumerable NewObjects; } /// /// This event is triggered by RemoveObjects before any change has been made to the list. /// public class ItemsRemovingEventArgs : CancellableEventArgs { /// /// Create an ItemsRemovingEventArgs /// /// public ItemsRemovingEventArgs(ICollection objectsToRemove) { ObjectsToRemove = objectsToRemove; } /// /// Gets or sets the objects that will be removed /// public ICollection ObjectsToRemove; } /// /// Triggered after the user types into a list /// public class AfterSearchingEventArgs : EventArgs { /// /// Create an AfterSearchingEventArgs /// /// /// public AfterSearchingEventArgs(string stringToFind, int indexSelected) { this.stringToFind = stringToFind; this.indexSelected = indexSelected; } /// /// Gets the string that was actually searched for /// public string StringToFind { get { return stringToFind; } } private string stringToFind; /// /// Gets or sets whether an the event handler already handled this event /// public bool Handled; /// /// Gets the index of the row that was selected by the search. /// -1 means that no row was matched /// public int IndexSelected { get { return indexSelected; } } private int indexSelected; } /// /// Triggered when the user types into a list /// public class BeforeSearchingEventArgs : CancellableEventArgs { /// /// Create BeforeSearchingEventArgs /// /// /// public BeforeSearchingEventArgs(string stringToFind, int startSearchFrom) { StringToFind = stringToFind; StartSearchFrom = startSearchFrom; } /// /// Gets or sets the string that will be found by the search routine /// /// Modifying this value does not modify the memory of what the user has typed. /// When the user next presses a character, the search string will revert to what /// the user has actually typed. public string StringToFind; /// /// Gets or sets the index of the first row that will be considered to matching. /// public int StartSearchFrom; } /// /// The parameter block when telling the world about a cell based event /// public class CellEventArgs : EventArgs { /// /// Gets the ObjectListView that is the source of the event /// public ObjectListView ListView { get { return listView; } internal set { listView = value; } } private ObjectListView listView; /// /// Gets the model object under the cell /// /// This is null for events triggered by the header. public object Model { get { return model; } internal set { model = value; } } private object model; /// /// Gets the row index of the cell /// /// This is -1 for events triggered by the header. public int RowIndex { get { return rowIndex; } internal set { rowIndex = value; } } private int rowIndex = -1; /// /// Gets the column index of the cell /// /// This is -1 when the view is not in details view. public int ColumnIndex { get { return columnIndex; } internal set { columnIndex = value; } } private int columnIndex = -1; /// /// Gets the column of the cell /// /// This is null when the view is not in details view. public OLVColumn Column { get { return column; } internal set { column = value; } } private OLVColumn column; /// /// Gets the location of the mouse at the time of the event /// public Point Location { get { return location; } internal set { location = value; } } private Point location; /// /// Gets the state of the modifier keys at the time of the event /// public Keys ModifierKeys { get { return modifierKeys; } internal set { modifierKeys = value; } } private Keys modifierKeys; /// /// Gets the item of the cell /// public OLVListItem Item { get { return item; } internal set { item = value; } } private OLVListItem item; /// /// Gets the subitem of the cell /// /// This is null when the view is not in details view and /// for event triggered by the header public OLVListSubItem SubItem { get { return subItem; } internal set { subItem = value; } } private OLVListSubItem subItem; /// /// Gets the HitTest object that determined which cell was hit /// public OlvListViewHitTestInfo HitTest { get { return hitTest; } internal set { hitTest = value; } } private OlvListViewHitTestInfo hitTest; /// /// Gets or set if this event completelely handled. If it was, no further processing /// will be done for it. /// public bool Handled; } /// /// Tells the world that a cell was clicked /// public class CellClickEventArgs : CellEventArgs { /// /// Gets or sets the number of clicks associated with this event /// public int ClickCount { get { return clickCount; } set { clickCount = value; } } private int clickCount; } /// /// Tells the world that a cell was right clicked /// public class CellRightClickEventArgs : CellEventArgs { /// /// Gets or sets the menu that should be displayed as a result of this event. /// /// The menu will be positioned at Location, so changing that property changes /// where the menu will be displayed. public ContextMenuStrip MenuStrip; } /// /// Tell the world that the mouse is over a given cell /// public class CellOverEventArgs : CellEventArgs { } /// /// Tells the world that the frozen-ness of the ObjectListView has changed. /// public class FreezeEventArgs : EventArgs { /// /// Make a FreezeEventArgs /// /// public FreezeEventArgs(int freeze) { FreezeLevel = freeze; } /// /// How frozen is the control? 0 means that the control is unfrozen, /// more than 0 indicates froze. /// public int FreezeLevel { get { return freezeLevel; } set { freezeLevel = value; } } private int freezeLevel; } /// /// The parameter block when telling the world that a tool tip is about to be shown. /// public class ToolTipShowingEventArgs : CellEventArgs { /// /// Gets the tooltip control that is triggering the tooltip event /// public ToolTipControl ToolTipControl { get { return toolTipControl; } internal set { toolTipControl = value; } } private ToolTipControl toolTipControl; /// /// Gets or sets the text should be shown on the tooltip for this event /// /// Setting this to empty or null prevents any tooltip from showing public string Text; /// /// In what direction should the text for this tooltip be drawn? /// public RightToLeft RightToLeft; /// /// Should the tooltip for this event been shown in bubble style? /// /// This doesn't work reliable under Vista public bool? IsBalloon; /// /// What color should be used for the background of the tooltip /// /// Setting this does nothing under Vista public Color? BackColor; /// /// What color should be used for the foreground of the tooltip /// /// Setting this does nothing under Vista public Color? ForeColor; /// /// What string should be used as the title for the tooltip for this event? /// public string Title; /// /// Which standard icon should be used for the tooltip for this event /// public ToolTipControl.StandardIcons? StandardIcon; /// /// How many milliseconds should the tooltip remain before it automatically /// disappears. /// public int? AutoPopDelay; /// /// What font should be used to draw the text of the tooltip? /// public Font Font; } /// /// Common information to all hyperlink events /// public class HyperlinkEventArgs : EventArgs { //TODO: Unified with CellEventArgs /// /// Gets the ObjectListView that is the source of the event /// public ObjectListView ListView { get { return listView; } internal set { listView = value; } } private ObjectListView listView; /// /// Gets the model object under the cell /// public object Model { get { return model; } internal set { model = value; } } private object model; /// /// Gets the row index of the cell /// public int RowIndex { get { return rowIndex; } internal set { rowIndex = value; } } private int rowIndex = -1; /// /// Gets the column index of the cell /// /// This is -1 when the view is not in details view. public int ColumnIndex { get { return columnIndex; } internal set { columnIndex = value; } } private int columnIndex = -1; /// /// Gets the column of the cell /// /// This is null when the view is not in details view. public OLVColumn Column { get { return column; } internal set { column = value; } } private OLVColumn column; /// /// Gets the item of the cell /// public OLVListItem Item { get { return item; } internal set { item = value; } } private OLVListItem item; /// /// Gets the subitem of the cell /// /// This is null when the view is not in details view public OLVListSubItem SubItem { get { return subItem; } internal set { subItem = value; } } private OLVListSubItem subItem; /// /// Gets the ObjectListView that is the source of the event /// public string Url { get { return url; } internal set { url = value; } } private string url; /// /// Gets or set if this event completelely handled. If it was, no further processing /// will be done for it. /// public bool Handled { get { return handled; } set { handled = value; } } private bool handled; } /// /// /// public class IsHyperlinkEventArgs : EventArgs { /// /// Gets the ObjectListView that is the source of the event /// public ObjectListView ListView { get { return listView; } internal set { listView = value; } } private ObjectListView listView; /// /// Gets the model object under the cell /// public object Model { get { return model; } internal set { model = value; } } private object model; /// /// Gets the column of the cell /// /// This is null when the view is not in details view. public OLVColumn Column { get { return column; } internal set { column = value; } } private OLVColumn column; /// /// Gets the text of the cell /// public string Text { get { return text; } internal set { text = value; } } private string text; /// /// Gets or sets whether or not this cell is a hyperlink. /// Defaults to true for enabled rows and false for disabled rows. /// public bool IsHyperlink { get { return isHyperlink; } set { isHyperlink = value; } } private bool isHyperlink; /// /// Gets or sets the url that should be invoked when this cell is clicked. /// /// Setting this to None or String.Empty means that this cell is not a hyperlink public string Url; } /// /// public class FormatRowEventArgs : EventArgs { //TODO: Unified with CellEventArgs /// /// Gets the ObjectListView that is the source of the event /// public ObjectListView ListView { get { return listView; } internal set { listView = value; } } private ObjectListView listView; /// /// Gets the item of the cell /// public OLVListItem Item { get { return item; } internal set { item = value; } } private OLVListItem item; /// /// Gets the model object under the cell /// public object Model { get { return Item.RowObject; } } /// /// Gets the row index of the cell /// public int RowIndex { get { return rowIndex; } internal set { rowIndex = value; } } private int rowIndex = -1; /// /// Gets the display index of the row /// public int DisplayIndex { get { return displayIndex; } internal set { displayIndex = value; } } private int displayIndex = -1; /// /// Should events be triggered for each cell in this row? /// public bool UseCellFormatEvents { get { return useCellFormatEvents; } set { useCellFormatEvents = value; } } private bool useCellFormatEvents; } /// /// Parameter block for FormatCellEvent /// public class FormatCellEventArgs : FormatRowEventArgs { /// /// Gets the column index of the cell /// /// This is -1 when the view is not in details view. public int ColumnIndex { get { return columnIndex; } internal set { columnIndex = value; } } private int columnIndex = -1; /// /// Gets the column of the cell /// /// This is null when the view is not in details view. public OLVColumn Column { get { return column; } internal set { column = value; } } private OLVColumn column; /// /// Gets the subitem of the cell /// /// This is null when the view is not in details view public OLVListSubItem SubItem { get { return subItem; } internal set { subItem = value; } } private OLVListSubItem subItem; /// /// Gets the model value that is being displayed by the cell. /// /// This is null when the view is not in details view public object CellValue { get { return SubItem == null ? null : SubItem.ModelValue; } } } /// /// The event args when a hyperlink is clicked /// public class HyperlinkClickedEventArgs : CellEventArgs { /// /// Gets the url that was associated with this cell. /// public string Url { get { return url; } set { url = value; } } private string url; } /// /// The event args when the check box in a column header is changing /// public class HeaderCheckBoxChangingEventArgs : CancelEventArgs { /// /// Get the column whose checkbox is changing /// public OLVColumn Column { get { return column; } internal set { column = value; } } private OLVColumn column; /// /// Get or set the new state that should be used by the column /// public CheckState NewCheckState { get { return newCheckState; } set { newCheckState = value; } } private CheckState newCheckState; } /// /// The event args when the hot item changed /// public class HotItemChangedEventArgs : EventArgs { /// /// Gets or set if this event completelely handled. If it was, no further processing /// will be done for it. /// public bool Handled { get { return handled; } set { handled = value; } } private bool handled; /// /// Gets the part of the cell that the mouse is over /// public HitTestLocation HotCellHitLocation { get { return newHotCellHitLocation; } internal set { newHotCellHitLocation = value; } } private HitTestLocation newHotCellHitLocation; /// /// Gets an extended indication of the part of item/subitem/group that the mouse is currently over /// public virtual HitTestLocationEx HotCellHitLocationEx { get { return hotCellHitLocationEx; } internal set { hotCellHitLocationEx = value; } } private HitTestLocationEx hotCellHitLocationEx; /// /// Gets the index of the column that the mouse is over /// /// In non-details view, this will always be 0. public int HotColumnIndex { get { return newHotColumnIndex; } internal set { newHotColumnIndex = value; } } private int newHotColumnIndex; /// /// Gets the index of the row that the mouse is over /// public int HotRowIndex { get { return newHotRowIndex; } internal set { newHotRowIndex = value; } } private int newHotRowIndex; /// /// Gets the group that the mouse is over /// public OLVGroup HotGroup { get { return hotGroup; } internal set { hotGroup = value; } } private OLVGroup hotGroup; /// /// Gets the part of the cell that the mouse used to be over /// public HitTestLocation OldHotCellHitLocation { get { return oldHotCellHitLocation; } internal set { oldHotCellHitLocation = value; } } private HitTestLocation oldHotCellHitLocation; /// /// Gets an extended indication of the part of item/subitem/group that the mouse used to be over /// public virtual HitTestLocationEx OldHotCellHitLocationEx { get { return oldHotCellHitLocationEx; } internal set { oldHotCellHitLocationEx = value; } } private HitTestLocationEx oldHotCellHitLocationEx; /// /// Gets the index of the column that the mouse used to be over /// public int OldHotColumnIndex { get { return oldHotColumnIndex; } internal set { oldHotColumnIndex = value; } } private int oldHotColumnIndex; /// /// Gets the index of the row that the mouse used to be over /// public int OldHotRowIndex { get { return oldHotRowIndex; } internal set { oldHotRowIndex = value; } } private int oldHotRowIndex; /// /// Gets the group that the mouse used to be over /// public OLVGroup OldHotGroup { get { return oldHotGroup; } internal set { oldHotGroup = value; } } private OLVGroup oldHotGroup; /// /// Returns a string that represents the current object. /// /// /// A string that represents the current object. /// /// 2 public override string ToString() { return string.Format("NewHotCellHitLocation: {0}, HotCellHitLocationEx: {1}, NewHotColumnIndex: {2}, NewHotRowIndex: {3}, HotGroup: {4}", newHotCellHitLocation, hotCellHitLocationEx, newHotColumnIndex, newHotRowIndex, hotGroup); } } /// /// Let the world know that a checkbox on a subitem is changing /// public class SubItemCheckingEventArgs : CancellableEventArgs { /// /// Create a new event block /// /// /// /// /// /// public SubItemCheckingEventArgs(OLVColumn column, OLVListItem item, int subItemIndex, CheckState currentValue, CheckState newValue) { this.column = column; listViewItem = item; this.subItemIndex = subItemIndex; this.currentValue = currentValue; this.newValue = newValue; } /// /// The column of the cell that is having its checkbox changed. /// public OLVColumn Column { get { return column; } } private OLVColumn column; /// /// The model object of the row of the cell that is having its checkbox changed. /// public Object RowObject { get { return listViewItem.RowObject; } } /// /// The listview item of the cell that is having its checkbox changed. /// public OLVListItem ListViewItem { get { return listViewItem; } } private OLVListItem listViewItem; /// /// The current check state of the cell. /// public CheckState CurrentValue { get { return currentValue; } } private CheckState currentValue; /// /// The proposed new check state of the cell. /// public CheckState NewValue { get { return newValue; } set { newValue = value; } } private CheckState newValue; /// /// The index of the cell that is going to be or has been edited. /// public int SubItemIndex { get { return subItemIndex; } } private int subItemIndex; } /// /// This event argument block is used when groups are created for a list. /// public class CreateGroupsEventArgs : EventArgs { /// /// Create a CreateGroupsEventArgs /// /// public CreateGroupsEventArgs(GroupingParameters parms) { parameters = parms; } /// /// Gets the settings that control the creation of groups /// public GroupingParameters Parameters { get { return parameters; } } private GroupingParameters parameters; /// /// Gets or sets the groups that should be used /// public IList Groups { get { return groups; } set { groups = value; } } private IList groups; /// /// Has this event been cancelled by the event handler? /// public bool Canceled { get { return canceled; } set { canceled = value; } } private bool canceled; } /// /// This event argument block is used when the text of a group task is clicked /// public class GroupTaskClickedEventArgs : EventArgs { /// /// Create a GroupTaskClickedEventArgs /// /// public GroupTaskClickedEventArgs(OLVGroup group) { this.group = group; } /// /// Gets which group was clicked /// public OLVGroup Group { get { return group; } } private readonly OLVGroup group; } /// /// This event argument block is used when a group is about to expand or collapse /// public class GroupExpandingCollapsingEventArgs : CancellableEventArgs { /// /// Create a GroupExpandingCollapsingEventArgs /// /// public GroupExpandingCollapsingEventArgs(OLVGroup group) { olvGroup = @group ?? throw new ArgumentNullException("group"); } /// /// Gets which group is expanding/collapsing /// public OLVGroup Group { get { return olvGroup; } } private readonly OLVGroup olvGroup; /// /// Gets whether this event is going to expand the group. /// If this is false, the group must be collapsing. /// public bool IsExpanding { get { return Group.Collapsed; } } } /// /// This event argument block is used when the state of group has changed (collapsed, selected) /// public class GroupStateChangedEventArgs : EventArgs { /// /// Create a GroupStateChangedEventArgs /// /// /// /// public GroupStateChangedEventArgs(OLVGroup group, GroupState oldState, GroupState newState) { this.group = group; this.oldState = oldState; this.newState = newState; } /// /// Gets whether the group was collapsed by this event /// public bool Collapsed { get { return ((oldState & GroupState.LVGS_COLLAPSED) != GroupState.LVGS_COLLAPSED) && ((newState & GroupState.LVGS_COLLAPSED) == GroupState.LVGS_COLLAPSED); } } /// /// Gets whether the group was focused by this event /// public bool Focused { get { return ((oldState & GroupState.LVGS_FOCUSED) != GroupState.LVGS_FOCUSED) && ((newState & GroupState.LVGS_FOCUSED) == GroupState.LVGS_FOCUSED); } } /// /// Gets whether the group was selected by this event /// public bool Selected { get { return ((oldState & GroupState.LVGS_SELECTED) != GroupState.LVGS_SELECTED) && ((newState & GroupState.LVGS_SELECTED) == GroupState.LVGS_SELECTED); } } /// /// Gets whether the group was uncollapsed by this event /// public bool Uncollapsed { get { return ((oldState & GroupState.LVGS_COLLAPSED) == GroupState.LVGS_COLLAPSED) && ((newState & GroupState.LVGS_COLLAPSED) != GroupState.LVGS_COLLAPSED); } } /// /// Gets whether the group was unfocused by this event /// public bool Unfocused { get { return ((oldState & GroupState.LVGS_FOCUSED) == GroupState.LVGS_FOCUSED) && ((newState & GroupState.LVGS_FOCUSED) != GroupState.LVGS_FOCUSED); } } /// /// Gets whether the group was unselected by this event /// public bool Unselected { get { return ((oldState & GroupState.LVGS_SELECTED) == GroupState.LVGS_SELECTED) && ((newState & GroupState.LVGS_SELECTED) != GroupState.LVGS_SELECTED); } } /// /// Gets which group had its state changed /// public OLVGroup Group { get { return group; } } private readonly OLVGroup group; /// /// Gets the previous state of the group /// public GroupState OldState { get { return oldState; } } private readonly GroupState oldState; /// /// Gets the new state of the group /// public GroupState NewState { get { return newState; } } private readonly GroupState newState; } /// /// This event argument block is used when a branch of a tree is about to be expanded /// public class TreeBranchExpandingEventArgs : CancellableEventArgs { /// /// Create a new event args /// /// /// public TreeBranchExpandingEventArgs(object model, OLVListItem item) { Model = model; Item = item; } /// /// Gets the model that is about to expand. If null, all branches are going to be expanded. /// public object Model { get { return model; } private set { model = value; } } private object model; /// /// Gets the OLVListItem that is about to be expanded /// public OLVListItem Item { get { return item; } private set { item = value; } } private OLVListItem item; } /// /// This event argument block is used when a branch of a tree has just been expanded /// public class TreeBranchExpandedEventArgs : EventArgs { /// /// Create a new event args /// /// /// public TreeBranchExpandedEventArgs(object model, OLVListItem item) { Model = model; Item = item; } /// /// Gets the model that is was expanded. If null, all branches were expanded. /// public object Model { get { return model; } private set { model = value; } } private object model; /// /// Gets the OLVListItem that was expanded /// public OLVListItem Item { get { return item; } private set { item = value; } } private OLVListItem item; } /// /// This event argument block is used when a branch of a tree is about to be collapsed /// public class TreeBranchCollapsingEventArgs : CancellableEventArgs { /// /// Create a new event args /// /// /// public TreeBranchCollapsingEventArgs(object model, OLVListItem item) { Model = model; Item = item; } /// /// Gets the model that is about to collapse. If this is null, all models are going to collapse. /// public object Model { get { return model; } private set { model = value; } } private object model; /// /// Gets the OLVListItem that is about to be collapsed. Can be null /// public OLVListItem Item { get { return item; } private set { item = value; } } private OLVListItem item; } /// /// This event argument block is used when a branch of a tree has just been collapsed /// public class TreeBranchCollapsedEventArgs : EventArgs { /// /// Create a new event args /// /// /// public TreeBranchCollapsedEventArgs(object model, OLVListItem item) { Model = model; Item = item; } /// /// Gets the model that is was collapsed. If null, all branches were collapsed /// public object Model { get { return model; } private set { model = value; } } private object model; /// /// Gets the OLVListItem that was collapsed /// public OLVListItem Item { get { return item; } private set { item = value; } } private OLVListItem item; } #endregion } ================================================ FILE: source/ObjectListView/Implementation/GroupingParameters.cs ================================================ /* * GroupingParameters - All the data that is used to create groups in an ObjectListView * * Author: Phillip Piper * Date: 31-March-2011 5:53 pm * * Change log: * 2011-03-31 JPP - Split into its own file * * Copyright (C) 2011-2014 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System.Collections.Generic; using System.Windows.Forms; namespace BrightIdeasSoftware { /// /// This class contains all the settings used when groups are created /// public class GroupingParameters { /// /// Create a GroupingParameters /// /// /// /// /// /// /// /// /// /// /// public GroupingParameters(ObjectListView olv, OLVColumn groupByColumn, SortOrder groupByOrder, OLVColumn column, SortOrder order, OLVColumn secondaryColumn, SortOrder secondaryOrder, string titleFormat, string titleSingularFormat, bool sortItemsByPrimaryColumn) { ListView = olv; GroupByColumn = groupByColumn; GroupByOrder = groupByOrder; PrimarySort = column; PrimarySortOrder = order; SecondarySort = secondaryColumn; SecondarySortOrder = secondaryOrder; SortItemsByPrimaryColumn = sortItemsByPrimaryColumn; TitleFormat = titleFormat; TitleSingularFormat = titleSingularFormat; } /// /// Gets or sets the ObjectListView being grouped /// public ObjectListView ListView { get { return listView; } set { listView = value; } } private ObjectListView listView; /// /// Gets or sets the column used to create groups /// public OLVColumn GroupByColumn { get { return groupByColumn; } set { groupByColumn = value; } } private OLVColumn groupByColumn; /// /// In what order will the groups themselves be sorted? /// public SortOrder GroupByOrder { get { return groupByOrder; } set { groupByOrder = value; } } private SortOrder groupByOrder; /// /// If this is set, this comparer will be used to order the groups /// public IComparer GroupComparer { get { return groupComparer; } set { groupComparer = value; } } private IComparer groupComparer; /// /// If this is set, this comparer will be used to order items within each group /// public IComparer ItemComparer { get { return itemComparer; } set { itemComparer = value; } } private IComparer itemComparer; /// /// Gets or sets the column that will be the primary sort /// public OLVColumn PrimarySort { get { return primarySort; } set { primarySort = value; } } private OLVColumn primarySort; /// /// Gets or sets the ordering for the primary sort /// public SortOrder PrimarySortOrder { get { return primarySortOrder; } set { primarySortOrder = value; } } private SortOrder primarySortOrder; /// /// Gets or sets the column used for secondary sorting /// public OLVColumn SecondarySort { get { return secondarySort; } set { secondarySort = value; } } private OLVColumn secondarySort; /// /// Gets or sets the ordering for the secondary sort /// public SortOrder SecondarySortOrder { get { return secondarySortOrder; } set { secondarySortOrder = value; } } private SortOrder secondarySortOrder; /// /// Gets or sets the title format used for groups with zero or more than one element /// public string TitleFormat { get { return titleFormat; } set { titleFormat = value; } } private string titleFormat; /// /// Gets or sets the title format used for groups with only one element /// public string TitleSingularFormat { get { return titleSingularFormat; } set { titleSingularFormat = value; } } private string titleSingularFormat; /// /// Gets or sets whether the items should be sorted by the primary column /// public bool SortItemsByPrimaryColumn { get { return sortItemsByPrimaryColumn; } set { sortItemsByPrimaryColumn = value; } } private bool sortItemsByPrimaryColumn; } } ================================================ FILE: source/ObjectListView/Implementation/Groups.cs ================================================ /* * Groups - Enhancements to the normal ListViewGroup * * Author: Phillip Piper * Date: 22/08/2009 6:03PM * * Change log: * v2.3 * 2009-09-09 JPP - Added Collapsed and Collapsible properties * 2009-09-01 JPP - Cleaned up code, added more docs * - Works under VS2005 again * 2009-08-22 JPP - Initial version * * To do: * - Implement subseting * - Implement footer items * * Copyright (C) 2009-2014 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System; using System.Collections; using System.Collections.Generic; using System.Reflection; using System.Windows.Forms; using System.Runtime.InteropServices; namespace BrightIdeasSoftware { /// /// These values indicate what is the state of the group. These values /// are taken directly from the SDK and many are not used by ObjectListView. /// [Flags] public enum GroupState { /// /// Normal /// LVGS_NORMAL = 0x0, /// /// Collapsed /// LVGS_COLLAPSED = 0x1, /// /// Hidden /// LVGS_HIDDEN = 0x2, /// /// NoHeader /// LVGS_NOHEADER = 0x4, /// /// Can be collapsed /// LVGS_COLLAPSIBLE = 0x8, /// /// Has focus /// LVGS_FOCUSED = 0x10, /// /// Is Selected /// LVGS_SELECTED = 0x20, /// /// Is subsetted /// LVGS_SUBSETED = 0x40, /// /// Subset link has focus /// LVGS_SUBSETLINKFOCUSED = 0x80, /// /// All styles /// LVGS_ALL = 0xFFFF } /// /// This mask indicates which members of a LVGROUP have valid data. These values /// are taken directly from the SDK and many are not used by ObjectListView. /// [Flags] public enum GroupMask { /// /// No mask /// LVGF_NONE = 0, /// /// Group has header /// LVGF_HEADER = 1, /// /// Group has footer /// LVGF_FOOTER = 2, /// /// Group has state /// LVGF_STATE = 4, /// /// /// LVGF_ALIGN = 8, /// /// /// LVGF_GROUPID = 0x10, /// /// pszSubtitle is valid /// LVGF_SUBTITLE = 0x00100, /// /// pszTask is valid /// LVGF_TASK = 0x00200, /// /// pszDescriptionTop is valid /// LVGF_DESCRIPTIONTOP = 0x00400, /// /// pszDescriptionBottom is valid /// LVGF_DESCRIPTIONBOTTOM = 0x00800, /// /// iTitleImage is valid /// LVGF_TITLEIMAGE = 0x01000, /// /// iExtendedImage is valid /// LVGF_EXTENDEDIMAGE = 0x02000, /// /// iFirstItem and cItems are valid /// LVGF_ITEMS = 0x04000, /// /// pszSubsetTitle is valid /// LVGF_SUBSET = 0x08000, /// /// readonly, cItems holds count of items in visible subset, iFirstItem is valid /// LVGF_SUBSETITEMS = 0x10000 } /// /// This mask indicates which members of a GROUPMETRICS structure are valid /// [Flags] public enum GroupMetricsMask { /// /// /// LVGMF_NONE = 0, /// /// /// LVGMF_BORDERSIZE = 1, /// /// /// LVGMF_BORDERCOLOR = 2, /// /// /// LVGMF_TEXTCOLOR = 4 } /// /// Instances of this class enhance the capabilities of a normal ListViewGroup, /// enabling the functionality that was released in v6 of the common controls. /// /// /// /// In this implementation (2009-09), these objects are essentially passive. /// Setting properties does not automatically change the associated group in /// the listview. Collapsed and Collapsible are two exceptions to this and /// give immediate results. /// /// /// This really should be a subclass of ListViewGroup, but that class is /// sealed (why is that?). So this class provides the same interface as a /// ListViewGroup, plus many other new properties. /// /// public class OLVGroup { #region Creation /// /// Create an OLVGroup /// public OLVGroup() : this("Default group header") { } /// /// Create a group with the given title /// /// Title of the group public OLVGroup(string header) { Header = header; Id = nextId++; TitleImage = -1; ExtendedImage = -1; } private static int nextId; #endregion #region Public properties /// /// Gets or sets the bottom description of the group /// /// /// Descriptions only appear when group is centered and there is a title image /// public string BottomDescription { get { return bottomDescription; } set { bottomDescription = value; } } private string bottomDescription; /// /// Gets or sets whether or not this group is collapsed /// public bool Collapsed { get { return GetOneState(GroupState.LVGS_COLLAPSED); } set { SetOneState(value, GroupState.LVGS_COLLAPSED); } } /// /// Gets or sets whether or not this group can be collapsed /// public bool Collapsible { get { return GetOneState(GroupState.LVGS_COLLAPSIBLE); } set { SetOneState(value, GroupState.LVGS_COLLAPSIBLE); } } /// /// Gets or sets some representation of the contents of this group /// /// This is user defined (like Tag) public IList Contents { get { return contents; } set { contents = value; } } private IList contents; /// /// Gets whether this group has been created. /// public bool Created { get { return ListView != null; } } /// /// Gets or sets the int or string that will select the extended image to be shown against the title /// public object ExtendedImage { get { return extendedImage; } set { extendedImage = value; } } private object extendedImage; /// /// Gets or sets the footer of the group /// public string Footer { get { return footer; } set { footer = value; } } private string footer; /// /// Gets the internal id of our associated ListViewGroup. /// public int GroupId { get { if (ListViewGroup == null) return Id; // Use reflection to get around the access control on the ID property if (groupIdPropInfo == null) { groupIdPropInfo = typeof(ListViewGroup).GetProperty("ID", BindingFlags.NonPublic | BindingFlags.Instance); System.Diagnostics.Debug.Assert(groupIdPropInfo != null); } return groupIdPropInfo.GetValue(ListViewGroup, null) is int groupId ? groupId : -1; } } private static PropertyInfo groupIdPropInfo; /// /// Gets or sets the header of the group /// public string Header { get { return header; } set { header = value; } } private string header; /// /// Gets or sets the horizontal alignment of the group header /// public HorizontalAlignment HeaderAlignment { get { return headerAlignment; } set { headerAlignment = value; } } private HorizontalAlignment headerAlignment; /// /// Gets or sets the internally created id of the group /// public int Id { get { return id; } set { id = value; } } private int id; /// /// Gets or sets ListViewItems that are members of this group /// /// Listener of the BeforeCreatingGroups event can populate this collection. /// It is only used on non-virtual lists. public IList Items { get { return items; } set { items = value; } } private IList items = new List(); /// /// Gets or sets the key that was used to partition objects into this group /// /// This is user defined (like Tag) public object Key { get { return key; } set { key = value; } } private object key; /// /// Gets the ObjectListView that this group belongs to /// /// If this is null, the group has not yet been created. public ObjectListView ListView { get { return listView; } protected set { listView = value; } } private ObjectListView listView; /// /// Gets or sets the name of the group /// /// As of 2009-09-01, this property is not used. public string Name { get { return name; } set { name = value; } } private string name; /// /// Gets or sets whether this group is focused /// public bool Focused { get { return GetOneState(GroupState.LVGS_FOCUSED); } set { SetOneState(value, GroupState.LVGS_FOCUSED); } } /// /// Gets or sets whether this group is selected /// public bool Selected { get { return GetOneState(GroupState.LVGS_SELECTED); } set { SetOneState(value, GroupState.LVGS_SELECTED); } } /// /// Gets or sets the text that will show that this group is subsetted /// /// /// As of WinSDK v7.0, subsetting of group is officially unimplemented. /// We can get around this using undocumented interfaces and may do so. /// public string SubsetTitle { get { return subsetTitle; } set { subsetTitle = value; } } private string subsetTitle; /// /// Gets or set the subtitleof the task /// public string Subtitle { get { return subtitle; } set { subtitle = value; } } private string subtitle; /// /// Gets or sets the value by which this group will be sorted. /// public IComparable SortValue { get { return sortValue; } set { sortValue = value; } } private IComparable sortValue; /// /// Gets or sets the state of the group /// public GroupState State { get { return state; } set { state = value; } } private GroupState state; /// /// Gets or sets which bits of State are valid /// public GroupState StateMask { get { return stateMask; } set { stateMask = value; } } private GroupState stateMask; /// /// Gets or sets whether this group is showing only a subset of its elements /// /// /// As of WinSDK v7.0, this property officially does nothing. /// public bool Subseted { get { return GetOneState(GroupState.LVGS_SUBSETED); } set { SetOneState(value, GroupState.LVGS_SUBSETED); } } /// /// Gets or sets the user-defined data attached to this group /// public object Tag { get { return tag; } set { tag = value; } } private object tag; /// /// Gets or sets the task of this group /// /// This task is the clickable text that appears on the right margin /// of the group header. public string Task { get { return task; } set { task = value; } } private string task; /// /// Gets or sets the int or string that will select the image to be shown against the title /// public object TitleImage { get { return titleImage; } set { titleImage = value; } } private object titleImage; /// /// Gets or sets the top description of the group /// /// /// Descriptions only appear when group is centered and there is a title image /// public string TopDescription { get { return topDescription; } set { topDescription = value; } } private string topDescription; /// /// Gets or sets the number of items that are within this group. /// /// This should only be used for virtual groups. public int VirtualItemCount { get { return virtualItemCount; } set { virtualItemCount = value; } } private int virtualItemCount; #endregion #region Protected properties /// /// Gets or sets the ListViewGroup that is shadowed by this group. /// /// For virtual groups, this will always be null. protected ListViewGroup ListViewGroup { get { return listViewGroup; } set { listViewGroup = value; } } private ListViewGroup listViewGroup; #endregion #region Calculations/Conversions /// /// Calculate the index into the group image list of the given image selector /// /// /// public int GetImageIndex(object imageSelector) { if (imageSelector == null || ListView == null || ListView.GroupImageList == null) return -1; if (imageSelector is Int32) return (int)imageSelector; if (imageSelector is string imageSelectorAsString) return ListView.GroupImageList.Images.IndexOfKey(imageSelectorAsString); return -1; } /// /// Convert this object to a string representation /// /// public override string ToString() { return Header; } #endregion #region Commands /// /// Insert a native group into the underlying Windows control, /// *without* using a ListViewGroup /// /// /// This is used when creating virtual groups public void InsertGroupNewStyle(ObjectListView olv) { ListView = olv; NativeMethods.InsertGroup(olv, AsNativeGroup(true)); } /// /// Insert a native group into the underlying control via a ListViewGroup /// /// public void InsertGroupOldStyle(ObjectListView olv) { ListView = olv; // Create/update the associated ListViewGroup if (ListViewGroup == null) ListViewGroup = new ListViewGroup(); ListViewGroup.Header = Header; ListViewGroup.HeaderAlignment = HeaderAlignment; ListViewGroup.Name = Name; // Remember which OLVGroup created the ListViewGroup ListViewGroup.Tag = this; // Add the group to the control olv.Groups.Add(ListViewGroup); // Add any extra information NativeMethods.SetGroupInfo(olv, GroupId, AsNativeGroup(false)); } /// /// Change the members of the group to match the current contents of Items, /// using a ListViewGroup /// public void SetItemsOldStyle() { if (Items is not List list) { foreach (OLVListItem item in Items) { ListViewGroup.Items.Add(item); } } else { ListViewGroup.Items.AddRange(list.ToArray()); } } #endregion #region Implementation /// /// Create a native LVGROUP structure that matches this group /// internal NativeMethods.LVGROUP2 AsNativeGroup(bool withId) { NativeMethods.LVGROUP2 group = new NativeMethods.LVGROUP2(); group.cbSize = (uint)Marshal.SizeOf(typeof(NativeMethods.LVGROUP2)); group.mask = (uint)(GroupMask.LVGF_HEADER ^ GroupMask.LVGF_ALIGN ^ GroupMask.LVGF_STATE); group.pszHeader = Header; group.uAlign = (uint)HeaderAlignment; group.stateMask = (uint)StateMask; group.state = (uint)State; if (withId) { group.iGroupId = GroupId; group.mask ^= (uint)GroupMask.LVGF_GROUPID; } if (!String.IsNullOrEmpty(Footer)) { group.pszFooter = Footer; group.mask ^= (uint)GroupMask.LVGF_FOOTER; } if (!String.IsNullOrEmpty(Subtitle)) { group.pszSubtitle = Subtitle; group.mask ^= (uint)GroupMask.LVGF_SUBTITLE; } if (!String.IsNullOrEmpty(Task)) { group.pszTask = Task; group.mask ^= (uint)GroupMask.LVGF_TASK; } if (!String.IsNullOrEmpty(TopDescription)) { group.pszDescriptionTop = TopDescription; group.mask ^= (uint)GroupMask.LVGF_DESCRIPTIONTOP; } if (!String.IsNullOrEmpty(BottomDescription)) { group.pszDescriptionBottom = BottomDescription; group.mask ^= (uint)GroupMask.LVGF_DESCRIPTIONBOTTOM; } int imageIndex = GetImageIndex(TitleImage); if (imageIndex >= 0) { group.iTitleImage = imageIndex; group.mask ^= (uint)GroupMask.LVGF_TITLEIMAGE; } imageIndex = GetImageIndex(ExtendedImage); if (imageIndex >= 0) { group.iExtendedImage = imageIndex; group.mask ^= (uint)GroupMask.LVGF_EXTENDEDIMAGE; } if (!String.IsNullOrEmpty(SubsetTitle)) { group.pszSubsetTitle = SubsetTitle; group.mask ^= (uint)GroupMask.LVGF_SUBSET; } if (VirtualItemCount > 0) { group.cItems = VirtualItemCount; group.mask ^= (uint)GroupMask.LVGF_ITEMS; } return group; } private bool GetOneState(GroupState mask) { if (Created) State = GetState(); return (State & mask) == mask; } /// /// Get the current state of this group from the underlying control /// protected GroupState GetState() { return NativeMethods.GetGroupState(ListView, GroupId, GroupState.LVGS_ALL); } /// /// Get the current state of this group from the underlying control /// protected int SetState(GroupState newState, GroupState mask) { NativeMethods.LVGROUP2 group = new NativeMethods.LVGROUP2(); group.cbSize = ((uint)Marshal.SizeOf(typeof(NativeMethods.LVGROUP2))); group.mask = (uint)GroupMask.LVGF_STATE; group.state = (uint)newState; group.stateMask = (uint)mask; return NativeMethods.SetGroupInfo(ListView, GroupId, group); } private void SetOneState(bool value, GroupState mask) { StateMask ^= mask; if (value) State ^= mask; else State &= ~mask; if (Created) SetState(State, mask); } #endregion } } ================================================ FILE: source/ObjectListView/Implementation/Munger.cs ================================================ /* * Munger - An Interface pattern on getting and setting values from object through Reflection * * Author: Phillip Piper * Date: 28/11/2008 17:15 * * Change log: * v2.5.1 * 2012-05-01 JPP - Added IgnoreMissingAspects property * v2.5 * 2011-05-20 JPP - Accessing through an indexer when the target had both a integer and * a string indexer didn't work reliably. * v2.4.1 * 2010-08-10 JPP - Refactored into Munger/SimpleMunger. 3x faster! * v2.3 * 2009-02-15 JPP - Made Munger a public class * 2009-01-20 JPP - Made the Munger capable of handling indexed access. * Incidentally, this removed the ugliness that the last change introduced. * 2009-01-18 JPP - Handle target objects from a DataListView (normally DataRowViews) * v2.0 * 2008-11-28 JPP Initial version * * TO DO: * * Copyright (C) 2006-2014 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System; using System.Collections.Generic; using System.Reflection; namespace BrightIdeasSoftware { /// /// An instance of Munger gets a value from or puts a value into a target object. The property /// to be peeked (or poked) is determined from a string. The peeking or poking is done using reflection. /// /// /// Name of the aspect to be peeked can be a field, property or parameterless method. The name of an /// aspect to poke can be a field, writable property or single parameter method. /// /// Aspect names can be dotted to chain a series of references. /// /// Order.Customer.HomeAddress.State /// public class Munger { #region Life and death /// /// Create a do nothing Munger /// public Munger() { } /// /// Create a Munger that works on the given aspect name /// /// The name of the public Munger(String aspectName) { AspectName = aspectName; } #endregion #region Static utility methods /// /// A helper method to put the given value into the given aspect of the given object. /// /// This method catches and silently ignores any errors that occur /// while modifying the target object /// The object to be modified /// The name of the property/field to be modified /// The value to be assigned /// Did the modification work? public static bool PutProperty(object target, string propertyName, object value) { try { Munger munger = new Munger(propertyName); return munger.PutValue(target, value); } catch (MungerException) { // Not a lot we can do about this. Something went wrong in the bowels // of the property. Let's take the ostrich approach and just ignore it :-) // Normally, we would never just silently ignore an exception. // However, in this case, this is a utility method that explicitly // contracts to catch and ignore errors. If this is not acceptible, // the programmer should not use this method. } return false; } /// /// Gets or sets whether Mungers will silently ignore missing aspect errors. /// /// /// /// By default, if a Munger is asked to fetch a field/property/method /// that does not exist from a model, it returns an error message, since that /// condition is normally a programming error. There are some use cases where /// this is not an error, and the munger should simply keep quiet. /// /// By default this is true during release builds. /// public static bool IgnoreMissingAspects { get { return ignoreMissingAspects; } set { ignoreMissingAspects = value; } } private static bool ignoreMissingAspects #if !DEBUG = true #endif ; #endregion #region Public properties /// /// The name of the aspect that is to be peeked or poked. /// /// /// /// This name can be a field, property or parameter-less method. /// /// /// The name can be dotted, which chains references. If any link in the chain returns /// null, the entire chain is considered to return null. /// /// /// "DateOfBirth" /// "Owner.HomeAddress.Postcode" public string AspectName { get { return aspectName; } set { aspectName = value; // Clear any cache aspectParts = null; } } private string aspectName; #endregion #region Public interface /// /// Extract the value indicated by our AspectName from the given target. /// /// If the aspect name is null or empty, this will return null. /// The object that will be peeked /// The value read from the target public Object GetValue(Object target) { if (Parts.Count == 0) return null; try { return EvaluateParts(target, Parts); } catch (MungerException ex) { if (IgnoreMissingAspects) return null; return String.Format("'{0}' is not a parameter-less method, property or field of type '{1}'", ex.Munger.AspectName, ex.Target.GetType()); } } /// /// Extract the value indicated by our AspectName from the given target, raising exceptions /// if the munger fails. /// /// If the aspect name is null or empty, this will return null. /// The object that will be peeked /// The value read from the target public Object GetValueEx(Object target) { if (Parts.Count == 0) return null; return EvaluateParts(target, Parts); } /// /// Poke the given value into the given target indicated by our AspectName. /// /// /// /// If the AspectName is a dotted path, all the selectors bar the last /// are used to find the object that should be updated, and the last /// selector is used as the property to update on that object. /// /// /// So, if 'target' is a Person and the AspectName is "HomeAddress.Postcode", /// this method will first fetch "HomeAddress" property, and then try to set the /// "Postcode" property on the home address object. /// /// /// The object that will be poked /// The value that will be poked into the target /// bool indicating whether the put worked public bool PutValue(Object target, Object value) { if (Parts.Count == 0) return false; SimpleMunger lastPart = Parts[Parts.Count - 1]; if (Parts.Count > 1) { List parts = new List(Parts); parts.RemoveAt(parts.Count - 1); try { target = EvaluateParts(target, parts); } catch (MungerException ex) { ReportPutValueException(ex); return false; } } if (target != null) { try { return lastPart.PutValue(target, value); } catch (MungerException ex) { ReportPutValueException(ex); } } return false; } #endregion #region Implementation /// /// Gets the list of SimpleMungers that match our AspectName /// private IList Parts { get { if (aspectParts == null) aspectParts = BuildParts(AspectName); return aspectParts; } } private IList aspectParts; /// /// Convert a possibly dotted AspectName into a list of SimpleMungers /// /// /// private IList BuildParts(string aspect) { List parts = new List(); if (!String.IsNullOrEmpty(aspect)) { foreach (string part in aspect.Split('.')) { parts.Add(new SimpleMunger(part.Trim())); } } return parts; } /// /// Evaluate the given chain of SimpleMungers against an initial target. /// /// /// /// private object EvaluateParts(object target, IList parts) { foreach (SimpleMunger part in parts) { if (target == null) break; target = part.GetValue(target); } return target; } private void ReportPutValueException(MungerException ex) { //TODO: How should we report this error? System.Diagnostics.Debug.WriteLine("PutValue failed"); System.Diagnostics.Debug.WriteLine(String.Format("- Culprit aspect: {0}", ex.Munger.AspectName)); System.Diagnostics.Debug.WriteLine(String.Format("- Target: {0} of type {1}", ex.Target, ex.Target.GetType())); System.Diagnostics.Debug.WriteLine(String.Format("- Inner exception: {0}", ex.InnerException)); } #endregion } /// /// A SimpleMunger deals with a single property/field/method on its target. /// /// /// Munger uses a chain of these resolve a dotted aspect name. /// public class SimpleMunger { #region Life and death /// /// Create a SimpleMunger /// /// public SimpleMunger(String aspectName) { this.aspectName = aspectName; } #endregion #region Public properties /// /// The name of the aspect that is to be peeked or poked. /// /// /// /// This name can be a field, property or method. /// When using a method to get a value, the method must be parameter-less. /// When using a method to set a value, the method must accept 1 parameter. /// /// /// It cannot be a dotted name. /// /// public string AspectName { get { return aspectName; } } private readonly string aspectName; #endregion #region Public interface /// /// Get a value from the given target /// /// /// public Object GetValue(Object target) { if (target == null) return null; ResolveName(target, AspectName, 0); try { if (resolvedPropertyInfo != null) return resolvedPropertyInfo.GetValue(target, null); if (resolvedMethodInfo != null) return resolvedMethodInfo.Invoke(target, null); if (resolvedFieldInfo != null) return resolvedFieldInfo.GetValue(target); // If that didn't work, try to use the indexer property. // This covers things like dictionaries and DataRows. if (indexerPropertyInfo != null) return indexerPropertyInfo.GetValue(target, new object[] { AspectName }); } catch (Exception ex) { // Lots of things can do wrong in these invocations throw new MungerException(this, target, ex); } // If we get to here, we couldn't find a match for the aspect throw new MungerException(this, target, new MissingMethodException()); } /// /// Poke the given value into the given target indicated by our AspectName. /// /// The object that will be poked /// The value that will be poked into the target /// bool indicating if the put worked public bool PutValue(object target, object value) { if (target == null) return false; ResolveName(target, AspectName, 1); try { if (resolvedPropertyInfo != null) { resolvedPropertyInfo.SetValue(target, value, null); return true; } if (resolvedMethodInfo != null) { resolvedMethodInfo.Invoke(target, new object[] { value }); return true; } if (resolvedFieldInfo != null) { resolvedFieldInfo.SetValue(target, value); return true; } // If that didn't work, try to use the indexer property. // This covers things like dictionaries and DataRows. if (indexerPropertyInfo != null) { indexerPropertyInfo.SetValue(target, value, new object[] { AspectName }); return true; } } catch (Exception ex) { // Lots of things can do wrong in these invocations throw new MungerException(this, target, ex); } return false; } #endregion #region Implementation private void ResolveName(object target, string name, int numberMethodParameters) { if (cachedTargetType == target.GetType() && cachedName == name && cachedNumberParameters == numberMethodParameters) return; cachedTargetType = target.GetType(); cachedName = name; cachedNumberParameters = numberMethodParameters; resolvedFieldInfo = null; resolvedPropertyInfo = null; resolvedMethodInfo = null; indexerPropertyInfo = null; const BindingFlags flags = BindingFlags.Public | BindingFlags.Instance /*| BindingFlags.NonPublic*/; foreach (PropertyInfo pinfo in target.GetType().GetProperties(flags)) { if (pinfo.Name == name) { resolvedPropertyInfo = pinfo; return; } // See if we can find an string indexer property while we are here. // We also need to allow for old style keyed collections. if (indexerPropertyInfo == null && pinfo.Name == "Item") { ParameterInfo[] par = pinfo.GetGetMethod().GetParameters(); if (par.Length > 0) { Type parameterType = par[0].ParameterType; if (parameterType == typeof(string) || parameterType == typeof(object)) indexerPropertyInfo = pinfo; } } } foreach (FieldInfo info in target.GetType().GetFields(flags)) { if (info.Name == name) { resolvedFieldInfo = info; return; } } foreach (MethodInfo info in target.GetType().GetMethods(flags)) { if (info.Name == name && info.GetParameters().Length == numberMethodParameters) { resolvedMethodInfo = info; return; } } } private Type cachedTargetType; private string cachedName; private int cachedNumberParameters; private FieldInfo resolvedFieldInfo; private PropertyInfo resolvedPropertyInfo; private MethodInfo resolvedMethodInfo; private PropertyInfo indexerPropertyInfo; #endregion } /// /// These exceptions are raised when a munger finds something it cannot process /// public class MungerException : ApplicationException { /// /// Create a MungerException /// /// /// /// public MungerException(SimpleMunger munger, object target, Exception ex) : base("Munger failed", ex) { this.munger = munger; this.target = target; } /// /// Get the munger that raised the exception /// public SimpleMunger Munger { get { return munger; } } private readonly SimpleMunger munger; /// /// Gets the target that threw the exception /// public object Target { get { return target; } } private readonly object target; } /* * We don't currently need this * 2010-08-06 * internal class SimpleBinder : Binder { public override FieldInfo BindToField(BindingFlags bindingAttr, FieldInfo[] match, object value, System.Globalization.CultureInfo culture) { //return Type.DefaultBinder.BindToField( throw new NotImplementedException(); } public override object ChangeType(object value, Type type, System.Globalization.CultureInfo culture) { throw new NotImplementedException(); } public override MethodBase BindToMethod(BindingFlags bindingAttr, MethodBase[] match, ref object[] args, ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, string[] names, out object state) { throw new NotImplementedException(); } public override void ReorderArgumentArray(ref object[] args, object state) { throw new NotImplementedException(); } public override MethodBase SelectMethod(BindingFlags bindingAttr, MethodBase[] match, Type[] types, ParameterModifier[] modifiers) { throw new NotImplementedException(); } public override PropertyInfo SelectProperty(BindingFlags bindingAttr, PropertyInfo[] match, Type returnType, Type[] indexes, ParameterModifier[] modifiers) { if (match == null) throw new ArgumentNullException("match"); if (match.Length == 0) return null; return match[0]; } } */ } ================================================ FILE: source/ObjectListView/Implementation/NativeMethods.cs ================================================ /* * NativeMethods - All the Windows SDK structures and imports * * Author: Phillip Piper * Date: 10/10/2006 * * Change log: * v2.8.0 * 2014-05-21 JPP - Added DeselectOneItem * - Added new imagelist drawing * v2.3 * 2006-10-10 JPP - Initial version * * To do: * * Copyright (C) 2006-2014 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System; using System.Drawing; using System.Runtime.InteropServices; using System.Windows.Forms; namespace BrightIdeasSoftware { /// /// Wrapper for all native method calls on ListView controls /// internal static class NativeMethods { #region Constants private const int LVM_FIRST = 0x1000; private const int LVM_GETCOLUMN = LVM_FIRST + 95; private const int LVM_GETCOUNTPERPAGE = LVM_FIRST + 40; private const int LVM_GETGROUPINFO = LVM_FIRST + 149; private const int LVM_GETGROUPSTATE = LVM_FIRST + 92; private const int LVM_GETHEADER = LVM_FIRST + 31; private const int LVM_GETTOOLTIPS = LVM_FIRST + 78; private const int LVM_GETTOPINDEX = LVM_FIRST + 39; private const int LVM_HITTEST = LVM_FIRST + 18; private const int LVM_INSERTGROUP = LVM_FIRST + 145; private const int LVM_REMOVEALLGROUPS = LVM_FIRST + 160; private const int LVM_SCROLL = LVM_FIRST + 20; private const int LVM_SETBKIMAGE = LVM_FIRST + 0x8A; private const int LVM_SETCOLUMN = LVM_FIRST + 96; private const int LVM_SETEXTENDEDLISTVIEWSTYLE = LVM_FIRST + 54; private const int LVM_SETGROUPINFO = LVM_FIRST + 147; private const int LVM_SETGROUPMETRICS = LVM_FIRST + 155; private const int LVM_SETIMAGELIST = LVM_FIRST + 3; private const int LVM_SETITEM = LVM_FIRST + 76; private const int LVM_SETITEMCOUNT = LVM_FIRST + 47; private const int LVM_SETITEMSTATE = LVM_FIRST + 43; private const int LVM_SETSELECTEDCOLUMN = LVM_FIRST + 140; private const int LVM_SETTOOLTIPS = LVM_FIRST + 74; private const int LVM_SUBITEMHITTEST = LVM_FIRST + 57; private const int LVS_EX_SUBITEMIMAGES = 0x0002; private const int LVIF_TEXT = 0x0001; private const int LVIF_IMAGE = 0x0002; private const int LVIF_PARAM = 0x0004; private const int LVIF_STATE = 0x0008; private const int LVIF_INDENT = 0x0010; private const int LVIF_NORECOMPUTE = 0x0800; private const int LVIS_SELECTED = 2; private const int LVCF_FMT = 0x0001; private const int LVCF_WIDTH = 0x0002; private const int LVCF_TEXT = 0x0004; private const int LVCF_SUBITEM = 0x0008; private const int LVCF_IMAGE = 0x0010; private const int LVCF_ORDER = 0x0020; private const int LVCFMT_LEFT = 0x0000; private const int LVCFMT_RIGHT = 0x0001; private const int LVCFMT_CENTER = 0x0002; private const int LVCFMT_JUSTIFYMASK = 0x0003; private const int LVCFMT_IMAGE = 0x0800; private const int LVCFMT_BITMAP_ON_RIGHT = 0x1000; private const int LVCFMT_COL_HAS_IMAGES = 0x8000; private const int LVBKIF_SOURCE_NONE = 0x0; private const int LVBKIF_SOURCE_HBITMAP = 0x1; private const int LVBKIF_SOURCE_URL = 0x2; private const int LVBKIF_SOURCE_MASK = 0x3; private const int LVBKIF_STYLE_NORMAL = 0x0; private const int LVBKIF_STYLE_TILE = 0x10; private const int LVBKIF_STYLE_MASK = 0x10; private const int LVBKIF_FLAG_TILEOFFSET = 0x100; private const int LVBKIF_TYPE_WATERMARK = 0x10000000; private const int LVBKIF_FLAG_ALPHABLEND = 0x20000000; private const int LVSICF_NOINVALIDATEALL = 1; private const int LVSICF_NOSCROLL = 2; private const int HDM_FIRST = 0x1200; private const int HDM_HITTEST = HDM_FIRST + 6; private const int HDM_GETITEMRECT = HDM_FIRST + 7; private const int HDM_GETITEM = HDM_FIRST + 11; private const int HDM_SETITEM = HDM_FIRST + 12; private const int HDI_WIDTH = 0x0001; private const int HDI_TEXT = 0x0002; private const int HDI_FORMAT = 0x0004; private const int HDI_BITMAP = 0x0010; private const int HDI_IMAGE = 0x0020; private const int HDF_LEFT = 0x0000; private const int HDF_RIGHT = 0x0001; private const int HDF_CENTER = 0x0002; private const int HDF_JUSTIFYMASK = 0x0003; private const int HDF_RTLREADING = 0x0004; private const int HDF_STRING = 0x4000; private const int HDF_BITMAP = 0x2000; private const int HDF_BITMAP_ON_RIGHT = 0x1000; private const int HDF_IMAGE = 0x0800; private const int HDF_SORTUP = 0x0400; private const int HDF_SORTDOWN = 0x0200; private const int SB_HORZ = 0; private const int SB_VERT = 1; private const int SB_CTL = 2; private const int SB_BOTH = 3; private const int SIF_RANGE = 0x0001; private const int SIF_PAGE = 0x0002; private const int SIF_POS = 0x0004; private const int SIF_DISABLENOSCROLL = 0x0008; private const int SIF_TRACKPOS = 0x0010; private const int SIF_ALL = (SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS); private const int ILD_NORMAL = 0x0; private const int ILD_TRANSPARENT = 0x1; private const int ILD_MASK = 0x10; private const int ILD_IMAGE = 0x20; private const int ILD_BLEND25 = 0x2; private const int ILD_BLEND50 = 0x4; const int SWP_NOSIZE = 1; const int SWP_NOMOVE = 2; const int SWP_NOZORDER = 4; const int SWP_NOREDRAW = 8; const int SWP_NOACTIVATE = 16; public const int SWP_FRAMECHANGED = 32; const int SWP_ZORDERONLY = SWP_NOSIZE | SWP_NOMOVE | SWP_NOREDRAW | SWP_NOACTIVATE; const int SWP_SIZEONLY = SWP_NOMOVE | SWP_NOREDRAW | SWP_NOZORDER | SWP_NOACTIVATE; const int SWP_UPDATE_FRAME = SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED; #endregion #region Structures [StructLayout(LayoutKind.Sequential)] public struct HDITEM { public int mask; public int cxy; public IntPtr pszText; public IntPtr hbm; public int cchTextMax; public int fmt; public IntPtr lParam; public int iImage; public int iOrder; //if (_WIN32_IE >= 0x0500) public int type; public IntPtr pvFilter; } [StructLayout(LayoutKind.Sequential)] public class HDHITTESTINFO { public int pt_x; public int pt_y; public int flags; public int iItem; } [StructLayout(LayoutKind.Sequential)] public class HDLAYOUT { public IntPtr prc; public IntPtr pwpos; } [StructLayout(LayoutKind.Sequential)] public struct IMAGELISTDRAWPARAMS { public int cbSize; public IntPtr himl; public int i; public IntPtr hdcDst; public int x; public int y; public int cx; public int cy; public int xBitmap; public int yBitmap; public uint rgbBk; public uint rgbFg; public uint fStyle; public uint dwRop; public uint fState; public uint Frame; public uint crEffect; } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct LVBKIMAGE { public int ulFlags; public IntPtr hBmp; [MarshalAs(UnmanagedType.LPTStr)] public string pszImage; public int cchImageMax; public int xOffset; public int yOffset; } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct LVCOLUMN { public int mask; public int fmt; public int cx; [MarshalAs(UnmanagedType.LPTStr)] public string pszText; public int cchTextMax; public int iSubItem; // These are available in Common Controls >= 0x0300 public int iImage; public int iOrder; }; [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct LVFINDINFO { public int flags; public string psz; public IntPtr lParam; public int ptX; public int ptY; public int vkDirection; } [StructLayout(LayoutKind.Sequential)] public struct LVGROUP { public uint cbSize; public uint mask; [MarshalAs(UnmanagedType.LPTStr)] public string pszHeader; public int cchHeader; [MarshalAs(UnmanagedType.LPTStr)] public string pszFooter; public int cchFooter; public int iGroupId; public uint stateMask; public uint state; public uint uAlign; } [StructLayout(LayoutKind.Sequential)] public struct LVGROUP2 { public uint cbSize; public uint mask; [MarshalAs(UnmanagedType.LPTStr)] public string pszHeader; public uint cchHeader; [MarshalAs(UnmanagedType.LPTStr)] public string pszFooter; public int cchFooter; public int iGroupId; public uint stateMask; public uint state; public uint uAlign; [MarshalAs(UnmanagedType.LPTStr)] public string pszSubtitle; public uint cchSubtitle; [MarshalAs(UnmanagedType.LPTStr)] public string pszTask; public uint cchTask; [MarshalAs(UnmanagedType.LPTStr)] public string pszDescriptionTop; public uint cchDescriptionTop; [MarshalAs(UnmanagedType.LPTStr)] public string pszDescriptionBottom; public uint cchDescriptionBottom; public int iTitleImage; public int iExtendedImage; public int iFirstItem; // Read only public int cItems; // Read only [MarshalAs(UnmanagedType.LPTStr)] public string pszSubsetTitle; // NULL if group is not subset public uint cchSubsetTitle; } [StructLayout(LayoutKind.Sequential)] public struct LVGROUPMETRICS { public uint cbSize; public uint mask; public uint Left; public uint Top; public uint Right; public uint Bottom; public int crLeft; public int crTop; public int crRight; public int crBottom; public int crHeader; public int crFooter; } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct LVHITTESTINFO { public int pt_x; public int pt_y; public int flags; public int iItem; public int iSubItem; public int iGroup; } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct LVITEM { public int mask; public int iItem; public int iSubItem; public int state; public int stateMask; [MarshalAs(UnmanagedType.LPTStr)] public string pszText; public int cchTextMax; public int iImage; public IntPtr lParam; // These are available in Common Controls >= 0x0300 public int iIndent; // These are available in Common Controls >= 0x056 public int iGroupId; public int cColumns; public IntPtr puColumns; }; [StructLayout(LayoutKind.Sequential)] public struct NMHDR { public IntPtr hwndFrom; public IntPtr idFrom; public int code; } [StructLayout(LayoutKind.Sequential)] public struct NMCUSTOMDRAW { public NMHDR nmcd; public int dwDrawStage; public IntPtr hdc; public RECT rc; public IntPtr dwItemSpec; public int uItemState; public IntPtr lItemlParam; } [StructLayout(LayoutKind.Sequential)] public struct NMHEADER { public NMHDR nhdr; public int iItem; public int iButton; public IntPtr pHDITEM; } const int MAX_LINKID_TEXT = 48; const int L_MAX_URL_LENGTH = 2048 + 32 + 4; //#define L_MAX_URL_LENGTH (2048 + 32 + sizeof("://")) [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct LITEM { public uint mask; public int iLink; public uint state; public uint stateMask; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_LINKID_TEXT)] public string szID; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = L_MAX_URL_LENGTH)] public string szUrl; } [StructLayout(LayoutKind.Sequential)] public struct NMLISTVIEW { public NMHDR hdr; public int iItem; public int iSubItem; public int uNewState; public int uOldState; public int uChanged; public IntPtr lParam; } [StructLayout(LayoutKind.Sequential)] public struct NMLVCUSTOMDRAW { public NMCUSTOMDRAW nmcd; public int clrText; public int clrTextBk; public int iSubItem; public int dwItemType; public int clrFace; public int iIconEffect; public int iIconPhase; public int iPartId; public int iStateId; public RECT rcText; public uint uAlign; } [StructLayout(LayoutKind.Sequential)] public struct NMLVFINDITEM { public NMHDR hdr; public int iStart; public LVFINDINFO lvfi; } [StructLayout(LayoutKind.Sequential)] public struct NMLVGETINFOTIP { public NMHDR hdr; public int dwFlags; public string pszText; public int cchTextMax; public int iItem; public int iSubItem; public IntPtr lParam; } [StructLayout(LayoutKind.Sequential)] public struct NMLVGROUP { public NMHDR hdr; public int iGroupId; // which group is changing public uint uNewState; // LVGS_xxx flags public uint uOldState; } [StructLayout(LayoutKind.Sequential)] public struct NMLVLINK { public NMHDR hdr; public LITEM link; public int iItem; public int iSubItem; } [StructLayout(LayoutKind.Sequential)] public struct NMLVSCROLL { public NMHDR hdr; public int dx; public int dy; } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct NMTTDISPINFO { public NMHDR hdr; [MarshalAs(UnmanagedType.LPTStr)] public string lpszText; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)] public string szText; public IntPtr hinst; public int uFlags; public IntPtr lParam; //public int hbmp; This is documented but doesn't work } [StructLayout(LayoutKind.Sequential)] public struct RECT { public int left; public int top; public int right; public int bottom; } [StructLayout(LayoutKind.Sequential)] public class SCROLLINFO { public int cbSize = Marshal.SizeOf(typeof(SCROLLINFO)); public int fMask; public int nMin; public int nMax; public int nPage; public int nPos; public int nTrackPos; } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public class TOOLINFO { public int cbSize = Marshal.SizeOf(typeof(TOOLINFO)); public int uFlags; public IntPtr hwnd; public IntPtr uId; public RECT rect; public IntPtr hinst = IntPtr.Zero; public IntPtr lpszText; public IntPtr lParam = IntPtr.Zero; } [StructLayout(LayoutKind.Sequential)] public struct WINDOWPOS { public IntPtr hwnd; public IntPtr hwndInsertAfter; public int x; public int y; public int cx; public int cy; public int flags; } #endregion #region Entry points // Various flavours of SendMessage: plain vanilla, and passing references to various structures [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, int lParam); [DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, int lParam); [DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, IntPtr lParam); [DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)] public static extern IntPtr SendMessageLVItem(IntPtr hWnd, int msg, int wParam, ref LVITEM lvi); [DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)] public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, ref LVHITTESTINFO ht); [DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)] public static extern IntPtr SendMessageRECT(IntPtr hWnd, int msg, int wParam, ref RECT r); //[DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)] //private static extern IntPtr SendMessageLVColumn(IntPtr hWnd, int m, int wParam, ref LVCOLUMN lvc); [DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)] private static extern IntPtr SendMessageHDItem(IntPtr hWnd, int msg, int wParam, ref HDITEM hdi); [DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)] public static extern IntPtr SendMessageHDHITTESTINFO(IntPtr hWnd, int Msg, IntPtr wParam, [In, Out] HDHITTESTINFO lParam); [DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)] public static extern IntPtr SendMessageTOOLINFO(IntPtr hWnd, int Msg, int wParam, TOOLINFO lParam); [DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)] public static extern IntPtr SendMessageLVBKIMAGE(IntPtr hWnd, int Msg, int wParam, ref LVBKIMAGE lParam); [DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)] public static extern IntPtr SendMessageString(IntPtr hWnd, int Msg, int wParam, string lParam); [DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)] public static extern IntPtr SendMessageIUnknown(IntPtr hWnd, int msg, [MarshalAs(UnmanagedType.IUnknown)] object wParam, int lParam); [DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, ref LVGROUP lParam); [DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, ref LVGROUP2 lParam); [DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, ref LVGROUPMETRICS lParam); [DllImport("gdi32.dll")] public static extern bool DeleteObject(IntPtr objectHandle); [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] public static extern bool GetClientRect(IntPtr hWnd, ref Rectangle r); [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] public static extern bool GetScrollInfo(IntPtr hWnd, int fnBar, SCROLLINFO scrollInfo); [DllImport("user32.dll", EntryPoint = "GetUpdateRect", CharSet = CharSet.Auto)] private static extern bool GetUpdateRectInternal(IntPtr hWnd, ref Rectangle r, bool eraseBackground); [DllImport("comctl32.dll", CharSet = CharSet.Auto)] private static extern bool ImageList_Draw(IntPtr himl, int i, IntPtr hdcDst, int x, int y, int fStyle); [DllImport("comctl32.dll", CharSet = CharSet.Auto)] private static extern bool ImageList_DrawIndirect(ref IMAGELISTDRAWPARAMS parms); [DllImport("user32.dll")] public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags); [DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern bool GetWindowRect(IntPtr hWnd, ref Rectangle r); [DllImport("user32.dll", EntryPoint = "GetWindowLong", CharSet = CharSet.Auto)] public static extern IntPtr GetWindowLong32(IntPtr hWnd, int nIndex); [DllImport("user32.dll", EntryPoint = "GetWindowLongPtr", CharSet = CharSet.Auto)] public static extern IntPtr GetWindowLongPtr64(IntPtr hWnd, int nIndex); [DllImport("user32.dll", EntryPoint = "SetWindowLong", CharSet = CharSet.Auto)] public static extern IntPtr SetWindowLongPtr32(IntPtr hWnd, int nIndex, int dwNewLong); [DllImport("user32.dll", EntryPoint = "SetWindowLongPtr", CharSet = CharSet.Auto)] public static extern IntPtr SetWindowLongPtr64(IntPtr hWnd, int nIndex, int dwNewLong); [DllImport("user32.dll")] public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); [DllImport("user32.dll", EntryPoint = "ValidateRect", CharSet = CharSet.Auto)] private static extern IntPtr ValidatedRectInternal(IntPtr hWnd, ref Rectangle r); #endregion //[DllImport("user32.dll", EntryPoint = "LockWindowUpdate", CharSet = CharSet.Auto)] //private static extern int LockWindowUpdateInternal(IntPtr hWnd); //public static void LockWindowUpdate(IWin32Window window) { // if (window == null) // NativeMethods.LockWindowUpdateInternal(IntPtr.Zero); // else // NativeMethods.LockWindowUpdateInternal(window.Handle); //} /// /// Put an image under the ListView. /// /// /// /// The ListView must have its handle created before calling this. /// /// /// This doesn't work very well. Specifically, it doesn't play well with owner drawn, /// and grid lines are drawn over it. /// /// /// /// The image to be used as the background. If this is null, any existing background image will be cleared. /// If this is true, the image is pinned to the bottom right and does not scroll. The other parameters are ignored /// If this is true, the image will be tiled to fill the whole control background. The offset parameters will be ignored. /// If both watermark and tiled are false, this indicates the horizontal percentage where the image will be placed. 0 is absolute left, 100 is absolute right. /// If both watermark and tiled are false, this indicates the vertical percentage where the image will be placed. /// public static bool SetBackgroundImage(ListView lv, Image image, bool isWatermark, bool isTiled, int xOffset, int yOffset) { LVBKIMAGE lvbkimage = new LVBKIMAGE(); // We have to clear any pre-existing background image, otherwise the attempt to set the image will fail. // We don't know which type may already have been set, so we just clear both the watermark and the image. lvbkimage.ulFlags = LVBKIF_TYPE_WATERMARK; IntPtr result = SendMessageLVBKIMAGE(lv.Handle, LVM_SETBKIMAGE, 0, ref lvbkimage); lvbkimage.ulFlags = LVBKIF_SOURCE_HBITMAP; result = SendMessageLVBKIMAGE(lv.Handle, LVM_SETBKIMAGE, 0, ref lvbkimage); if (image is Bitmap bm) { lvbkimage.hBmp = bm.GetHbitmap(); lvbkimage.ulFlags = isWatermark ? LVBKIF_TYPE_WATERMARK : (isTiled ? LVBKIF_SOURCE_HBITMAP | LVBKIF_STYLE_TILE : LVBKIF_SOURCE_HBITMAP); lvbkimage.xOffset = xOffset; lvbkimage.yOffset = yOffset; result = SendMessageLVBKIMAGE(lv.Handle, LVM_SETBKIMAGE, 0, ref lvbkimage); } return (result != IntPtr.Zero); } public static bool DrawImageList(Graphics g, ImageList il, int index, int x, int y, bool isSelected, bool isDisabled) { ImageListDrawItemConstants flags = (isSelected ? ImageListDrawItemConstants.ILD_SELECTED : ImageListDrawItemConstants.ILD_NORMAL) | ImageListDrawItemConstants.ILD_TRANSPARENT; ImageListDrawStateConstants state = isDisabled ? ImageListDrawStateConstants.ILS_SATURATE : ImageListDrawStateConstants.ILS_NORMAL; try { IntPtr hdc = g.GetHdc(); return DrawImage(il, hdc, index, x, y, flags, 0, 0, state); } finally { g.ReleaseHdc(); } } /// /// Flags controlling how the Image List item is /// drawn /// [Flags] public enum ImageListDrawItemConstants { /// /// Draw item normally. /// ILD_NORMAL = 0x0, /// /// Draw item transparently. /// ILD_TRANSPARENT = 0x1, /// /// Draw item blended with 25% of the specified foreground colour /// or the Highlight colour if no foreground colour specified. /// ILD_BLEND25 = 0x2, /// /// Draw item blended with 50% of the specified foreground colour /// or the Highlight colour if no foreground colour specified. /// ILD_SELECTED = 0x4, /// /// Draw the icon's mask /// ILD_MASK = 0x10, /// /// Draw the icon image without using the mask /// ILD_IMAGE = 0x20, /// /// Draw the icon using the ROP specified. /// ILD_ROP = 0x40, /// /// Preserves the alpha channel in dest. XP only. /// ILD_PRESERVEALPHA = 0x1000, /// /// Scale the image to cx, cy instead of clipping it. XP only. /// ILD_SCALE = 0x2000, /// /// Scale the image to the current DPI of the display. XP only. /// ILD_DPISCALE = 0x4000 } /// /// Enumeration containing XP ImageList Draw State options /// [Flags] public enum ImageListDrawStateConstants { /// /// The image state is not modified. /// ILS_NORMAL = (0x00000000), /// /// Adds a glow effect to the icon, which causes the icon to appear to glow /// with a given color around the edges. (Note: does not appear to be implemented) /// ILS_GLOW = (0x00000001), //The color for the glow effect is passed to the IImageList::Draw method in the crEffect member of IMAGELISTDRAWPARAMS. /// /// Adds a drop shadow effect to the icon. (Note: does not appear to be implemented) /// ILS_SHADOW = (0x00000002), //The color for the drop shadow effect is passed to the IImageList::Draw method in the crEffect member of IMAGELISTDRAWPARAMS. /// /// Saturates the icon by increasing each color component /// of the RGB triplet for each pixel in the icon. (Note: only ever appears to result in a completely unsaturated icon) /// ILS_SATURATE = (0x00000004), // The amount to increase is indicated by the frame member in the IMAGELISTDRAWPARAMS method. /// /// Alpha blends the icon. Alpha blending controls the transparency /// level of an icon, according to the value of its alpha channel. /// (Note: does not appear to be implemented). /// ILS_ALPHA = (0x00000008) //The value of the alpha channel is indicated by the frame member in the IMAGELISTDRAWPARAMS method. The alpha channel can be from 0 to 255, with 0 being completely transparent, and 255 being completely opaque. } private const uint CLR_DEFAULT = 0xFF000000; /// /// Draws an image using the specified flags and state on XP systems. /// /// The image list from which an item will be drawn /// Device context to draw to /// Index of image to draw /// X Position to draw at /// Y Position to draw at /// Drawing flags /// Width to draw /// Height to draw /// State flags public static bool DrawImage(ImageList il, IntPtr hdc, int index, int x, int y, ImageListDrawItemConstants flags, int cx, int cy, ImageListDrawStateConstants stateFlags) { IMAGELISTDRAWPARAMS pimldp = new IMAGELISTDRAWPARAMS(); pimldp.hdcDst = hdc; pimldp.cbSize = Marshal.SizeOf(pimldp.GetType()); pimldp.i = index; pimldp.x = x; pimldp.y = y; pimldp.cx = cx; pimldp.cy = cy; pimldp.rgbFg = CLR_DEFAULT; pimldp.fStyle = (uint) flags; pimldp.fState = (uint) stateFlags; pimldp.himl = il.Handle; return ImageList_DrawIndirect(ref pimldp); } /// /// Make sure the ListView has the extended style that says to display subitem images. /// /// This method must be called after any .NET call that update the extended styles /// since they seem to erase this setting. /// The listview to send a m to public static void ForceSubItemImagesExStyle(ListView list) { SendMessage(list.Handle, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_SUBITEMIMAGES, LVS_EX_SUBITEMIMAGES); } /// /// Change the virtual list size of the given ListView (which must be in virtual mode) /// /// This will not change the scroll position /// The listview to send a message to /// How many rows should the list have? public static void SetItemCount(ListView list, int count) { SendMessage(list.Handle, LVM_SETITEMCOUNT, count, LVSICF_NOSCROLL); } /// /// Make sure the ListView has the extended style that says to display subitem images. /// /// This method must be called after any .NET call that update the extended styles /// since they seem to erase this setting. /// The listview to send a m to /// /// public static void SetExtendedStyle(ListView list, int style, int styleMask) { SendMessage(list.Handle, LVM_SETEXTENDEDLISTVIEWSTYLE, styleMask, style); } /// /// Calculates the number of items that can fit vertically in the visible area of a list-view (which /// must be in details or list view. /// /// The listView /// Number of visible items per page public static int GetCountPerPage(ListView list) { return (int)SendMessage(list.Handle, LVM_GETCOUNTPERPAGE, 0, 0); } /// /// For the given item and subitem, make it display the given image /// /// The listview to send a m to /// row number (0 based) /// subitem (0 is the item itself) /// index into the image list public static void SetSubItemImage(ListView list, int itemIndex, int subItemIndex, int imageIndex) { LVITEM lvItem = new LVITEM(); lvItem.mask = LVIF_IMAGE; lvItem.iItem = itemIndex; lvItem.iSubItem = subItemIndex; lvItem.iImage = imageIndex; SendMessageLVItem(list.Handle, LVM_SETITEM, 0, ref lvItem); } /// /// Setup the given column of the listview to show the given image to the right of the text. /// If the image index is -1, any previous image is cleared /// /// The listview to send a m to /// Index of the column to modifiy /// /// Index into the small image list public static void SetColumnImage(ListView list, int columnIndex, SortOrder order, int imageIndex) { IntPtr hdrCntl = GetHeaderControl(list); if (hdrCntl.ToInt32() == 0) return; HDITEM item = new HDITEM(); item.mask = HDI_FORMAT; IntPtr result = SendMessageHDItem(hdrCntl, HDM_GETITEM, columnIndex, ref item); item.fmt &= ~(HDF_SORTUP | HDF_SORTDOWN | HDF_IMAGE | HDF_BITMAP_ON_RIGHT); if (HasBuiltinSortIndicators()) { if (order == SortOrder.Ascending) item.fmt |= HDF_SORTUP; if (order == SortOrder.Descending) item.fmt |= HDF_SORTDOWN; } else { item.mask |= HDI_IMAGE; item.fmt |= (HDF_IMAGE | HDF_BITMAP_ON_RIGHT); item.iImage = imageIndex; } result = SendMessageHDItem(hdrCntl, HDM_SETITEM, columnIndex, ref item); } /// /// Does this version of the operating system have builtin sort indicators? /// /// Are there builtin sort indicators /// XP and later have these public static bool HasBuiltinSortIndicators() { return OSFeature.Feature.GetVersionPresent(OSFeature.Themes) != null; } /// /// Return the bounds of the update region on the given control. /// /// The BeginPaint() system call validates the update region, effectively wiping out this information. /// So this call has to be made before the BeginPaint() call. /// The control whose update region is be calculated /// A rectangle public static Rectangle GetUpdateRect(Control cntl) { Rectangle r = new Rectangle(); GetUpdateRectInternal(cntl.Handle, ref r, false); return r; } /// /// Validate an area of the given control. A validated area will not be repainted at the next redraw. /// /// The control to be validated /// The area of the control to be validated public static void ValidateRect(Control cntl, Rectangle r) { ValidatedRectInternal(cntl.Handle, ref r); } /// /// Select all rows on the given listview /// /// The listview whose items are to be selected public static void SelectAllItems(ListView list) { SetItemState(list, -1, LVIS_SELECTED, LVIS_SELECTED); } /// /// Deselect all rows on the given listview /// /// The listview whose items are to be deselected public static void DeselectAllItems(ListView list) { SetItemState(list, -1, LVIS_SELECTED, 0); } /// /// Deselect a single row /// /// /// public static void DeselectOneItem(ListView list, int index) { SetItemState(list, index, LVIS_SELECTED, 0); } /// /// Set the item state on the given item /// /// The listview whose item's state is to be changed /// The index of the item to be changed /// Which bits of the value are to be set? /// The value to be set public static void SetItemState(ListView list, int itemIndex, int mask, int value) { LVITEM lvItem = new LVITEM(); lvItem.stateMask = mask; lvItem.state = value; SendMessageLVItem(list.Handle, LVM_SETITEMSTATE, itemIndex, ref lvItem); } /// /// Scroll the given listview by the given deltas /// /// /// /// /// true if the scroll succeeded public static bool Scroll(ListView list, int dx, int dy) { return SendMessage(list.Handle, LVM_SCROLL, dx, dy) != IntPtr.Zero; } /// /// Return the handle to the header control on the given list /// /// The listview whose header control is to be returned /// The handle to the header control public static IntPtr GetHeaderControl(ListView list) { return SendMessage(list.Handle, LVM_GETHEADER, 0, 0); } /// /// Return the edges of the given column. /// /// /// /// A Point holding the left and right co-ords of the column. /// -1 means that the sides could not be retrieved. public static Point GetColumnSides(ObjectListView lv, int columnIndex) { Point sides = new Point(-1, -1); IntPtr hdr = GetHeaderControl(lv); if (hdr == IntPtr.Zero) return new Point(-1, -1); RECT r = new RECT(); SendMessageRECT(hdr, HDM_GETITEMRECT, columnIndex, ref r); return new Point(r.left, r.right); } /// /// Return the edges of the given column. /// /// /// /// A Point holding the left and right co-ords of the column. /// -1 means that the sides could not be retrieved. public static Point GetScrolledColumnSides(ListView lv, int columnIndex) { IntPtr hdr = GetHeaderControl(lv); if (hdr == IntPtr.Zero) return new Point(-1, -1); RECT r = new RECT(); IntPtr result = SendMessageRECT(hdr, HDM_GETITEMRECT, columnIndex, ref r); int scrollH = GetScrollPosition(lv, true); return new Point(r.left - scrollH, r.right - scrollH); } /// /// Return the index of the column of the header that is under the given point. /// Return -1 if no column is under the pt /// /// The list we are interested in /// The client co-ords /// The index of the column under the point, or -1 if no column header is under that point public static int GetColumnUnderPoint(IntPtr handle, Point pt) { const int HHT_ONHEADER = 2; const int HHT_ONDIVIDER = 4; return HeaderControlHitTest(handle, pt, HHT_ONHEADER | HHT_ONDIVIDER); } private static int HeaderControlHitTest(IntPtr handle, Point pt, int flag) { HDHITTESTINFO testInfo = new HDHITTESTINFO(); testInfo.pt_x = pt.X; testInfo.pt_y = pt.Y; IntPtr result = SendMessageHDHITTESTINFO(handle, HDM_HITTEST, IntPtr.Zero, testInfo); if ((testInfo.flags & flag) != 0) return testInfo.iItem; else return -1; } /// /// Return the index of the divider under the given point. Return -1 if no divider is under the pt /// /// The list we are interested in /// The client co-ords /// The index of the divider under the point, or -1 if no divider is under that point public static int GetDividerUnderPoint(IntPtr handle, Point pt) { const int HHT_ONDIVIDER = 4; return HeaderControlHitTest(handle, pt, HHT_ONDIVIDER); } /// /// Get the scroll position of the given scroll bar /// /// /// /// public static int GetScrollPosition(ListView lv, bool horizontalBar) { int fnBar = (horizontalBar ? SB_HORZ : SB_VERT); SCROLLINFO scrollInfo = new SCROLLINFO(); scrollInfo.fMask = SIF_POS; if (GetScrollInfo(lv.Handle, fnBar, scrollInfo)) return scrollInfo.nPos; else return -1; } /// /// Change the z-order to the window 'toBeMoved' so it appear directly on top of 'reference' /// /// /// /// public static bool ChangeZOrder(IWin32Window toBeMoved, IWin32Window reference) { return SetWindowPos(toBeMoved.Handle, reference.Handle, 0, 0, 0, 0, SWP_ZORDERONLY); } /// /// Make the given control/window a topmost window /// /// /// public static bool MakeTopMost(IWin32Window toBeMoved) { IntPtr HWND_TOPMOST = (IntPtr)(-1); return SetWindowPos(toBeMoved.Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_ZORDERONLY); } /// /// Change the size of the window without affecting any other attributes /// /// /// /// /// public static bool ChangeSize(IWin32Window toBeMoved, int width, int height) { return SetWindowPos(toBeMoved.Handle, IntPtr.Zero, 0, 0, width, height, SWP_SIZEONLY); } /// /// Show the given window without activating it /// /// The window to show static public void ShowWithoutActivate(IWin32Window win) { const int SW_SHOWNA = 8; ShowWindow(win.Handle, SW_SHOWNA); } /// /// Mark the given column as being selected. /// /// /// The OLVColumn or null to clear /// /// This method works, but it prevents subitems in the given column from having /// back colors. /// static public void SetSelectedColumn(ListView objectListView, ColumnHeader value) { SendMessage(objectListView.Handle, LVM_SETSELECTEDCOLUMN, (value == null) ? -1 : value.Index, 0); } static public int GetTopIndex(ListView lv) { return (int)SendMessage(lv.Handle, LVM_GETTOPINDEX, 0, 0); } static public IntPtr GetTooltipControl(ListView lv) { return SendMessage(lv.Handle, LVM_GETTOOLTIPS, 0, 0); } static public IntPtr SetTooltipControl(ListView lv, ToolTipControl tooltip) { return SendMessage(lv.Handle, LVM_SETTOOLTIPS, 0, tooltip.Handle); } static public bool HasHorizontalScrollBar(ListView lv) { const int GWL_STYLE = -16; const int WS_HSCROLL = 0x00100000; return (GetWindowLong(lv.Handle, GWL_STYLE) & WS_HSCROLL) != 0; } public static int GetWindowLong(IntPtr hWnd, int nIndex) { if (IntPtr.Size == 4) return (int)GetWindowLong32(hWnd, nIndex); else return (int)(long)GetWindowLongPtr64(hWnd, nIndex); } public static int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong) { if (IntPtr.Size == 4) return (int)SetWindowLongPtr32(hWnd, nIndex, dwNewLong); else return (int)(long)SetWindowLongPtr64(hWnd, nIndex, dwNewLong); } [DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)] public static extern IntPtr SetBkColor(IntPtr hDC, int clr); [DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)] public static extern IntPtr SetTextColor(IntPtr hDC, int crColor); [DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)] public static extern IntPtr SelectObject(IntPtr hdc, IntPtr obj); [DllImport("uxtheme.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)] public static extern IntPtr SetWindowTheme(IntPtr hWnd, string subApp, string subIdList); [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] public static extern bool InvalidateRect(IntPtr hWnd, int ignored, bool erase); [StructLayout(LayoutKind.Sequential)] public struct LVITEMINDEX { public int iItem; public int iGroup; } [StructLayout(LayoutKind.Sequential)] public struct POINT { public int x; public int y; } public static int GetGroupInfo(ObjectListView olv, int groupId, ref LVGROUP2 group) { return (int)SendMessage(olv.Handle, LVM_GETGROUPINFO, groupId, ref group); } public static GroupState GetGroupState(ObjectListView olv, int groupId, GroupState mask) { return (GroupState)SendMessage(olv.Handle, LVM_GETGROUPSTATE, groupId, (int)mask); } public static int InsertGroup(ObjectListView olv, LVGROUP2 group) { return (int)SendMessage(olv.Handle, LVM_INSERTGROUP, -1, ref group); } public static int SetGroupInfo(ObjectListView olv, int groupId, LVGROUP2 group) { return (int)SendMessage(olv.Handle, LVM_SETGROUPINFO, groupId, ref group); } public static int SetGroupMetrics(ObjectListView olv, LVGROUPMETRICS metrics) { return (int)SendMessage(olv.Handle, LVM_SETGROUPMETRICS, 0, ref metrics); } public static void ClearGroups(VirtualObjectListView virtualObjectListView) { SendMessage(virtualObjectListView.Handle, LVM_REMOVEALLGROUPS, 0, 0); } public static void SetGroupImageList(ObjectListView olv, ImageList il) { const int LVSIL_GROUPHEADER = 3; IntPtr handle = IntPtr.Zero; if (il != null) handle = il.Handle; SendMessage(olv.Handle, LVM_SETIMAGELIST, LVSIL_GROUPHEADER, handle); } public static int HitTest(ObjectListView olv, ref LVHITTESTINFO hittest) { return (int)SendMessage(olv.Handle, olv.View == View.Details ? LVM_SUBITEMHITTEST : LVM_HITTEST, -1, ref hittest); } } } ================================================ FILE: source/ObjectListView/Implementation/NullableDictionary.cs ================================================ /* * NullableDictionary - A simple Dictionary that can handle null as a key * * Author: Phillip Piper * Date: 31-March-2011 5:53 pm * * Change log: * 2011-03-31 JPP - Split into its own file * * Copyright (C) 2011-2014 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System.Collections.Generic; using System.Collections; namespace BrightIdeasSoftware { /// /// A simple-minded implementation of a Dictionary that can handle null as a key. /// /// The type of the dictionary key /// The type of the values to be stored /// This is not a full implementation and is only meant to handle /// collecting groups by their keys, since groups can have null as a key value. internal class NullableDictionary : Dictionary { private bool hasNullKey; private TValue nullValue; new public TValue this[TKey key] { get { if (key != null) return base[key]; if (hasNullKey) return nullValue; throw new KeyNotFoundException(); } set { if (key == null) { hasNullKey = true; nullValue = value; } else base[key] = value; } } new public bool ContainsKey(TKey key) { return key == null ? hasNullKey : base.ContainsKey(key); } new public IList Keys { get { ArrayList list = new ArrayList(base.Keys); if (hasNullKey) list.Add(null); return list; } } new public IList Values { get { List list = new List(base.Values); if (hasNullKey) list.Add(nullValue); return list; } } } } ================================================ FILE: source/ObjectListView/Implementation/OLVListItem.cs ================================================ /* * OLVListItem - A row in an ObjectListView * * Author: Phillip Piper * Date: 31-March-2011 5:53 pm * * Change log: * 2015-08-22 JPP - Added OLVListItem.SelectedBackColor and SelectedForeColor * 2015-06-09 JPP - Added HasAnyHyperlinks property * v2.8 * 2014-09-27 JPP - Remove faulty caching of CheckState * 2014-05-06 JPP - Added OLVListItem.Enabled flag * vOld * 2011-03-31 JPP - Split into its own file * * Copyright (C) 2011-2015 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System; using System.Collections.Generic; using System.Windows.Forms; using System.Drawing; using System.Linq; namespace BrightIdeasSoftware { /// /// OLVListItems are specialized ListViewItems that know which row object they came from, /// and the row index at which they are displayed, even when in group view mode. They /// also know the image they should draw against themselves /// public class OLVListItem : ListViewItem { #region Constructors /// /// Create a OLVListItem for the given row object /// public OLVListItem(object rowObject) { this.rowObject = rowObject; } /// /// Create a OLVListItem for the given row object, represented by the given string and image /// public OLVListItem(object rowObject, string text, Object image) : base(text, -1) { this.rowObject = rowObject; imageSelector = image; } #endregion. #region Properties /// /// Gets the bounding rectangle of the item, including all subitems /// new public Rectangle Bounds { get { try { return base.Bounds; } catch (ArgumentException) { // If the item is part of a collapsed group, Bounds will throw an exception return Rectangle.Empty; } } } /// /// Gets or sets how many pixels will be left blank around each cell of this item /// /// This setting only takes effect when the control is owner drawn. public Rectangle? CellPadding { get { return cellPadding; } set { cellPadding = value; } } private Rectangle? cellPadding; /// /// Gets or sets how the cells of this item will be vertically aligned /// /// This setting only takes effect when the control is owner drawn. public StringAlignment? CellVerticalAlignment { get { return cellVerticalAlignment; } set { cellVerticalAlignment = value; } } private StringAlignment? cellVerticalAlignment; /// /// Gets or sets the checkedness of this item. /// /// /// Virtual lists don't handle checkboxes well, so we have to intercept attempts to change them /// through the items, and change them into something that will work. /// Unfortunately, this won't work if this property is set through the base class, since /// the property is not declared as virtual. /// new public bool Checked { get { return base.Checked; } set { if (Checked != value) { if (value) ((ObjectListView)ListView).CheckObject(RowObject); else ((ObjectListView)ListView).UncheckObject(RowObject); } } } /// /// Enable tri-state checkbox. /// /// .NET's Checked property was not built to handle tri-state checkboxes, /// and will return True for both Checked and Indeterminate states. public CheckState CheckState { get { switch (StateImageIndex) { case 0: return CheckState.Unchecked; case 1: return CheckState.Checked; case 2: return CheckState.Indeterminate; default: return CheckState.Unchecked; } } set { switch (value) { case CheckState.Unchecked: StateImageIndex = 0; break; case CheckState.Checked: StateImageIndex = 1; break; case CheckState.Indeterminate: StateImageIndex = 2; break; } } } /// /// Gets if this item has any decorations set for it. /// public bool HasDecoration { get { return decorations != null && decorations.Count > 0; } } /// /// Gets or sets the decoration that will be drawn over this item /// /// Setting this replaces all other decorations public IDecoration Decoration { get { if (HasDecoration) return Decorations[0]; else return null; } set { Decorations.Clear(); if (value != null) Decorations.Add(value); } } /// /// Gets the collection of decorations that will be drawn over this item /// public IList Decorations { get { if (decorations == null) decorations = new List(); return decorations; } } private IList decorations; /// /// Gets whether or not this row can be selected and activated /// public bool Enabled { get { return enabled; } internal set { enabled = value; } } private bool enabled; /// /// Gets whether any cell on this item is showing a hyperlink /// public bool HasAnyHyperlinks { get { return SubItems.OfType().Any(subItem => !string.IsNullOrEmpty(subItem.Url)); } } /// /// Get or set the image that should be shown against this item /// /// This can be an Image, a string or an int. A string or an int will /// be used as an index into the small image list. public Object ImageSelector { get { return imageSelector; } set { imageSelector = value; if (value is Int32) ImageIndex = (Int32)value; else if (value is String) ImageKey = (String)value; else ImageIndex = -1; } } private Object imageSelector; /// /// Gets or sets the the model object that is source of the data for this list item. /// public object RowObject { get { return rowObject; } set { rowObject = value; } } private object rowObject; /// /// Gets or sets the color that will be used for this row's background when it is selected and /// the control is focused. /// /// /// To work reliably, this property must be set during a FormatRow event. /// /// If this is not set, the normal selection BackColor will be used. /// /// public Color? SelectedBackColor { get { return selectedBackColor; } set { selectedBackColor = value; } } private Color? selectedBackColor; /// /// Gets or sets the color that will be used for this row's foreground when it is selected and /// the control is focused. /// /// /// To work reliably, this property must be set during a FormatRow event. /// /// If this is not set, the normal selection ForeColor will be used. /// /// public Color? SelectedForeColor { get { return selectedForeColor; } set { selectedForeColor = value; } } private Color? selectedForeColor; #endregion #region Accessing /// /// Return the sub item at the given index /// /// Index of the subitem to be returned /// An OLVListSubItem public virtual OLVListSubItem GetSubItem(int index) { if (index >= 0 && index < SubItems.Count) return (OLVListSubItem)SubItems[index]; return null; } /// /// Return bounds of the given subitem /// /// This correctly calculates the bounds even for column 0. public virtual Rectangle GetSubItemBounds(int subItemIndex) { if (subItemIndex == 0) { Rectangle r = Bounds; Point sides = NativeMethods.GetScrolledColumnSides(ListView, subItemIndex); r.X = sides.X + 1; r.Width = sides.Y - sides.X; return r; } OLVListSubItem subItem = GetSubItem(subItemIndex); return subItem == null ? new Rectangle() : subItem.Bounds; } #endregion } } ================================================ FILE: source/ObjectListView/Implementation/OLVListSubItem.cs ================================================ /* * OLVListSubItem - A single cell in an ObjectListView * * Author: Phillip Piper * Date: 31-March-2011 5:53 pm * * Change log: * 2011-03-31 JPP - Split into its own file * * Copyright (C) 2011-2014 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System; using System.Collections.Generic; using System.Drawing; using System.Windows.Forms; using System.ComponentModel; namespace BrightIdeasSoftware { /// /// A ListViewSubItem that knows which image should be drawn against it. /// [Browsable(false)] public class OLVListSubItem : ListViewItem.ListViewSubItem { #region Constructors /// /// Create a OLVListSubItem /// public OLVListSubItem() { } /// /// Create a OLVListSubItem that shows the given string and image /// public OLVListSubItem(object modelValue, string text, Object image) { ModelValue = modelValue; Text = text; ImageSelector = image; } #endregion #region Properties /// /// Gets or sets how many pixels will be left blank around this cell /// /// This setting only takes effect when the control is owner drawn. public Rectangle? CellPadding { get { return cellPadding; } set { cellPadding = value; } } private Rectangle? cellPadding; /// /// Gets or sets how this cell will be vertically aligned /// /// This setting only takes effect when the control is owner drawn. public StringAlignment? CellVerticalAlignment { get { return cellVerticalAlignment; } set { cellVerticalAlignment = value; } } private StringAlignment? cellVerticalAlignment; /// /// Gets or sets the model value is being displayed by this subitem. /// public object ModelValue { get { return modelValue; } private set { modelValue = value; } } private object modelValue; /// /// Gets if this subitem has any decorations set for it. /// public bool HasDecoration { get { return decorations != null && decorations.Count > 0; } } /// /// Gets or sets the decoration that will be drawn over this item /// /// Setting this replaces all other decorations public IDecoration Decoration { get { return HasDecoration ? Decorations[0] : null; } set { Decorations.Clear(); if (value != null) Decorations.Add(value); } } /// /// Gets the collection of decorations that will be drawn over this item /// public IList Decorations { get { if (decorations == null) decorations = new List(); return decorations; } } private IList decorations; /// /// Get or set the image that should be shown against this item /// /// This can be an Image, a string or an int. A string or an int will /// be used as an index into the small image list. public Object ImageSelector { get { return imageSelector; } set { imageSelector = value; } } private Object imageSelector; /// /// Gets or sets the url that should be invoked when this subitem is clicked /// public string Url { get { return url; } set { url = value; } } private string url; /// /// Gets or sets whether this cell is selected /// public bool Selected { get { return selected; } set { selected = value; } } private bool selected; #endregion #region Implementation Properties /// /// Return the state of the animatation of the image on this subitem. /// Null means there is either no image, or it is not an animation /// internal ImageRenderer.AnimationState AnimationState; #endregion } } ================================================ FILE: source/ObjectListView/Implementation/OlvListViewHitTestInfo.cs ================================================ /* * OlvListViewHitTestInfo - All information gathered during a OlvHitTest() operation * * Author: Phillip Piper * Date: 31-March-2011 5:53 pm * * Change log: * 2011-03-31 JPP - Split into its own file * * Copyright (C) 2011-2014 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System; using System.Windows.Forms; namespace BrightIdeasSoftware { /// /// An indication of where a hit was within ObjectListView cell /// public enum HitTestLocation { /// /// Nowhere /// Nothing, /// /// On the text /// Text, /// /// On the image /// Image, /// /// On the checkbox /// CheckBox, /// /// On the expand button (TreeListView) /// ExpandButton, /// /// in a button (cell must have ButtonRenderer) /// Button, /// /// in the cell but not in any more specific location /// InCell, /// /// UserDefined location1 (used for custom renderers) /// UserDefined, /// /// On the expand/collapse widget of the group /// GroupExpander, /// /// Somewhere on a group /// Group, /// /// Somewhere in a column header /// Header, /// /// Somewhere in a column header checkbox /// HeaderCheckBox, /// /// Somewhere in a header divider /// HeaderDivider, } /// /// A collection of ListViewHitTest constants /// [Flags] public enum HitTestLocationEx { /// /// /// LVHT_NOWHERE = 0x00000001, /// /// /// LVHT_ONITEMICON = 0x00000002, /// /// /// LVHT_ONITEMLABEL = 0x00000004, /// /// /// LVHT_ONITEMSTATEICON = 0x00000008, /// /// /// LVHT_ONITEM = (LVHT_ONITEMICON | LVHT_ONITEMLABEL | LVHT_ONITEMSTATEICON), /// /// /// LVHT_ABOVE = 0x00000008, /// /// /// LVHT_BELOW = 0x00000010, /// /// /// LVHT_TORIGHT = 0x00000020, /// /// /// LVHT_TOLEFT = 0x00000040, /// /// /// LVHT_EX_GROUP_HEADER = 0x10000000, /// /// /// LVHT_EX_GROUP_FOOTER = 0x20000000, /// /// /// LVHT_EX_GROUP_COLLAPSE = 0x40000000, /// /// /// LVHT_EX_GROUP_BACKGROUND = -2147483648, // 0x80000000 /// /// /// LVHT_EX_GROUP_STATEICON = 0x01000000, /// /// /// LVHT_EX_GROUP_SUBSETLINK = 0x02000000, /// /// /// LVHT_EX_GROUP = (LVHT_EX_GROUP_BACKGROUND | LVHT_EX_GROUP_COLLAPSE | LVHT_EX_GROUP_FOOTER | LVHT_EX_GROUP_HEADER | LVHT_EX_GROUP_STATEICON | LVHT_EX_GROUP_SUBSETLINK), /// /// /// LVHT_EX_GROUP_MINUS_FOOTER_AND_BKGRD = (LVHT_EX_GROUP_COLLAPSE | LVHT_EX_GROUP_HEADER | LVHT_EX_GROUP_STATEICON | LVHT_EX_GROUP_SUBSETLINK), /// /// /// LVHT_EX_ONCONTENTS = 0x04000000, // On item AND not on the background /// /// /// LVHT_EX_FOOTER = 0x08000000, } /// /// Instances of this class encapsulate the information gathered during a OlvHitTest() /// operation. /// /// Custom renderers can use HitTestLocation.UserDefined and the UserData /// object to store more specific locations for use during event handlers. public class OlvListViewHitTestInfo { /// /// Create a OlvListViewHitTestInfo /// public OlvListViewHitTestInfo(OLVListItem olvListItem, OLVListSubItem subItem, int flags, OLVGroup group, int iColumn) { item = olvListItem; this.subItem = subItem; location = ConvertNativeFlagsToDotNetLocation(olvListItem, flags); HitTestLocationEx = (HitTestLocationEx)flags; Group = group; ColumnIndex = iColumn; ListView = olvListItem == null ? null : (ObjectListView)olvListItem.ListView; switch (location) { case ListViewHitTestLocations.StateImage: HitTestLocation = HitTestLocation.CheckBox; break; case ListViewHitTestLocations.Image: HitTestLocation = HitTestLocation.Image; break; case ListViewHitTestLocations.Label: HitTestLocation = HitTestLocation.Text; break; default: if ((HitTestLocationEx & HitTestLocationEx.LVHT_EX_GROUP_COLLAPSE) == HitTestLocationEx.LVHT_EX_GROUP_COLLAPSE) HitTestLocation = HitTestLocation.GroupExpander; else if ((HitTestLocationEx & HitTestLocationEx.LVHT_EX_GROUP_MINUS_FOOTER_AND_BKGRD) != 0) HitTestLocation = HitTestLocation.Group; else HitTestLocation = HitTestLocation.Nothing; break; } } /// /// Create a OlvListViewHitTestInfo when the header was hit /// public OlvListViewHitTestInfo(ObjectListView olv, int iColumn, bool isOverCheckBox, int iDivider) { ListView = olv; ColumnIndex = iColumn; HeaderDividerIndex = iDivider; HitTestLocation = isOverCheckBox ? HitTestLocation.HeaderCheckBox : (iDivider < 0 ? HitTestLocation.Header : HitTestLocation.HeaderDivider); } private static ListViewHitTestLocations ConvertNativeFlagsToDotNetLocation(OLVListItem hitItem, int flags) { // Untangle base .NET behaviour. // In Windows SDK, the value 8 can have two meanings here: LVHT_ONITEMSTATEICON or LVHT_ABOVE. // .NET changes these to be: // - LVHT_ABOVE becomes ListViewHitTestLocations.AboveClientArea (which is 0x100). // - LVHT_ONITEMSTATEICON becomes ListViewHitTestLocations.StateImage (which is 0x200). // So, if we see the 8 bit set in flags, we change that to either a state image hit // (if we hit an item) or to AboveClientAream if nothing was hit. if ((8 & flags) == 8) return (ListViewHitTestLocations)(0xf7 & flags | (hitItem == null ? 0x100 : 0x200)); // Mask off the LVHT_EX_XXXX values since ListViewHitTestLocations doesn't have them return (ListViewHitTestLocations)(flags & 0xffff); } #region Public fields /// /// Where is the hit location? /// public HitTestLocation HitTestLocation; /// /// Where is the hit location? /// public HitTestLocationEx HitTestLocationEx; /// /// Which group was hit? /// public OLVGroup Group; /// /// Custom renderers can use this information to supply more details about the hit location /// public Object UserData; #endregion #region Public read-only properties /// /// Gets the item that was hit /// public OLVListItem Item { get { return item; } internal set { item = value; } } private OLVListItem item; /// /// Gets the subitem that was hit /// public OLVListSubItem SubItem { get { return subItem; } internal set { subItem = value; } } private OLVListSubItem subItem; /// /// Gets the part of the subitem that was hit /// public ListViewHitTestLocations Location { get { return location; } internal set { location = value; } } private ListViewHitTestLocations location; /// /// Gets the ObjectListView that was tested /// public ObjectListView ListView { get { return listView; } internal set { listView = value; } } private ObjectListView listView; /// /// Gets the model object that was hit /// public Object RowObject { get { return Item == null ? null : Item.RowObject; } } /// /// Gets the index of the row under the hit point or -1 /// public int RowIndex { get { return Item == null ? -1 : Item.Index; } } /// /// Gets the index of the column under the hit point /// public int ColumnIndex { get { return columnIndex; } internal set { columnIndex = value; } } private int columnIndex; /// /// Gets the index of the header divider /// public int HeaderDividerIndex { get { return headerDividerIndex; } internal set { headerDividerIndex = value; } } private int headerDividerIndex = -1; /// /// Gets the column that was hit /// public OLVColumn Column { get { int index = ColumnIndex; return index < 0 || ListView == null ? null : ListView.GetColumn(index); } } #endregion /// /// Returns a string that represents the current object. /// /// /// A string that represents the current object. /// /// 2 public override string ToString() { return string.Format("HitTestLocation: {0}, HitTestLocationEx: {1}, Item: {2}, SubItem: {3}, Location: {4}, Group: {5}, ColumnIndex: {6}", HitTestLocation, HitTestLocationEx, item, subItem, location, Group, ColumnIndex); } internal class HeaderHitTestInfo { public int ColumnIndex; public bool IsOverCheckBox; public int OverDividerIndex; } } } ================================================ FILE: source/ObjectListView/Implementation/TreeDataSourceAdapter.cs ================================================ using System.Collections; using System.ComponentModel; namespace BrightIdeasSoftware { /// /// A TreeDataSourceAdapter knows how to build a tree structure from a binding list. /// /// To build a tree public class TreeDataSourceAdapter : DataSourceAdapter { #region Life and death /// /// Create a data source adaptor that knows how to build a tree structure /// /// public TreeDataSourceAdapter(DataTreeListView tlv) : base(tlv) { treeListView = tlv; treeListView.CanExpandGetter = delegate(object model) { return CalculateHasChildren(model); }; treeListView.ChildrenGetter = delegate(object model) { return CalculateChildren(model); }; } #endregion #region Properties /// /// Gets or sets the name of the property/column that uniquely identifies each row. /// /// /// /// The value contained by this column must be unique across all rows /// in the data source. Odd and unpredictable things will happen if two /// rows have the same id. /// /// Null cannot be a valid key value. /// public virtual string KeyAspectName { get { return keyAspectName; } set { if (keyAspectName == value) return; keyAspectName = value; keyMunger = new Munger(KeyAspectName); InitializeDataSource(); } } private string keyAspectName; /// /// Gets or sets the name of the property/column that contains the key of /// the parent of a row. /// /// /// /// The test condition for deciding if one row is the parent of another is functionally /// equivilent to this: /// /// Object.Equals(candidateParentRow[this.KeyAspectName], row[this.ParentKeyAspectName]) /// /// /// Unlike key value, parent keys can be null but a null parent key can only be used /// to identify root objects. /// public virtual string ParentKeyAspectName { get { return parentKeyAspectName; } set { if (parentKeyAspectName == value) return; parentKeyAspectName = value; parentKeyMunger = new Munger(ParentKeyAspectName); InitializeDataSource(); } } private string parentKeyAspectName; /// /// Gets or sets the value that identifies a row as a root object. /// When the ParentKey of a row equals the RootKeyValue, that row will /// be treated as root of the TreeListView. /// /// /// /// The test condition for deciding a root object is functionally /// equivilent to this: /// /// Object.Equals(candidateRow[this.ParentKeyAspectName], this.RootKeyValue) /// /// /// The RootKeyValue can be null. /// public virtual object RootKeyValue { get { return rootKeyValue; } set { if (Equals(rootKeyValue, value)) return; rootKeyValue = value; InitializeDataSource(); } } private object rootKeyValue; /// /// Gets or sets whether or not the key columns (id and parent id) should /// be shown to the user. /// /// This must be set before the DataSource is set. It has no effect /// afterwards. public virtual bool ShowKeyColumns { get { return showKeyColumns; } set { showKeyColumns = value; } } private bool showKeyColumns = true; #endregion #region Implementation properties /// /// Gets the DataTreeListView that is being managed /// protected DataTreeListView TreeListView { get { return treeListView; } } private readonly DataTreeListView treeListView; #endregion #region Implementation /// /// /// protected override void InitializeDataSource() { base.InitializeDataSource(); TreeListView.RebuildAll(true); } /// /// /// protected override void SetListContents() { TreeListView.Roots = CalculateRoots(); } /// /// /// /// /// protected override bool ShouldCreateColumn(PropertyDescriptor property) { // If the property is a key column, and we aren't supposed to show keys, don't show it if (!ShowKeyColumns && (property.Name == KeyAspectName || property.Name == ParentKeyAspectName)) return false; return base.ShouldCreateColumn(property); } /// /// /// /// protected override void HandleListChangedItemChanged(ListChangedEventArgs e) { // If the id or the parent id of a row changes, we just rebuild everything. // We can't do anything more specific. We don't know what the previous values, so we can't // tell the previous parent to refresh itself. If the id itself has changed, things that used // to be children will no longer be children. Just rebuild everything. // It seems PropertyDescriptor is only filled in .NET 4 :( if (e.PropertyDescriptor != null && (e.PropertyDescriptor.Name == KeyAspectName || e.PropertyDescriptor.Name == ParentKeyAspectName)) InitializeDataSource(); else base.HandleListChangedItemChanged(e); } /// /// /// /// protected override void ChangePosition(int index) { // We can't use our base method directly, since the normal position management // doesn't know about our tree structure. They treat our dataset as a flat list // but we have a collapsable structure. This means that the 5'th row to them // may not even be visible to us // To display the n'th row, we have to make sure that all its ancestors // are expanded. Then we will be able to select it. object model = CurrencyManager.List[index]; object parent = CalculateParent(model); while (parent != null && !TreeListView.IsExpanded(parent)) { TreeListView.Expand(parent); parent = CalculateParent(parent); } base.ChangePosition(index); } private IEnumerable CalculateRoots() { foreach (object x in CurrencyManager.List) { object parentKey = GetParentValue(x); if (Equals(RootKeyValue, parentKey)) yield return x; } } private bool CalculateHasChildren(object model) { object keyValue = GetKeyValue(model); if (keyValue == null) return false; foreach (object x in CurrencyManager.List) { object parentKey = GetParentValue(x); if (Equals(keyValue, parentKey)) return true; } return false; } private IEnumerable CalculateChildren(object model) { object keyValue = GetKeyValue(model); if (keyValue != null) { foreach (object x in CurrencyManager.List) { object parentKey = GetParentValue(x); if (Equals(keyValue, parentKey)) yield return x; } } } private object CalculateParent(object model) { object parentValue = GetParentValue(model); if (parentValue == null) return null; foreach (object x in CurrencyManager.List) { object key = GetKeyValue(x); if (Equals(parentValue, key)) return x; } return null; } private object GetKeyValue(object model) { return keyMunger == null ? null : keyMunger.GetValue(model); } private object GetParentValue(object model) { return parentKeyMunger == null ? null : parentKeyMunger.GetValue(model); } #endregion private Munger keyMunger; private Munger parentKeyMunger; } } ================================================ FILE: source/ObjectListView/Implementation/VirtualGroups.cs ================================================ /* * Virtual groups - Classes and interfaces needed to implement virtual groups * * Author: Phillip Piper * Date: 28/08/2009 11:10am * * Change log: * 2011-02-21 JPP - Correctly honor group comparer and collapsible groups settings * v2.3 * 2009-08-28 JPP - Initial version * * To do: * * Copyright (C) 2009-2014 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System; using System.Collections.Generic; using System.Windows.Forms; using System.Runtime.InteropServices; namespace BrightIdeasSoftware { /// /// A IVirtualGroups is the interface that a virtual list must implement to support virtual groups /// public interface IVirtualGroups { /// /// Return the list of groups that should be shown according to the given parameters /// /// /// IList GetGroups(GroupingParameters parameters); /// /// Return the index of the item that appears at the given position within the given group. /// /// /// /// int GetGroupMember(OLVGroup group, int indexWithinGroup); /// /// Return the index of the group to which the given item belongs /// /// /// int GetGroup(int itemIndex); /// /// Return the index at which the given item is shown in the given group /// /// /// /// int GetIndexWithinGroup(OLVGroup group, int itemIndex); /// /// A hint that the given range of items are going to be required /// /// /// /// /// void CacheHint(int fromGroupIndex, int fromIndex, int toGroupIndex, int toIndex); } /// /// This is a safe, do nothing implementation of a grouping strategy /// public class AbstractVirtualGroups : IVirtualGroups { /// /// Return the list of groups that should be shown according to the given parameters /// /// /// public virtual IList GetGroups(GroupingParameters parameters) { return new List(); } /// /// Return the index of the item that appears at the given position within the given group. /// /// /// /// public virtual int GetGroupMember(OLVGroup group, int indexWithinGroup) { return -1; } /// /// Return the index of the group to which the given item belongs /// /// /// public virtual int GetGroup(int itemIndex) { return -1; } /// /// Return the index at which the given item is shown in the given group /// /// /// /// public virtual int GetIndexWithinGroup(OLVGroup group, int itemIndex) { return -1; } /// /// A hint that the given range of items are going to be required /// /// /// /// /// public virtual void CacheHint(int fromGroupIndex, int fromIndex, int toGroupIndex, int toIndex) { } } /// /// Provides grouping functionality to a FastObjectListView /// public class FastListGroupingStrategy : AbstractVirtualGroups { /// /// Create groups for FastListView /// /// /// public override IList GetGroups(GroupingParameters parmameters) { // There is a lot of overlap between this method and ObjectListView.MakeGroups() // Any changes made here may need to be reflected there // This strategy can only be used on FastObjectListViews FastObjectListView folv = (FastObjectListView)parmameters.ListView; // Separate the list view items into groups, using the group key as the descrimanent int objectCount = 0; NullableDictionary> map = new NullableDictionary>(); foreach (object model in folv.FilteredObjects) { object key = parmameters.GroupByColumn.GetGroupKey(model); if (!map.ContainsKey(key)) map[key] = new List(); map[key].Add(model); objectCount++; } // Sort the items within each group // TODO: Give parameters a ModelComparer property OLVColumn primarySortColumn = parmameters.SortItemsByPrimaryColumn ? parmameters.ListView.GetColumn(0) : parmameters.PrimarySort; ModelObjectComparer sorter = new ModelObjectComparer(primarySortColumn, parmameters.PrimarySortOrder, parmameters.SecondarySort, parmameters.SecondarySortOrder); foreach (object key in map.Keys) { map[key].Sort(sorter); } // Make a list of the required groups List groups = new List(); foreach (object key in map.Keys) { string title = parmameters.GroupByColumn.ConvertGroupKeyToTitle(key); if (!String.IsNullOrEmpty(parmameters.TitleFormat)) { int count = map[key].Count; string format = (count == 1 ? parmameters.TitleSingularFormat : parmameters.TitleFormat); try { title = String.Format(format, title, count); } catch (FormatException) { title = "Invalid group format: " + format; } } OLVGroup lvg = new OLVGroup(title); lvg.Collapsible = folv.HasCollapsibleGroups; lvg.Key = key; lvg.SortValue = key as IComparable; lvg.Contents = map[key].ConvertAll(delegate(object x) { return folv.IndexOf(x); }); lvg.VirtualItemCount = map[key].Count; if (parmameters.GroupByColumn.GroupFormatter != null) parmameters.GroupByColumn.GroupFormatter(lvg, parmameters); groups.Add(lvg); } // Sort the groups if (parmameters.GroupByOrder != SortOrder.None) groups.Sort(parmameters.GroupComparer ?? new OLVGroupComparer(parmameters.GroupByOrder)); // Build an array that remembers which group each item belongs to. indexToGroupMap = new List(objectCount); indexToGroupMap.AddRange(new int[objectCount]); for (int i = 0; i < groups.Count; i++) { OLVGroup group = groups[i]; List members = (List)group.Contents; foreach (int j in members) indexToGroupMap[j] = i; } return groups; } private List indexToGroupMap; /// /// /// /// /// /// public override int GetGroupMember(OLVGroup group, int indexWithinGroup) { return (int)group.Contents[indexWithinGroup]; } /// /// /// /// /// public override int GetGroup(int itemIndex) { return indexToGroupMap[itemIndex]; } /// /// /// /// /// /// public override int GetIndexWithinGroup(OLVGroup group, int itemIndex) { return group.Contents.IndexOf(itemIndex); } } /// /// This is the COM interface that a ListView must be given in order for groups in virtual lists to work. /// /// /// This interface is NOT documented by MS. It was found on Greg Chapell's site. This means that there is /// no guarantee that it will work on future versions of Windows, nor continue to work on current ones. /// [ComImport(), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("44C09D56-8D3B-419D-A462-7B956B105B47")] internal interface IOwnerDataCallback { /// /// Not sure what this does /// /// /// void GetItemPosition(int i, out NativeMethods.POINT pt); /// /// Not sure what this does /// /// /// void SetItemPosition(int t, NativeMethods.POINT pt); /// /// Get the index of the item that occurs at the n'th position of the indicated group. /// /// Index of the group /// Index within the group /// Index of the item within the whole list void GetItemInGroup(int groupIndex, int n, out int itemIndex); /// /// Get the index of the group to which the given item belongs /// /// Index of the item within the whole list /// Which occurences of the item is wanted /// Index of the group void GetItemGroup(int itemIndex, int occurrenceCount, out int groupIndex); /// /// Get the number of groups that contain the given item /// /// Index of the item within the whole list /// How many groups does it occur within void GetItemGroupCount(int itemIndex, out int occurrenceCount); /// /// A hint to prepare any cache for the given range of requests /// /// /// void OnCacheHint(NativeMethods.LVITEMINDEX i, NativeMethods.LVITEMINDEX j); } /// /// A default implementation of the IOwnerDataCallback interface /// [Guid("6FC61F50-80E8-49b4-B200-3F38D3865ABD")] internal class OwnerDataCallbackImpl : IOwnerDataCallback { public OwnerDataCallbackImpl(VirtualObjectListView olv) { this.olv = olv; } VirtualObjectListView olv; #region IOwnerDataCallback Members public void GetItemPosition(int i, out NativeMethods.POINT pt) { //System.Diagnostics.Debug.WriteLine("GetItemPosition"); throw new NotSupportedException(); } public void SetItemPosition(int t, NativeMethods.POINT pt) { //System.Diagnostics.Debug.WriteLine("SetItemPosition"); throw new NotSupportedException(); } public void GetItemInGroup(int groupIndex, int n, out int itemIndex) { //System.Diagnostics.Debug.WriteLine(String.Format("-> GetItemInGroup({0}, {1})", groupIndex, n)); itemIndex = olv.GroupingStrategy.GetGroupMember(olv.OLVGroups[groupIndex], n); //System.Diagnostics.Debug.WriteLine(String.Format("<- {0}", itemIndex)); } public void GetItemGroup(int itemIndex, int occurrenceCount, out int groupIndex) { //System.Diagnostics.Debug.WriteLine(String.Format("GetItemGroup({0}, {1})", itemIndex, occurrenceCount)); groupIndex = olv.GroupingStrategy.GetGroup(itemIndex); //System.Diagnostics.Debug.WriteLine(String.Format("<- {0}", groupIndex)); } public void GetItemGroupCount(int itemIndex, out int occurrenceCount) { //System.Diagnostics.Debug.WriteLine(String.Format("GetItemGroupCount({0})", itemIndex)); occurrenceCount = 1; } public void OnCacheHint(NativeMethods.LVITEMINDEX from, NativeMethods.LVITEMINDEX to) { //System.Diagnostics.Debug.WriteLine(String.Format("OnCacheHint({0}, {1}, {2}, {3})", from.iGroup, from.iItem, to.iGroup, to.iItem)); olv.GroupingStrategy.CacheHint(from.iGroup, from.iItem, to.iGroup, to.iItem); } #endregion } } ================================================ FILE: source/ObjectListView/Implementation/VirtualListDataSource.cs ================================================ /* * VirtualListDataSource - Encapsulate how data is provided to a virtual list * * Author: Phillip Piper * Date: 28/08/2009 11:10am * * Change log: * v2.4 * 2010-04-01 JPP - Added IFilterableDataSource * v2.3 * 2009-08-28 JPP - Initial version (Separated from VirtualObjectListView.cs) * * To do: * * Copyright (C) 2009-2014 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System; using System.Collections; using System.Windows.Forms; namespace BrightIdeasSoftware { /// /// A VirtualListDataSource is a complete manner to provide functionality to a virtual list. /// An object that implements this interface provides a VirtualObjectListView with all the /// information it needs to be fully functional. /// /// Implementors must provide functioning implementations of at least GetObjectCount() /// and GetNthObject(), otherwise nothing will appear in the list. public interface IVirtualListDataSource { /// /// Return the object that should be displayed at the n'th row. /// /// The index of the row whose object is to be returned. /// The model object at the n'th row, or null if the fetching was unsuccessful. Object GetNthObject(int n); /// /// Return the number of rows that should be visible in the virtual list /// /// The number of rows the list view should have. int GetObjectCount(); /// /// Get the index of the row that is showing the given model object /// /// The model object sought /// The index of the row showing the model, or -1 if the object could not be found. int GetObjectIndex(Object model); /// /// The ListView is about to request the given range of items. Do /// whatever caching seems appropriate. /// /// /// void PrepareCache(int first, int last); /// /// Find the first row that "matches" the given text in the given range. /// /// The text typed by the user /// Start searching from this index. This may be greater than the 'to' parameter, /// in which case the search should descend /// Do not search beyond this index. This may be less than the 'from' parameter. /// The column that should be considered when looking for a match. /// Return the index of row that was matched, or -1 if no match was found int SearchText(string value, int first, int last, OLVColumn column); /// /// Sort the model objects in the data source. /// /// /// void Sort(OLVColumn column, SortOrder order); //----------------------------------------------------------------------------------- // Modification commands // THINK: Should we split these four into a separate interface? /// /// Add the given collection of model objects to this control. /// /// A collection of model objects void AddObjects(ICollection modelObjects); /// /// Insert the given collection of model objects to this control at the position /// /// Index where the collection will be added /// A collection of model objects void InsertObjects(int index, ICollection modelObjects); /// /// Remove all of the given objects from the control /// /// Collection of objects to be removed void RemoveObjects(ICollection modelObjects); /// /// Set the collection of objects that this control will show. /// /// void SetObjects(IEnumerable collection); /// /// Update/replace the nth object with the given object /// /// /// void UpdateObject(int index, object modelObject); } /// /// This extension allow virtual lists to filter their contents /// public interface IFilterableDataSource { /// /// All subsequent retrievals on this data source should be filtered /// through the given filters. null means no filtering of that kind. /// /// /// void ApplyFilters(IModelFilter modelFilter, IListFilter listFilter); } /// /// A do-nothing implementation of the VirtualListDataSource interface. /// public class AbstractVirtualListDataSource : IVirtualListDataSource, IFilterableDataSource { /// /// Creates an AbstractVirtualListDataSource /// /// public AbstractVirtualListDataSource(VirtualObjectListView listView) { this.listView = listView; } /// /// The list view that this data source is giving information to. /// protected VirtualObjectListView listView; /// /// /// /// /// public virtual object GetNthObject(int n) { return null; } /// /// /// /// public virtual int GetObjectCount() { return -1; } /// /// /// /// /// public virtual int GetObjectIndex(object model) { return -1; } /// /// /// /// /// public virtual void PrepareCache(int from, int to) { } /// /// /// /// /// /// /// /// public virtual int SearchText(string value, int first, int last, OLVColumn column) { return -1; } /// /// /// /// /// public virtual void Sort(OLVColumn column, SortOrder order) { } /// /// /// /// public virtual void AddObjects(ICollection modelObjects) { } /// /// /// /// /// public virtual void InsertObjects(int index, ICollection modelObjects) { } /// /// /// /// public virtual void RemoveObjects(ICollection modelObjects) { } /// /// /// /// public virtual void SetObjects(IEnumerable collection) { } /// /// Update/replace the nth object with the given object /// /// /// public virtual void UpdateObject(int index, object modelObject) { } /// /// This is a useful default implementation of SearchText method, intended to be called /// by implementors of IVirtualListDataSource. /// /// /// /// /// /// /// static public int DefaultSearchText(string value, int first, int last, OLVColumn column, IVirtualListDataSource source) { if (first <= last) { for (int i = first; i <= last; i++) { string data = column.GetStringValue(source.GetNthObject(i)); if (data.StartsWith(value, StringComparison.CurrentCultureIgnoreCase)) return i; } } else { for (int i = first; i >= last; i--) { string data = column.GetStringValue(source.GetNthObject(i)); if (data.StartsWith(value, StringComparison.CurrentCultureIgnoreCase)) return i; } } return -1; } #region IFilterableDataSource Members /// /// /// /// /// virtual public void ApplyFilters(IModelFilter modelFilter, IListFilter listFilter) { } #endregion } /// /// This class mimics the behavior of VirtualObjectListView v1.x. /// public class VirtualListVersion1DataSource : AbstractVirtualListDataSource { /// /// Creates a VirtualListVersion1DataSource /// /// public VirtualListVersion1DataSource(VirtualObjectListView listView) : base(listView) { } #region Public properties /// /// How will the n'th object of the data source be fetched? /// public RowGetterDelegate RowGetter { get { return rowGetter; } set { rowGetter = value; } } private RowGetterDelegate rowGetter; #endregion #region IVirtualListDataSource implementation /// /// /// /// /// public override object GetNthObject(int n) { if (RowGetter == null) return null; else return RowGetter(n); } /// /// /// /// /// /// /// /// public override int SearchText(string value, int first, int last, OLVColumn column) { return DefaultSearchText(value, first, last, column, this); } #endregion } } ================================================ FILE: source/ObjectListView/OLVColumn.cs ================================================ /* * OLVColumn - A column in an ObjectListView * * Author: Phillip Piper * Date: 31-March-2011 5:53 pm * * Change log: * 2015-06-12 JPP - HeaderTextAlign became nullable so that it can be "not set" (this was always the intent) * 2014-09-07 JPP - Added ability to have checkboxes in headers * * 2011-05-27 JPP - Added Sortable, Hideable, Groupable, Searchable, ShowTextInHeader properties * 2011-04-12 JPP - Added HasFilterIndicator * 2011-03-31 JPP - Split into its own file * * Copyright (C) 2011-2014 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System; using System.ComponentModel; using System.Windows.Forms; using System.Drawing; using System.Collections; using System.Drawing.Design; namespace BrightIdeasSoftware { // TODO //[TypeConverter(typeof(ExpandableObjectConverter))] //public class CheckBoxSettings //{ // private bool useSettings; // private Image checkedImage; // public bool UseSettings { // get { return useSettings; } // set { useSettings = value; } // } // public Image CheckedImage { // get { return checkedImage; } // set { checkedImage = value; } // } // public Image UncheckedImage { // get { return checkedImage; } // set { checkedImage = value; } // } // public Image IndeterminateImage { // get { return checkedImage; } // set { checkedImage = value; } // } //} /// /// An OLVColumn knows which aspect of an object it should present. /// /// /// The column knows how to: /// /// extract its aspect from the row object /// convert an aspect to a string /// calculate the image for the row object /// extract a group "key" from the row object /// convert a group "key" into a title for the group /// /// For sorting to work correctly, aspects from the same column /// must be of the same type, that is, the same aspect cannot sometimes /// return strings and other times integers. /// [Browsable(false)] public partial class OLVColumn : ColumnHeader { /// /// How should the button be sized? /// public enum ButtonSizingMode { /// /// Every cell will have the same sized button, as indicated by ButtonSize property /// FixedBounds, /// /// Every cell will draw a button that fills the cell, inset by ButtonPadding /// CellBounds, /// /// Each button will be resized to contain the text of the Aspect /// TextBounds } #region Life and death /// /// Create an OLVColumn /// public OLVColumn() { } /// /// Initialize a column to have the given title, and show the given aspect /// /// The title of the column /// The aspect to be shown in the column public OLVColumn(string title, string aspect) : this() { Text = title; AspectName = aspect; } #endregion #region Public Properties /// /// This delegate will be used to extract a value to be displayed in this column. /// /// /// If this is set, AspectName is ignored. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public AspectGetterDelegate AspectGetter { get { return aspectGetter; } set { aspectGetter = value; } } private AspectGetterDelegate aspectGetter; /// /// Remember if this aspect getter for this column was generated internally, and can therefore /// be regenerated at will /// [Obsolete("This property is no longer maintained", true), Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool AspectGetterAutoGenerated { get { return aspectGetterAutoGenerated; } set { aspectGetterAutoGenerated = value; } } private bool aspectGetterAutoGenerated; /// /// The name of the property or method that should be called to get the value to display in this column. /// This is only used if a ValueGetterDelegate has not been given. /// /// This name can be dotted to chain references to properties or parameter-less methods. /// "DateOfBirth" /// "Owner.HomeAddress.Postcode" [Category("ObjectListView"), Description("The name of the property or method that should be called to get the aspect to display in this column"), DefaultValue(null)] public string AspectName { get { return aspectName; } set { aspectName = value; aspectMunger = null; } } private string aspectName; /// /// This delegate will be used to put an edited value back into the model object. /// /// /// This does nothing if IsEditable == false. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public AspectPutterDelegate AspectPutter { get { return aspectPutter; } set { aspectPutter = value; } } private AspectPutterDelegate aspectPutter; /// /// The delegate that will be used to translate the aspect to display in this column into a string. /// /// If this value is set, AspectToStringFormat will be ignored. [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public AspectToStringConverterDelegate AspectToStringConverter { get { return aspectToStringConverter; } set { aspectToStringConverter = value; } } private AspectToStringConverterDelegate aspectToStringConverter; /// /// This format string will be used to convert an aspect to its string representation. /// /// /// This string is passed as the first parameter to the String.Format() method. /// This is only used if AspectToStringConverter has not been set. /// "{0:C}" to convert a number to currency [Category("ObjectListView"), Description("The format string that will be used to convert an aspect to its string representation"), DefaultValue(null)] public string AspectToStringFormat { get { return aspectToStringFormat; } set { aspectToStringFormat = value; } } private string aspectToStringFormat; /// /// Gets or sets whether the cell editor should use AutoComplete /// [Category("ObjectListView"), Description("Should the editor for cells of this column use AutoComplete"), DefaultValue(true)] public bool AutoCompleteEditor { get { return AutoCompleteEditorMode != AutoCompleteMode.None; } set { if (value) { if (AutoCompleteEditorMode == AutoCompleteMode.None) AutoCompleteEditorMode = AutoCompleteMode.Append; } else AutoCompleteEditorMode = AutoCompleteMode.None; } } /// /// Gets or sets whether the cell editor should use AutoComplete /// [Category("ObjectListView"), Description("Should the editor for cells of this column use AutoComplete"), DefaultValue(AutoCompleteMode.Append)] public AutoCompleteMode AutoCompleteEditorMode { get { return autoCompleteEditorMode; } set { autoCompleteEditorMode = value; } } private AutoCompleteMode autoCompleteEditorMode = AutoCompleteMode.Append; /// /// Gets whether this column can be hidden by user actions /// /// This take into account both the Hideable property and whether this column /// is the primary column of the listview (column 0). [Browsable(false)] public bool CanBeHidden { get { return Hideable && (Index != 0); } } /// /// When a cell is edited, should the whole cell be used (minus any space used by checkbox or image)? /// /// /// This is always treated as true when the control is NOT owner drawn. /// /// When this is false (the default) and the control is owner drawn, /// ObjectListView will try to calculate the width of the cell's /// actual contents, and then size the editing control to be just the right width. If this is true, /// the whole width of the cell will be used, regardless of the cell's contents. /// /// If this property is not set on the column, the value from the control will be used /// /// This value is only used when the control is in Details view. /// Regardless of this setting, developers can specify the exact size of the editing control /// by listening for the CellEditStarting event. /// [Category("ObjectListView"), Description("When a cell is edited, should the whole cell be used?"), DefaultValue(null)] public virtual bool? CellEditUseWholeCell { get { return cellEditUseWholeCell; } set { cellEditUseWholeCell = value; } } private bool? cellEditUseWholeCell; /// /// Get whether the whole cell should be used when editing a cell in this column /// /// This calculates the current effective value, which may be different to CellEditUseWholeCell [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual bool CellEditUseWholeCellEffective { get { bool? columnSpecificValue = ListView.View == View.Details ? CellEditUseWholeCell : (bool?) null; return (columnSpecificValue ?? ((ObjectListView) ListView).CellEditUseWholeCell); } } /// /// Gets or sets how many pixels will be left blank around this cells in this column /// /// This setting only takes effect when the control is owner drawn. [Category("ObjectListView"), Description("How many pixels will be left blank around the cells in this column?"), DefaultValue(null)] public Rectangle? CellPadding { get { return cellPadding; } set { cellPadding = value; } } private Rectangle? cellPadding; /// /// Gets or sets how cells in this column will be vertically aligned. /// /// /// /// This setting only takes effect when the control is owner drawn. /// /// /// If this is not set, the value from the control itself will be used. /// /// [Category("ObjectListView"), Description("How will cell values be vertically aligned?"), DefaultValue(null)] public virtual StringAlignment? CellVerticalAlignment { get { return cellVerticalAlignment; } set { cellVerticalAlignment = value; } } private StringAlignment? cellVerticalAlignment; /// /// Gets or sets whether this column will show a checkbox. /// /// /// Setting this on column 0 has no effect. Column 0 check box is controlled /// by the CheckBoxes property on the ObjectListView itself. /// [Category("ObjectListView"), Description("Should values in this column be treated as a checkbox, rather than a string?"), DefaultValue(false)] public virtual bool CheckBoxes { get { return checkBoxes; } set { if (checkBoxes == value) return; checkBoxes = value; if (checkBoxes) { if (Renderer == null) Renderer = new CheckStateRenderer(); } else { if (Renderer is CheckStateRenderer) Renderer = null; } } } private bool checkBoxes; /// /// Gets or sets the clustering strategy used for this column. /// /// /// /// The clustering strategy is used to build a Filtering menu for this item. /// If this is null, a useful default will be chosen. /// /// /// To disable filtering on this colummn, set UseFiltering to false. /// /// /// Cluster strategies belong to a particular column. The same instance /// cannot be shared between multiple columns. /// /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public IClusteringStrategy ClusteringStrategy { get { if (clusteringStrategy == null) ClusteringStrategy = DecideDefaultClusteringStrategy(); return clusteringStrategy; } set { clusteringStrategy = value; if (clusteringStrategy != null) clusteringStrategy.Column = this; } } private IClusteringStrategy clusteringStrategy; /// /// Gets or sets whether the button in this column (if this column is drawing buttons) will be enabled /// even if the row itself is disabled /// [Category("ObjectListView"), Description("If this column contains a button, should the button be enabled even if the row is disabled?"), DefaultValue(false)] public bool EnableButtonWhenItemIsDisabled { get { return enableButtonWhenItemIsDisabled; } set { enableButtonWhenItemIsDisabled = value; } } private bool enableButtonWhenItemIsDisabled; /// /// Should this column resize to fill the free space in the listview? /// /// /// /// If you want two (or more) columns to equally share the available free space, set this property to True. /// If you want this column to have a larger or smaller share of the free space, you must /// set the FreeSpaceProportion property explicitly. /// /// /// Space filling columns are still governed by the MinimumWidth and MaximumWidth properties. /// /// /// [Category("ObjectListView"), Description("Will this column resize to fill unoccupied horizontal space in the listview?"), DefaultValue(false)] public bool FillsFreeSpace { get { return FreeSpaceProportion > 0; } set { FreeSpaceProportion = value ? 1 : 0; } } /// /// What proportion of the unoccupied horizontal space in the control should be given to this column? /// /// /// /// There are situations where it would be nice if a column (normally the rightmost one) would expand as /// the list view expands, so that as much of the column was visible as possible without having to scroll /// horizontally (you should never, ever make your users have to scroll anything horizontally!). /// /// /// A space filling column is resized to occupy a proportion of the unoccupied width of the listview (the /// unoccupied width is the width left over once all the the non-filling columns have been given their space). /// This property indicates the relative proportion of that unoccupied space that will be given to this column. /// The actual value of this property is not important -- only its value relative to the value in other columns. /// For example: /// /// /// If there is only one space filling column, it will be given all the free space, regardless of the value in FreeSpaceProportion. /// /// /// If there are two or more space filling columns and they all have the same value for FreeSpaceProportion, /// they will share the free space equally. /// /// /// If there are three space filling columns with values of 3, 2, and 1 /// for FreeSpaceProportion, then the first column with occupy half the free space, the second will /// occupy one-third of the free space, and the third column one-sixth of the free space. /// /// /// /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public int FreeSpaceProportion { get { return freeSpaceProportion; } set { freeSpaceProportion = Math.Max(0, value); } } private int freeSpaceProportion; /// /// Gets or sets whether groups will be rebuild on this columns values when this column's header is clicked. /// /// /// This setting is only used when ShowGroups is true. /// /// If this is false, clicking the header will not rebuild groups. It will not provide /// any feedback as to why the list is not being regrouped. It is the programmers responsibility to /// provide appropriate feedback. /// /// When this is false, BeforeCreatingGroups events are still fired, which can be used to allow grouping /// or give feedback, on a case by case basis. /// [Category("ObjectListView"), Description("Will the list create groups when this header is clicked?"), DefaultValue(true)] public bool Groupable { get { return groupable; } set { groupable = value; } } private bool groupable = true; /// /// This delegate is called when a group has been created but not yet made /// into a real ListViewGroup. The user can take this opportunity to fill /// in lots of other details about the group. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public GroupFormatterDelegate GroupFormatter { get { return groupFormatter; } set { groupFormatter = value; } } private GroupFormatterDelegate groupFormatter; /// /// This delegate is called to get the object that is the key for the group /// to which the given row belongs. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public GroupKeyGetterDelegate GroupKeyGetter { get { return groupKeyGetter; } set { groupKeyGetter = value; } } private GroupKeyGetterDelegate groupKeyGetter; /// /// This delegate is called to convert a group key into a title for that group. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public GroupKeyToTitleConverterDelegate GroupKeyToTitleConverter { get { return groupKeyToTitleConverter; } set { groupKeyToTitleConverter = value; } } private GroupKeyToTitleConverterDelegate groupKeyToTitleConverter; /// /// When the listview is grouped by this column and group title has an item count, /// how should the lable be formatted? /// /// /// The given format string can/should have two placeholders: /// /// {0} - the original group title /// {1} - the number of items in the group /// /// /// "{0} [{1} items]" [Category("ObjectListView"), Description("The format to use when suffixing item counts to group titles"), DefaultValue(null), Localizable(true)] public string GroupWithItemCountFormat { get { return groupWithItemCountFormat; } set { groupWithItemCountFormat = value; } } private string groupWithItemCountFormat; /// /// Gets this.GroupWithItemCountFormat or a reasonable default /// /// /// If GroupWithItemCountFormat is not set, its value will be taken from the ObjectListView if possible. /// [Browsable(false)] public string GroupWithItemCountFormatOrDefault { get { if (!String.IsNullOrEmpty(GroupWithItemCountFormat)) return GroupWithItemCountFormat; if (ListView != null) { cachedGroupWithItemCountFormat = ((ObjectListView)ListView).GroupWithItemCountFormatOrDefault; return cachedGroupWithItemCountFormat; } // There is one rare but pathelogically possible case where the ListView can // be null (if the column is grouping a ListView, but is not one of the columns // for that ListView) so we have to provide a workable default for that rare case. return cachedGroupWithItemCountFormat ?? "{0} [{1} items]"; } } private string cachedGroupWithItemCountFormat; /// /// When the listview is grouped by this column and a group title has an item count, /// how should the lable be formatted if there is only one item in the group? /// /// /// The given format string can/should have two placeholders: /// /// {0} - the original group title /// {1} - the number of items in the group (always 1) /// /// /// "{0} [{1} item]" [Category("ObjectListView"), Description("The format to use when suffixing item counts to group titles"), DefaultValue(null), Localizable(true)] public string GroupWithItemCountSingularFormat { get { return groupWithItemCountSingularFormat; } set { groupWithItemCountSingularFormat = value; } } private string groupWithItemCountSingularFormat; /// /// Get this.GroupWithItemCountSingularFormat or a reasonable default /// /// /// If this value is not set, the values from the list view will be used /// [Browsable(false)] public string GroupWithItemCountSingularFormatOrDefault { get { if (!String.IsNullOrEmpty(GroupWithItemCountSingularFormat)) return GroupWithItemCountSingularFormat; if (ListView != null) { cachedGroupWithItemCountSingularFormat = ((ObjectListView)ListView).GroupWithItemCountSingularFormatOrDefault; return cachedGroupWithItemCountSingularFormat; } // There is one rare but pathelogically possible case where the ListView can // be null (if the column is grouping a ListView, but is not one of the columns // for that ListView) so we have to provide a workable default for that rare case. return cachedGroupWithItemCountSingularFormat ?? "{0} [{1} item]"; } } private string cachedGroupWithItemCountSingularFormat; /// /// Gets whether this column should be drawn with a filter indicator in the column header. /// [Browsable(false)] public bool HasFilterIndicator { get { return UseFiltering && ValuesChosenForFiltering != null && ValuesChosenForFiltering.Count > 0; } } /// /// Gets or sets a delegate that will be used to own draw header column. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public HeaderDrawingDelegate HeaderDrawing { get { return headerDrawing; } set { headerDrawing = value; } } private HeaderDrawingDelegate headerDrawing; /// /// Gets or sets the style that will be used to draw the header for this column /// /// This is only uses when the owning ObjectListView has HeaderUsesThemes set to false. [Category("ObjectListView"), Description("What style will be used to draw the header of this column"), DefaultValue(null)] public HeaderFormatStyle HeaderFormatStyle { get { return headerFormatStyle; } set { headerFormatStyle = value; } } private HeaderFormatStyle headerFormatStyle; /// /// Gets or sets the font in which the header for this column will be drawn /// /// You should probably use a HeaderFormatStyle instead of this property /// This is only uses when HeaderUsesThemes is false. [Category("ObjectListView"), Description("Which font will be used to draw the header?"), DefaultValue(null)] public Font HeaderFont { get { return HeaderFormatStyle == null ? null : HeaderFormatStyle.Normal.Font; } set { if (value == null && HeaderFormatStyle == null) return; if (HeaderFormatStyle == null) HeaderFormatStyle = new HeaderFormatStyle(); HeaderFormatStyle.SetFont(value); } } /// /// Gets or sets the color in which the text of the header for this column will be drawn /// /// You should probably use a HeaderFormatStyle instead of this property /// This is only uses when HeaderUsesThemes is false. [Category("ObjectListView"), Description("In what color will the header text be drawn?"), DefaultValue(typeof(Color), "")] public Color HeaderForeColor { get { return HeaderFormatStyle == null ? Color.Empty : HeaderFormatStyle.Normal.ForeColor; } set { if (value.IsEmpty && HeaderFormatStyle == null) return; if (HeaderFormatStyle == null) HeaderFormatStyle = new HeaderFormatStyle(); HeaderFormatStyle.SetForeColor(value); } } /// /// Gets or sets whether the text values in this column will act like hyperlinks /// /// This is only taken into account when HeaderUsesThemes is false. [Category("ObjectListView"), Description("Name of the image that will be shown in the column header."), DefaultValue(null), TypeConverter(typeof(ImageKeyConverter)), Editor("System.Windows.Forms.Design.ImageIndexEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor)), RefreshProperties(RefreshProperties.Repaint)] public string HeaderImageKey { get { return headerImageKey; } set { headerImageKey = value; } } private string headerImageKey; /// /// Gets or sets how the text of the header will be drawn? /// [Category("ObjectListView"), Description("How will the header text be aligned? If this is not set, the alignment of the header will follow the alignment of the column"), DefaultValue(null)] public HorizontalAlignment? HeaderTextAlign { get { return headerTextAlign; } set { headerTextAlign = value; } } private HorizontalAlignment? headerTextAlign; /// /// Return the text alignment of the header. This will either have been set explicitly, /// or will follow the alignment of the text in the column /// [Browsable(false)] public HorizontalAlignment HeaderTextAlignOrDefault { get { return headerTextAlign.HasValue ? headerTextAlign.Value : TextAlign; } } /// /// Gets the header alignment converted to a StringAlignment /// [Browsable(false)] public StringAlignment HeaderTextAlignAsStringAlignment { get { switch (HeaderTextAlignOrDefault) { case HorizontalAlignment.Left: return StringAlignment.Near; case HorizontalAlignment.Center: return StringAlignment.Center; case HorizontalAlignment.Right: return StringAlignment.Far; default: return StringAlignment.Near; } } } /// /// Gets whether or not this column has an image in the header /// [Browsable(false)] public bool HasHeaderImage { get { return (ListView != null && ListView.SmallImageList != null && ListView.SmallImageList.Images.ContainsKey(HeaderImageKey)); } } /// /// Gets or sets whether this header will place a checkbox in the header /// [Category("ObjectListView"), Description("Draw a checkbox in the header of this column"), DefaultValue(false)] public bool HeaderCheckBox { get { return headerCheckBox; } set { headerCheckBox = value; } } private bool headerCheckBox; /// /// Gets or sets whether this header will place a tri-state checkbox in the header /// [Category("ObjectListView"), Description("Draw a tri-state checkbox in the header of this column"), DefaultValue(false)] public bool HeaderTriStateCheckBox { get { return headerTriStateCheckBox; } set { headerTriStateCheckBox = value; } } private bool headerTriStateCheckBox; /// /// Gets or sets the checkedness of the checkbox in the header of this column /// [Category("ObjectListView"), Description("Checkedness of the header checkbox"), DefaultValue(CheckState.Unchecked)] public CheckState HeaderCheckState { get { return headerCheckState; } set { headerCheckState = value; } } private CheckState headerCheckState = CheckState.Unchecked; /// /// Gets or sets whether the /// checking/unchecking the value of the header's checkbox will result in the /// checkboxes for all cells in this column being set to the same checked/unchecked. /// Defaults to true. /// /// /// /// There is no reverse of this function that automatically updates the header when the /// checkedness of a cell changes. /// /// /// This property's behaviour on a TreeListView is probably best describes as undefined /// and should be avoided. /// /// /// The performance of this action (checking/unchecking all rows) is O(n) where n is the /// number of rows. It will work on large virtual lists, but it may take some time. /// /// [Category("ObjectListView"), Description("Update row checkboxs when the header checkbox is clicked by the user"), DefaultValue(true)] public bool HeaderCheckBoxUpdatesRowCheckBoxes { get { return headerCheckBoxUpdatesRowCheckBoxes; } set { headerCheckBoxUpdatesRowCheckBoxes = value; } } private bool headerCheckBoxUpdatesRowCheckBoxes = true; /// /// Gets or sets whether the checkbox in the header is disabled /// /// /// Clicking on a disabled checkbox does not change its value, though it does raise /// a HeaderCheckBoxChanging event, which allows the programmer the opportunity to do /// something appropriate. [Category("ObjectListView"), Description("Is the checkbox in the header of this column disabled"), DefaultValue(false)] public bool HeaderCheckBoxDisabled { get { return headerCheckBoxDisabled; } set { headerCheckBoxDisabled = value; } } private bool headerCheckBoxDisabled; /// /// Gets or sets whether this column can be hidden by the user. /// /// /// Column 0 can never be hidden, regardless of this setting. /// [Category("ObjectListView"), Description("Will the user be able to choose to hide this column?"), DefaultValue(true)] public bool Hideable { get { return hideable; } set { hideable = value; } } private bool hideable = true; /// /// Gets or sets whether the text values in this column will act like hyperlinks /// [Category("ObjectListView"), Description("Will the text values in the cells of this column act like hyperlinks?"), DefaultValue(false)] public bool Hyperlink { get { return hyperlink; } set { hyperlink = value; } } private bool hyperlink; /// /// This is the name of property that will be invoked to get the image selector of the /// image that should be shown in this column. /// It can return an int, string, Image or null. /// /// /// This is ignored if ImageGetter is not null. /// The property can use these return value to identify the image: /// /// null or -1 -- indicates no image /// an int -- the int value will be used as an index into the image list /// a String -- the string value will be used as a key into the image list /// an Image -- the Image will be drawn directly (only in OwnerDrawn mode) /// /// [Category("ObjectListView"), Description("The name of the property that holds the image selector"), DefaultValue(null)] public string ImageAspectName { get { return imageAspectName; } set { imageAspectName = value; } } private string imageAspectName; /// /// This delegate is called to get the image selector of the image that should be shown in this column. /// It can return an int, string, Image or null. /// /// This delegate can use these return value to identify the image: /// /// null or -1 -- indicates no image /// an int -- the int value will be used as an index into the image list /// a String -- the string value will be used as a key into the image list /// an Image -- the Image will be drawn directly (only in OwnerDrawn mode) /// /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public ImageGetterDelegate ImageGetter { get { return imageGetter; } set { imageGetter = value; } } private ImageGetterDelegate imageGetter; /// /// Gets or sets whether this column will draw buttons in its cells /// /// /// /// When this is set to true, the renderer for the column is become a ColumnButtonRenderer /// if it isn't already. If this is set to false, any previous button renderer will be discarded /// /// If the cell's aspect is null or empty, nothing will be drawn in the cell. [Category("ObjectListView"), Description("Does this column draw its cells as buttons?"), DefaultValue(false)] public bool IsButton { get { return isButton; } set { isButton = value; if (value) { if (Renderer is not ColumnButtonRenderer buttonRenderer) { Renderer = CreateColumnButtonRenderer(); FillInColumnButtonRenderer(); } } else { if (Renderer is ColumnButtonRenderer) Renderer = null; } } } private bool isButton; /// /// Create a ColumnButtonRenderer to draw buttons in this column /// /// protected virtual ColumnButtonRenderer CreateColumnButtonRenderer() { return new ColumnButtonRenderer(); } /// /// Fill in details to our ColumnButtonRenderer based on the properties set on the column /// protected virtual void FillInColumnButtonRenderer() { if (Renderer is not ColumnButtonRenderer buttonRenderer) return; buttonRenderer.SizingMode = ButtonSizing; buttonRenderer.ButtonSize = ButtonSize; buttonRenderer.ButtonPadding = ButtonPadding; buttonRenderer.MaxButtonWidth = ButtonMaxWidth; } /// /// Gets or sets the maximum width that a button can occupy. /// -1 means there is no maximum width. /// /// This is only considered when the SizingMode is TextBounds [Category("ObjectListView"), Description("The maximum width that a button can occupy when the SizingMode is TextBounds"), DefaultValue(-1)] public int ButtonMaxWidth { get { return buttonMaxWidth; } set { buttonMaxWidth = value; FillInColumnButtonRenderer(); } } private int buttonMaxWidth = -1; /// /// Gets or sets the extra space that surrounds the cell when the SizingMode is TextBounds /// [Category("ObjectListView"), Description("The extra space that surrounds the cell when the SizingMode is TextBounds"), DefaultValue(null)] public Size? ButtonPadding { get { return buttonPadding; } set { buttonPadding = value; FillInColumnButtonRenderer(); } } private Size? buttonPadding; /// /// Gets or sets the size of the button when the SizingMode is FixedBounds /// /// If this is not set, the bounds of the cell will be used [Category("ObjectListView"), Description("The size of the button when the SizingMode is FixedBounds"), DefaultValue(null)] public Size? ButtonSize { get { return buttonSize; } set { buttonSize = value; FillInColumnButtonRenderer(); } } private Size? buttonSize; /// /// Gets or sets how each button will be sized if this column is displaying buttons /// [Category("ObjectListView"), Description("If this column is showing buttons, how each button will be sized"), DefaultValue(ButtonSizingMode.TextBounds)] public ButtonSizingMode ButtonSizing { get { return buttonSizing; } set { buttonSizing = value; FillInColumnButtonRenderer(); } } private ButtonSizingMode buttonSizing = ButtonSizingMode.TextBounds; /// /// Can the values shown in this column be edited? /// /// This defaults to true, since the primary means to control the editability of a listview /// is on the listview itself. Once a listview is editable, all the columns are too, unless the /// programmer explicitly marks them as not editable [Category("ObjectListView"), Description("Can the value in this column be edited?"), DefaultValue(true)] public bool IsEditable { get { return isEditable; } set { isEditable = value; } } private bool isEditable = true; /// /// Is this column a fixed width column? /// [Browsable(false)] public bool IsFixedWidth { get { return (MinimumWidth != -1 && MaximumWidth != -1 && MinimumWidth >= MaximumWidth); } } /// /// Get/set whether this column should be used when the view is switched to tile view. /// /// Column 0 is always included in tileview regardless of this setting. /// Tile views do not work well with many "columns" of information. /// Two or three works best. [Category("ObjectListView"), Description("Will this column be used when the view is switched to tile view"), DefaultValue(false)] public bool IsTileViewColumn { get { return isTileViewColumn; } set { isTileViewColumn = value; } } private bool isTileViewColumn; /// /// Gets or sets whether the text of this header should be rendered vertically. /// /// /// If this is true, it is a good idea to set ToolTipText to the name of the column so it's easy to read. /// Vertical headers are text only. They do not draw their image. /// [Category("ObjectListView"), Description("Will the header for this column be drawn vertically?"), DefaultValue(false)] public bool IsHeaderVertical { get { return isHeaderVertical; } set { isHeaderVertical = value; } } private bool isHeaderVertical; /// /// Can this column be seen by the user? /// /// After changing this value, you must call RebuildColumns() before the changes will take effect. [Category("ObjectListView"), Description("Can this column be seen by the user?"), DefaultValue(true)] public bool IsVisible { get { return isVisible; } set { if (isVisible == value) return; isVisible = value; OnVisibilityChanged(EventArgs.Empty); } } private bool isVisible = true; /// /// Where was this column last positioned within the Detail view columns /// /// DisplayIndex is volatile. Once a column is removed from the control, /// there is no way to discover where it was in the display order. This property /// guards that information even when the column is not in the listview's active columns. [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public int LastDisplayIndex { get { return lastDisplayIndex; } set { lastDisplayIndex = value; } } private int lastDisplayIndex = -1; /// /// What is the maximum width that the user can give to this column? /// /// -1 means there is no maximum width. Give this the same value as MinimumWidth to make a fixed width column. [Category("ObjectListView"), Description("What is the maximum width to which the user can resize this column? -1 means no limit"), DefaultValue(-1)] public int MaximumWidth { get { return maxWidth; } set { maxWidth = value; if (maxWidth != -1 && Width > maxWidth) Width = maxWidth; } } private int maxWidth = -1; /// /// What is the minimum width that the user can give to this column? /// /// -1 means there is no minimum width. Give this the same value as MaximumWidth to make a fixed width column. [Category("ObjectListView"), Description("What is the minimum width to which the user can resize this column? -1 means no limit"), DefaultValue(-1)] public int MinimumWidth { get { return minWidth; } set { minWidth = value; if (Width < minWidth) Width = minWidth; } } private int minWidth = -1; /// /// Get/set the renderer that will be invoked when a cell needs to be redrawn /// [Category("ObjectListView"), Description("The renderer will draw this column when the ListView is owner drawn"), DefaultValue(null)] public IRenderer Renderer { get { return renderer; } set { renderer = value; } } private IRenderer renderer; /// /// This delegate is called when a cell needs to be drawn in OwnerDrawn mode. /// /// This method is kept primarily for backwards compatibility. /// New code should implement an IRenderer, though this property will be maintained. [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public RenderDelegate RendererDelegate { get { return Renderer is Version1Renderer version1Renderer ? version1Renderer.RenderDelegate : null; } set { Renderer = value == null ? null : new Version1Renderer(value); } } /// /// Gets or sets whether the text in this column's cell will be used when doing text searching. /// /// /// /// If this is false, text filters will not trying searching this columns cells when looking for matches. /// /// [Category("ObjectListView"), Description("Will the text of the cells in this column be considered when searching?"), DefaultValue(true)] public bool Searchable { get { return searchable; } set { searchable = value; } } private bool searchable = true; /// /// Gets or sets a delegate which will return the array of text values that should be /// considered for text matching when using a text based filter. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public SearchValueGetterDelegate SearchValueGetter { get { return searchValueGetter; } set { searchValueGetter = value; } } private SearchValueGetterDelegate searchValueGetter; /// /// Gets or sets whether the header for this column will include the column's Text. /// /// /// /// If this is false, the only thing rendered in the column header will be the image from . /// /// This setting is only considered when is false on the owning ObjectListView. /// [Category("ObjectListView"), Description("Will the header for this column include text?"), DefaultValue(true)] public bool ShowTextInHeader { get { return showTextInHeader; } set { showTextInHeader = value; } } private bool showTextInHeader = true; /// /// Gets or sets whether the contents of the list will be resorted when the user clicks the /// header of this column. /// /// /// /// If this is false, clicking the header will not sort the list, but will not provide /// any feedback as to why the list is not being sorted. It is the programmers responsibility to /// provide appropriate feedback. /// /// When this is false, BeforeSorting events are still fired, which can be used to allow sorting /// or give feedback, on a case by case basis. /// [Category("ObjectListView"), Description("Will clicking this columns header resort the list?"), DefaultValue(true)] public bool Sortable { get { return sortable; } set { sortable = value; } } private bool sortable = true; /// /// Gets or sets the horizontal alignment of the contents of the column. /// /// .NET will not allow column 0 to have any alignment except /// to the left. We can't change the basic behaviour of the listview, /// but when owner drawn, column 0 can now have other alignments. [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] new public HorizontalAlignment TextAlign { get { return textAlign.HasValue ? textAlign.Value : base.TextAlign; } set { textAlign = value; base.TextAlign = value; } } private HorizontalAlignment? textAlign; /// /// Gets the StringAlignment equivilent of the column text alignment /// [Browsable(false)] public StringAlignment TextStringAlign { get { switch (TextAlign) { case HorizontalAlignment.Center: return StringAlignment.Center; case HorizontalAlignment.Left: return StringAlignment.Near; case HorizontalAlignment.Right: return StringAlignment.Far; default: return StringAlignment.Near; } } } /// /// What string should be displayed when the mouse is hovered over the header of this column? /// /// If a HeaderToolTipGetter is installed on the owning ObjectListView, this /// value will be ignored. [Category("ObjectListView"), Description("The tooltip to show when the mouse is hovered over the header of this column"), DefaultValue((String)null), Localizable(true)] public String ToolTipText { get { return toolTipText; } set { toolTipText = value; } } private String toolTipText; /// /// Should this column have a tri-state checkbox? /// /// /// If this is true, the user can choose the third state (normally Indeterminate). /// [Category("ObjectListView"), Description("Should values in this column be treated as a tri-state checkbox?"), DefaultValue(false)] public virtual bool TriStateCheckBoxes { get { return triStateCheckBoxes; } set { triStateCheckBoxes = value; if (value && !CheckBoxes) CheckBoxes = true; } } private bool triStateCheckBoxes; /// /// Group objects by the initial letter of the aspect of the column /// /// /// One common pattern is to group column by the initial letter of the value for that group. /// The aspect must be a string (obviously). /// [Category("ObjectListView"), Description("The name of the property or method that should be called to get the aspect to display in this column"), DefaultValue(false)] public bool UseInitialLetterForGroup { get { return useInitialLetterForGroup; } set { useInitialLetterForGroup = value; } } private bool useInitialLetterForGroup; /// /// Gets or sets whether or not this column should be user filterable /// [Category("ObjectListView"), Description("Does this column want to show a Filter menu item when its header is right clicked"), DefaultValue(true)] public bool UseFiltering { get { return useFiltering; } set { useFiltering = value; } } private bool useFiltering = true; /// /// Gets or sets a filter that will only include models where the model's value /// for this column is one of the values in ValuesChosenForFiltering /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public IModelFilter ValueBasedFilter { get { if (!UseFiltering) return null; if (valueBasedFilter != null) return valueBasedFilter; if (ClusteringStrategy == null) return null; if (ValuesChosenForFiltering == null || ValuesChosenForFiltering.Count == 0) return null; return ClusteringStrategy.CreateFilter(ValuesChosenForFiltering); } set { valueBasedFilter = value; } } private IModelFilter valueBasedFilter; /// /// Gets or sets the values that will be used to generate a filter for this /// column. For a model to be included by the generated filter, its value for this column /// must be in this list. If the list is null or empty, this column will /// not be used for filtering. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public IList ValuesChosenForFiltering { get { return valuesChosenForFiltering; } set { valuesChosenForFiltering = value; } } private IList valuesChosenForFiltering = new ArrayList(); /// /// What is the width of this column? /// [Category("ObjectListView"), Description("The width in pixels of this column"), DefaultValue(60)] new public int Width { get { return base.Width; } set { if (MaximumWidth != -1 && value > MaximumWidth) base.Width = MaximumWidth; else base.Width = Math.Max(MinimumWidth, value); } } /// /// Gets or set whether the contents of this column's cells should be word wrapped /// /// If this column uses a custom IRenderer (that is, one that is not descended /// from BaseRenderer), then that renderer is responsible for implementing word wrapping. [Category("ObjectListView"), Description("Draw this column cell's word wrapped"), DefaultValue(false)] public bool WordWrap { get { return wordWrap; } set { wordWrap = value; // If there isn't a renderer and they are turning word wrap off, we don't need to do anything if (Renderer == null && !wordWrap) return; // All other cases require a renderer of some sort if (Renderer == null) Renderer = new HighlightTextRenderer(); // If there is a custom renderer (not descended from BaseRenderer), // we leave it up to them to implement wrapping if (Renderer is not BaseRenderer baseRenderer) return; baseRenderer.CanWrap = wordWrap; } } private bool wordWrap; #endregion #region Object commands /// /// For a given group value, return the string that should be used as the groups title. /// /// The group key that is being converted to a title /// string public string ConvertGroupKeyToTitle(object value) { if (groupKeyToTitleConverter != null) return groupKeyToTitleConverter(value); return value == null ? ObjectListView.GroupTitleDefault : ValueToString(value); } /// /// Get the checkedness of the given object for this column /// /// The row object that is being displayed /// The checkedness of the object public CheckState GetCheckState(object rowObject) { if (!CheckBoxes) return CheckState.Unchecked; if (GetValue(rowObject) is bool aspectAsBool) { if (aspectAsBool) return CheckState.Checked; else return CheckState.Unchecked; } else return CheckState.Indeterminate; } /// /// Put the checkedness of the given object for this column /// /// The row object that is being displayed /// /// The checkedness of the object public void PutCheckState(object rowObject, CheckState newState) { if (newState == CheckState.Checked) PutValue(rowObject, true); else if (newState == CheckState.Unchecked) PutValue(rowObject, false); else PutValue(rowObject, null); } /// /// For a given row object, extract the value indicated by the AspectName property of this column. /// /// The row object that is being displayed /// An object, which is the aspect named by AspectName public object GetAspectByName(object rowObject) { if (aspectMunger == null) aspectMunger = new Munger(AspectName); return aspectMunger.GetValue(rowObject); } private Munger aspectMunger; /// /// For a given row object, return the object that is the key of the group that this row belongs to. /// /// The row object that is being displayed /// Group key object public object GetGroupKey(object rowObject) { if (groupKeyGetter != null) return groupKeyGetter(rowObject); object key = GetValue(rowObject); if (UseInitialLetterForGroup) { String keyAsString = key as String; if (!String.IsNullOrEmpty(keyAsString)) return keyAsString.Substring(0, 1).ToUpper(); } return key; } /// /// For a given row object, return the image selector of the image that should displayed in this column. /// /// The row object that is being displayed /// int or string or Image. int or string will be used as index into image list. null or -1 means no image public Object GetImage(object rowObject) { if (CheckBoxes) return GetCheckStateImage(rowObject); if (ImageGetter != null) return ImageGetter(rowObject); if (!String.IsNullOrEmpty(ImageAspectName)) { if (imageAspectMunger == null) imageAspectMunger = new Munger(ImageAspectName); return imageAspectMunger.GetValue(rowObject); } // I think this is wrong. ImageKey is meant for the image in the header, not in the rows if (!String.IsNullOrEmpty(ImageKey)) return ImageKey; return ImageIndex; } private Munger imageAspectMunger; /// /// Return the image that represents the check box for the given model /// /// /// public string GetCheckStateImage(Object rowObject) { CheckState checkState = GetCheckState(rowObject); if (checkState == CheckState.Checked) return ObjectListView.CHECKED_KEY; if (checkState == CheckState.Unchecked) return ObjectListView.UNCHECKED_KEY; return ObjectListView.INDETERMINATE_KEY; } /// /// For a given row object, return the strings that will be searched when trying to filter by string. /// /// /// This will normally be the simple GetStringValue result, but if this column is non-textual (e.g. image) /// you might want to install a SearchValueGetter delegate which can return something that could be used /// for text filtering. /// /// /// The array of texts to be searched. If this returns null, search will not match that object. public string[] GetSearchValues(object rowObject) { if (SearchValueGetter != null) return SearchValueGetter(rowObject); var stringValue = GetStringValue(rowObject); if (Renderer is DescribedTaskRenderer dtr) { return new string[] { stringValue, dtr.GetDescription(rowObject) }; } return new string[] { stringValue }; } /// /// For a given row object, return the string representation of the value shown in this column. /// /// /// For aspects that are string (e.g. aPerson.Name), the aspect and its string representation are the same. /// For non-strings (e.g. aPerson.DateOfBirth), the string representation is very different. /// /// /// public string GetStringValue(object rowObject) { return ValueToString(GetValue(rowObject)); } /// /// For a given row object, return the object that is to be displayed in this column. /// /// The row object that is being displayed /// An object, which is the aspect to be displayed public object GetValue(object rowObject) { if (AspectGetter == null) return GetAspectByName(rowObject); else return AspectGetter(rowObject); } /// /// Update the given model object with the given value using the column's /// AspectName. /// /// The model object to be updated /// The value to be put into the model public void PutAspectByName(Object rowObject, Object newValue) { if (aspectMunger == null) aspectMunger = new Munger(AspectName); aspectMunger.PutValue(rowObject, newValue); } /// /// Update the given model object with the given value /// /// The model object to be updated /// The value to be put into the model public void PutValue(Object rowObject, Object newValue) { if (aspectPutter == null) PutAspectByName(rowObject, newValue); else aspectPutter(rowObject, newValue); } /// /// Convert the aspect object to its string representation. /// /// /// If the column has been given a AspectToStringConverter, that will be used to do /// the conversion, otherwise just use ToString(). /// The returned value will not be null. Nulls are always converted /// to empty strings. /// /// The value of the aspect that should be displayed /// A string representation of the aspect public string ValueToString(object value) { // Give the installed converter a chance to work (even if the value is null) if (AspectToStringConverter != null) return AspectToStringConverter(value) ?? String.Empty; // Without a converter, nulls become simple empty strings if (value == null) return String.Empty; string fmt = AspectToStringFormat; if (String.IsNullOrEmpty(fmt)) return value.ToString(); else return String.Format(fmt, value); } #endregion #region Utilities /// /// Decide the clustering strategy that will be used for this column /// /// private IClusteringStrategy DecideDefaultClusteringStrategy() { if (!UseFiltering) return null; if (DataType == typeof(DateTime)) return new DateTimeClusteringStrategy(); return new ClustersFromGroupsStrategy(); } /// /// Gets or sets the type of data shown in this column. /// /// If this is not set, it will try to get the type /// by looking through the rows of the listview. [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public Type DataType { get { if (dataType == null) { if (ListView is ObjectListView olv) { object value = olv.GetFirstNonNullValue(this); if (value != null) return value.GetType(); // THINK: Should we cache this? } } return dataType; } set { dataType = value; } } private Type dataType; #region Events /// /// This event is triggered when the visibility of this column changes. /// [Category("ObjectListView"), Description("This event is triggered when the visibility of the column changes.")] public event EventHandler VisibilityChanged; /// /// Tell the world when visibility of a column changes. /// public virtual void OnVisibilityChanged(EventArgs e) { if (VisibilityChanged != null) VisibilityChanged(this, e); } #endregion /// /// Create groupies /// This is an untyped version to help with Generator and OLVColumn attributes /// /// /// public void MakeGroupies(object[] values, string[] descriptions) { MakeGroupies(values, descriptions, null, null, null); } /// /// Create groupies /// /// /// /// public void MakeGroupies(T[] values, string[] descriptions) { MakeGroupies(values, descriptions, null, null, null); } /// /// Create groupies /// /// /// /// /// public void MakeGroupies(T[] values, string[] descriptions, object[] images) { MakeGroupies(values, descriptions, images, null, null); } /// /// Create groupies /// /// /// /// /// /// public void MakeGroupies(T[] values, string[] descriptions, object[] images, string[] subtitles) { MakeGroupies(values, descriptions, images, subtitles, null); } /// /// Create groupies. /// Install delegates that will group the columns aspects into progressive partitions. /// If an aspect is less than value[n], it will be grouped with description[n]. /// If an aspect has a value greater than the last element in "values", it will be grouped /// with the last element in "descriptions". /// /// Array of values. Values must be able to be /// compared to the aspect (using IComparable) /// The description for the matching value. The last element is the default description. /// If there are n values, there must be n+1 descriptions. /// /// this.salaryColumn.MakeGroupies( /// new UInt32[] { 20000, 100000 }, /// new string[] { "Lowly worker", "Middle management", "Rarified elevation"}); /// /// /// /// /// public void MakeGroupies(T[] values, string[] descriptions, object[] images, string[] subtitles, string[] tasks) { // Sanity checks if (values == null) throw new ArgumentNullException("values"); if (descriptions == null) throw new ArgumentNullException("descriptions"); if (values.Length + 1 != descriptions.Length) throw new ArgumentException("descriptions must have one more element than values."); // Install a delegate that returns the index of the description to be shown GroupKeyGetter = delegate(object row) { Object aspect = GetValue(row); if (aspect == null || aspect == DBNull.Value) return -1; IComparable comparable = (IComparable)aspect; for (int i = 0; i < values.Length; i++) { if (comparable.CompareTo(values[i]) < 0) return i; } // Display the last element in the array return descriptions.Length - 1; }; // Install a delegate that simply looks up the given index in the descriptions. GroupKeyToTitleConverter = delegate(object key) { if ((int)key < 0) return ""; return descriptions[(int)key]; }; // Install one delegate that does all the other formatting GroupFormatter = delegate(OLVGroup group, GroupingParameters parms) { int key = (int)group.Key; // we know this is an int since we created it in GroupKeyGetter if (key >= 0) { if (images != null && key < images.Length) group.TitleImage = images[key]; if (subtitles != null && key < subtitles.Length) group.Subtitle = subtitles[key]; if (tasks != null && key < tasks.Length) group.Task = tasks[key]; } }; } /// /// Create groupies based on exact value matches. /// /// /// Install delegates that will group rows into partitions based on equality of this columns aspects. /// If an aspect is equal to value[n], it will be grouped with description[n]. /// If an aspect is not equal to any value, it will be grouped with "[other]". /// /// Array of values. Values must be able to be /// equated to the aspect /// The description for the matching value. /// /// this.marriedColumn.MakeEqualGroupies( /// new MaritalStatus[] { MaritalStatus.Single, MaritalStatus.Married, MaritalStatus.Divorced, MaritalStatus.Partnered }, /// new string[] { "Looking", "Content", "Looking again", "Mostly content" }); /// /// /// /// /// public void MakeEqualGroupies(T[] values, string[] descriptions, object[] images, string[] subtitles, string[] tasks) { // Sanity checks if (values == null) throw new ArgumentNullException("values"); if (descriptions == null) throw new ArgumentNullException("descriptions"); if (values.Length != descriptions.Length) throw new ArgumentException("descriptions must have the same number of elements as values."); ArrayList valuesArray = new ArrayList(values); // Install a delegate that returns the index of the description to be shown GroupKeyGetter = delegate(object row) { return valuesArray.IndexOf(GetValue(row)); }; // Install a delegate that simply looks up the given index in the descriptions. GroupKeyToTitleConverter = delegate(object key) { int intKey = (int)key; // we know this is an int since we created it in GroupKeyGetter return (intKey < 0) ? "[other]" : descriptions[intKey]; }; // Install one delegate that does all the other formatting GroupFormatter = delegate(OLVGroup group, GroupingParameters parms) { int key = (int)group.Key; // we know this is an int since we created it in GroupKeyGetter if (key >= 0) { if (images != null && key < images.Length) group.TitleImage = images[key]; if (subtitles != null && key < subtitles.Length) group.Subtitle = subtitles[key]; if (tasks != null && key < tasks.Length) group.Task = tasks[key]; } }; } #endregion } } ================================================ FILE: source/ObjectListView/ObjectListView.DesignTime.cs ================================================ /* * DesignSupport - Design time support for the various classes within ObjectListView * * Author: Phillip Piper * Date: 12/08/2009 8:36 PM * * Change log: * 2012-08-27 JPP - Fall back to more specific type name for the ListViewDesigner if * the first GetType() fails. * v2.5.1 * 2012-04-26 JPP - Filter group events from TreeListView since it can't have groups * 2011-06-06 JPP - Vastly improved ObjectListViewDesigner, based off information in * "'Inheriting' from an Internal WinForms Designer" on CodeProject. * v2.3 * 2009-08-12 JPP - Initial version * * To do: * * Copyright (C) 2009-2014 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.Design; using System.Diagnostics; using System.Drawing; using System.Reflection; using System.Windows.Forms; using System.Windows.Forms.Design; namespace BrightIdeasSoftware.Design { /// /// Designer for and its subclasses. /// /// /// /// This designer removes properties and events that are available on ListView but that are not /// useful on ObjectListView. /// /// /// We can't inherit from System.Windows.Forms.Design.ListViewDesigner, since it is marked internal. /// So, this class uses reflection to create a ListViewDesigner and then forwards messages to that designer. /// /// public class ObjectListViewDesigner : ControlDesigner { #region Initialize & Dispose /// /// Initializes the designer with the specified component. /// /// The to associate the designer with. This component must always be an instance of, or derive from, . public override void Initialize(IComponent component) { // Debug.WriteLine("ObjectListViewDesigner.Initialize"); // Use reflection to bypass the "internal" marker on ListViewDesigner // If we can't get the unversioned designer, look specifically for .NET 4.0 version of it. Type tListViewDesigner = Type.GetType("System.Windows.Forms.Design.ListViewDesigner, System.Design") ?? Type.GetType("System.Windows.Forms.Design.ListViewDesigner, System.Design, " + "Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"); if (tListViewDesigner == null) throw new ArgumentException("Could not load ListViewDesigner"); listViewDesigner = (ControlDesigner)Activator.CreateInstance(tListViewDesigner, BindingFlags.Instance | BindingFlags.Public, null, null, null); designerFilter = listViewDesigner; // Fetch the methods from the ListViewDesigner that we know we want to use listViewDesignGetHitTest = tListViewDesigner.GetMethod("GetHitTest", BindingFlags.Instance | BindingFlags.NonPublic); listViewDesignWndProc = tListViewDesigner.GetMethod("WndProc", BindingFlags.Instance | BindingFlags.NonPublic); Debug.Assert(listViewDesignGetHitTest != null, "Required method (GetHitTest) not found on ListViewDesigner"); Debug.Assert(listViewDesignWndProc != null, "Required method (WndProc) not found on ListViewDesigner"); // Tell the Designer to use properties of default designer as well as the properties of this class (do before base.Initialize) TypeDescriptor.CreateAssociation(component, listViewDesigner); IServiceContainer site = (IServiceContainer)component.Site; if (site != null && GetService(typeof(DesignerCommandSet)) == null) { site.AddService(typeof(DesignerCommandSet), new CDDesignerCommandSet(this)); } else { Debug.Fail("site != null && GetService(typeof (DesignerCommandSet)) == null"); } listViewDesigner.Initialize(component); base.Initialize(component); RemoveDuplicateDockingActionList(); } /// /// Initializes a newly created component. /// /// A name/value dictionary of default values to apply to properties. May be null if no default values are specified. public override void InitializeNewComponent(IDictionary defaultValues) { // Debug.WriteLine("ObjectListViewDesigner.InitializeNewComponent"); base.InitializeNewComponent(defaultValues); listViewDesigner.InitializeNewComponent(defaultValues); } /// /// Releases the unmanaged resources used by the and optionally releases the managed resources. /// /// true to release both managed and unmanaged resources; false to release only unmanaged resources. protected override void Dispose(bool disposing) { // Debug.WriteLine("ObjectListViewDesigner.Dispose"); if (disposing) { if (listViewDesigner != null) { listViewDesigner.Dispose(); // Normally we would now null out the designer, but this designer // still has methods called AFTER it is disposed. } } base.Dispose(disposing); } /// /// Removes the duplicate DockingActionList added by this designer to the . /// /// /// adds an internal DockingActionList : 'Dock/Undock in Parent Container'. /// But the default designer has already added that action list. So we need to remove one. /// private void RemoveDuplicateDockingActionList() { // This is a true hack -- in a class that is basically a huge hack itself. // Reach into the bowel of our base class, get a private field, and use that fields value to // remove an action from the designer. // In ControlDesigner, there is "private DockingActionList dockingAction;" // Don't you just love Reflector?! FieldInfo fi = typeof(ControlDesigner).GetField("dockingAction", BindingFlags.Instance | BindingFlags.NonPublic); if (fi != null) { DesignerActionList dockingAction = (DesignerActionList)fi.GetValue(this); if (dockingAction != null) { DesignerActionService service = (DesignerActionService)GetService(typeof(DesignerActionService)); if (service != null) { service.Remove(Control, dockingAction); } } } } #endregion #region IDesignerFilter overrides /// /// Adjusts the set of properties the component exposes through a . /// /// An containing the properties for the class of the component. protected override void PreFilterProperties(IDictionary properties) { // Debug.WriteLine("ObjectListViewDesigner.PreFilterProperties"); // Always call the base PreFilterProperties implementation // before you modify the properties collection. base.PreFilterProperties(properties); // Give the listviewdesigner a chance to filter the properties // (though we already know it's not going to do anything) designerFilter.PreFilterProperties(properties); // I'd like to just remove the redundant properties, but that would // break backward compatibility. The deserialiser that handles the XXX.Designer.cs file // works off the designer, so even if the property exists in the class, the deserialiser will // throw an error if the associated designer actually removes that property. // So we shadow the unwanted properties, and give the replacement properties // non-browsable attributes so that they are hidden from the user List unwantedProperties = new List(new string[] { "BackgroundImage", "BackgroundImageTiled", "HotTracking", "HoverSelection", "LabelEdit", "VirtualListSize", "VirtualMode" }); // Also hid Tooltip properties, since giving a tooltip to the control through the IDE // messes up the tooltip handling foreach (string propertyName in properties.Keys) { if (propertyName.StartsWith("ToolTip")) { unwantedProperties.Add(propertyName); } } // If we are looking at a TreeListView, remove group related properties // since TreeListViews can't show groups if (Control is TreeListView) { unwantedProperties.AddRange(new string[] { "GroupImageList", "GroupWithItemCountFormat", "GroupWithItemCountSingularFormat", "HasCollapsibleGroups", "SpaceBetweenGroups", "ShowGroups", "SortGroupItemsByPrimaryColumn", "ShowItemCountOnGroups" }); } // Shadow the unwanted properties, and give the replacement properties // non-browsable attributes so that they are hidden from the user foreach (string unwantedProperty in unwantedProperties) { PropertyDescriptor propertyDesc = TypeDescriptor.CreateProperty( typeof(ObjectListView), (PropertyDescriptor)properties[unwantedProperty], new BrowsableAttribute(false)); properties[unwantedProperty] = propertyDesc; } } /// /// Allows a designer to add to the set of events that it exposes through a . /// /// The events for the class of the component. protected override void PreFilterEvents(IDictionary events) { // Debug.WriteLine("ObjectListViewDesigner.PreFilterEvents"); base.PreFilterEvents(events); designerFilter.PreFilterEvents(events); // Remove the events that don't make sense for an ObjectListView. // See PreFilterProperties() for why we do this dance rather than just remove the event. List unwanted = new List(new string[] { "AfterLabelEdit", "BeforeLabelEdit", "DrawColumnHeader", "DrawItem", "DrawSubItem", "RetrieveVirtualItem", "SearchForVirtualItem", "VirtualItemsSelectionRangeChanged" }); // If we are looking at a TreeListView, remove group related events // since TreeListViews can't show groups if (Control is TreeListView) { unwanted.AddRange(new string[] { "AboutToCreateGroups", "AfterCreatingGroups", "BeforeCreatingGroups", "GroupTaskClicked", "GroupExpandingCollapsing", "GroupStateChanged" }); } foreach (string unwantedEvent in unwanted) { EventDescriptor eventDesc = TypeDescriptor.CreateEvent( typeof(ObjectListView), (EventDescriptor)events[unwantedEvent], new BrowsableAttribute(false)); events[unwantedEvent] = eventDesc; } } /// /// Allows a designer to change or remove items from the set of attributes that it exposes through a . /// /// The attributes for the class of the component. protected override void PostFilterAttributes(IDictionary attributes) { // Debug.WriteLine("ObjectListViewDesigner.PostFilterAttributes"); designerFilter.PostFilterAttributes(attributes); base.PostFilterAttributes(attributes); } /// /// Allows a designer to change or remove items from the set of events that it exposes through a . /// /// The events for the class of the component. protected override void PostFilterEvents(IDictionary events) { // Debug.WriteLine("ObjectListViewDesigner.PostFilterEvents"); designerFilter.PostFilterEvents(events); base.PostFilterEvents(events); } #endregion #region Overrides /// /// Gets the design-time action lists supported by the component associated with the designer. /// /// /// The design-time action lists supported by the component associated with the designer. /// public override DesignerActionListCollection ActionLists { get { // We want to change the first action list so it only has the commands we want DesignerActionListCollection actionLists = listViewDesigner.ActionLists; if (actionLists.Count > 0 && !(actionLists[0] is ListViewActionListAdapter)) { actionLists[0] = new ListViewActionListAdapter(this, actionLists[0]); } return actionLists; } } /// /// Gets the collection of components associated with the component managed by the designer. /// /// /// The components that are associated with the component managed by the designer. /// public override ICollection AssociatedComponents { get { ArrayList components = new ArrayList(base.AssociatedComponents); components.AddRange(listViewDesigner.AssociatedComponents); return components; } } /// /// Indicates whether a mouse click at the specified point should be handled by the control. /// /// /// true if a click at the specified point is to be handled by the control; otherwise, false. /// /// A indicating the position at which the mouse was clicked, in screen coordinates. protected override bool GetHitTest(Point point) { // The ListViewDesigner wants to allow column dividers to be resized return (bool)listViewDesignGetHitTest.Invoke(listViewDesigner, new object[] { point }); } /// /// Processes Windows messages and optionally routes them to the control. /// /// The to process. protected override void WndProc(ref Message m) { switch (m.Msg) { case 0x4e: case 0x204e: // The listview designer is interested in HDN_ENDTRACK notifications listViewDesignWndProc.Invoke(listViewDesigner, new object[] { m }); break; default: base.WndProc(ref m); break; } } #endregion #region Implementation variables private ControlDesigner listViewDesigner; private IDesignerFilter designerFilter; private MethodInfo listViewDesignGetHitTest; private MethodInfo listViewDesignWndProc; #endregion #region Custom action list /// /// This class modifies a ListViewActionList, by removing the "Edit Items" and "Edit Groups" actions. /// /// /// /// That class is internal, so we cannot simply subclass it, which would be simplier. /// /// /// Action lists use reflection to determine if that action can be executed, so we not /// only have to modify the returned collection of actions, but we have to implement /// the properties and commands that the returned actions use. /// private class ListViewActionListAdapter : DesignerActionList { public ListViewActionListAdapter(ObjectListViewDesigner designer, DesignerActionList wrappedList) : base(wrappedList.Component) { this.designer = designer; this.wrappedList = wrappedList; } public override DesignerActionItemCollection GetSortedActionItems() { DesignerActionItemCollection items = wrappedList.GetSortedActionItems(); items.RemoveAt(2); // remove Edit Groups items.RemoveAt(0); // remove Edit Items return items; } private void EditValue(ComponentDesigner componentDesigner, IComponent iComponent, string propertyName) { // One more complication. The ListViewActionList classes uses an internal class, EditorServiceContext, to // edit the items/columns/groups collections. So, we use reflection to bypass the data hiding. Type tEditorServiceContext = Type.GetType("System.Windows.Forms.Design.EditorServiceContext, System.Design"); tEditorServiceContext.InvokeMember("EditValue", BindingFlags.InvokeMethod | BindingFlags.Static, null, null, new object[] { componentDesigner, iComponent, propertyName }); } private void SetValue(object target, string propertyName, object value) { TypeDescriptor.GetProperties(target)[propertyName].SetValue(target, value); } public void InvokeColumnsDialog() { EditValue(designer, Component, "Columns"); } // Don't need these since we removed their corresponding actions from the list. // Keep the methods just in case. //public void InvokeGroupsDialog() { // EditValue(this.designer, base.Component, "Groups"); //} //public void InvokeItemsDialog() { // EditValue(this.designer, base.Component, "Items"); //} public ImageList LargeImageList { get { return ((ListView)Component).LargeImageList; } set { SetValue(Component, "LargeImageList", value); } } public ImageList SmallImageList { get { return ((ListView)Component).SmallImageList; } set { SetValue(Component, "SmallImageList", value); } } public View View { get { return ((ListView)Component).View; } set { SetValue(Component, "View", value); } } ObjectListViewDesigner designer; DesignerActionList wrappedList; } #endregion #region DesignerCommandSet private class CDDesignerCommandSet : DesignerCommandSet { public CDDesignerCommandSet(ComponentDesigner componentDesigner) { this.componentDesigner = componentDesigner; } public override ICollection GetCommands(string name) { // Debug.WriteLine("CDDesignerCommandSet.GetCommands:" + name); if (componentDesigner != null) { if (name.Equals("Verbs")) { return componentDesigner.Verbs; } if (name.Equals("ActionLists")) { return componentDesigner.ActionLists; } } return base.GetCommands(name); } private readonly ComponentDesigner componentDesigner; } #endregion } /// /// This class works in conjunction with the OLVColumns property to allow OLVColumns /// to be added to the ObjectListView. /// public class OLVColumnCollectionEditor : CollectionEditor { /// /// Create a OLVColumnCollectionEditor /// /// public OLVColumnCollectionEditor(Type t) : base(t) { } /// /// What type of object does this editor create? /// /// protected override Type CreateCollectionItemType() { return typeof(OLVColumn); } /// /// Edit a given value /// /// /// /// /// public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value) { if (context == null) throw new ArgumentNullException("context"); if (provider == null) throw new ArgumentNullException("provider"); // Figure out which ObjectListView we are working on. This should be the Instance of the context. ObjectListView olv = context.Instance as ObjectListView; Debug.Assert(olv != null, "Instance must be an ObjectListView"); // Edit all the columns, not just the ones that are visible base.EditValue(context, provider, olv.AllColumns); // Set the columns on the ListView to just the visible columns List newColumns = olv.GetFilteredColumns(View.Details); olv.Columns.Clear(); olv.Columns.AddRange(newColumns.ToArray()); return olv.Columns; } /// /// What text should be shown in the list for the given object? /// /// /// protected override string GetDisplayText(object value) { if (value is not OLVColumn col || String.IsNullOrEmpty(col.AspectName)) return base.GetDisplayText(value); return String.Format("{0} ({1})", base.GetDisplayText(value), col.AspectName); } } /// /// Control how the overlay is presented in the IDE /// internal class OverlayConverter : ExpandableObjectConverter { public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) { return destinationType == typeof(string) || base.CanConvertTo(context, destinationType); } public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType) { if (destinationType == typeof(string)) { if (value is ImageOverlay imageOverlay) { return imageOverlay.Image == null ? "(none)" : "(set)"; } if (value is TextOverlay textOverlay) { return String.IsNullOrEmpty(textOverlay.Text) ? "(none)" : "(set)"; } } return base.ConvertTo(context, culture, value, destinationType); } } } ================================================ FILE: source/ObjectListView/ObjectListView.FxCop ================================================  True c:\program files\microsoft fxcop 1.36\Xml\FxCopReport.xsl True True True 10 1 False False 120 True 2.0 $(ProjectDir)/trunk/ObjectListView/bin/Debug/ 'ObjectListView.dll' 'BarRenderer' 'Pen' 'BarRenderer.BarRenderer(Pen, Brush)' 'BarRenderer.UseStandardBar' 'bool' false 'BarRenderer.BarRenderer(int, int, Pen, Brush)' 'BarRenderer.UseStandardBar' 'bool' false 'BarRenderer.BackgroundColor' 'BaseRenderer.GetBackgroundColor()' 'BaseRenderer.GetBackgroundColor()' 'BaseRenderer.GetForegroundColor()' 'BaseRenderer.GetImageSelector()' 'BaseRenderer.GetText()' 'BaseRenderer.GetTextBackgroundColor()' 'BorderDecoration' 'SolidBrush' 'CellEditEventHandler' 'g' 'CheckStateRenderer.CalculateCheckBoxBounds(Graphics, Rectangle)' 'ColumnRightClickEventHandler' 'ComboBoxItem.Key.get()' 'DataListView.currencyManager_ListChanged(object, ListChangedEventArgs)' 'DataListView.currencyManager_MetaDataChanged(object, EventArgs)' 'DataListView.currencyManager_PositionChanged(object, EventArgs)' 'DescribedTaskRenderer.GetDescription()' 'DropTargetLocation' 'collection' 'ICollection' 'FastObjectListDataSource.EnumerableToArray(IEnumerable)' castclass 'FastObjectListDataSource.FilteredObjectList.get()' Flag 'FlagRenderer' 'FloatCellEditor.Value.get()' 'FloatCellEditor.Value.set(double)' 'GlassPanelForm.CreateParams.get()' 'Form.CreateParams.get()' [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)] 'GlassPanelForm.WndProc(ref Message)' 'Form.WndProc(ref Message)' [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)] 'GroupMetricsMask' 'GroupMetricsMask.LVGMF_NONE' 'GroupMetricsMask' 'GroupState' 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000 'GroupState' 'GroupState.LVGS_NORMAL' 'GroupState' 'HeaderControl.HeaderControl(ObjectListView)' 'NativeWindow.AssignHandle(IntPtr)' ->'HeaderControl.HeaderControl(ObjectListView)' ->'HeaderControl.HeaderControl(ObjectListView)' 'HeaderControl.HeaderControl(ObjectListView)' 'NativeWindow.NativeWindow()' ->'HeaderControl.HeaderControl(ObjectListView)' ->'HeaderControl.HeaderControl(ObjectListView)' 'g' 'HeaderControl.CalculateHeight(Graphics)' 'Graphics' 'IDeviceContext' 'g' 'HeaderControl.DrawHeaderText(Graphics, Rectangle, OLVColumn, HeaderStateStyle)' 'Graphics' 'IDeviceContext' 'g' 'HeaderControl.DrawThemedBackground(Graphics, Rectangle, int, bool)' 'Graphics' 'IDeviceContext' 'g' 'HeaderControl.DrawThemedSortIndicator(Graphics, Rectangle)' 'Graphics' 'IDeviceContext' Unthemed 'HeaderControl.DrawUnthemedBackground(Graphics, Rectangle, int, bool, HeaderStateStyle)' Unthemed 'HeaderControl.DrawUnthemedSortIndicator(Graphics, Rectangle)' 'm' 'HeaderControl.HandleDestroy(ref Message)' 'm' 'HeaderControl.HandleMouseMove(ref Message)' 'm' 'HeaderControl.HandleNotify(ref Message)' 'Message.GetLParam(Type)' ->'HeaderControl.HandleNotify(ref Message)' ->'HeaderControl.HandleNotify(ref Message)' 'HeaderControl.HandleNotify(ref Message)' 'Message.LParam.get()' ->'HeaderControl.HandleNotify(ref Message)' ->'HeaderControl.HandleNotify(ref Message)' 'm' 'value' 'HeaderControl.HotFontStyle.set(FontStyle)' Flags 'HeaderControl.TextFormatFlags' 'HeaderControl.WndProc(ref Message)' 'NativeWindow.WndProc(ref Message)' [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)] 'HeaderControl.WndProc(ref Message)' 'Message.Msg.get()' ->'HeaderControl.WndProc(ref Message)' ->'HeaderControl.WndProc(ref Message)' 'HeaderControl.WndProc(ref Message)' 'NativeWindow.WndProc(ref Message)' ->'HeaderControl.WndProc(ref Message)' ->'HeaderControl.WndProc(ref Message)' 'text' 'HighlightTextRenderer.HighlightTextRenderer(string)' 'value' 'HighlightTextRenderer.StringComparison.set(StringComparison)' 'value' 'HighlightTextRenderer.TextToHighlight.set(string)' 'HyperlinkEventArgs.Column.set(OLVColumn)' 'HyperlinkEventArgs.ColumnIndex.set(int)' 'HyperlinkEventArgs.Item.set(OLVListItem)' 'HyperlinkEventArgs.ListView.set(ObjectListView)' 'HyperlinkEventArgs.Model.set(object)' 'HyperlinkEventArgs.RowIndex.set(int)' 'HyperlinkEventArgs.SubItem.set(OLVListSubItem)' 'HyperlinkEventArgs.Url' 'HyperlinkEventArgs.Url.set(string)' 'ImageRenderer.GetImageFromAspect()' 'IntUpDown.Value.get()' 'IntUpDown.Value.set(int)' 'IVirtualListDataSource.GetObjectCount()' Multi 'MultiImageRenderer' 'MultiImageRenderer.ImageSelector' 'BaseRenderer.GetImageSelector()' 'Munger.GetValue(object)' 'object' 'Munger.PutValue(object, object)' 'object' 'Munger.PutValue(object, object)' 'object' 'NativeMethods.ChangeSize(IWin32Window, int, int)' 'NativeMethods.ChangeZOrder(IWin32Window, IWin32Window)' 'NativeMethods.DeleteObject(IntPtr)' 'NativeMethods.DrawImageList(Graphics, ImageList, int, int, int, bool)' 'NativeMethods.GetClientRect(IntPtr, ref Rectangle)' 'NativeMethods.GetColumnSides(ObjectListView, int)' 'NativeMethods.GetColumnSides(ObjectListView, int)' 'Point' 'NativeMethods.GetGroupInfo(ObjectListView, int, ref NativeMethods.LVGROUP2)' 'NativeMethods.GetScrollInfo(IntPtr, int, NativeMethods.SCROLLINFO)' 'NativeMethods.GetUpdateRect(Control)' 'NativeMethods.GetUpdateRectInternal(IntPtr, ref Rectangle, bool)' 'eraseBackground' 'NativeMethods.GetUpdateRectInternal(IntPtr, ref Rectangle, bool)' 'NativeMethods.GetWindowLong32(IntPtr, int)' 8 64-bit 4 'IntPtr' 'NativeMethods.GetWindowLongPtr64(IntPtr, int)' 'user32.dll' GetWindowLongPtr 'NativeMethods.ImageList_Draw(IntPtr, int, IntPtr, int, int, int)' 'NativeMethods.ImageList_Draw(IntPtr, int, IntPtr, int, int, int)' 'erase' 'NativeMethods.InvalidateRect(IntPtr, int, bool)' 'NativeMethods.InvalidateRect(IntPtr, int, bool)' 'NativeMethods.SendMessage(IntPtr, int, int, ref NativeMethods.LVGROUP)' 'wParam' 'NativeMethods.SendMessage(IntPtr, int, int, ref NativeMethods.LVGROUP)' 4 64-bit 8 'int' 'wParam' 'NativeMethods.SendMessage(IntPtr, int, int, ref NativeMethods.LVGROUP2)' 4 64-bit 8 'int' 'wParam' 'NativeMethods.SendMessage(IntPtr, int, int, ref NativeMethods.LVGROUPMETRICS)' 4 64-bit 8 'int' 'NativeMethods.SendMessage(IntPtr, int, int, ref NativeMethods.LVHITTESTINFO)' 'wParam' 'NativeMethods.SendMessage(IntPtr, int, int, ref NativeMethods.LVHITTESTINFO)' 4 64-bit 8 'int' 'wParam' 'NativeMethods.SendMessage(IntPtr, int, int, int)' 4 64-bit 8 'int' 'lParam' 'NativeMethods.SendMessage(IntPtr, int, int, int)' 4 64-bit 8 'int' 'wParam' 'NativeMethods.SendMessage(IntPtr, int, int, IntPtr)' 4 64-bit 8 'int' 'lParam' 'NativeMethods.SendMessage(IntPtr, int, IntPtr, int)' 4 64-bit 8 'int' 'wParam' 'NativeMethods.SendMessageHDItem(IntPtr, int, int, ref NativeMethods.HDITEM)' 4 64-bit 8 'int' 'NativeMethods.SendMessageIUnknown(IntPtr, int, object, int)' 'lParam' 'NativeMethods.SendMessageIUnknown(IntPtr, int, object, int)' 4 64-bit 8 'int' 'NativeMethods.SendMessageLVBKIMAGE(IntPtr, int, int, ref NativeMethods.LVBKIMAGE)' 'wParam' 'NativeMethods.SendMessageLVBKIMAGE(IntPtr, int, int, ref NativeMethods.LVBKIMAGE)' 4 64-bit 8 'int' 'wParam' 'NativeMethods.SendMessageLVItem(IntPtr, int, int, ref NativeMethods.LVITEM)' 4 64-bit 8 'int' 'wParam' 'NativeMethods.SendMessageRECT(IntPtr, int, int, ref NativeMethods.RECT)' 4 64-bit 8 'int' 'wParam' 'NativeMethods.SendMessageString(IntPtr, int, int, string)' 4 64-bit 8 'int' 'lParam' 'wParam' 'NativeMethods.SendMessageTOOLINFO(IntPtr, int, int, NativeMethods.TOOLINFO)' 4 64-bit 8 'int' 'NativeMethods.SetBackgroundImage(ListView, Image)' 'NativeMethods.SetBkColor(IntPtr, int)' 'NativeMethods.SetSelectedColumn(ListView, ColumnHeader)' 'NativeMethods.SetTextColor(IntPtr, int)' 'NativeMethods.SetTooltipControl(ListView, ToolTipControl)' 'NativeMethods.SetWindowLongPtr32(IntPtr, int, int)' 8 64-bit 4 'IntPtr' 'dwNewLong' 'NativeMethods.SetWindowLongPtr64(IntPtr, int, int)' 4 64-bit 8 'int' 'NativeMethods.SetWindowLongPtr64(IntPtr, int, int)' 'user32.dll' SetWindowLongPtr 'NativeMethods.SetWindowPos(IntPtr, IntPtr, int, int, int, int, uint)' 'NativeMethods.SetWindowTheme(IntPtr, string, string)' 8 64-bit 4 'IntPtr' 'subApp' 'subIdList' 'NativeMethods.ShowWindow(IntPtr, int)' 'NativeMethods.ValidatedRectInternal(IntPtr, ref Rectangle)' 'NativeMethods.ValidateRect(Control, Rectangle)' 'NativeMethods.SCROLLINFO.SCROLLINFO()' 'Marshal.SizeOf(Type)' ->'NativeMethods.SCROLLINFO.SCROLLINFO()' ->'NativeMethods.SCROLLINFO.SCROLLINFO()' ->'NativeMethods.GetScrollPosition(ListView, bool)' ->'HeaderControl.ColumnIndexUnderCursor.get()' 'NativeMethods.SCROLLINFO.SCROLLINFO()' 'Marshal.SizeOf(Type)' ->'NativeMethods.SCROLLINFO.SCROLLINFO()' ->'NativeMethods.SCROLLINFO.SCROLLINFO()' ->'NativeMethods.GetScrollPosition(ListView, bool)' ->'HeaderControl.IsCursorOverLockedDivider.get()' 'NativeMethods.SCROLLINFO.SCROLLINFO()' 'Marshal.SizeOf(Type)' ->'NativeMethods.SCROLLINFO.SCROLLINFO()' ->'NativeMethods.SCROLLINFO.SCROLLINFO()' ->'NativeMethods.GetScrollPosition(ListView, bool)' ->'NativeMethods.GetScrolledColumnSides(ListView, int)' ->'OLVListItem.GetSubItemBounds(int)' 'NativeMethods.SCROLLINFO.SCROLLINFO()' 'Marshal.SizeOf(Type)' ->'NativeMethods.SCROLLINFO.SCROLLINFO()' ->'NativeMethods.SCROLLINFO.SCROLLINFO()' ->'NativeMethods.GetScrollPosition(ListView, bool)' ->'NativeMethods.GetScrolledColumnSides(ListView, int)' ->'ObjectListView.CalculateCellBounds(OLVListItem, int, ItemBoundsPortion)' ->'ObjectListView.CalculateCellBounds(OLVListItem, int)' 'NativeMethods.SCROLLINFO.SCROLLINFO()' 'Marshal.SizeOf(Type)' ->'NativeMethods.SCROLLINFO.SCROLLINFO()' ->'NativeMethods.SCROLLINFO.SCROLLINFO()' ->'NativeMethods.GetScrollPosition(ListView, bool)' ->'NativeMethods.GetScrolledColumnSides(ListView, int)' ->'ObjectListView.CalculateCellBounds(OLVListItem, int, ItemBoundsPortion)' ->'ObjectListView.CalculateCellTextBounds(OLVListItem, int)' 'NativeMethods.SCROLLINFO.SCROLLINFO()' 'Marshal.SizeOf(Type)' ->'NativeMethods.SCROLLINFO.SCROLLINFO()' ->'NativeMethods.SCROLLINFO.SCROLLINFO()' ->'NativeMethods.GetScrollPosition(ListView, bool)' ->'NativeMethods.GetScrolledColumnSides(ListView, int)' ->'ObjectListView.OlvHitTest(int, int)' 'NativeMethods.SCROLLINFO.SCROLLINFO()' 'Marshal.SizeOf(Type)' ->'NativeMethods.SCROLLINFO.SCROLLINFO()' ->'NativeMethods.SCROLLINFO.SCROLLINFO()' ->'NativeMethods.GetScrollPosition(ListView, bool)' ->'NativeMethods.GetScrolledColumnSides(ListView, int)' ->'TintedColumnDecoration.Draw(ObjectListView, Graphics, Rectangle)' 'NativeMethods.SCROLLINFO.SCROLLINFO()' 'Marshal.SizeOf(Type)' ->'NativeMethods.SCROLLINFO.SCROLLINFO()' ->'NativeMethods.SCROLLINFO.SCROLLINFO()' ->'NativeMethods.GetScrollPosition(ListView, bool)' ->'ObjectListView.EnsureGroupVisible(ListViewGroup)' 'NativeMethods.SCROLLINFO.SCROLLINFO()' 'Marshal.SizeOf(Type)' ->'NativeMethods.SCROLLINFO.SCROLLINFO()' ->'NativeMethods.SCROLLINFO.SCROLLINFO()' ->'NativeMethods.GetScrollPosition(ListView, bool)' ->'ObjectListView.HandleBeginScroll(ref Message)' 'NativeMethods.SCROLLINFO.SCROLLINFO()' 'Marshal.SizeOf(Type)' ->'NativeMethods.SCROLLINFO.SCROLLINFO()' ->'NativeMethods.SCROLLINFO.SCROLLINFO()' ->'NativeMethods.GetScrollPosition(ListView, bool)' ->'ObjectListView.HandleKeyDown(ref Message)' 'NativeMethods.TOOLINFO.TOOLINFO()' 'Marshal.SizeOf(Type)' ->'NativeMethods.TOOLINFO.TOOLINFO()' ->'NativeMethods.TOOLINFO.TOOLINFO()' ->'ToolTipControl.MakeToolInfoStruct(IWin32Window)' ->'ToolTipControl.AddTool(IWin32Window)' 'NativeMethods.TOOLINFO.TOOLINFO()' 'Marshal.SizeOf(Type)' ->'NativeMethods.TOOLINFO.TOOLINFO()' ->'NativeMethods.TOOLINFO.TOOLINFO()' ->'ToolTipControl.MakeToolInfoStruct(IWin32Window)' ->'ToolTipControl.RemoveToolTip(IWin32Window)' 'ObjectListView.AllColumns' 'List<OLVColumn>' 'ObjectListView.AllColumns' 'rowIndex' 'ObjectListView.ApplyHyperlinkStyle(int, OLVListItem)' 'ObjectListView.BooleanCheckStateGetter' 'ObjectListView.BooleanCheckStatePutter' 'item' 'ObjectListView.CalculateCellBounds(OLVListItem, int)' 'OLVListItem' 'ListViewItem' 'ObjectListView.CellEditor' 'ObjectListView.GetCellEditor(OLVListItem, int)' 'ObjectListView.CellEditor_Validating(object, CancelEventArgs)' 'ObjectListView.CellToolTip' 'ObjectListView.GetCellToolTip(int, int)' 'ObjectListView.CheckedObject' 'ObjectListView.GetCheckedObject()' 'ObjectListView.CheckedObjects' 'ObjectListView.GetCheckedObjects()' 'ObjectListView.CheckedObjects' 'List<OLVColumn>' 'ObjectListView.ColumnsInDisplayOrder' 'ObjectListView.ConfigureAutoComplete(TextBox, OLVColumn)' tb 'tb' 'ObjectListView.ConfigureAutoComplete(TextBox, OLVColumn, int)' tb 'tb' 'List<OLVListItem>' 'ObjectListView.DrawAllDecorations(Graphics, List<OLVListItem>)' 'ObjectListView.EditorRegistry' 'ObjectListView.EnsureGroupVisible(ListViewGroup)' lvg 'lvg' 'ObjectListView.FilterObjects(IEnumerable, IModelFilter, IListFilter)' a 'aListFilter' 'ObjectListView.FilterObjects(IEnumerable, IModelFilter, IListFilter)' a 'aModelFilter' 'control' 'CheckBox' 'ObjectListView.GetControlValue(Control)' castclass 'control' 'ComboBox' 'ObjectListView.GetControlValue(Control)' castclass 'control' 'TextBox' 'ObjectListView.GetControlValue(Control)' castclass 'List<OLVColumn>' 'ObjectListView.GetFilteredColumns(View)' 'selectedColumn' 'ObjectListView.GetItemCount()' 'ObjectListView.GetLastItemInDisplayOrder()' 'ObjectListView.GetSelectedObject()' 'ObjectListView.GetSelectedObjects()' 'ObjectListView.HandleApplicationIdle(object, EventArgs)' 'ObjectListView.HandleApplicationIdle_ResizeColumns(object, EventArgs)' 'ObjectListView.HandleCellToolTipShowing(object, ToolTipShowingEventArgs)' 'ObjectListView.HandleChar(ref Message)' 'Control.ProcessKeyEventArgs(ref Message)' ->'ObjectListView.HandleChar(ref Message)' ->'ObjectListView.HandleChar(ref Message)' 'ObjectListView.HandleChar(ref Message)' 'Message.WParam.get()' ->'ObjectListView.HandleChar(ref Message)' ->'ObjectListView.HandleChar(ref Message)' 'm' 'ObjectListView.HandleColumnClick(object, ColumnClickEventArgs)' 'ObjectListView.HandleColumnWidthChanged(object, ColumnWidthChangedEventArgs)' 'ObjectListView.HandleColumnWidthChanging(object, ColumnWidthChangingEventArgs)' 'ObjectListView.HandleContextMenu(ref Message)' 'Message.LParam.get()' ->'ObjectListView.HandleContextMenu(ref Message)' ->'ObjectListView.HandleContextMenu(ref Message)' 'ObjectListView.HandleContextMenu(ref Message)' 'Message.WParam.get()' ->'ObjectListView.HandleContextMenu(ref Message)' ->'ObjectListView.HandleContextMenu(ref Message)' 'm' 'ObjectListView.HandleFindItem(ref Message)' 'Message.GetLParam(Type)' ->'ObjectListView.HandleFindItem(ref Message)' ->'ObjectListView.HandleFindItem(ref Message)' 'ObjectListView.HandleFindItem(ref Message)' 'Message.Result.set(IntPtr)' ->'ObjectListView.HandleFindItem(ref Message)' ->'ObjectListView.HandleFindItem(ref Message)' 'ObjectListView.HandleFindItem(ref Message)' 'Message.WParam.get()' ->'ObjectListView.HandleFindItem(ref Message)' ->'ObjectListView.HandleFindItem(ref Message)' 'm' 'ObjectListView.HandleHeaderToolTipShowing(object, ToolTipShowingEventArgs)' 'ObjectListView.HandleLayout(object, LayoutEventArgs)' 'ObjectListView.HandleNotify(ref Message)' 'Marshal.PtrToStructure(IntPtr, Type)' ->'ObjectListView.HandleNotify(ref Message)' ->'ObjectListView.HandleNotify(ref Message)' 'ObjectListView.HandleNotify(ref Message)' 'Marshal.StructureToPtr(object, IntPtr, bool)' ->'ObjectListView.HandleNotify(ref Message)' ->'ObjectListView.HandleNotify(ref Message)' 'ObjectListView.HandleNotify(ref Message)' 'Message.GetLParam(Type)' ->'ObjectListView.HandleNotify(ref Message)' ->'ObjectListView.HandleNotify(ref Message)' 'ObjectListView.HandleNotify(ref Message)' 'Message.Result.set(IntPtr)' ->'ObjectListView.HandleNotify(ref Message)' ->'ObjectListView.HandleNotify(ref Message)' 'ObjectListView.HandleNotify(ref Message)' 'NativeWindow.Handle.get()' ->'ObjectListView.HandleNotify(ref Message)' ->'ObjectListView.HandleNotify(ref Message)' 'm' 'ObjectListView.HandleReflectNotify(ref Message)' 'Marshal.StructureToPtr(object, IntPtr, bool)' ->'ObjectListView.HandleReflectNotify(ref Message)' ->'ObjectListView.HandleReflectNotify(ref Message)' 'ObjectListView.HandleReflectNotify(ref Message)' 'Message.GetLParam(Type)' ->'ObjectListView.HandleReflectNotify(ref Message)' ->'ObjectListView.HandleReflectNotify(ref Message)' 'ObjectListView.HandleReflectNotify(ref Message)' 'Message.LParam.get()' ->'ObjectListView.HandleReflectNotify(ref Message)' ->'ObjectListView.HandleReflectNotify(ref Message)' 'm' 'ObjectListView.HeaderToolTip' 'ObjectListView.GetHeaderToolTip(int)' 'url' 'ObjectListView.IsUrlVisited(string)' 'url' 'ObjectListView.MarkUrlVisited(string)' Unsort 'ObjectListView.MenuLabelUnsort' 'ObjectListView.ProcessDialogKey(Keys)' 'Control.ProcessDialogKey(Keys)' [UIPermission(SecurityAction.LinkDemand, Window = UIPermissionWindow.AllWindows)] 'ObjectListView.ProcessDialogKey(Keys)' 'Control.ProcessDialogKey(Keys)' ->'ObjectListView.ProcessDialogKey(Keys)' ->'ObjectListView.ProcessDialogKey(Keys)' 'ObjectListView.SelectedObject' 'ObjectListView.GetSelectedObject()' 'ObjectListView.SelectedObjects' 'ObjectListView.GetSelectedObjects()' 'ObjectListView.SelectedObjects' 'control' 'ComboBox' 'ObjectListView.SetControlValue(Control, object, string)' castclass Checkedness 'ObjectListView.SetObjectCheckedness(object, CheckState)' 'item' 'ObjectListView.SetSubItemImages(int, OLVListItem, bool)' 'OLVListItem' 'ListViewItem' 'columnToSort' 'ObjectListView.ShowSortIndicator(OLVColumn, SortOrder)' 'OLVColumn' 'ColumnHeader' 'ObjectListView.SORT_INDICATOR_DOWN_KEY' 'ObjectListView.SORT_INDICATOR_UP_KEY' 'ObjectListView' 'ISupportInitialize.BeginInit()' 'ObjectListView' 'ISupportInitialize.EndInit()' Renderering 'ObjectListView.TextRendereringHint' Unsort 'ObjectListView.Unsort()' 'ObjectListView.WndProc(ref Message)' 'ListView.WndProc(ref Message)' [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)] 'ObjectListView.WndProc(ref Message)' 'Control.DefWndProc(ref Message)' ->'ObjectListView.WndProc(ref Message)' ->'ObjectListView.WndProc(ref Message)' 'ObjectListView.WndProc(ref Message)' 'ListView.WndProc(ref Message)' ->'ObjectListView.WndProc(ref Message)' ->'ObjectListView.WndProc(ref Message)' 'ObjectListView.WndProc(ref Message)' 'Message.Msg.get()' ->'ObjectListView.WndProc(ref Message)' ->'ObjectListView.WndProc(ref Message)' 'ObjectListView.ObjectListViewState.VersionNumber' 'OLVColumnAttribute' 'OLVColumnAttribute.Title' 'title' 'OLVColumnAttribute' Cutoffs 'OLVColumnAttribute.GroupCutoffs' 'OLVColumnAttribute.GroupCutoffs' 'OLVColumnAttribute.GroupDescriptions' 'OLVDataObject.ConvertToHtmlFragment(string)' 'string.IndexOf(string)' 'string.IndexOf(string, StringComparison)' 'OLVGroup.GetState()' 'OLVGroup.State' 'OLVGroup.GetState()' Subseted 'OLVGroup.Subseted' 'OLVListItem' 'OLVListItem.Bounds' 'ListViewItem.GetBounds(ItemBoundsPortion)' 'value' 'string' 'OLVListItem.ImageSelector.set(object)' castclass 'OLVListSubItem.Url' 'SimpleDropSink' 'Timer' 'Timer.Interval.set(int)' 'SimpleDropSink.SimpleDropSink()' 'TextAdornment' 'StringFormat' 'TextMatchFilter.TextMatchFilter(ObjectListView, string, OLVColumn[])' StringComparison.InvariantCultureIgnoreCase 'TextMatchFilter.TextMatchFilter(ObjectListView, string, OLVColumn[], TextMatchFilter.MatchKind, StringComparison)' 'TextMatchFilter.TextMatchFilter(ObjectListView, string, TextMatchFilter.MatchKind)' StringComparison.InvariantCultureIgnoreCase 'TextMatchFilter.TextMatchFilter(ObjectListView, string, OLVColumn[], TextMatchFilter.MatchKind, StringComparison)' 'TextMatchFilter.Columns' 'TextMatchFilter.IsIncluded(OLVColumn)' 'TextMatchFilter.MatchKind' 'TintedColumnDecoration' 'SolidBrush' Disp 'ToolTipControl.HandleGetDispInfo(ref Message)' 'window' 'ToolTipControl.PopToolTip(IWin32Window)' 'ToolTipControl.StandardIcons' 'List<TreeListView.Branch>' 'TreeListView.Branch.ChildBranches' 'List<TreeListView.Branch>' 'TreeListView.Branch.FilteredChildBranches' Flag 'TreeListView.Branch.ManageLastChildFlag(MethodInvoker)' Flags 'TreeListView.Branch.BranchFlags' 'TreeListView.Tree.GetBranchComparer()' 'TreeListView.TreeRenderer.PIXELS_PER_LEVEL' 'TypedObjectListView<T>.BooleanCheckStateGetter' 'TypedObjectListView<T>.BooleanCheckStatePutter' 'TypedObjectListView<T>.CellToolTipGetter' 'TypedObjectListView<T>.CheckedObjects' 'TypedObjectListView<T>.SelectedObjects' 'UintUpDown.Value.get()' 'UintUpDown.Value.set(uint)' 'VirtualObjectListView.CheckedObjects' 'VirtualObjectListView.HandleCacheVirtualItems(object, CacheVirtualItemsEventArgs)' 'VirtualObjectListView.HandleRetrieveVirtualItem(object, RetrieveVirtualItemEventArgs)' 'VirtualObjectListView.HandleSearchForVirtualItem(object, SearchForVirtualItemEventArgs)' 'VirtualObjectListView.SetVirtualListSize(int)' 'Exception' These should be methods rather than properties The out parameter is necessary since this method returns two pieces of information: the item under the point and the subitem item too This is used to ensure we understand the newly load state. All these properties should be assignable. Our project is build with unsafe code enabled, so it automatically has the SecurityProperty set These initializations are not unnecessary We have to pass the windows message by reference Instances of this class do not need to be disposable These are utility methods that could well be used at runtime Old style constants. Can't change now These are OK like this. We need List<>, not IList<> since only List has a ToArray() method Legacy cases that have to be kept like this These are acceptable as methods rather than properties windows messages should be passed by reference This is not a security risk There are several problems that can occur here and we want to ignore them all These spellings are acceptable These will only be used by OL types Not appropriate here Can't change now we want to catch everthing MS! not flags MS! MS Sign {0} with a strong name key. Consider a design that does not require that {0} be an out parameter. {0} appears to have no upstream public or protected callers. Seal {0}, if possible. It appears that field {0} is never used or is only ever assigned to. Use this field or remove it. Change {0} to be read-only by removing the property setter. Consider changing the type of parameter {0} in {1} from {2} to its base type {3}. This method appears to only require base class members in its implementation. Suppress this violation if there is a compelling reason to require the more derived type in the method signature. Remove the property setter from {0} or reduce its accessibility because it corresponds to positional argument {1}. {0}, a parameter, is cast to type {1} multiple times in method {2}. Cache the result of the 'as' operator or direct cast in order to eliminate the redundant {3} instruction. Modify {0} to catch a more specific exception than {1} or rethrow the exception. Change {0} in {1} to use Collection<T>, ReadOnlyCollection<T> or KeyedCollection<K,V> {0} calls {1} but does not use the HRESULT or error code that the method returns. This could lead to unexpected behavior in error conditions or low-resource situations. Use the result in a conditional statement, assign the result to a variable, or pass it as an argument to another method. {0} creates a new instance of {1} which is never used. Pass the instance as an argument to another method, assign the instance to a variable, or remove the object creation if it is unnecessary. {0} initializes field {1} of type {2} to {3}. Remove this initialization because it will be done automatically by the runtime. {0} is marked with FlagsAttribute but a discrete member cannot be found for every settable bit that is used across the range of enum values. Remove FlagsAttribute from the type or define new members for the following (currently missing) values: {1} Modify the call to {0} in method {1} to set the timer interval to a value that's greater than or equal to one second. In enum {0}, change the name of {1} to 'None'. If enumeration name {0} is singular, change it to a plural form. Correct the spelling of '{0}' in member name {1} or remove it entirely if it represents any sort of Hungarian notation. In method {0}, correct the spelling of '{1}' in parameter name {2} or remove it entirely if it represents any sort of Hungarian notation. Correct the spelling of '{0}' in type name {1}. Make {0} sealed (a breaking change if this class has previously shipped), implement the method non-explicitly, or implement a new method that exposes the functionality of {1} and is visible to derived classes. Specify AttributeUsage on {0}. Add the MarshalAsAttribute to parameter {0} of P/Invoke {1}. If the corresponding unmanaged parameter is a 4-byte Win32 'BOOL', use [MarshalAs(UnmanagedType.Bool)]. For a 1-byte C++ 'bool', use MarshalAs(UnmanagedType.U1). Add the MarshalAsAttribute to the return type of P/Invoke {0}. If the corresponding unmanaged return type is a 4-byte Win32 'BOOL', use MarshalAs(UnmanagedType.Bool). For a 1-byte C++ 'bool', use MarshalAs(UnmanagedType.U1). The constituent members of {0} appear to represent flags that can be combined rather than discrete values. If this is correct, mark the enumeration with FlagsAttribute. Add [Serializable] to {0} as this type implements ISerializable. Consider making {0} non-public or a constant. If the name {0} is plural, change it to its singular form. Add the following security attribute to {0} in order to match a LinkDemand on base method {1}: {2}. As it is declared in your code, parameter {0} of P/Invoke {1} will be {2} bytes wide on {3} platforms. This is not correct, as the actual native declaration of this API indicates it should be {4} bytes wide on {3} platforms. Consult the MSDN Platform SDK documentation for help determining what data type should be used instead of {5}. As it is declared in your code, the return type of P/Invoke {0} will be {1} bytes wide on {2} platforms. This is not correct, as the actual native declaration of this API indicates it should be {3} bytes wide on {2} platforms. Consult the MSDN Platform SDK documentation for help determining what data type should be used instead of {4}. Correct the declaration of {0} so that it correctly points to an existing entry point in {1}. The unmanaged entry point name currently linked to is {2}. Because property {0} is write-only, either add a property getter with an accessibility that is greater than or equal to its setter or convert this property into a method. Change {0} to return a collection or make it a method. The property name {0} is confusing given the existence of inherited method {1}. Rename or remove this property. The property name {0} is confusing given the existence of method {1}. Rename or remove one of these members. Parameter {0} of {1} is never used. Remove the parameter or use it in the method body. Consider making {0} not externally visible. To reduce security risk, marshal parameter {0} as Unicode, by setting DllImport.CharSet to CharSet.Unicode, or by explicitly marshaling the parameter as UnmanagedType.LPWStr. If you need to marshal this string as ANSI or system-dependent, set BestFitMapping=false; for added security, also set ThrowOnUnmappableChar=true. {0} makes a call to {1} that does not explicitly provide a StringComparison. This should be replaced with a call to {2}. Implement IDisposable on {0} because it creates members of the following IDisposable types: {1}. If {0} has previously shipped, adding new members that implement IDisposable to this type is considered a breaking change to existing consumers. Change the type of parameter {0} of method {1} from string to System.Uri, or provide an overload of {1}, that allows {0} to be passed as a System.Uri object. Change the type of property {0} from string to System.Uri. Remove {0} and replace its usage with EventHandler<T> {0} passes {1} as an argument to {2}. Replace this usage with StringComparison.Ordinal or StringComparison.OrdinalIgnoreCase if appropriate. Replace the term '{0}' in member name {1} with an appropriate alternate or remove it entirely. Replace the term '{0}' in type name {1} with an appropriate alternate or remove it entirely. Change {0} to a property if appropriate. ================================================ FILE: source/ObjectListView/ObjectListView.cs ================================================ /* * ObjectListView - A listview to show various aspects of a collection of objects * * Author: Phillip Piper * Date: 9/10/2006 11:15 AM * * Change log * v2.9.1 * 2015-12-30 JPP - Added CellRendererGetter to allow each cell to have a different renderer. * - Obsolete properties are no longer code-gen'ed. * * v2.9.0 * 2015-08-22 JPP - Allow selected row back/fore colours to be specified for each row * - Renamed properties related to selection colours: * - HighlightBackgroundColor -> SelectedBackColor * - HighlightForegroundColor -> SelectedForeColor * - UnfocusedHighlightBackgroundColor -> UnfocusedSelectedBackColor * - UnfocusedHighlightForegroundColor -> UnfocusedSelectedForeColor * - UseCustomSelectionColors is no longer used * 2015-08-03 JPP - Added ObjectListView.CellEditFinished event * - Added EditorRegistry.Unregister() * 2015-07-08 JPP - All ObjectListViews are now OwnerDrawn by default. This allows all the great features * of ObjectListView to work correctly at the slight cost of more processing at render time. * It also avoids the annoying "hot item background ignored in column 0" behaviour that native * ListView has. Programmers can still turn it back off if they wish. * 2015-06-27 JPP - Yet another attempt to disable ListView's "shift click toggles checkboxes" behaviour. * The last strategy (fake right click) worked, but had nasty side effects. This one works * by intercepting a HITTEST message so that it fails. It no longer creates fake right mouse events. * - Trigger SelectionChanged when filter is changed * 2015-06-23 JPP - [BIG] Added support for Buttons * 2015-06-22 JPP - Added OLVColumn.SearchValueGetter to allow the text used when text filtering to be customised * - The default DefaultRenderer is now a HighlightTextRenderer, since that seems more generally useful * 2015-06-17 JPP - Added FocusedObject property * - Hot item is now always applied to the row even if FullRowSelect is false * 2015-06-11 JPP - Added DefaultHotItemStyle property * 2015-06-07 JPP - Added HeaderMinimumHeight property * - Added ObjectListView.CellEditUsesWholeCell and OLVColumn.CellEditUsesWholeCell properties. * 2015-05-15 JPP - Allow ImageGetter to return an Image (which I can't believe didn't work from the beginning!) * 2015-04-27 JPP - Fix bug where setting View to LargeIcon in the designer was not persisted * 2015-04-07 JPP - Ensure changes to row.Font in FormatRow are not wiped out by FormatCell (SF #141) * * v2.8.1 * 2014-10-15 JPP - Added CellEditActivateMode.SingleClickAlways mode * - Fire Filter event event if ModelFilter and ListFilter are null (SF #126) * - Fixed issue where single-click editing didn't work (SF #128) * v2.8.0 * 2014-10-11 JPP - Fixed some XP-only flicker issues * 2014-09-26 JPP - Fixed intricate bug involving checkboxes on non-owner-drawn virtual lists. * - Fixed long standing (but previously unreported) error on non-details virtual lists where * users could not click on checkboxes. * 2014-09-07 JPP - (Major) Added ability to have checkboxes in headers * - CellOver events are raised when the mouse moves over the header. Set TriggerCellOverEventsWhenOverHeader * to false to disable this behaviour. * - Freeze/Unfreeze now use BeginUpdate/EndUpdate to disable Window level drawing * - Changed default value of ObjectListView.HeaderUsesThemes from true to false. Too many people were * being confused, trying to make something interesting appear in the header and nothing showing up * 2014-08-04 JPP - Final attempt to fix the multiple hyperlink events being raised. This involves turning * a NM_CLICK notification into a NM_RCLICK. * 2014-05-21 JPP - (Major) Added ability to disable rows. DisabledObjects, DisableObjects(), DisabledItemStyle. * 2014-04-25 JPP - Fixed issue where virtual lists containing a single row didn't update hyperlinks on MouseOver * - Added sanity check before BuildGroups() * 2014-03-22 JPP - Fixed some subtle bugs resulting from misuse of TryGetValue() * 2014-03-09 JPP - Added CollapsedGroups property * - Several minor Resharper complaints quiesced. * v2.7 * 2014-02-14 JPP - Fixed issue with ShowHeaderInAllViews (another one!) where setting it to false caused the list to lose * its other extended styles, leading to nasty flickering and worse. * 2014-02-06 JPP - Fix issue on virtual lists where the filter was not correctly reapplied after columns were added or removed. * - Made disposing of cell editors optional (defaults to true). This allows controls to be cached and reused. * - Bracketed column resizing with BeginUpdate/EndUpdate to smooth redraws (thanks to Davide) * 2014-02-01 JPP - Added static property ObjectListView.GroupTitleDefault to allow the default group title to be localised. * 2013-09-24 JPP - Fixed issue in RefreshObjects() when model objects overrode the Equals()/GetHashCode() methods. * - Made sure get state checker were used when they should have been * 2013-04-21 JPP - Clicking on a non-groupable column header when showing groups will now sort * the group contents by that column. * v2.6 * 2012-08-16 JPP - Added ObjectListView.EditModel() -- a convenience method to start an edit operation on a model * 2012-08-10 JPP - Don't trigger selection changed events during sorting/grouping or add/removing columns * 2012-08-06 JPP - Don't start a cell edit operation when the user clicks on the background of a checkbox cell. * - Honor values from the BeforeSorting event when calling a CustomSorter * 2012-08-02 JPP - Added CellVerticalAlignment and CellPadding properties. * 2012-07-04 JPP - Fixed issue with cell editing where the cell editing didn't finish until the first idle event. * This meant that if you clicked and held on the scroll thumb to finish a cell edit, the editor * wouldn't be removed until the mouse was released. * 2012-07-03 JPP - Fixed issue with SingleClick cell edit mode where the cell editing would not begin until the * mouse moved after the click. * 2012-06-25 JPP - Fixed bug where removing a column from a LargeIcon or SmallIcon view would crash the control. * 2012-06-15 JPP - Added Reset() method, which definitively removes all rows *and* columns from an ObjectListView. * 2012-06-11 JPP - Added FilteredObjects property which returns the collection of objects that survives any installed filters. * 2012-06-04 JPP - [Big] Added UseNotifyPropertyChanged to allow OLV to listen for INotifyPropertyChanged events on models. * 2012-05-30 JPP - Added static property ObjectListView.IgnoreMissingAspects. If this is set to true, all * ObjectListViews will silently ignore missing aspect errors. Read the remarks to see why this would be useful. * 2012-05-23 JPP - Setting UseFilterIndicator to true now sets HeaderUsesTheme to false. * Also, changed default value of UseFilterIndicator to false. Previously, HeaderUsesTheme and UseFilterIndicator * defaulted to true, which was pointless since when the HeaderUsesTheme is true, UseFilterIndicator does nothing. * v2.5.1 * 2012-05-06 JPP - Fix bug where collapsing the first group would cause decorations to stop being drawn (SR #3502608) * 2012-04-23 JPP - Trigger GroupExpandingCollapsing event to allow the expand/collapse to be cancelled * - Fixed SetGroupSpacing() so it corrects updates the space between all groups. * - ResizeLastGroup() now does nothing since it was broken and I can't remember what it was * even supposed to do :) * 2012-04-18 JPP - Upgraded hit testing to include hits on groups. * - HotItemChanged is now correctly recalculated on each mouse move. Includes "hot" group information. * 2012-04-14 JPP - Added GroupStateChanged event. Useful for knowing when a group is collapsed/expanded. * - Added AdditionalFilter property. This filter is combined with the Excel-like filtering that * the end user might enact at runtime. * 2012-04-10 JPP - Added PersistentCheckBoxes property to allow primary checkboxes to remember their values * across list rebuilds. * 2012-04-05 JPP - Reverted some code to .NET 2.0 standard. * - Tweaked some code * 2012-02-05 JPP - Fixed bug when selecting a separator on a drop down menu * 2011-06-24 JPP - Added CanUseApplicationIdle property to cover cases where Application.Idle events * are not triggered. For example, when used within VS (and probably Office) extensions * Application.Idle is never triggered. Set CanUseApplicationIdle to false to handle * these cases. * - Handle cases where a second tool tip is installed onto the ObjectListView. * - Correctly recolour rows after an Insert or Move * - Removed m.LParam cast which could cause overflow issues on Win7/64 bit. * v2.5.0 * 2011-05-31 JPP - SelectObject() and SelectObjects() no longer deselect all other rows. Set the SelectedObject or SelectedObjects property to do that. * - Added CheckedObjectsEnumerable * - Made setting CheckedObjects more efficient on large collections * - Deprecated GetSelectedObject() and GetSelectedObjects() * 2011-04-25 JPP - Added SubItemChecking event * - Fixed bug in handling of NewValue on CellEditFinishing event * 2011-04-12 JPP - Added UseFilterIndicator * - Added some more localizable messages * 2011-04-10 JPP - FormatCellEventArgs now has a CellValue property, which is the model value displayed * by the cell. For example, for the Birthday column, the CellValue might be * DateTime(1980, 12, 31), whereas the cell's text might be 'Dec 31, 1980'. * 2011-04-04 JPP - Tweaked UseTranslucentSelection and UseTranslucentHotItem to look (a little) more * like Vista/Win7. * - Alternate colours are now only applied in Details view (as they always should have been) * - Alternate colours are now correctly recalculated after removing objects * 2011-03-29 JPP - Added SelectColumnsOnRightClickBehaviour to allow the selecting of columns mechanism * to be changed. Can now be InlineMenu (the default), SubMenu, or ModelDialog. * - ColumnSelectionForm was moved from the demo into the ObjectListView project itself. * - Ctrl-C copying is now able to use the DragSource to create the data transfer object. * 2011-03-19 JPP - All model object comparisons now use Equals rather than == (thanks to vulkanino) * - [Small Break] GetNextItem() and GetPreviousItem() now accept and return OLVListView * rather than ListViewItems. * 2011-03-07 JPP - [Big] Added Excel-style filtering. Right click on a header to show a Filtering menu. * - Added CellEditKeyEngine to allow key handling when cell editing to be completely customised. * Add CellEditTabChangesRows and CellEditEnterChangesRows to show some of these abilities. * 2011-03-06 JPP - Added OLVColumn.AutoCompleteEditorMode in preference to AutoCompleteEditor * (which is now just a wrapper). Thanks to Clive Haskins * - Added lots of docs to new classes * 2011-02-25 JPP - Preserve word wrap settings on TreeListView * - Resize last group to keep it on screen (thanks to ?) * 2010-11-16 JPP - Fixed (once and for all) DisplayIndex problem with Generator * - Changed the serializer used in SaveState()/RestoreState() so that it resolves on * class name alone. * - Fixed bug in GroupWithItemCountSingularFormatOrDefault * - Fixed strange flickering in grouped, owner drawn OLV's using RefreshObject() * v2.4.1 * 2010-08-25 JPP - Fixed bug where setting OLVColumn.CheckBoxes to false gave it a renderer * specialized for checkboxes. Oddly, this made Generator created owner drawn * lists appear to be completely empty. * - In IDE, all ObjectListView properties are now in a single "ObjectListView" category, * rather than splitting them between "Appearance" and "Behavior" categories. * - Added GroupingParameters.GroupComparer to allow groups to be sorted in a customizable fashion. * - Sorting of items within a group can be disabled by setting * GroupingParameters.PrimarySortOrder to None. * 2010-08-24 JPP - Added OLVColumn.IsHeaderVertical to make a column draw its header vertical. * - Added OLVColumn.HeaderTextAlign to control the alignment of a column's header text. * - Added HeaderMaximumHeight to limit how tall the header section can become * 2010-08-18 JPP - Fixed long standing bug where having 0 columns caused a InvalidCast exception. * - Added IncludeAllColumnsInDataObject property * - Improved BuildList(bool) so that it preserves scroll position even when * the listview is grouped. * 2010-08-08 JPP - Added OLVColumn.HeaderImageKey to allow column headers to have an image. * - CellEdit validation and finish events now have NewValue property. * 2010-08-03 JPP - Subitem checkboxes improvements: obey IsEditable, can be hot, can be disabled. * - No more flickering of selection when tabbing between cells * - Added EditingCellBorderDecoration to make it clearer which cell is being edited. * 2010-08-01 JPP - Added ObjectListView.SmoothingMode to control the smoothing of all graphics * operations * - Columns now cache their group item format strings so that they still work as * grouping columns after they have been removed from the listview. This cached * value is only used when the column is not part of the listview. * 2010-07-25 JPP - Correctly trigger a Click event when the mouse is clicked. * 2010-07-16 JPP - Invalidate the control before and after cell editing to make sure it looks right * 2010-06-23 JPP - Right mouse clicks on checkboxes no longer confuse them * 2010-06-21 JPP - Avoid bug in underlying ListView control where virtual lists in SmallIcon view * generate GETTOOLINFO msgs with invalid item indices. * - Fixed bug where FastObjectListView would throw an exception when showing hyperlinks * in any view except Details. * 2010-06-15 JPP - Fixed bug in ChangeToFilteredColumns() that resulted in column display order * being lost when a column was hidden. * - Renamed IsVista property to IsVistaOrLater which more accurately describes its function. * v2.4 * 2010-04-14 JPP - Prevent object disposed errors when mouse event handlers cause the * ObjectListView to be destroyed (e.g. closing a form during a * double click event). * - Avoid checkbox munging bug in standard ListView when shift clicking on non-primary * columns when FullRowSelect is true. * 2010-04-12 JPP - Fixed bug in group sorting (thanks Mike). * 2010-04-07 JPP - Prevent hyperlink processing from triggering spurious MouseUp events. * This showed itself by launching the same url multiple times. * 2010-04-06 JPP - Space filling columns correctly resize upon initial display * - ShowHeaderInAllViews is better but still not working reliably. * See comments on property for more details. * 2010-03-23 JPP - Added ObjectListView.HeaderFormatStyle and OLVColumn.HeaderFormatStyle. * This makes HeaderFont and HeaderForeColor properties unnecessary -- * they will be marked obsolete in the next version and removed after that. * 2010-03-16 JPP - Changed object checking so that objects can be pre-checked before they * are added to the list. Normal ObjectListViews managed "checkedness" in * the ListViewItem, so this won't work for them, unless check state getters * and putters have been installed. It will work on on virtual lists (thus fast lists and * tree views) since they manage their own check state. * 2010-03-06 JPP - Hide "Items" and "Groups" from the IDE properties grid since they shouldn't be set like that. * They can still be accessed through "Custom Commands" and there's nothing we can do * about that. * 2010-03-05 JPP - Added filtering * 2010-01-18 JPP - Overlays can be turned off. They also only work on 32-bit displays * v2.3 * 2009-10-30 JPP - Plugged possible resource leak by using using() with CreateGraphics() * 2009-10-28 JPP - Fix bug when right clicking in the empty area of the header * 2009-10-20 JPP - Redraw the control after setting EmptyListMsg property * v2.3 * 2009-09-30 JPP - Added Dispose() method to properly release resources * 2009-09-16 JPP - Added OwnerDrawnHeader, which you can set to true if you want to owner draw * the header yourself. * 2009-09-15 JPP - Added UseExplorerTheme, which allow complete visual compliance with Vista explorer. * But see property documentation for its many limitations. * - Added ShowHeaderInAllViews. To make this work, Columns are no longer * changed when switching to/from Tile view. * 2009-09-11 JPP - Added OLVColumn.AutoCompleteEditor to allow the autocomplete of cell editors * to be disabled. * 2009-09-01 JPP - Added ObjectListView.TextRenderingHint property which controls the * text rendering hint of all drawn text. * 2009-08-28 JPP - [BIG] Added group formatting to supercharge what is possible with groups * - [BIG] Virtual groups now work * - Extended MakeGroupies() to handle more aspects of group creation * 2009-08-19 JPP - Added ability to show basic column commands when header is right clicked * - Added SelectedRowDecoration, UseTranslucentSelection and UseTranslucentHotItem. * - Added PrimarySortColumn and PrimarySortOrder * 2009-08-15 JPP - Correct problems with standard hit test and subitems * 2009-08-14 JPP - [BIG] Support Decorations * - [BIG] Added header formatting capabilities: font, color, word wrap * - Gave ObjectListView its own designer to hide unwanted properties * - Separated design time stuff into separate file * - Added FormatRow and FormatCell events * 2009-08-09 JPP - Get around bug in HitTest when not FullRowSelect * - Added OLVListItem.GetSubItemBounds() method which works correctly * for all columns including column 0 * 2009-08-07 JPP - Added Hot* properties that track where the mouse is * - Added HotItemChanged event * - Overrode TextAlign on columns so that column 0 can have something other * than just left alignment. This is only honored when owner drawn. * v2.2.1 * 2009-08-03 JPP - Subitem edit rectangles always allowed for an image in the cell, even if there was none. * Now they only allow for an image when there actually is one. * - Added Bounds property to OLVListItem which handles items being part of collapsed groups. * 2009-07-29 JPP - Added GetSubItem() methods to ObjectListView and OLVListItem * 2009-07-26 JPP - Avoided bug in .NET framework involving column 0 of owner drawn listviews not being * redrawn when the listview was scrolled horizontally (this was a LOT of work to track * down and fix!) * - The cell edit rectangle is now correctly calculated when the listview is scrolled * horizontally. * 2009-07-14 JPP - If the user clicks/double clicks on a tree list cell, an edit operation will no longer begin * if the click was to the left of the expander. This is implemented in such a way that * other renderers can have similar "dead" zones. * 2009-07-11 JPP - CalculateCellBounds() messed with the FullRowSelect property, which confused the * tooltip handling on the underlying control. It no longer does this. * - The cell edit rectangle is now correctly calculated for owner-drawn, non-Details views. * 2009-07-08 JPP - Added Cell events (CellClicked, CellOver, CellRightClicked) * - Made BuildList(), AddObject() and RemoveObject() thread-safe * 2009-07-04 JPP - Space bar now properly toggles checkedness of selected rows * 2009-07-02 JPP - Fixed bug with tooltips when the underlying Windows control was destroyed. * - CellToolTipShowing events are now triggered in all views. * v2.2 * 2009-06-02 JPP - BeforeSortingEventArgs now has a Handled property to let event handlers do * the item sorting themselves. * - AlwaysGroupByColumn works again, as does SortGroupItemsByPrimaryColumn and all their * various permutations. * - SecondarySortOrder and SecondarySortColumn are now "null" by default * 2009-05-15 JPP - Fixed bug so that KeyPress events are again triggered * 2009-05-10 JPP - Removed all unsafe code * 2009-05-07 JPP - Don't use glass panel for overlays when in design mode. It's too confusing. * 2009-05-05 JPP - Added Scroll event (thanks to Christophe Hosten for the complete patch to implement this) * - Added Unfocused foreground and background colors (also thanks to Christophe Hosten) * 2009-04-29 JPP - Added SelectedColumn property, which puts a slight tint on that column. Combine * this with TintSortColumn property and the sort column is automatically tinted. * - Use an overlay to implement "empty list" msg. Default empty list msg is now prettier. * 2009-04-28 JPP - Fixed bug where DoubleClick events were not triggered when CheckBoxes was true * 2009-04-23 JPP - Fixed various bugs under Vista. * - Made groups collapsible - Vista only. Thanks to Crustyapplesniffer. * - Forward events from DropSink to the control itself. This allows handlers to be defined * within the IDE for drop events * 2009-04-16 JPP - Made several properties localizable. * 2009-04-11 JPP - Correctly renderer checkboxes when RowHeight is non-standard * 2009-04-11 JPP - Implemented overlay architecture, based on CustomDraw scheme. * This unified drag drop feedback, empty list msgs and overlay images. * - Added OverlayImage and friends, which allows an image to be drawn * transparently over the listview * 2009-04-10 JPP - Fixed long-standing annoying flicker on owner drawn virtual lists! * This means, amongst other things, that grid lines no longer get confused, * and drag-select no longer flickers. * 2009-04-07 JPP - Calculate edit rectangles more accurately * 2009-04-06 JPP - Double-clicking no longer toggles the checkbox * - Double-clicking on a checkbox no longer confuses the checkbox * 2009-03-16 JPP - Optimized the build of autocomplete lists * v2.1 * 2009-02-24 JPP - Fix bug where double-clicking VERY quickly on two different cells * could give two editors * - Maintain focused item when rebuilding list (SF #2547060) * 2009-02-22 JPP - Reworked checkboxes so that events are triggered for virtual lists * 2009-02-15 JPP - Added ObjectListView.ConfigureAutoComplete utility method * 2009-02-02 JPP - Fixed bug with AlwaysGroupByColumn where column header clicks would not resort groups. * 2009-02-01 JPP - OLVColumn.CheckBoxes and TriStateCheckBoxes now work. * 2009-01-28 JPP - Complete overhaul of renderers! * - Use IRenderer * - Added ObjectListView.ItemRenderer to draw whole items * 2009-01-23 JPP - Simple Checkboxes now work properly * - Added TriStateCheckBoxes property to control whether the user can * set the row checkbox to have the Indeterminate value * - CheckState property is now just a wrapper around the StateImageIndex property * 2009-01-20 JPP - Changed to always draw columns when owner drawn, rather than falling back on DrawDefault. * This simplified several owner drawn problems * - Added DefaultRenderer property to help with the above * - HotItem background color is applied to all cells even when FullRowSelect is false * - Allow grouping by CheckedAspectName columns * - Commented out experimental animations. Still needs work. * 2009-01-17 JPP - Added HotItemStyle and UseHotItem to highlight the row under the cursor * - Added UseCustomSelectionColors property * - Owner draw mode now honors ForeColor and BackColor settings on the list * 2009-01-16 JPP - Changed to use EditorRegistry rather than hard coding cell editors * 2009-01-10 JPP - Changed to use Equals() method rather than == to compare model objects. * v2.0.1 * 2009-01-08 JPP - Fixed long-standing "multiple columns generated" problem. * Thanks to pinkjones for his help with solving this one! * - Added EnsureGroupVisible() * 2009-01-07 JPP - Made all public and protected methods virtual * - FinishCellEditing, PossibleFinishCellEditing and CancelCellEditing are now public * 2008-12-20 JPP - Fixed bug with group comparisons when a group key was null (SF#2445761) * 2008-12-19 JPP - Fixed bug with space filling columns and layout events * - Fixed RowHeight so that it only changes the row height, not the width of the images. * v2.0 * 2008-12-10 JPP - Handle Backspace key. Resets the search-by-typing state without delay * - Made some changes to the column collection editor to try and avoid * the multiple column generation problem. * - Updated some documentation * 2008-12-07 JPP - Search-by-typing now works when showing groups * - Added BeforeSearching and AfterSearching events which are triggered when the user types * into the list. * - Added secondary sort information to Before/AfterSorting events * - Reorganized group sorting code. Now triggers Sorting events. * - Added GetItemIndexInDisplayOrder() * - Tweaked in the interaction of the column editor with the IDE so that we (normally) * don't rely on a hack to find the owning ObjectListView * - Changed all 'DefaultValue(typeof(Color), "Empty")' to 'DefaultValue(typeof(Color), "")' * since the first does not given Color.Empty as I thought, but the second does. * 2008-11-28 JPP - Fixed long standing bug with horizontal scrollbar when shrinking the window. * (thanks to Bartosz Borowik) * 2008-11-25 JPP - Added support for dynamic tooltips * - Split out comparers and header controls stuff into their own files * 2008-11-21 JPP - Fixed bug where enabling grouping when there was not a sort column would not * produce a grouped list. Grouping column now defaults to column 0. * - Preserve selection on virtual lists when sorting * 2008-11-20 JPP - Added ability to search by sort column to ObjectListView. Unified this with * ability that was already in VirtualObjectListView * 2008-11-19 JPP - Fixed bug in ChangeToFilteredColumns() where DisplayOrder was not always restored correctly. * 2008-10-29 JPP - Event argument blocks moved to directly within the namespace, rather than being * nested inside ObjectListView class. * - Removed OLVColumn.CellEditor since it was never used. * - Marked OLVColumn.AspectGetterAutoGenerated as obsolete (it has not been used for * several versions now). * 2008-10-28 JPP - SelectedObjects is now an IList, rather than an ArrayList. This allows * it to accept generic list (eg List). * 2008-10-09 JPP - Support indeterminate checkbox values. * [BREAKING CHANGE] CheckStateGetter/CheckStatePutter now use CheckState types only. * BooleanCheckStateGetter and BooleanCheckStatePutter added to ease transition. * 2008-10-08 JPP - Added setFocus parameter to SelectObject(), which allows focus to be set * at the same time as selecting. * 2008-09-27 JPP - BIG CHANGE: Fissioned this file into separate files for each component * 2008-09-24 JPP - Corrected bug with owner drawn lists where a column 0 with a renderer * would draw at column 0 even if column 0 was dragged to another position. * - Correctly handle space filling columns when columns are added/removed * 2008-09-16 JPP - Consistently use try..finally for BeginUpdate()/EndUpdate() pairs * 2008-08-24 JPP - If LastSortOrder is None when adding objects, don't force a resort. * 2008-08-22 JPP - Catch and ignore some problems with setting TopIndex on FastObjectListViews. * 2008-08-05 JPP - In the right-click column select menu, columns are now sorted by display order, rather than alphabetically * v1.13 * 2008-07-23 JPP - Consistently use copy-on-write semantics with Add/RemoveObject methods * 2008-07-10 JPP - Enable validation on cell editors through a CellEditValidating event. * (thanks to Artiom Chilaru for the initial suggestion and implementation). * 2008-07-09 JPP - Added HeaderControl.Handle to allow OLV to be used within UserControls. * (thanks to Michael Coffey for tracking this down). * 2008-06-23 JPP - Split the more generally useful CopyObjectsToClipboard() method * out of CopySelectionToClipboard() * 2008-06-22 JPP - Added AlwaysGroupByColumn and AlwaysGroupBySortOrder, which * force the list view to always be grouped by a particular column. * 2008-05-31 JPP - Allow check boxes on FastObjectListViews * - Added CheckedObject and CheckedObjects properties * 2008-05-11 JPP - Allow selection foreground and background colors to be changed. * Windows doesn't allow this, so we can only make it happen when owner * drawing. Set the HighlightForegroundColor and HighlightBackgroundColor * properties and then call EnableCustomSelectionColors(). * v1.12 * 2008-05-08 JPP - Fixed bug where the column select menu would not appear if the * ObjectListView has a context menu installed. * 2008-05-05 JPP - Non detail views can now be owner drawn. The renderer installed for * primary column is given the chance to render the whole item. * See BusinessCardRenderer in the demo for an example. * - BREAKING CHANGE: RenderDelegate now returns a bool to indicate if default * rendering should be done. Previously returned void. Only important if your * code used RendererDelegate directly. Renderers derived from BaseRenderer * are unchanged. * 2008-05-03 JPP - Changed cell editing to use values directly when the values are Strings. * Previously, values were always handed to the AspectToStringConverter. * - When editing a cell, tabbing no longer tries to edit the next subitem * when not in details view! * 2008-05-02 JPP - MappedImageRenderer can now handle a Aspects that return a collection * of values. Each value will be drawn as its own image. * - Made AddObjects() and RemoveObjects() work for all flavours (or at least not crash) * - Fixed bug with clearing virtual lists that has been scrolled vertically * - Made TopItemIndex work with virtual lists. * 2008-05-01 JPP - Added AddObjects() and RemoveObjects() to allow faster mods to the list * - Reorganised public properties. Now alphabetical. * - Made the class ObjectListViewState internal, as it always should have been. * v1.11 * 2008-04-29 JPP - Preserve scroll position when building the list or changing columns. * - Added TopItemIndex property. Due to problems with the underlying control, this * property is not always reliable. See property docs for info. * 2008-04-27 JPP - Added SelectedIndex property. * - Use a different, more general strategy to handle Invoke(). Removed all delegates * that were only declared to support Invoke(). * - Check all native structures for 64-bit correctness. * 2008-04-25 JPP - Released on SourceForge. * 2008-04-13 JPP - Added ColumnRightClick event. * - Made the assembly CLS-compliant. To do this, our cell editors were made internal, and * the constraint on FlagRenderer template parameter was removed (the type must still * be an IConvertible, but if it isn't, the error will be caught at runtime, not compile time). * 2008-04-12 JPP - Changed HandleHeaderRightClick() to have a columnIndex parameter, which tells * exactly which column was right-clicked. * 2008-03-31 JPP - Added SaveState() and RestoreState() * - When cell editing, scrolling with a mouse wheel now ends the edit operation. * v1.10 * 2008-03-25 JPP - Added space filling columns. See OLVColumn.FreeSpaceProportion property for details. * A space filling columns fills all (or a portion) of the width unoccupied by other columns. * 2008-03-23 JPP - Finished tinkering with support for Mono. Compile with conditional compilation symbol 'MONO' * to enable. On Windows, current problems with Mono: * - grid lines on virtual lists crashes * - when grouped, items sometimes are not drawn when any item is scrolled out of view * - i can't seem to get owner drawing to work * - when editing cell values, the editing controls always appear behind the listview, * where they function fine -- the user just can't see them :-) * 2008-03-16 JPP - Added some methods suggested by Chris Marlowe (thanks for the suggestions Chris) * - ClearObjects() * - GetCheckedObject(), GetCheckedObjects() * - GetItemAt() variation that gets both the item and the column under a point * 2008-02-28 JPP - Fixed bug with subitem colors when using OwnerDrawn lists and a RowFormatter. * v1.9.1 * 2008-01-29 JPP - Fixed bug that caused owner-drawn virtual lists to use 100% CPU * - Added FlagRenderer to help draw bitwise-OR'ed flag values * 2008-01-23 JPP - Fixed bug (introduced in v1.9) that made alternate row colour with groups not quite right * - Ensure that DesignerSerializationVisibility.Hidden is set on all non-browsable properties * - Make sure that sort indicators are shown after changing which columns are visible * 2008-01-21 JPP - Added FastObjectListView * v1.9 * 2008-01-18 JPP - Added IncrementalUpdate() * 2008-01-16 JPP - Right clicking on column header will allow the user to choose which columns are visible. * Set SelectColumnsOnRightClick to false to prevent this behaviour. * - Added ImagesRenderer to draw more than one images in a column * - Changed the positioning of the empty list m to use all the client area. Thanks to Matze. * 2007-12-13 JPP - Added CopySelectionToClipboard(). Ctrl-C invokes this method. Supports text * and HTML formats. * 2007-12-12 JPP - Added support for checkboxes via CheckStateGetter and CheckStatePutter properties. * - Made ObjectListView and OLVColumn into partial classes so that others can extend them. * 2007-12-09 JPP - Added ability to have hidden columns, i.e. columns that the ObjectListView knows * about but that are not visible to the user. Controlled by OLVColumn.IsVisible. * Added ColumnSelectionForm to the project to show how it could be used in an application. * * v1.8 * 2007-11-26 JPP - Cell editing fully functional * 2007-11-21 JPP - Added SelectionChanged event. This event is triggered once when the * selection changes, no matter how many items are selected or deselected (in * contrast to SelectedIndexChanged which is called once for every row that * is selected or deselected). Thanks to lupokehl42 (Daniel) for his suggestions and * improvements on this idea. * 2007-11-19 JPP - First take at cell editing * 2007-11-17 JPP - Changed so that items within a group are not sorted if lastSortOrder == None * - Only call MakeSortIndicatorImages() if we haven't already made the sort indicators * (Corrected misspelling in the name of the method too) * 2007-11-06 JPP - Added ability to have secondary sort criteria when sorting * (SecondarySortColumn and SecondarySortOrder properties) * - Added SortGroupItemsByPrimaryColumn to allow group items to be sorted by the * primary column. Previous default was to sort by the grouping column. * v1.7 * No big changes to this version but made to work with ListViewPrinter and released with it. * * 2007-11-05 JPP - Changed BaseRenderer to use DrawString() rather than TextRenderer, since TextRenderer * does not work when printing. * v1.6 * 2007-11-03 JPP - Fixed some bugs in the rebuilding of DataListView. * 2007-10-31 JPP - Changed to use builtin sort indicators on XP and later. This also avoids alignment * problems on Vista. (thanks to gravybod for the suggestion and example implementation) * 2007-10-21 JPP - Added MinimumWidth and MaximumWidth properties to OLVColumn. * - Added ability for BuildList() to preserve selection. Calling BuildList() directly * tries to preserve selection; calling SetObjects() does not. * - Added SelectAll() and DeselectAll() methods. Useful for working with large lists. * 2007-10-08 JPP - Added GetNextItem() and GetPreviousItem(), which walk sequentially through the * listview items, even when the view is grouped. * - Added SelectedItem property * 2007-09-28 JPP - Optimized aspect-to-string conversion. BuildList() 15% faster. * - Added empty implementation of RefreshObjects() to VirtualObjectListView since * RefreshObjects() cannot work on virtual lists. * 2007-09-13 JPP - Corrected bug with custom sorter in VirtualObjectListView (thanks for mpgjunky) * 2007-09-07 JPP - Corrected image scaling bug in DrawAlignedImage() (thanks to krita970) * 2007-08-29 JPP - Allow item count labels on groups to be set per column (thanks to cmarlow for idea) * 2007-08-14 JPP - Major rework of DataListView based on Ian Griffiths's great work * 2007-08-11 JPP - When empty, the control can now draw a "List Empty" m * - Added GetColumn() and GetItem() methods * v1.5 * 2007-08-03 JPP - Support animated GIFs in ImageRenderer * - Allow height of rows to be specified - EXPERIMENTAL! * 2007-07-26 JPP - Optimised redrawing of owner-drawn lists by remembering the update rect * - Allow sort indicators to be turned off * 2007-06-30 JPP - Added RowFormatter delegate * - Allow a different label when there is only one item in a group (thanks to cmarlow) * v1.4 * 2007-04-12 JPP - Allow owner drawn on steriods! * - Column headers now display sort indicators * - ImageGetter delegates can now return ints, strings or Images * (Images are only visible if the list is owner drawn) * - Added OLVColumn.MakeGroupies to help with group partitioning * - All normal listview views are now supported * - Allow dotted aspect names, e.g. Owner.Workgroup.Name (thanks to OlafD) * - Added SelectedObject and SelectedObjects properties * v1.3 * 2007-03-01 JPP - Added DataListView * - Added VirtualObjectListView * - Added Freeze/Unfreeze capabilities * - Allowed sort handler to be installed * - Simplified sort comparisons: handles 95% of cases with only 6 lines of code! * - Fixed bug with alternative line colors on unsorted lists (thanks to cmarlow) * 2007-01-13 JPP - Fixed bug with lastSortOrder (thanks to Kwan Fu Sit) * - Non-OLVColumns are no longer allowed * 2007-01-04 JPP - Clear sorter before rebuilding list. 10x faster! (thanks to aaberg) * - Include GetField in GetAspectByName() so field values can be Invoked too. * - Fixed subtle bug in RefreshItem() that erased background colors. * 2006-11-01 JPP - Added alternate line colouring * 2006-10-20 JPP - Refactored all sorting comparisons and made it extendable. See ComparerManager. * - Improved IDE integration * - Made control DoubleBuffered * - Added object selection methods * 2006-10-13 JPP Implemented grouping and column sorting * 2006-10-09 JPP Initial version * * TO DO: * - Support undocumented group features: subseted groups, group footer items * * Copyright (C) 2006-2016 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.InteropServices; using System.Runtime.Serialization.Formatters.Binary; using System.Windows.Forms; using System.Windows.Forms.VisualStyles; using System.Runtime.Serialization.Formatters; using System.Threading; using System.Xml.Serialization; using MethodInvoker = System.Windows.Forms.MethodInvoker; namespace BrightIdeasSoftware { /// /// An ObjectListView is a much easier to use, and much more powerful, version of the ListView. /// /// /// /// An ObjectListView automatically populates a ListView control with information taken /// from a given collection of objects. It can do this because each column is configured /// to know which bit of the model object (the "aspect") it should be displaying. Columns similarly /// understand how to sort the list based on their aspect, and how to construct groups /// using their aspect. /// /// /// Aspects are extracted by giving the name of a method to be called or a /// property to be fetched. These names can be simple names or they can be dotted /// to chain property access e.g. "Owner.Address.Postcode". /// Aspects can also be extracted by installing a delegate. /// /// /// An ObjectListView can show a "this list is empty" message when there is nothing to show in the list, /// so that the user knows the control is supposed to be empty. /// /// /// Right clicking on a column header should present a menu which can contain: /// commands (sort, group, ungroup); filtering; and column selection. Whether these /// parts of the menu appear is controlled by ShowCommandMenuOnRightClick, /// ShowFilterMenuOnRightClick and SelectColumnsOnRightClick respectively. /// /// /// The groups created by an ObjectListView can be configured to include other formatting /// information, including a group icon, subtitle and task button. Using some undocumented /// interfaces, these groups can even on virtual lists. /// /// /// ObjectListView supports dragging rows to other places, including other application. /// Special support is provide for drops from other ObjectListViews in the same application. /// In many cases, an ObjectListView becomes a full drag source by setting to /// true. Similarly, to accept drops, it is usually enough to set to true, /// and then handle the and events (or the and /// events, if you only want to handle drops from other ObjectListViews in your application). /// /// /// For these classes to build correctly, the project must have references to these assemblies: /// /// /// System /// System.Data /// System.Design /// System.Drawing /// System.Windows.Forms (obviously) /// /// [Designer(typeof(Design.ObjectListViewDesigner))] public partial class ObjectListView : ListView, ISupportInitialize { #region Life and death /// /// Create an ObjectListView /// public ObjectListView() { ColumnClick += new ColumnClickEventHandler(HandleColumnClick); Layout += new LayoutEventHandler(HandleLayout); ColumnWidthChanging += new ColumnWidthChangingEventHandler(HandleColumnWidthChanging); ColumnWidthChanged += new ColumnWidthChangedEventHandler(HandleColumnWidthChanged); base.View = View.Details; // Turn on owner draw so that we are responsible for our own fates (and isolated from bugs in the underlying ListView) OwnerDraw = true; // ReSharper disable DoNotCallOverridableMethodsInConstructor DoubleBuffered = true; // kill nasty flickers. hiss... me hates 'em ShowSortIndicators = true; // Setup the overlays that will be controlled by the IDE settings InitializeStandardOverlays(); InitializeEmptyListMsgOverlay(); // ReSharper restore DoNotCallOverridableMethodsInConstructor } /// /// Dispose of any resources this instance has been using /// /// protected override void Dispose(bool disposing) { base.Dispose(disposing); if (!disposing) return; foreach (GlassPanelForm glassPanel in glassPanels) { glassPanel.Unbind(); glassPanel.Dispose(); } glassPanels.Clear(); UnsubscribeNotifications(null); } #endregion // TODO //public CheckBoxSettings CheckBoxSettings { // get { return checkBoxSettings; } // private set { checkBoxSettings = value; } //} #region Static properties /// /// Gets whether or not the left mouse button is down at this very instant /// public static bool IsLeftMouseDown { get { return (MouseButtons & MouseButtons.Left) == MouseButtons.Left; } } /// /// Gets whether the program running on Vista or later? /// public static bool IsVistaOrLater { get { if (!sIsVistaOrLater.HasValue) sIsVistaOrLater = Environment.OSVersion.Version.Major >= 6; return sIsVistaOrLater.Value; } } private static bool? sIsVistaOrLater; /// /// Gets whether the program running on Win7 or later? /// public static bool IsWin7OrLater { get { if (!sIsWin7OrLater.HasValue) { // For some reason, Win7 is v6.1, not v7.0 Version version = Environment.OSVersion.Version; sIsWin7OrLater = version.Major > 6 || (version.Major == 6 && version.Minor > 0); } return sIsWin7OrLater.Value; } } private static bool? sIsWin7OrLater; /// /// Gets or sets how what smoothing mode will be applied to graphic operations. /// public static System.Drawing.Drawing2D.SmoothingMode SmoothingMode { get { return sSmoothingMode; } set { sSmoothingMode = value; } } private static System.Drawing.Drawing2D.SmoothingMode sSmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; /// /// Gets or sets how should text be renderered. /// public static System.Drawing.Text.TextRenderingHint TextRenderingHint { get { return sTextRendereringHint; } set { sTextRendereringHint = value; } } private static System.Drawing.Text.TextRenderingHint sTextRendereringHint = System.Drawing.Text.TextRenderingHint.SystemDefault; /// /// Gets or sets the string that will be used to title groups when the group key is null. /// Exposed so it can be localized. /// public static string GroupTitleDefault { get { return sGroupTitleDefault; } set { sGroupTitleDefault = value ?? "{null}"; } } private static string sGroupTitleDefault = "{null}"; /// /// Convert the given enumerable into an ArrayList as efficiently as possible /// /// The source collection /// If true, this method will always create a new /// collection. /// An ArrayList with the same contents as the given collection. /// /// When we move to .NET 3.5, we can use LINQ and not need this method. /// public static ArrayList EnumerableToArray(IEnumerable collection, bool alwaysCreate) { if (collection == null) return new ArrayList(); if (!alwaysCreate) { if (collection is ArrayList array) return array; if (collection is IList iList) return ArrayList.Adapter(iList); } if (collection is ICollection iCollection) return new ArrayList(iCollection); ArrayList newObjects = new ArrayList(); foreach (object x in collection) newObjects.Add(x); return newObjects; } /// /// Return the count of items in the given enumerable /// /// /// /// When we move to .NET 3.5, we can use LINQ and not need this method. public static int EnumerableCount(IEnumerable collection) { if (collection == null) return 0; if (collection is ICollection iCollection) return iCollection.Count; int i = 0; // ReSharper disable once UnusedVariable foreach (object x in collection) i++; return i; } /// /// Return whether or not the given enumerable is empty. A string is regarded as /// an empty collection. /// /// /// True if the given collection is null or empty /// /// When we move to .NET 3.5, we can use LINQ and not need this method. /// public static bool IsEnumerableEmpty(IEnumerable collection) { return collection == null || (collection is string) || !collection.GetEnumerator().MoveNext(); } /// /// Gets or sets whether all ObjectListViews will silently ignore missing aspect errors. /// /// /// /// By default, if an ObjectListView is asked to display an aspect /// (i.e. a field/property/method) /// that does not exist from a model, it displays an error message in that cell, since that /// condition is normally a programming error. There are some use cases where /// this is not an error -- in those cases, set this to true and ObjectListView will /// simply display an empty cell. /// /// Be warned: if you set this to true, it can be very difficult to track down /// typing mistakes or name changes in AspectNames. /// public static bool IgnoreMissingAspects { get { return Munger.IgnoreMissingAspects; } set { Munger.IgnoreMissingAspects = value; } } /// /// Gets or sets whether the control will draw a rectangle in each cell showing the cell padding. /// /// /// /// This can help with debugging display problems from cell padding. /// /// As with all cell padding, this setting only takes effect when the control is owner drawn. /// public static bool ShowCellPaddingBounds { get { return sShowCellPaddingBounds; } set { sShowCellPaddingBounds = value; } } private static bool sShowCellPaddingBounds; /// /// Gets the style that will be used by default to format disabled rows /// public static SimpleItemStyle DefaultDisabledItemStyle { get { if (sDefaultDisabledItemStyle == null) { sDefaultDisabledItemStyle = new SimpleItemStyle(); sDefaultDisabledItemStyle.ForeColor = Color.DarkGray; } return sDefaultDisabledItemStyle; } } private static SimpleItemStyle sDefaultDisabledItemStyle; /// /// Gets the style that will be used by default to format hot rows /// public static HotItemStyle DefaultHotItemStyle { get { if (sDefaultHotItemStyle == null) { sDefaultHotItemStyle = new HotItemStyle(); sDefaultHotItemStyle.BackColor = Color.FromArgb(224, 235, 253); } return sDefaultHotItemStyle; } } private static HotItemStyle sDefaultHotItemStyle; #endregion #region Public properties /// /// Gets or sets an model filter that is combined with any column filtering that the end-user specifies. /// /// This is different from the ModelFilter property, since setting that will replace /// any column filtering, whereas setting this will combine this filter with the column filtering [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual IModelFilter AdditionalFilter { get { return additionalFilter; } set { if (additionalFilter == value) return; additionalFilter = value; UpdateColumnFiltering(); } } private IModelFilter additionalFilter; /// /// Get or set all the columns that this control knows about. /// Only those columns where IsVisible is true will be seen by the user. /// /// /// /// If you want to add new columns programmatically, add them to /// AllColumns and then call RebuildColumns(). Normally, you do not have to /// deal with this property directly. Just use the IDE. /// /// If you do add or remove columns from the AllColumns collection, /// you have to call RebuildColumns() to make those changes take effect. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] public virtual List AllColumns { get { return allColumns; } set { allColumns = value ?? new List(); } } private List allColumns = new(); /// /// Gets or sets the background color of every second row /// [Category("ObjectListView"), Description("If using alternate colors, what color should the background of alterate rows be?"), DefaultValue(typeof(Color), "")] public Color AlternateRowBackColor { get { return alternateRowBackColor; } set { alternateRowBackColor = value; } } private Color alternateRowBackColor = Color.Empty; /// /// Gets the alternate row background color that has been set, or the default color /// [Browsable(false)] public virtual Color AlternateRowBackColorOrDefault { get { return alternateRowBackColor == Color.Empty ? Color.LemonChiffon : alternateRowBackColor; } } /// /// This property forces the ObjectListView to always group items by the given column. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual OLVColumn AlwaysGroupByColumn { get { return alwaysGroupByColumn; } set { alwaysGroupByColumn = value; } } private OLVColumn alwaysGroupByColumn; /// /// If AlwaysGroupByColumn is not null, this property will be used to decide how /// those groups are sorted. If this property has the value SortOrder.None, then /// the sort order will toggle according to the users last header click. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual SortOrder AlwaysGroupBySortOrder { get { return alwaysGroupBySortOrder; } set { alwaysGroupBySortOrder = value; } } private SortOrder alwaysGroupBySortOrder = SortOrder.None; /// /// Give access to the image list that is actually being used by the control /// /// /// Normally, it is preferable to use SmallImageList. Only use this property /// if you know exactly what you are doing. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual ImageList BaseSmallImageList { get { return base.SmallImageList; } set { base.SmallImageList = value; } } /// /// How does the user indicate that they want to edit a cell? /// None means that the listview cannot be edited. /// /// Columns can also be marked as editable. [Category("ObjectListView"), Description("How does the user indicate that they want to edit a cell?"), DefaultValue(CellEditActivateMode.None)] public virtual CellEditActivateMode CellEditActivation { get { return cellEditActivation; } set { cellEditActivation = value; if (Created) Invalidate(); } } private CellEditActivateMode cellEditActivation = CellEditActivateMode.None; /// /// When a cell is edited, should the whole cell be used (minus any space used by checkbox or image)? /// Defaults to true. /// /// /// This is always treated as true when the control is NOT owner drawn. /// /// When this is false and the control is owner drawn, /// ObjectListView will try to calculate the width of the cell's /// actual contents, and then size the editing control to be just the right width. If this is true, /// the whole width of the cell will be used, regardless of the cell's contents. /// /// Each column can have a different value for property. This value from the control is only /// used when a column is not specified one way or another. /// Regardless of this setting, developers can specify the exact size of the editing control /// by listening for the CellEditStarting event. /// [Category("ObjectListView"), Description("When a cell is edited, should the whole cell be used?"), DefaultValue(true)] public virtual bool CellEditUseWholeCell { get { return cellEditUseWholeCell; } set { cellEditUseWholeCell = value; } } private bool cellEditUseWholeCell; /// /// Gets or sets the engine that will handle key presses during a cell edit operation. /// Settings this to null will reset it to default value. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public CellEditKeyEngine CellEditKeyEngine { get { return cellEditKeyEngine ?? (cellEditKeyEngine = new CellEditKeyEngine()); } set { cellEditKeyEngine = value; } } private CellEditKeyEngine cellEditKeyEngine; /// /// Gets the control that is currently being used for editing a cell. /// /// This will obviously be null if no cell is being edited. [Browsable(false)] public Control CellEditor { get { return cellEditor; } } /// /// Gets or sets the behaviour of the Tab key when editing a cell on the left or right /// edge of the control. If this is false (the default), pressing Tab will wrap to the other side /// of the same row. If this is true, pressing Tab when editing the right most cell will advance /// to the next row /// and Shift-Tab when editing the left-most cell will change to the previous row. /// [Category("ObjectListView"), Description("Should Tab/Shift-Tab change rows while cell editing?"), DefaultValue(false)] public virtual bool CellEditTabChangesRows { get { return cellEditTabChangesRows; } set { cellEditTabChangesRows = value; if (cellEditTabChangesRows) { CellEditKeyEngine.SetKeyBehaviour(Keys.Tab, CellEditCharacterBehaviour.ChangeColumnRight, CellEditAtEdgeBehaviour.ChangeRow); CellEditKeyEngine.SetKeyBehaviour(Keys.Tab | Keys.Shift, CellEditCharacterBehaviour.ChangeColumnLeft, CellEditAtEdgeBehaviour.ChangeRow); } else { CellEditKeyEngine.SetKeyBehaviour(Keys.Tab, CellEditCharacterBehaviour.ChangeColumnRight, CellEditAtEdgeBehaviour.Wrap); CellEditKeyEngine.SetKeyBehaviour(Keys.Tab | Keys.Shift, CellEditCharacterBehaviour.ChangeColumnLeft, CellEditAtEdgeBehaviour.Wrap); } } } private bool cellEditTabChangesRows; /// /// Gets or sets the behaviour of the Enter keys while editing a cell. /// If this is false (the default), pressing Enter will simply finish the editing operation. /// If this is true, Enter will finish the edit operation and start a new edit operation /// on the cell below the current cell, wrapping to the top of the next row when at the bottom cell. /// [Category("ObjectListView"), Description("Should Enter change rows while cell editing?"), DefaultValue(false)] public virtual bool CellEditEnterChangesRows { get { return cellEditEnterChangesRows; } set { cellEditEnterChangesRows = value; if (cellEditEnterChangesRows) { CellEditKeyEngine.SetKeyBehaviour(Keys.Enter, CellEditCharacterBehaviour.ChangeRowDown, CellEditAtEdgeBehaviour.ChangeColumn); CellEditKeyEngine.SetKeyBehaviour(Keys.Enter | Keys.Shift, CellEditCharacterBehaviour.ChangeRowUp, CellEditAtEdgeBehaviour.ChangeColumn); } else { CellEditKeyEngine.SetKeyBehaviour(Keys.Enter, CellEditCharacterBehaviour.EndEdit, CellEditAtEdgeBehaviour.EndEdit); CellEditKeyEngine.SetKeyBehaviour(Keys.Enter | Keys.Shift, CellEditCharacterBehaviour.EndEdit, CellEditAtEdgeBehaviour.EndEdit); } } } private bool cellEditEnterChangesRows; /// /// Gets the tool tip control that shows tips for the cells /// [Browsable(false)] public ToolTipControl CellToolTip { get { if (cellToolTip == null) { CreateCellToolTip(); } return cellToolTip; } } private ToolTipControl cellToolTip; /// /// Gets or sets how many pixels will be left blank around each cell of this item. /// Cell contents are aligned after padding has been taken into account. /// /// /// Each value of the given rectangle will be treated as an inset from /// the corresponding side. The width of the rectangle is the padding for the /// right cell edge. The height of the rectangle is the padding for the bottom /// cell edge. /// /// /// So, this.olv1.CellPadding = new Rectangle(1, 2, 3, 4); will leave one pixel /// of space to the left of the cell, 2 pixels at the top, 3 pixels of space /// on the right edge, and 4 pixels of space at the bottom of each cell. /// /// /// This setting only takes effect when the control is owner drawn. /// /// This setting only affects the contents of the cell. The background is /// not affected. /// If you set this to a foolish value, your control will appear to be empty. /// [Category("ObjectListView"), Description("How much padding will be applied to each cell in this control?"), DefaultValue(null)] public Rectangle? CellPadding { get { return cellPadding; } set { cellPadding = value; } } private Rectangle? cellPadding; /// /// Gets or sets how cells will be vertically aligned by default. /// /// This setting only takes effect when the control is owner drawn. It will only be noticable /// when RowHeight has been set such that there is some vertical space in each row. [Category("ObjectListView"), Description("How will cell values be vertically aligned?"), DefaultValue(StringAlignment.Center)] public virtual StringAlignment CellVerticalAlignment { get { return cellVerticalAlignment; } set { cellVerticalAlignment = value; } } private StringAlignment cellVerticalAlignment = StringAlignment.Center; /// /// Should this list show checkboxes? /// [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public new bool CheckBoxes { get { return base.CheckBoxes; } set { // Due to code in the base ListView class, turning off CheckBoxes on a virtual // list always throws an InvalidOperationException. We have to do some major hacking // to get around that if (VirtualMode) { // Leave virtual mode StateImageList = null; VirtualListSize = 0; VirtualMode = false; // Change the CheckBox setting while not in virtual mode base.CheckBoxes = value; // Reinstate virtual mode VirtualMode = true; // Re-enact the bits that we lost by switching to virtual mode ShowGroups = ShowGroups; BuildList(true); } else { base.CheckBoxes = value; // Initialize the state image list so we can display indetermined values. InitializeStateImageList(); } } } /// /// Return the model object of the row that is checked or null if no row is checked /// or more than one row is checked /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual Object CheckedObject { get { IList checkedObjects = CheckedObjects; return checkedObjects.Count == 1 ? checkedObjects[0] : null; } set { CheckedObjects = new ArrayList(new Object[] { value }); } } /// /// Get or set the collection of model objects that are checked. /// When setting this property, any row whose model object isn't /// in the given collection will be unchecked. Setting to null is /// equivilent to unchecking all. /// /// /// /// This property returns a simple collection. Changes made to the returned /// collection do NOT affect the list. This is different to the behaviour of /// CheckedIndicies collection. /// /// /// .NET's CheckedItems property is not helpful. It is just a short-hand for /// iterating through the list looking for items that are checked. /// /// /// The performance of the get method is O(n), where n is the number of items /// in the control. The performance of the set method is /// O(n + m) where m is the number of objects being checked. Be careful on long lists. /// /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual IList CheckedObjects { get { ArrayList list = new ArrayList(); if (CheckBoxes) { if (!VirtualMode) { // Faster than index access, but doesn't work on virtual lists foreach (OLVListItem olvi in Items) { if (olvi.CheckState == CheckState.Checked) list.Add(olvi.RowObject); } } else { for (int i = 0; i < GetItemCount(); i++) { OLVListItem olvi = GetItem(i); if (olvi.CheckState == CheckState.Checked) list.Add(olvi.RowObject); } } } return list; } set { if (!CheckBoxes) return; Stopwatch sw = Stopwatch.StartNew(); // Set up an efficient way of testing for the presence of a particular model Hashtable table = new Hashtable(GetItemCount()); if (value != null) { foreach (object x in value) table[x] = true; } BeginUpdate(); foreach (Object x in Objects) { SetObjectCheckedness(x, table.ContainsKey(x) ? CheckState.Checked : CheckState.Unchecked); } EndUpdate(); Debug.WriteLine(String.Format("PERF - Setting CheckedObjects on {2} objects took {0}ms / {1} ticks", sw.ElapsedMilliseconds, sw.ElapsedTicks, GetItemCount())); } } /// /// Gets or sets the checked objects from an enumerable. /// /// /// Useful for checking all objects in the list. /// /// /// this.olv1.CheckedObjectsEnumerable = this.olv1.Objects; /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual IEnumerable CheckedObjectsEnumerable { get { return CheckedObjects; } set { CheckedObjects = EnumerableToArray(value, true); } } /// /// Gets Columns for this list. We hide the original so we can associate /// a specialised editor with it. /// [Editor("BrightIdeasSoftware.Design.OLVColumnCollectionEditor", "System.Drawing.Design.UITypeEditor")] public new ColumnHeaderCollection Columns { get { return base.Columns; } } /// /// Get/set the list of columns that should be used when the list switches to tile view. /// [Browsable(false), Obsolete("Use GetFilteredColumns() and OLVColumn.IsTileViewColumn instead"), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public List ColumnsForTileView { get { return GetFilteredColumns(View.Tile); } } /// /// Return the visible columns in the order they are displayed to the user /// [Browsable(false)] public virtual List ColumnsInDisplayOrder { get { OLVColumn[] columnsInDisplayOrder = new OLVColumn[Columns.Count]; foreach (OLVColumn col in Columns) { columnsInDisplayOrder[col.DisplayIndex] = col; } return new List(columnsInDisplayOrder); } } /// /// Get the area of the control that shows the list, minus any header control /// [Browsable(false)] public Rectangle ContentRectangle { get { Rectangle r = ClientRectangle; // If the listview has a header control, remove the header from the control area if ((View == View.Details || ShowHeaderInAllViews) && HeaderControl != null) { Rectangle hdrBounds = new Rectangle(); NativeMethods.GetClientRect(HeaderControl.Handle, ref hdrBounds); r.Y = hdrBounds.Height; r.Height -= hdrBounds.Height; } return r; } } /// /// Gets or sets if the selected rows should be copied to the clipboard when the user presses Ctrl-C /// [Category("ObjectListView"), Description("Should the control copy the selection to the clipboard when the user presses Ctrl-C?"), DefaultValue(true)] public virtual bool CopySelectionOnControlC { get { return copySelectionOnControlC; } set { copySelectionOnControlC = value; } } private bool copySelectionOnControlC = true; /// /// Gets or sets whether the Control-C copy to clipboard functionality should use /// the installed DragSource to create the data object that is placed onto the clipboard. /// /// This is normally what is desired, unless a custom DragSource is installed /// that does some very specialized drag-drop behaviour. [Category("ObjectListView"), Description("Should the Ctrl-C copy process use the DragSource to create the Clipboard data object?"), DefaultValue(true)] public bool CopySelectionOnControlCUsesDragSource { get { return copySelectionOnControlCUsesDragSource; } set { copySelectionOnControlCUsesDragSource = value; } } private bool copySelectionOnControlCUsesDragSource = true; /// /// Gets the list of decorations that will be drawn the ListView /// /// /// /// Do not modify the contents of this list directly. Use the AddDecoration() and RemoveDecoration() methods. /// /// /// A decoration scrolls with the list contents. An overlay is fixed in place. /// /// [Browsable(false)] protected IList Decorations { get { return decorations; } } private readonly List decorations = new(); /// /// When owner drawing, this renderer will draw columns that do not have specific renderer /// given to them /// /// If you try to set this to null, it will revert to a HighlightTextRenderer [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public IRenderer DefaultRenderer { get { return defaultRenderer; } set { defaultRenderer = value ?? new HighlightTextRenderer(); } } private IRenderer defaultRenderer = new HighlightTextRenderer(); /// /// Get the renderer to be used to draw the given cell. /// /// The row model for the row /// The column to be drawn /// The renderer used for drawing a cell. Must not return null. public IRenderer GetCellRenderer(object model, OLVColumn column) { IRenderer renderer = CellRendererGetter == null ? null : CellRendererGetter(model, column); return renderer ?? column.Renderer ?? DefaultRenderer; } /// /// Gets or sets the style that will be applied to disabled items. /// /// If this is not set explicitly, will be used. [Category("ObjectListView"), Description("The style that will be applied to disabled items"), DefaultValue(null)] public SimpleItemStyle DisabledItemStyle { get { return disabledItemStyle; } set { disabledItemStyle = value; } } private SimpleItemStyle disabledItemStyle; /// /// Gets or sets the list of model objects that are disabled. /// Disabled objects cannot be selected or activated. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual IEnumerable DisabledObjects { get { return disabledObjects.Keys; } set { disabledObjects.Clear(); DisableObjects(value); } } private readonly Hashtable disabledObjects = new(); /// /// Is this given model object disabled? /// /// /// public bool IsDisabled(object model) { return model != null && disabledObjects.ContainsKey(model); } /// /// Disable the given model object. /// Disabled objects cannot be selected or activated. /// /// Must not be null public void DisableObject(object model) { ArrayList list = new ArrayList(); list.Add(model); DisableObjects(list); } /// /// Disable all the given model objects /// /// public void DisableObjects(IEnumerable models) { if (models == null) return; ArrayList list = EnumerableToArray(models, false); foreach (object model in list) { if (model == null) continue; disabledObjects[model] = true; int modelIndex = IndexOf(model); if (modelIndex >= 0) NativeMethods.DeselectOneItem(this, modelIndex); } RefreshObjects(list); } /// /// Enable the given model object, so it can be selected and activated again. /// /// Must not be null public void EnableObject(object model) { disabledObjects.Remove(model); RefreshObject(model); } /// /// Enable all the given model objects /// /// public void EnableObjects(IEnumerable models) { if (models == null) return; ArrayList list = EnumerableToArray(models, false); foreach (object model in list) { if (model != null) disabledObjects.Remove(model); } RefreshObjects(list); } /// /// Forget all disabled objects. This does not trigger a redraw or rebuild /// protected void ClearDisabledObjects() { disabledObjects.Clear(); } /// /// Gets or sets the object that controls how drags start from this control /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public IDragSource DragSource { get { return dragSource; } set { dragSource = value; } } private IDragSource dragSource; /// /// Gets or sets the object that controls how drops are accepted and processed /// by this ListView. /// /// /// /// If the given sink is an instance of SimpleDropSink, then events from the drop sink /// will be automatically forwarded to the ObjectListView (which means that handlers /// for those event can be configured within the IDE). /// /// If this is set to null, the control will not accept drops. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public IDropSink DropSink { get { return dropSink; } set { if (dropSink == value) return; // Stop listening for events on the old sink if (dropSink is SimpleDropSink oldSink) { oldSink.CanDrop -= new EventHandler(DropSinkCanDrop); oldSink.Dropped -= new EventHandler(DropSinkDropped); oldSink.ModelCanDrop -= new EventHandler(DropSinkModelCanDrop); oldSink.ModelDropped -= new EventHandler(DropSinkModelDropped); } dropSink = value; AllowDrop = (value != null); if (dropSink != null) dropSink.ListView = this; // Start listening for events on the new sink if (value is SimpleDropSink newSink) { newSink.CanDrop += new EventHandler(DropSinkCanDrop); newSink.Dropped += new EventHandler(DropSinkDropped); newSink.ModelCanDrop += new EventHandler(DropSinkModelCanDrop); newSink.ModelDropped += new EventHandler(DropSinkModelDropped); } } } private IDropSink dropSink; // Forward events from the drop sink to the control itself private void DropSinkCanDrop(object sender, OlvDropEventArgs e) { OnCanDrop(e); } private void DropSinkDropped(object sender, OlvDropEventArgs e) { OnDropped(e); } private void DropSinkModelCanDrop(object sender, ModelDropEventArgs e) { OnModelCanDrop(e); } private void DropSinkModelDropped(object sender, ModelDropEventArgs e) { OnModelDropped(e); } /// /// This registry decides what control should be used to edit what cells, based /// on the type of the value in the cell. /// /// /// All instances of ObjectListView share the same editor registry. // ReSharper disable FieldCanBeMadeReadOnly.Global public static EditorRegistry EditorRegistry = new(); // ReSharper restore FieldCanBeMadeReadOnly.Global /// /// Gets or sets the text that should be shown when there are no items in this list view. /// /// If the EmptyListMsgOverlay has been changed to something other than a TextOverlay, /// this property does nothing [Category("ObjectListView"), Description("When the list has no items, show this message in the control"), DefaultValue(null), Localizable(true)] public virtual String EmptyListMsg { get { return EmptyListMsgOverlay is not TextOverlay overlay ? null : overlay.Text; } set { if (EmptyListMsgOverlay is TextOverlay overlay) { overlay.Text = value; Invalidate(); } } } /// /// Gets or sets the font in which the List Empty message should be drawn /// /// If the EmptyListMsgOverlay has been changed to something other than a TextOverlay, /// this property does nothing [Category("ObjectListView"), Description("What font should the 'list empty' message be drawn in?"), DefaultValue(null)] public virtual Font EmptyListMsgFont { get { return EmptyListMsgOverlay is not TextOverlay overlay ? null : overlay.Font; } set { if (EmptyListMsgOverlay is TextOverlay overlay) overlay.Font = value; } } /// /// Return the font for the 'list empty' message or a reasonable default /// [Browsable(false)] public virtual Font EmptyListMsgFontOrDefault { get { return EmptyListMsgFont ?? new Font("Tahoma", 14); } } /// /// Gets or sets the overlay responsible for drawing the List Empty msg. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual IOverlay EmptyListMsgOverlay { get { return emptyListMsgOverlay; } set { if (emptyListMsgOverlay != value) { emptyListMsgOverlay = value; Invalidate(); } } } private IOverlay emptyListMsgOverlay; /// /// Gets the collection of objects that survive any filtering that may be in place. /// /// /// /// This collection is the result of filtering the current list of objects. /// It is not a snapshot of the filtered list that was last used to build the control. /// /// /// Normal warnings apply when using this with virtual lists. It will work, but it /// may take a while. /// /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual IEnumerable FilteredObjects { get { if (UseFiltering) return FilterObjects(Objects, ModelFilter, ListFilter); return Objects; } } /// /// Gets or sets the strategy object that will be used to build the Filter menu /// /// If this is null, no filter menu will be built. [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public FilterMenuBuilder FilterMenuBuildStrategy { get { return filterMenuBuilder; } set { filterMenuBuilder = value; } } private FilterMenuBuilder filterMenuBuilder = new(); /// /// Gets or sets the row that has keyboard focus /// /// /// /// Setting an object to be focused does *not* select it. If you want to select and focus a row, /// use . /// /// /// This property is not generally used and is only useful in specialized situations. /// /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual Object FocusedObject { get { return FocusedItem == null ? null : ((OLVListItem)FocusedItem).RowObject; } set { OLVListItem item = ModelToItem(value); if (item != null) item.Focused = true; } } /// /// Hide the Groups collection so it's not visible in the Properties grid. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public new ListViewGroupCollection Groups { get { return base.Groups; } } /// /// Gets or sets the image list from which group header will take their images /// /// If this is not set, then group headers will not show any images. [Category("ObjectListView"), Description("The image list from which group header will take their images"), DefaultValue(null)] public new ImageList GroupImageList { get { return groupImageList; } set { groupImageList = value; if (Created) { NativeMethods.SetGroupImageList(this, value); } } } private ImageList groupImageList; /// /// Gets how the group label should be formatted when a group is empty or /// contains more than one item /// /// /// The given format string must have two placeholders: /// /// {0} - the original group title /// {1} - the number of items in the group /// /// /// "{0} [{1} items]" [Category("ObjectListView"), Description("The format to use when suffixing item counts to group titles"), DefaultValue(null), Localizable(true)] public virtual string GroupWithItemCountFormat { get { return groupWithItemCountFormat; } set { groupWithItemCountFormat = value; } } private string groupWithItemCountFormat; /// /// Return this.GroupWithItemCountFormat or a reasonable default /// [Browsable(false)] public virtual string GroupWithItemCountFormatOrDefault { get { return String.IsNullOrEmpty(GroupWithItemCountFormat) ? "{0} [{1} items]" : GroupWithItemCountFormat; } } /// /// Gets how the group label should be formatted when a group contains only a single item /// /// /// The given format string must have two placeholders: /// /// {0} - the original group title /// {1} - the number of items in the group (always 1) /// /// /// "{0} [{1} item]" [Category("ObjectListView"), Description("The format to use when suffixing item counts to group titles"), DefaultValue(null), Localizable(true)] public virtual string GroupWithItemCountSingularFormat { get { return groupWithItemCountSingularFormat; } set { groupWithItemCountSingularFormat = value; } } private string groupWithItemCountSingularFormat; /// /// Gets GroupWithItemCountSingularFormat or a reasonable default /// [Browsable(false)] public virtual string GroupWithItemCountSingularFormatOrDefault { get { return String.IsNullOrEmpty(GroupWithItemCountSingularFormat) ? "{0} [{1} item]" : GroupWithItemCountSingularFormat; } } /// /// Gets or sets whether or not the groups in this ObjectListView should be collapsible. /// /// /// This feature only works under Vista and later. /// [Browsable(true), Category("ObjectListView"), Description("Should the groups in this control be collapsible (Vista and later only)."), DefaultValue(true)] public bool HasCollapsibleGroups { get { return hasCollapsibleGroups; } set { hasCollapsibleGroups = value; } } private bool hasCollapsibleGroups = true; /// /// Does this listview have a message that should be drawn when the list is empty? /// [Browsable(false)] public virtual bool HasEmptyListMsg { get { return !String.IsNullOrEmpty(EmptyListMsg); } } /// /// Get whether there are any overlays to be drawn /// [Browsable(false)] public bool HasOverlays { get { return (Overlays.Count > 2 || imageOverlay.Image != null || !String.IsNullOrEmpty(textOverlay.Text)); } } /// /// Gets the header control for the ListView /// [Browsable(false)] public HeaderControl HeaderControl { get { return headerControl ?? (headerControl = new HeaderControl(this)); } } private HeaderControl headerControl; /// /// Gets or sets the font in which the text of the column headers will be drawn /// /// Individual columns can override this through their HeaderFormatStyle property. [DefaultValue(null)] [Browsable(false)] [Obsolete("Use a HeaderFormatStyle instead", false)] public Font HeaderFont { get { return HeaderFormatStyle == null ? null : HeaderFormatStyle.Normal.Font; } set { if (value == null && HeaderFormatStyle == null) return; if (HeaderFormatStyle == null) HeaderFormatStyle = new HeaderFormatStyle(); HeaderFormatStyle.SetFont(value); } } /// /// Gets or sets the style that will be used to draw the columm headers of the listview /// /// /// /// This is only used when HeaderUsesThemes is false. /// /// /// Individual columns can override this through their HeaderFormatStyle property. /// /// [Category("ObjectListView"), Description("What style will be used to draw the control's header"), DefaultValue(null)] public HeaderFormatStyle HeaderFormatStyle { get { return headerFormatStyle; } set { headerFormatStyle = value; } } private HeaderFormatStyle headerFormatStyle; /// /// Gets or sets the maximum height of the header. -1 means no maximum. /// [Category("ObjectListView"), Description("What is the maximum height of the header? -1 means no maximum"), DefaultValue(-1)] public int HeaderMaximumHeight { get { return headerMaximumHeight; } set { headerMaximumHeight = value; } } private int headerMaximumHeight = -1; /// /// Gets or sets the minimum height of the header. -1 means no minimum. /// [Category("ObjectListView"), Description("What is the minimum height of the header? -1 means no minimum"), DefaultValue(-1)] public int HeaderMinimumHeight { get { return headerMinimumHeight; } set { headerMinimumHeight = value; } } private int headerMinimumHeight = -1; /// /// Gets or sets whether the header will be drawn strictly according to the OS's theme. /// /// /// /// If this is set to true, the header will be rendered completely by the system, without /// any of ObjectListViews fancy processing -- no images in header, no filter indicators, /// no word wrapping, no header styling, no checkboxes. /// /// If this is set to false, ObjectListView will render the header as it thinks best. /// If no special features are required, then ObjectListView will delegate rendering to the OS. /// Otherwise, ObjectListView will draw the header according to the configuration settings. /// /// /// The effect of not being themed will be different from OS to OS. At /// very least, the sort indicator will not be standard. /// /// [Category("ObjectListView"), Description("Will the column headers be drawn strictly according to OS theme?"), DefaultValue(false)] public bool HeaderUsesThemes { get { return headerUsesThemes; } set { headerUsesThemes = value; } } private bool headerUsesThemes; /// /// Gets or sets the whether the text in the header will be word wrapped. /// /// /// Line breaks will be applied between words. Words that are too long /// will still be ellipsed. /// /// As with all settings that make the header look different, HeaderUsesThemes must be set to false, otherwise /// the OS will be responsible for drawing the header, and it does not allow word wrapped text. /// /// [Category("ObjectListView"), Description("Will the text of the column headers be word wrapped?"), DefaultValue(false)] public bool HeaderWordWrap { get { return headerWordWrap; } set { headerWordWrap = value; if (headerControl != null) headerControl.WordWrap = value; } } private bool headerWordWrap; /// /// Gets the tool tip that shows tips for the column headers /// [Browsable(false)] public ToolTipControl HeaderToolTip { get { return HeaderControl.ToolTip; } } /// /// Gets the index of the row that the mouse is currently over /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual int HotRowIndex { get { return hotRowIndex; } protected set { hotRowIndex = value; } } private int hotRowIndex; /// /// Gets the index of the subitem that the mouse is currently over /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual int HotColumnIndex { get { return hotColumnIndex; } protected set { hotColumnIndex = value; } } private int hotColumnIndex; /// /// Gets the part of the item/subitem that the mouse is currently over /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual HitTestLocation HotCellHitLocation { get { return hotCellHitLocation; } protected set { hotCellHitLocation = value; } } private HitTestLocation hotCellHitLocation; /// /// Gets an extended indication of the part of item/subitem/group that the mouse is currently over /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual HitTestLocationEx HotCellHitLocationEx { get { return hotCellHitLocationEx; } protected set { hotCellHitLocationEx = value; } } private HitTestLocationEx hotCellHitLocationEx; /// /// Gets the group that the mouse is over /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public OLVGroup HotGroup { get { return hotGroup; } internal set { hotGroup = value; } } private OLVGroup hotGroup; /// /// The index of the item that is 'hot', i.e. under the cursor. -1 means no item. /// [Browsable(false), Obsolete("Use HotRowIndex instead", false)] public virtual int HotItemIndex { get { return HotRowIndex; } } /// /// What sort of formatting should be applied to the row under the cursor? /// /// /// /// This only takes effect when UseHotItem is true. /// /// If the style has an overlay, it must be set /// *before* assigning it to this property. Adding it afterwards will be ignored. /// [Category("ObjectListView"), Description("How should the row under the cursor be highlighted"), DefaultValue(null)] public virtual HotItemStyle HotItemStyle { get { return hotItemStyle; } set { if (HotItemStyle != null) RemoveOverlay(HotItemStyle.Overlay); hotItemStyle = value; if (HotItemStyle != null) AddOverlay(HotItemStyle.Overlay); } } private HotItemStyle hotItemStyle; /// /// Gets the installed hot item style or a reasonable default. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual HotItemStyle HotItemStyleOrDefault { get { return HotItemStyle ?? DefaultHotItemStyle; } } /// /// What sort of formatting should be applied to hyperlinks? /// [Category("ObjectListView"), Description("How should hyperlinks be drawn"), DefaultValue(null)] public virtual HyperlinkStyle HyperlinkStyle { get { return hyperlinkStyle; } set { hyperlinkStyle = value; } } private HyperlinkStyle hyperlinkStyle; /// /// What color should be used for the background of selected rows? /// [Category("ObjectListView"), Description("The background of selected rows when the control is owner drawn"), DefaultValue(typeof(Color), "")] public virtual Color SelectedBackColor { get { return selectedBackColor; } set { selectedBackColor = value; } } private Color selectedBackColor = Color.Empty; /// /// Return the color should be used for the background of selected rows or a reasonable default /// [Browsable(false)] public virtual Color SelectedBackColorOrDefault { get { return SelectedBackColor.IsEmpty ? SystemColors.Highlight : SelectedBackColor; } } /// /// What color should be used for the foreground of selected rows? /// [Category("ObjectListView"), Description("The foreground color of selected rows (when the control is owner drawn)"), DefaultValue(typeof(Color), "")] public virtual Color SelectedForeColor { get { return selectedForeColor; } set { selectedForeColor = value; } } private Color selectedForeColor = Color.Empty; /// /// Return the color should be used for the foreground of selected rows or a reasonable default /// [Browsable(false)] public virtual Color SelectedForeColorOrDefault { get { return SelectedForeColor.IsEmpty ? SystemColors.HighlightText : SelectedForeColor; } } [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [Obsolete("Use SelectedBackColor instead")] public virtual Color HighlightBackgroundColor { get { return SelectedBackColor; } set { SelectedBackColor = value; } } [Obsolete("Use SelectedBackColorOrDefault instead")] public virtual Color HighlightBackgroundColorOrDefault { get { return SelectedBackColorOrDefault; } } [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [Obsolete("Use SelectedForeColor instead")] public virtual Color HighlightForegroundColor { get { return SelectedForeColor; } set { SelectedForeColor = value; } } [Obsolete("Use SelectedForeColorOrDefault instead")] public virtual Color HighlightForegroundColorOrDefault { get { return SelectedForeColorOrDefault; } } [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [Obsolete("Use UnfocusedSelectedBackColor instead")] public virtual Color UnfocusedHighlightBackgroundColor { get { return UnfocusedSelectedBackColor; } set { UnfocusedSelectedBackColor = value; } } [Obsolete("Use UnfocusedSelectedBackColorOrDefault instead")] public virtual Color UnfocusedHighlightBackgroundColorOrDefault { get { return UnfocusedSelectedBackColorOrDefault; } } [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [Obsolete("Use UnfocusedSelectedForeColor instead")] public virtual Color UnfocusedHighlightForegroundColor { get { return UnfocusedSelectedForeColor; } set { UnfocusedSelectedForeColor = value; } } [Obsolete("Use UnfocusedSelectedForeColorOrDefault instead")] public virtual Color UnfocusedHighlightForegroundColorOrDefault { get { return UnfocusedSelectedForeColorOrDefault; } } /// /// Gets or sets whether or not hidden columns should be included in the text representation /// of rows that are copied or dragged to another application. If this is false (the default), /// only visible columns will be included. /// [Category("ObjectListView"), Description("When rows are copied or dragged, will data in hidden columns be included in the text? If this is false, only visible columns will be included."), DefaultValue(false)] public virtual bool IncludeHiddenColumnsInDataTransfer { get { return includeHiddenColumnsInDataTransfer; } set { includeHiddenColumnsInDataTransfer = value; } } private bool includeHiddenColumnsInDataTransfer; /// /// Gets or sets whether or not hidden columns should be included in the text representation /// of rows that are copied or dragged to another application. If this is false (the default), /// only visible columns will be included. /// [Category("ObjectListView"), Description("When rows are copied, will column headers be in the text?."), DefaultValue(false)] public virtual bool IncludeColumnHeadersInCopy { get { return includeColumnHeadersInCopy; } set { includeColumnHeadersInCopy = value; } } private bool includeColumnHeadersInCopy; /// /// Return true if a cell edit operation is currently happening /// [Browsable(false)] public virtual bool IsCellEditing { get { return cellEditor != null; } } /// /// Return true if the ObjectListView is being used within the development environment. /// [Browsable(false)] public virtual bool IsDesignMode { get { return DesignMode; } } /// /// Gets whether or not the current list is filtering its contents /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual bool IsFiltering { get { return UseFiltering && (ModelFilter != null || ListFilter != null); } } /// /// When the user types into a list, should the values in the current sort column be searched to find a match? /// If this is false, the primary column will always be used regardless of the sort column. /// /// When this is true, the behavior is like that of ITunes. [Category("ObjectListView"), Description("When the user types into a list, should the values in the current sort column be searched to find a match?"), DefaultValue(true)] public virtual bool IsSearchOnSortColumn { get { return isSearchOnSortColumn; } set { isSearchOnSortColumn = value; } } private bool isSearchOnSortColumn = true; /// /// Gets or sets if this control will use a SimpleDropSink to receive drops /// /// /// /// Setting this replaces any previous DropSink. /// /// /// After setting this to true, the SimpleDropSink will still need to be configured /// to say when it can accept drops and what should happen when something is dropped. /// The need to do these things makes this property mostly useless :( /// /// [Category("ObjectListView"), Description("Should this control will use a SimpleDropSink to receive drops."), DefaultValue(false)] public virtual bool IsSimpleDropSink { get { return DropSink != null; } set { DropSink = value ? new SimpleDropSink() : null; } } /// /// Gets or sets if this control will use a SimpleDragSource to initiate drags /// /// Setting this replaces any previous DragSource [Category("ObjectListView"), Description("Should this control use a SimpleDragSource to initiate drags out from this control"), DefaultValue(false)] public virtual bool IsSimpleDragSource { get { return DragSource != null; } set { DragSource = value ? new SimpleDragSource() : null; } } /// /// Hide the Items collection so it's not visible in the Properties grid. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public new ListViewItemCollection Items { get { return base.Items; } } /// /// This renderer draws the items when in the list is in non-details view. /// In details view, the renderers for the individuals columns are responsible. /// [Category("ObjectListView"), Description("The owner drawn renderer that draws items when the list is in non-Details view."), DefaultValue(null)] public IRenderer ItemRenderer { get { return itemRenderer; } set { itemRenderer = value; } } private IRenderer itemRenderer; /// /// Which column did we last sort by /// /// This is an alias for PrimarySortColumn [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual OLVColumn LastSortColumn { get { return PrimarySortColumn; } set { PrimarySortColumn = value; } } /// /// Which direction did we last sort /// /// This is an alias for PrimarySortOrder [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual SortOrder LastSortOrder { get { return PrimarySortOrder; } set { PrimarySortOrder = value; } } /// /// Gets or sets the filter that is applied to our whole list of objects. /// /// /// The list is updated immediately to reflect this filter. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual IListFilter ListFilter { get { return listFilter; } set { listFilter = value; if (UseFiltering) UpdateFiltering(); } } private IListFilter listFilter; /// /// Gets or sets the filter that is applied to each model objects in the list /// /// /// You may want to consider using instead of this property, /// since AdditionalFilter combines with column filtering at runtime. Setting this property simply /// replaces any column filter the user may have given. /// /// The list is updated immediately to reflect this filter. /// /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual IModelFilter ModelFilter { get { return modelFilter; } set { modelFilter = value; NotifyNewModelFilter(); if (UseFiltering) { UpdateFiltering(); // When the filter changes, it's likely/possible that the selection has also changed. // It's expensive to see if the selection has actually changed (for large virtual lists), // so we just fake a selection changed event, just in case. SF #144 OnSelectedIndexChanged(EventArgs.Empty); } } } private IModelFilter modelFilter; /// /// Gets the hit test info last time the mouse was moved. /// /// Useful for hot item processing. [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual OlvListViewHitTestInfo MouseMoveHitTest { get { return mouseMoveHitTest; } private set { mouseMoveHitTest = value; } } private OlvListViewHitTestInfo mouseMoveHitTest; /// /// Gets or sets the list of groups shown by the listview. /// /// /// This property does not work like the .NET Groups property. It should /// be treated as a read-only property. /// Changes made to the list are NOT reflected in the ListView itself -- it is pointless to add /// or remove groups to/from this list. Such modifications will do nothing. /// To do such things, you must listen for /// BeforeCreatingGroups or AboutToCreateGroups events, and change the list of /// groups in those events. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public IList OLVGroups { get { return olvGroups; } set { olvGroups = value; } } private IList olvGroups; /// /// Gets or sets the collection of OLVGroups that are collapsed. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public IEnumerable CollapsedGroups { get { if (OLVGroups != null) { foreach (OLVGroup group in OLVGroups) { if (group.Collapsed) yield return group; } } } set { if (OLVGroups == null) return; Hashtable shouldCollapse = new Hashtable(); if (value != null) { foreach (OLVGroup group in value) shouldCollapse[group.Key] = true; } foreach (OLVGroup group in OLVGroups) { group.Collapsed = shouldCollapse.ContainsKey(group.Key); } } } /// /// Gets or sets whether the user wants to owner draw the header control /// themselves. If this is false (the default), ObjectListView will use /// custom drawing to render the header, if needed. /// /// /// If you listen for the DrawColumnHeader event, you need to set this to true, /// otherwise your event handler will not be called. /// [Category("ObjectListView"), Description("Should the DrawColumnHeader event be triggered"), DefaultValue(false)] public bool OwnerDrawnHeader { get { return ownerDrawnHeader; } set { ownerDrawnHeader = value; } } private bool ownerDrawnHeader; /// /// Get/set the collection of objects that this list will show /// /// /// /// The contents of the control will be updated immediately after setting this property. /// /// This method preserves selection, if possible. Use if /// you do not want to preserve the selection. Preserving selection is the slowest part of this /// code and performance is O(n) where n is the number of selected rows. /// This method is not thread safe. /// The property DOES work on virtual lists: setting is problem-free, but if you try to get it /// and the list has 10 million objects, it may take some time to return. /// This collection is unfiltered. Use to access just those objects /// that survive any installed filters. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual IEnumerable Objects { get { return objects; } set { SetObjects(value, true); } } private IEnumerable objects; /// /// Gets the collection of objects that will be considered when creating clusters /// (which are used to generate Excel-like column filters) /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual IEnumerable ObjectsForClustering { get { return Objects; } } /// /// Gets or sets the image that will be drawn over the top of the ListView /// [Category("ObjectListView"), Description("The image that will be drawn over the top of the ListView"), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] public ImageOverlay OverlayImage { get { return imageOverlay; } set { if (imageOverlay == value) return; RemoveOverlay(imageOverlay); imageOverlay = value; AddOverlay(imageOverlay); } } private ImageOverlay imageOverlay; /// /// Gets or sets the text that will be drawn over the top of the ListView /// [Category("ObjectListView"), Description("The text that will be drawn over the top of the ListView"), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] public TextOverlay OverlayText { get { return textOverlay; } set { if (textOverlay == value) return; RemoveOverlay(textOverlay); textOverlay = value; AddOverlay(textOverlay); } } private TextOverlay textOverlay; /// /// Gets or sets the transparency of all the overlays. /// 0 is completely transparent, 255 is completely opaque. /// /// /// This is obsolete. Use Transparency on each overlay. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public int OverlayTransparency { get { return overlayTransparency; } set { overlayTransparency = Math.Min(255, Math.Max(0, value)); } } private int overlayTransparency = 128; /// /// Gets the list of overlays that will be drawn on top of the ListView /// /// /// You can add new overlays and remove overlays that you have added, but /// don't mess with the overlays that you didn't create. /// [Browsable(false)] protected IList Overlays { get { return overlays; } } private readonly List overlays = new(); /// /// Gets or sets whether the ObjectListView will be owner drawn. Defaults to true. /// /// /// /// When this is true, all of ObjectListView's neat features are available. /// /// We have to reimplement this property, even though we just call the base /// property, in order to change the [DefaultValue] to true. /// /// [Category("Appearance"), Description("Should the ListView do its own rendering"), DefaultValue(true)] public new bool OwnerDraw { get { return base.OwnerDraw; } set { base.OwnerDraw = value; } } /// /// Gets or sets whether or not primary checkboxes will persistent their values across list rebuild /// and filtering operations. /// /// /// /// This property is only useful when you don't explicitly set CheckStateGetter/Putter. /// If you use CheckStateGetter/Putter, the checkedness of a row will already be persisted /// by those methods. /// /// This defaults to true. If this is false, checkboxes will lose their values when the /// list if rebuild or filtered. /// If you set it to false on virtual lists, /// you have to install CheckStateGetter/Putters. /// [Category("ObjectListView"), Description("Will primary checkboxes persistent their values across list rebuilds"), DefaultValue(true)] public virtual bool PersistentCheckBoxes { get { return persistentCheckBoxes; } set { if (persistentCheckBoxes == value) return; persistentCheckBoxes = value; ClearPersistentCheckState(); } } private bool persistentCheckBoxes = true; /// /// Gets or sets a dictionary that remembers the check state of model objects /// /// This is used when PersistentCheckBoxes is true and for virtual lists. protected Dictionary CheckStateMap { get { return checkStateMap ?? (checkStateMap = new Dictionary()); } set { checkStateMap = value; } } private Dictionary checkStateMap; /// /// Get checked objects even if they are filtered and currently not visible on the list. /// This works only when PersistentCheckBoxes is true and for virtual lists. /// public IEnumerable GetAllObjectsWithMappedCheckState(CheckState state) { return CheckStateMap.Where(x => x.Value == state).Select(x => x.Key); } /// /// Which column did we last sort by /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual OLVColumn PrimarySortColumn { get { return primarySortColumn; } set { primarySortColumn = value; if (TintSortColumn) SelectedColumn = value; } } private OLVColumn primarySortColumn; /// /// Which direction did we last sort /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual SortOrder PrimarySortOrder { get { return primarySortOrder; } set { primarySortOrder = value; } } private SortOrder primarySortOrder; /// /// Gets or sets if non-editable checkboxes are drawn as disabled. Default is false. /// /// /// This only has effect in owner drawn mode. /// [Category("ObjectListView"), Description("Should non-editable checkboxes be drawn as disabled?"), DefaultValue(false)] public virtual bool RenderNonEditableCheckboxesAsDisabled { get { return renderNonEditableCheckboxesAsDisabled; } set { renderNonEditableCheckboxesAsDisabled = value; } } private bool renderNonEditableCheckboxesAsDisabled; /// /// Specify the height of each row in the control in pixels. /// /// The row height in a listview is normally determined by the font size and the small image list size. /// This setting allows that calculation to be overridden (within reason: you still cannot set the line height to be /// less than the line height of the font used in the control). /// Setting it to -1 means use the normal calculation method. /// This feature is experiemental! Strange things may happen to your program, /// your spouse or your pet if you use it. /// [Category("ObjectListView"), Description("Specify the height of each row in pixels. -1 indicates default height"), DefaultValue(-1)] public virtual int RowHeight { get { return rowHeight; } set { if (value < 1) rowHeight = -1; else rowHeight = value; if (DesignMode) return; SetupBaseImageList(); if (CheckBoxes) InitializeStateImageList(); } } private int rowHeight = -1; /// /// How many pixels high is each row? /// [Browsable(false)] public virtual int RowHeightEffective { get { switch (View) { case View.List: case View.SmallIcon: case View.Details: return Math.Max(SmallImageSize.Height, Font.Height); case View.Tile: return TileSize.Height; case View.LargeIcon: if (LargeImageList == null) return Font.Height; return Math.Max(LargeImageList.ImageSize.Height, Font.Height); default: // This should never happen return 0; } } } /// /// How many rows appear on each page of this control /// [Browsable(false)] public virtual int RowsPerPage { get { return NativeMethods.GetCountPerPage(this); } } /// /// Get/set the column that will be used to resolve comparisons that are equal when sorting. /// /// There is no user interface for this setting. It must be set programmatically. [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual OLVColumn SecondarySortColumn { get { return secondarySortColumn; } set { secondarySortColumn = value; } } private OLVColumn secondarySortColumn; /// /// When the SecondarySortColumn is used, in what order will it compare results? /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual SortOrder SecondarySortOrder { get { return secondarySortOrder; } set { secondarySortOrder = value; } } private SortOrder secondarySortOrder = SortOrder.None; /// /// Gets or sets if all rows should be selected when the user presses Ctrl-A /// [Category("ObjectListView"), Description("Should the control select all rows when the user presses Ctrl-A?"), DefaultValue(true)] public virtual bool SelectAllOnControlA { get { return selectAllOnControlA; } set { selectAllOnControlA = value; } } private bool selectAllOnControlA = true; /// /// When the user right clicks on the column headers, should a menu be presented which will allow /// them to choose which columns will be shown in the view? /// /// This is just a compatibility wrapper for the SelectColumnsOnRightClickBehaviour /// property. [Category("ObjectListView"), Description("When the user right clicks on the column headers, should a menu be presented which will allow them to choose which columns will be shown in the view?"), DefaultValue(true)] public virtual bool SelectColumnsOnRightClick { get { return SelectColumnsOnRightClickBehaviour != ColumnSelectBehaviour.None; } set { if (value) { if (SelectColumnsOnRightClickBehaviour == ColumnSelectBehaviour.None) SelectColumnsOnRightClickBehaviour = ColumnSelectBehaviour.InlineMenu; } else { SelectColumnsOnRightClickBehaviour = ColumnSelectBehaviour.None; } } } /// /// Gets or sets how the user will be able to select columns when the header is right clicked /// [Category("ObjectListView"), Description("When the user right clicks on the column headers, how will the user be able to select columns?"), DefaultValue(ColumnSelectBehaviour.InlineMenu)] public virtual ColumnSelectBehaviour SelectColumnsOnRightClickBehaviour { get { return selectColumnsOnRightClickBehaviour; } set { selectColumnsOnRightClickBehaviour = value; } } private ColumnSelectBehaviour selectColumnsOnRightClickBehaviour = ColumnSelectBehaviour.InlineMenu; /// /// When the column select menu is open, should it stay open after an item is selected? /// Staying open allows the user to turn more than one column on or off at a time. /// /// This only works when SelectColumnsOnRightClickBehaviour is set to InlineMenu. /// It has no effect when the behaviour is set to SubMenu. [Category("ObjectListView"), Description("When the column select inline menu is open, should it stay open after an item is selected?"), DefaultValue(true)] public virtual bool SelectColumnsMenuStaysOpen { get { return selectColumnsMenuStaysOpen; } set { selectColumnsMenuStaysOpen = value; } } private bool selectColumnsMenuStaysOpen = true; /// /// Gets or sets the column that is drawn with a slight tint. /// /// /// /// If TintSortColumn is true, the sort column will automatically /// be made the selected column. /// /// /// The colour of the tint is controlled by SelectedColumnTint. /// /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public OLVColumn SelectedColumn { get { return selectedColumn; } set { selectedColumn = value; if (value == null) { RemoveDecoration(selectedColumnDecoration); } else { if (!HasDecoration(selectedColumnDecoration)) AddDecoration(selectedColumnDecoration); } } } private OLVColumn selectedColumn; private readonly TintedColumnDecoration selectedColumnDecoration = new(); /// /// Gets or sets the decoration that will be drawn on all selected rows /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual IDecoration SelectedRowDecoration { get { return selectedRowDecoration; } set { selectedRowDecoration = value; } } private IDecoration selectedRowDecoration; /// /// What color should be used to tint the selected column? /// /// /// The tint color must be alpha-blendable, so if the given color is solid /// (i.e. alpha = 255), it will be changed to have a reasonable alpha value. /// [Category("ObjectListView"), Description("The color that will be used to tint the selected column"), DefaultValue(typeof(Color), "")] public virtual Color SelectedColumnTint { get { return selectedColumnTint; } set { selectedColumnTint = value.A == 255 ? Color.FromArgb(15, value) : value; selectedColumnDecoration.Tint = selectedColumnTint; } } private Color selectedColumnTint = Color.Empty; /// /// Gets or sets the index of the row that is currently selected. /// When getting the index, if no row is selected,or more than one is selected, return -1. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual int SelectedIndex { get { return SelectedIndices.Count == 1 ? SelectedIndices[0] : -1; } set { SelectedIndices.Clear(); if (value >= 0 && value < Items.Count) SelectedIndices.Add(value); } } /// /// Gets or sets the ListViewItem that is currently selected . If no row is selected, or more than one is selected, return null. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual OLVListItem SelectedItem { get { return SelectedIndices.Count == 1 ? GetItem(SelectedIndices[0]) : null; } set { SelectedIndices.Clear(); if (value != null) SelectedIndices.Add(value.Index); } } /// /// Gets the model object from the currently selected row, if there is only one row selected. /// If no row is selected, or more than one is selected, returns null. /// When setting, this will select the row that is displaying the given model object and focus on it. /// All other rows are deselected. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual Object SelectedObject { get { return SelectedIndices.Count == 1 ? GetModelObject(SelectedIndices[0]) : null; } set { // If the given model is already selected, don't do anything else (prevents an flicker) object selectedObject = SelectedObject; if (selectedObject != null && selectedObject.Equals(value)) return; SelectedIndices.Clear(); SelectObject(value, true); } } /// /// Get the model objects from the currently selected rows. If no row is selected, the returned List will be empty. /// When setting this value, select the rows that is displaying the given model objects. All other rows are deselected. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual IList SelectedObjects { get { ArrayList list = new ArrayList(); foreach (int index in SelectedIndices) list.Add(GetModelObject(index)); return list; } set { SelectedIndices.Clear(); SelectObjects(value); } } /// /// When the user right clicks on the column headers, should a menu be presented which will allow /// them to choose common tasks to perform on the listview? /// [Category("ObjectListView"), Description("When the user right clicks on the column headers, should a menu be presented which will allow them to perform common tasks on the listview?"), DefaultValue(false)] public virtual bool ShowCommandMenuOnRightClick { get { return showCommandMenuOnRightClick; } set { showCommandMenuOnRightClick = value; } } private bool showCommandMenuOnRightClick; /// /// Gets or sets whether this ObjectListView will show Excel like filtering /// menus when the header control is right clicked /// [Category("ObjectListView"), Description("If this is true, right clicking on a column header will show a Filter menu option"), DefaultValue(true)] public bool ShowFilterMenuOnRightClick { get { return showFilterMenuOnRightClick; } set { showFilterMenuOnRightClick = value; } } private bool showFilterMenuOnRightClick = true; /// /// Should this list show its items in groups? /// [Category("Appearance"), Description("Should the list view show items in groups?"), DefaultValue(true)] public new virtual bool ShowGroups { get { return base.ShowGroups; } set { GroupImageList = GroupImageList; base.ShowGroups = value; } } /// /// Should the list view show a bitmap in the column header to show the sort direction? /// /// /// The only reason for not wanting to have sort indicators is that, on pre-XP versions of /// Windows, having sort indicators required the ListView to have a small image list, and /// as soon as you give a ListView a SmallImageList, the text of column 0 is bumped 16 /// pixels to the right, even if you never used an image. /// [Category("ObjectListView"), Description("Should the list view show sort indicators in the column headers?"), DefaultValue(true)] public virtual bool ShowSortIndicators { get { return showSortIndicators; } set { showSortIndicators = value; } } private bool showSortIndicators; /// /// Should the list view show images on subitems? /// /// /// Virtual lists have to be owner drawn in order to show images on subitems /// [Category("ObjectListView"), Description("Should the list view show images on subitems?"), DefaultValue(false)] public virtual bool ShowImagesOnSubItems { get { return showImagesOnSubItems; } set { showImagesOnSubItems = value; if (Created) ApplyExtendedStyles(); if (value && VirtualMode) OwnerDraw = true; } } private bool showImagesOnSubItems; /// /// This property controls whether group labels will be suffixed with a count of items. /// /// /// The format of the suffix is controlled by GroupWithItemCountFormat/GroupWithItemCountSingularFormat properties /// [Category("ObjectListView"), Description("Will group titles be suffixed with a count of the items in the group?"), DefaultValue(false)] public virtual bool ShowItemCountOnGroups { get { return showItemCountOnGroups; } set { showItemCountOnGroups = value; } } private bool showItemCountOnGroups; /// /// Gets or sets whether the control will show column headers in all /// views (true), or only in Details view (false) /// /// /// /// This property is not working correctly. JPP 2010/04/06. /// It works fine if it is set before the control is created. /// But if it turned off once the control is created, the control /// loses its checkboxes (weird!) /// /// /// To changed this setting after the control is created, things /// are complicated. If it is off and we want it on, we have /// to change the View and the header will appear. If it is currently /// on and we want to turn it off, we have to both change the view /// AND recreate the handle. Recreating the handle is a problem /// since it makes our checkbox style disappear. /// /// /// This property doesn't work on XP. /// [Category("ObjectListView"), Description("Will the control will show column headers in all views?"), DefaultValue(true)] public bool ShowHeaderInAllViews { get { return IsVistaOrLater && showHeaderInAllViews; } set { if (showHeaderInAllViews == value) return; showHeaderInAllViews = value; // If the control isn't already created, everything is fine. if (!Created) return; // If the header is being hidden, we have to recreate the control // to remove the style (not sure why this is) if (showHeaderInAllViews) ApplyExtendedStyles(); else RecreateHandle(); // Still more complications. The change doesn't become visible until the View is changed if (View != View.Details) { View temp = View; View = View.Details; View = temp; } } } private bool showHeaderInAllViews = true; /// /// Override the SmallImageList property so we can correctly shadow its operations. /// /// If you use the RowHeight property to specify the row height, the SmallImageList /// must be fully initialised before setting/changing the RowHeight. If you add new images to the image /// list after setting the RowHeight, you must assign the imagelist to the control again. Something as simple /// as this will work: /// listView1.SmallImageList = listView1.SmallImageList; /// [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public new ImageList SmallImageList { get { return shadowedImageList; } set { shadowedImageList = value; if (UseSubItemCheckBoxes) SetupSubItemCheckBoxes(); SetupBaseImageList(); } } private ImageList shadowedImageList; /// /// Return the size of the images in the small image list or a reasonable default /// [Browsable(false)] public virtual Size SmallImageSize { get { return BaseSmallImageList == null ? new Size(16, 16) : BaseSmallImageList.ImageSize; } } /// /// When the listview is grouped, should the items be sorted by the primary column? /// If this is false, the items will be sorted by the same column as they are grouped. /// [Category("ObjectListView"), Description("When the listview is grouped, should the items be sorted by the primary column? If this is false, the items will be sorted by the same column as they are grouped."), DefaultValue(true)] public virtual bool SortGroupItemsByPrimaryColumn { get { return sortGroupItemsByPrimaryColumn; } set { sortGroupItemsByPrimaryColumn = value; } } private bool sortGroupItemsByPrimaryColumn = true; /// /// When the listview is grouped, how many pixels should exist between the end of one group and the /// beginning of the next? /// [Category("ObjectListView"), Description("How many pixels of space will be between groups"), DefaultValue(0)] public virtual int SpaceBetweenGroups { get { return spaceBetweenGroups; } set { if (spaceBetweenGroups == value) return; spaceBetweenGroups = value; SetGroupSpacing(); } } private int spaceBetweenGroups; private void SetGroupSpacing() { if (!IsHandleCreated) return; NativeMethods.LVGROUPMETRICS metrics = new NativeMethods.LVGROUPMETRICS(); metrics.cbSize = ((uint)Marshal.SizeOf(typeof(NativeMethods.LVGROUPMETRICS))); metrics.mask = (uint)GroupMetricsMask.LVGMF_BORDERSIZE; metrics.Bottom = (uint)SpaceBetweenGroups; NativeMethods.SetGroupMetrics(this, metrics); } /// /// Should the sort column show a slight tinge? /// [Category("ObjectListView"), Description("Should the sort column show a slight tinting?"), DefaultValue(false)] public virtual bool TintSortColumn { get { return tintSortColumn; } set { tintSortColumn = value; if (value && PrimarySortColumn != null) SelectedColumn = PrimarySortColumn; else SelectedColumn = null; } } private bool tintSortColumn; /// /// Should each row have a tri-state checkbox? /// /// /// If this is true, the user can choose the third state (normally Indeterminate). Otherwise, user clicks /// alternate between checked and unchecked. CheckStateGetter can still return Indeterminate when this /// setting is false. /// [Category("ObjectListView"), Description("Should the primary column have a checkbox that behaves as a tri-state checkbox?"), DefaultValue(false)] public virtual bool TriStateCheckBoxes { get { return triStateCheckBoxes; } set { triStateCheckBoxes = value; if (value && !CheckBoxes) CheckBoxes = true; InitializeStateImageList(); } } private bool triStateCheckBoxes; /// /// Get or set the index of the top item of this listview /// /// /// /// This property only works when the listview is in Details view and not showing groups. /// /// /// The reason that it does not work when showing groups is that, when groups are enabled, /// the Windows msg LVM_GETTOPINDEX always returns 0, regardless of the /// scroll position. /// /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual int TopItemIndex { get { if (View == View.Details && IsHandleCreated) return NativeMethods.GetTopIndex(this); return -1; } set { int newTopIndex = Math.Min(value, GetItemCount() - 1); if (View != View.Details || newTopIndex < 0) return; try { TopItem = Items[newTopIndex]; // Setting the TopItem sometimes gives off by one errors, // that (bizarrely) are correct on a second attempt if (TopItem != null && TopItem.Index != newTopIndex) TopItem = GetItem(newTopIndex); } catch (NullReferenceException) { // There is a bug in the .NET code where setting the TopItem // will sometimes throw null reference exceptions // There is nothing we can do to get around it. } } } /// /// Gets or sets whether moving the mouse over the header will trigger CellOver events. /// Defaults to true. /// /// /// Moving the mouse over the header did not previously trigger CellOver events, since the /// header is considered a separate control. /// If this change in behaviour causes your application problems, set this to false. /// If you are interested in knowing when the mouse moves over the header, set this property to true (the default). /// [Category("ObjectListView"), Description("Should moving the mouse over the header trigger CellOver events?"), DefaultValue(true)] public bool TriggerCellOverEventsWhenOverHeader { get { return triggerCellOverEventsWhenOverHeader; } set { triggerCellOverEventsWhenOverHeader = value; } } private bool triggerCellOverEventsWhenOverHeader = true; /// /// When resizing a column by dragging its divider, should any space filling columns be /// resized at each mouse move? If this is false, the filling columns will be /// updated when the mouse is released. /// /// /// /// If you have a space filling column /// is in the left of the column that is being resized, this will look odd: /// the right edge of the column will be dragged, but /// its left edge will move since the space filling column is shrinking. /// /// This is logical behaviour -- it just looks wrong. /// /// /// Given the above behavior is probably best to turn this property off if your space filling /// columns aren't the right-most columns. /// [Category("ObjectListView"), Description("When resizing a column by dragging its divider, should any space filling columns be resized at each mouse move?"), DefaultValue(true)] public virtual bool UpdateSpaceFillingColumnsWhenDraggingColumnDivider { get { return updateSpaceFillingColumnsWhenDraggingColumnDivider; } set { updateSpaceFillingColumnsWhenDraggingColumnDivider = value; } } private bool updateSpaceFillingColumnsWhenDraggingColumnDivider = true; /// /// What color should be used for the background of selected rows when the control doesn't have the focus? /// [Category("ObjectListView"), Description("The background color of selected rows when the control doesn't have the focus"), DefaultValue(typeof(Color), "")] public virtual Color UnfocusedSelectedBackColor { get { return unfocusedSelectedBackColor; } set { unfocusedSelectedBackColor = value; } } private Color unfocusedSelectedBackColor = Color.Empty; /// /// Return the color should be used for the background of selected rows when the control doesn't have the focus or a reasonable default /// [Browsable(false)] public virtual Color UnfocusedSelectedBackColorOrDefault { get { return UnfocusedSelectedBackColor.IsEmpty ? SystemColors.Control : UnfocusedSelectedBackColor; } } /// /// What color should be used for the foreground of selected rows when the control doesn't have the focus? /// [Category("ObjectListView"), Description("The foreground color of selected rows when the control is owner drawn and doesn't have the focus"), DefaultValue(typeof(Color), "")] public virtual Color UnfocusedSelectedForeColor { get { return unfocusedSelectedForeColor; } set { unfocusedSelectedForeColor = value; } } private Color unfocusedSelectedForeColor = Color.Empty; /// /// Return the color should be used for the foreground of selected rows when the control doesn't have the focus or a reasonable default /// [Browsable(false)] public virtual Color UnfocusedSelectedForeColorOrDefault { get { return UnfocusedSelectedForeColor.IsEmpty ? SystemColors.ControlText : UnfocusedSelectedForeColor; } } /// /// Gets or sets whether the list give a different background color to every second row? Defaults to false. /// /// The color of the alternate rows is given by AlternateRowBackColor. /// There is a "feature" in .NET for listviews in non-full-row-select mode, where /// selected rows are not drawn with their correct background color. [Category("ObjectListView"), Description("Should the list view use a different backcolor to alternate rows?"), DefaultValue(false)] public virtual bool UseAlternatingBackColors { get { return useAlternatingBackColors; } set { useAlternatingBackColors = value; } } private bool useAlternatingBackColors; /// /// Should FormatCell events be called for each cell in the control? /// /// /// In many situations, no cell level formatting is performed. ObjectListView /// can run somewhat faster if it does not trigger a format cell event for every cell /// unless it is required. So, by default, it does not raise an event for each cell. /// /// ObjectListView *does* raise a FormatRow event every time a row is rebuilt. /// Individual rows can decide whether to raise FormatCell /// events for every cell in row. /// /// /// Regardless of this setting, FormatCell events are only raised when the ObjectListView /// is in Details view. /// [Category("ObjectListView"), Description("Should FormatCell events be triggered to every cell that is built?"), DefaultValue(false)] public bool UseCellFormatEvents { get { return useCellFormatEvents; } set { useCellFormatEvents = value; } } private bool useCellFormatEvents; /// /// Should the selected row be drawn with non-standard foreground and background colors? /// /// v2.9 This property is no longer required [Category("ObjectListView"), Description("Should the selected row be drawn with non-standard foreground and background colors?"), DefaultValue(false)] public bool UseCustomSelectionColors { get { return false; } // ReSharper disable once ValueParameterNotUsed set { } } /// /// Gets or sets whether this ObjectListView will use the same hot item and selection /// mechanism that Vista Explorer does. /// /// /// /// This property has many imperfections: /// /// This only works on Vista and later /// It does not work well with AlternateRowBackColors. /// It does not play well with HotItemStyles. /// It looks a little bit silly is FullRowSelect is false. /// It doesn't work at all when the list is owner drawn (since the renderers /// do all the drawing). As such, it won't work with TreeListView's since they *have to be* /// owner drawn. You can still set it, but it's just not going to be happy. /// /// But if you absolutely have to look like Vista/Win7, this is your property. /// Do not complain if settings this messes up other things. /// /// /// When this property is set to true, the ObjectListView will be not owner drawn. This will /// disable many of the pretty drawing-based features of ObjectListView. /// /// [Category("ObjectListView"), Description("Should the list use the same hot item and selection mechanism as Vista?"), DefaultValue(false)] public bool UseExplorerTheme { get { return useExplorerTheme; } set { useExplorerTheme = value; if (Created) NativeMethods.SetWindowTheme(Handle, value ? "explorer" : "", null); OwnerDraw = !value; } } private bool useExplorerTheme; /// /// Gets or sets whether the list should enable filtering /// [Category("ObjectListView"), Description("Should the list enable filtering?"), DefaultValue(false)] public virtual bool UseFiltering { get { return useFiltering; } set { if (useFiltering == value) return; useFiltering = value; UpdateFiltering(); } } private bool useFiltering; /// /// Gets or sets whether the list should put an indicator into a column's header to show that /// it is filtering on that column /// /// If you set this to true, HeaderUsesThemes is automatically set to false, since /// we can only draw a filter indicator when not using a themed header. [Category("ObjectListView"), Description("Should an image be drawn in a column's header when that column is being used for filtering?"), DefaultValue(false)] public virtual bool UseFilterIndicator { get { return useFilterIndicator; } set { if (useFilterIndicator == value) return; useFilterIndicator = value; if (useFilterIndicator) HeaderUsesThemes = false; Invalidate(); } } private bool useFilterIndicator; /// /// Should controls (checkboxes or buttons) that are under the mouse be drawn "hot"? /// /// /// If this is false, control will not be drawn differently when the mouse is over them. /// /// If this is false AND UseHotItem is false AND UseHyperlinks is false, then the ObjectListView /// can skip some processing on mouse move. This make mouse move processing use almost no CPU. /// /// [Category("ObjectListView"), Description("Should controls (checkboxes or buttons) that are under the mouse be drawn hot?"), DefaultValue(true)] public bool UseHotControls { get { return useHotControls; } set { useHotControls = value; } } private bool useHotControls = true; /// /// Should the item under the cursor be formatted in a special way? /// [Category("ObjectListView"), Description("Should HotTracking be used? Hot tracking applies special formatting to the row under the cursor"), DefaultValue(false)] public bool UseHotItem { get { return useHotItem; } set { useHotItem = value; if (value) AddOverlay(HotItemStyleOrDefault.Overlay); else RemoveOverlay(HotItemStyleOrDefault.Overlay); } } private bool useHotItem; /// /// Gets or sets whether this listview should show hyperlinks in the cells. /// [Category("ObjectListView"), Description("Should hyperlinks be shown on this control?"), DefaultValue(false)] public bool UseHyperlinks { get { return useHyperlinks; } set { useHyperlinks = value; if (value && HyperlinkStyle == null) HyperlinkStyle = new HyperlinkStyle(); } } private bool useHyperlinks; /// /// Should this control show overlays /// /// Overlays are enabled by default and would only need to be disabled /// if they were causing problems in your development environment. [Category("ObjectListView"), Description("Should this control show overlays"), DefaultValue(true)] public bool UseOverlays { get { return useOverlays; } set { useOverlays = value; } } private bool useOverlays = true; /// /// Should this control be configured to show check boxes on subitems? /// /// If this is set to True, the control will be given a SmallImageList if it /// doesn't already have one. Also, if it is a virtual list, it will be set to owner /// drawn, since virtual lists can't draw check boxes without being owner drawn. [Category("ObjectListView"), Description("Should this control be configured to show check boxes on subitems."), DefaultValue(false)] public bool UseSubItemCheckBoxes { get { return useSubItemCheckBoxes; } set { useSubItemCheckBoxes = value; if (value) SetupSubItemCheckBoxes(); } } private bool useSubItemCheckBoxes; /// /// Gets or sets if the ObjectListView will use a translucent selection mechanism like Vista. /// /// /// /// Unlike UseExplorerTheme, this Vista-like scheme works on XP and for both /// owner and non-owner drawn lists. /// /// /// This will replace any SelectedRowDecoration that has been installed. /// /// /// If you don't like the colours used for the selection, ignore this property and /// just create your own RowBorderDecoration and assigned it to SelectedRowDecoration, /// just like this property setter does. /// /// [Category("ObjectListView"), Description("Should the list use a translucent selection mechanism (like Vista)"), DefaultValue(false)] public bool UseTranslucentSelection { get { return useTranslucentSelection; } set { useTranslucentSelection = value; if (value) { RowBorderDecoration rbd = new RowBorderDecoration(); rbd.BorderPen = new Pen(Color.FromArgb(154, 223, 251)); rbd.FillBrush = new SolidBrush(Color.FromArgb(48, 163, 217, 225)); rbd.BoundsPadding = new Size(0, 0); rbd.CornerRounding = 6.0f; SelectedRowDecoration = rbd; } else SelectedRowDecoration = null; } } private bool useTranslucentSelection; /// /// Gets or sets if the ObjectListView will use a translucent hot row highlighting mechanism like Vista. /// /// /// /// Setting this will replace any HotItemStyle that has been installed. /// /// /// If you don't like the colours used for the hot item, ignore this property and /// just create your own HotItemStyle, fill in the values you want, and assigned it to HotItemStyle property, /// just like this property setter does. /// /// [Category("ObjectListView"), Description("Should the list use a translucent hot row highlighting mechanism (like Vista)"), DefaultValue(false)] public bool UseTranslucentHotItem { get { return useTranslucentHotItem; } set { useTranslucentHotItem = value; if (value) { RowBorderDecoration rbd = new RowBorderDecoration(); rbd.BorderPen = new Pen(Color.FromArgb(154, 223, 251)); rbd.BoundsPadding = new Size(0, 0); rbd.CornerRounding = 6.0f; rbd.FillGradientFrom = Color.FromArgb(0, 255, 255, 255); rbd.FillGradientTo = Color.FromArgb(64, 183, 237, 240); HotItemStyle his = new HotItemStyle(); his.Decoration = rbd; HotItemStyle = his; } else HotItemStyle = null; UseHotItem = value; } } private bool useTranslucentHotItem; /// /// Get/set the style of view that this listview is using /// /// Switching to tile or details view installs the columns appropriate to that view. /// Confusingly, in tile view, every column is shown as a row of information. [Category("Appearance"), Description("Select the layout of the items within this control)"), DefaultValue(null)] public new View View { get { return base.View; } set { if (base.View == value) return; if (Frozen) { base.View = value; SetupBaseImageList(); } else { Freeze(); if (value == View.Tile) CalculateReasonableTileSize(); base.View = value; SetupBaseImageList(); Unfreeze(); } } } #endregion #region Callbacks /// /// This delegate fetches the checkedness of an object as a boolean only. /// /// Use this if you never want to worry about the /// Indeterminate state (which is fairly common). /// /// This is a convenience wrapper around the CheckStateGetter property. /// /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual BooleanCheckStateGetterDelegate BooleanCheckStateGetter { set { if (value == null) CheckStateGetter = null; else CheckStateGetter = delegate (Object x) { return value(x) ? CheckState.Checked : CheckState.Unchecked; }; } } /// /// This delegate sets the checkedness of an object as a boolean only. It must return /// true or false indicating if the object was checked or not. /// /// Use this if you never want to worry about the /// Indeterminate state (which is fairly common). /// /// This is a convenience wrapper around the CheckStatePutter property. /// /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual BooleanCheckStatePutterDelegate BooleanCheckStatePutter { set { if (value == null) CheckStatePutter = null; else CheckStatePutter = delegate (Object x, CheckState state) { bool isChecked = (state == CheckState.Checked); return value(x, isChecked) ? CheckState.Checked : CheckState.Unchecked; }; } } /// /// Gets whether or not this listview is capabale of showing groups /// [Browsable(false)] public virtual bool CanShowGroups { get { return true; } } /// /// Gets or sets whether ObjectListView can rely on Application.Idle events /// being raised. /// /// In some host environments (e.g. when running as an extension within /// VisualStudio and possibly Office), Application.Idle events are never raised. /// Set this to false when Idle events will not be raised, and ObjectListView will /// raise those events itself. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual bool CanUseApplicationIdle { get { return canUseApplicationIdle; } set { canUseApplicationIdle = value; } } private bool canUseApplicationIdle = true; /// /// This delegate fetches the renderer for a particular cell. /// /// /// /// If this returns null (or is not installed), the renderer for the column will be used. /// If the column renderer is null, then will be used. /// /// /// This is called every time any cell is drawn. It must be efficient! /// /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual CellRendererGetterDelegate CellRendererGetter { get { return cellRendererGetter; } set { cellRendererGetter = value; } } private CellRendererGetterDelegate cellRendererGetter; /// /// This delegate is called when the list wants to show a tooltip for a particular cell. /// The delegate should return the text to display, or null to use the default behavior /// (which is to show the full text of truncated cell values). /// /// /// Displaying the full text of truncated cell values only work for FullRowSelect listviews. /// This is MS's behavior, not mine. Don't complain to me :) /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual CellToolTipGetterDelegate CellToolTipGetter { get { return cellToolTipGetter; } set { cellToolTipGetter = value; } } private CellToolTipGetterDelegate cellToolTipGetter; /// /// The name of the property (or field) that holds whether or not a model is checked. /// /// /// The property be modifiable. It must have a return type of bool (or of bool? if /// TriStateCheckBoxes is true). /// Setting this property replaces any CheckStateGetter or CheckStatePutter that have been installed. /// Conversely, later setting the CheckStateGetter or CheckStatePutter properties will take precedence /// over the behavior of this property. /// [Category("ObjectListView"), Description("The name of the property or field that holds the 'checkedness' of the model"), DefaultValue(null)] public virtual string CheckedAspectName { get { return checkedAspectName; } set { checkedAspectName = value; if (String.IsNullOrEmpty(checkedAspectName)) { checkedAspectMunger = null; CheckStateGetter = null; CheckStatePutter = null; } else { checkedAspectMunger = new Munger(checkedAspectName); CheckStateGetter = delegate (Object modelObject) { if (checkedAspectMunger.GetValue(modelObject) is bool result) return result ? CheckState.Checked : CheckState.Unchecked; return TriStateCheckBoxes ? CheckState.Indeterminate : CheckState.Unchecked; }; CheckStatePutter = delegate (Object modelObject, CheckState newValue) { if (TriStateCheckBoxes && newValue == CheckState.Indeterminate) checkedAspectMunger.PutValue(modelObject, null); else checkedAspectMunger.PutValue(modelObject, newValue == CheckState.Checked); return CheckStateGetter(modelObject); }; } } } private string checkedAspectName; private Munger checkedAspectMunger; /// /// This delegate will be called whenever the ObjectListView needs to know the check state /// of the row associated with a given model object. /// /// /// .NET has no support for indeterminate values, but as of v2.0, this class allows /// indeterminate values. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual CheckStateGetterDelegate CheckStateGetter { get { return checkStateGetter; } set { checkStateGetter = value; } } private CheckStateGetterDelegate checkStateGetter; /// /// This delegate will be called whenever the user tries to change the check state of a row. /// The delegate should return the state that was actually set, which may be different /// to the state given. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual CheckStatePutterDelegate CheckStatePutter { get { return checkStatePutter; } set { checkStatePutter = value; } } private CheckStatePutterDelegate checkStatePutter; /// /// This delegate can be used to sort the table in a custom fasion. /// /// /// /// The delegate must install a ListViewItemSorter on the ObjectListView. /// Installing the ItemSorter does the actual work of sorting the ListViewItems. /// See ColumnComparer in the code for an example of what an ItemSorter has to do. /// /// /// Do not install a CustomSorter on a VirtualObjectListView. Override the SortObjects() /// method of the IVirtualListDataSource instead. /// /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual SortDelegate CustomSorter { get { return customSorter; } set { customSorter = value; } } private SortDelegate customSorter; /// /// This delegate is called when the list wants to show a tooltip for a particular header. /// The delegate should return the text to display, or null to use the default behavior /// (which is to not show any tooltip). /// /// /// Installing a HeaderToolTipGetter takes precedence over any text in OLVColumn.ToolTipText. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual HeaderToolTipGetterDelegate HeaderToolTipGetter { get { return headerToolTipGetter; } set { headerToolTipGetter = value; } } private HeaderToolTipGetterDelegate headerToolTipGetter; /// /// This delegate can be used to format a OLVListItem before it is added to the control. /// /// /// The model object for the row can be found through the RowObject property of the OLVListItem object. /// All subitems normally have the same style as list item, so setting the forecolor on one /// subitem changes the forecolor of all subitems. /// To allow subitems to have different attributes, do this: /// myListViewItem.UseItemStyleForSubItems = false;. /// /// If UseAlternatingBackColors is true, the backcolor of the listitem will be calculated /// by the control and cannot be controlled by the RowFormatter delegate. /// In general, trying to use a RowFormatter /// when UseAlternatingBackColors is true does not work well. /// As it says in the summary, this is called before the item is added to the control. /// Many properties of the OLVListItem itself are not available at that point, including: /// Index, Selected, Focused, Bounds, Checked, DisplayIndex. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual RowFormatterDelegate RowFormatter { get { return rowFormatter; } set { rowFormatter = value; } } private RowFormatterDelegate rowFormatter; #endregion #region List commands /// /// Add the given model object to this control. /// /// The model object to be displayed /// See AddObjects() for more details public virtual void AddObject(object modelObject) { if (InvokeRequired) Invoke((MethodInvoker)delegate () { AddObject(modelObject); }); else AddObjects(new object[] { modelObject }); } /// /// Add the given collection of model objects to this control. /// /// A collection of model objects /// /// The added objects will appear in their correct sort position, if sorting /// is active (i.e. if PrimarySortColumn is not null). Otherwise, they will appear at the end of the list. /// No check is performed to see if any of the objects are already in the ListView. /// Null objects are silently ignored. /// public virtual void AddObjects(ICollection modelObjects) { if (InvokeRequired) { Invoke((MethodInvoker)delegate () { AddObjects(modelObjects); }); return; } InsertObjects(EnumerableCount(Objects), modelObjects); Sort(PrimarySortColumn, PrimarySortOrder); } /// /// Resize the columns to the maximum of the header width and the data. /// public virtual void AutoResizeColumns() { foreach (OLVColumn c in Columns) { AutoResizeColumn(c.Index, ColumnHeaderAutoResizeStyle.HeaderSize); } } /// /// Set up any automatically initialized column widths (columns that /// have a width of 0 or -1 will be resized to the width of their /// contents or header respectively). /// /// /// Obviously, this will only work once. Once it runs, the columns widths will /// be changed to something else (other than 0 or -1), so it wont do anything the /// second time through. Use to force all columns /// to change their size. /// public virtual void AutoSizeColumns() { // If we are supposed to resize to content, but if there is no content, // resize to the header size instead. ColumnHeaderAutoResizeStyle resizeToContentStyle = GetItemCount() == 0 ? ColumnHeaderAutoResizeStyle.HeaderSize : ColumnHeaderAutoResizeStyle.ColumnContent; foreach (ColumnHeader column in Columns) { switch (column.Width) { case 0: AutoResizeColumn(column.Index, resizeToContentStyle); break; case -1: AutoResizeColumn(column.Index, ColumnHeaderAutoResizeStyle.HeaderSize); break; } } } /// /// Organise the view items into groups, based on the last sort column or the first column /// if there is no last sort column /// public virtual void BuildGroups() { BuildGroups(PrimarySortColumn, PrimarySortOrder == SortOrder.None ? SortOrder.Ascending : PrimarySortOrder); } /// /// Organise the view items into groups, based on the given column /// /// /// /// If the AlwaysGroupByColumn property is not null, /// the list view items will be organisd by that column, /// and the 'column' parameter will be ignored. /// /// This method triggers sorting events: BeforeSorting and AfterSorting. /// /// The column whose values should be used for sorting. /// public virtual void BuildGroups(OLVColumn column, SortOrder order) { // Sanity if (GetItemCount() == 0 || Columns.Count == 0) return; BeforeSortingEventArgs args = BuildBeforeSortingEventArgs(column, order); OnBeforeSorting(args); if (args.Canceled) return; BuildGroups(args.ColumnToGroupBy, args.GroupByOrder, args.ColumnToSort, args.SortOrder, args.SecondaryColumnToSort, args.SecondarySortOrder); OnAfterSorting(new AfterSortingEventArgs(args)); } private BeforeSortingEventArgs BuildBeforeSortingEventArgs(OLVColumn column, SortOrder order) { OLVColumn groupBy = AlwaysGroupByColumn ?? column ?? GetColumn(0); SortOrder groupByOrder = AlwaysGroupBySortOrder; if (order == SortOrder.None) { order = Sorting; if (order == SortOrder.None) order = SortOrder.Ascending; } if (groupByOrder == SortOrder.None) groupByOrder = order; BeforeSortingEventArgs args = new BeforeSortingEventArgs( groupBy, groupByOrder, column, order, SecondarySortColumn ?? GetColumn(0), SecondarySortOrder == SortOrder.None ? order : SecondarySortOrder); if (column != null) args.Canceled = !column.Sortable; return args; } /// /// Organise the view items into groups, based on the given columns /// /// What column will be used for grouping /// What ordering will be used for groups /// The column whose values should be used for sorting. Cannot be null /// The order in which the values from column will be sorted /// When the values from 'column' are equal, use the values provided by this column /// How will the secondary values be sorted /// This method does not trigger sorting events. Use BuildGroups() to do that public virtual void BuildGroups(OLVColumn groupByColumn, SortOrder groupByOrder, OLVColumn column, SortOrder order, OLVColumn secondaryColumn, SortOrder secondaryOrder) { // Sanity checks if (groupByColumn == null) return; // Getting the Count forces any internal cache of the ListView to be flushed. Without // this, iterating over the Items will not work correctly if the ListView handle // has not yet been created. #pragma warning disable 168 // ReSharper disable once UnusedVariable int dummy = Items.Count; #pragma warning restore 168 // Collect all the information that governs the creation of groups GroupingParameters parms = CollectGroupingParameters(groupByColumn, groupByOrder, column, order, secondaryColumn, secondaryOrder); // Trigger an event to let the world create groups if they want CreateGroupsEventArgs args = new CreateGroupsEventArgs(parms); if (parms.GroupByColumn != null) args.Canceled = !parms.GroupByColumn.Groupable; OnBeforeCreatingGroups(args); if (args.Canceled) return; // If the event didn't create them for us, use our default strategy if (args.Groups == null) args.Groups = MakeGroups(parms); // Give the world a chance to munge the groups before they are created OnAboutToCreateGroups(args); if (args.Canceled) return; // Create the groups now OLVGroups = args.Groups; CreateGroups(args.Groups); // Tell the world that new groups have been created OnAfterCreatingGroups(args); lastGroupingParameters = args.Parameters; } private GroupingParameters lastGroupingParameters; /// /// Collect and return all the variables that influence the creation of groups /// /// protected virtual GroupingParameters CollectGroupingParameters(OLVColumn groupByColumn, SortOrder groupByOrder, OLVColumn sortByColumn, SortOrder sortByOrder, OLVColumn secondaryColumn, SortOrder secondaryOrder) { // If the user tries to group by a non-groupable column, keep the current group by // settings, but use the non-groupable column for sorting if (!groupByColumn.Groupable && lastGroupingParameters != null) { sortByColumn = groupByColumn; sortByOrder = groupByOrder; groupByColumn = lastGroupingParameters.GroupByColumn; groupByOrder = lastGroupingParameters.GroupByOrder; } string titleFormat = ShowItemCountOnGroups ? groupByColumn.GroupWithItemCountFormatOrDefault : null; string titleSingularFormat = ShowItemCountOnGroups ? groupByColumn.GroupWithItemCountSingularFormatOrDefault : null; GroupingParameters parms = new GroupingParameters(this, groupByColumn, groupByOrder, sortByColumn, sortByOrder, secondaryColumn, secondaryOrder, titleFormat, titleSingularFormat, SortGroupItemsByPrimaryColumn); return parms; } /// /// Make a list of groups that should be shown according to the given parameters /// /// /// The list of groups to be created /// This should not change the state of the control. It is possible that the /// groups created will not be used. They may simply be discarded. protected virtual IList MakeGroups(GroupingParameters parms) { // There is a lot of overlap between this method and FastListGroupingStrategy.MakeGroups() // Any changes made here may need to be reflected there // Separate the list view items into groups, using the group key as the descrimanent NullableDictionary> map = new NullableDictionary>(); foreach (OLVListItem olvi in parms.ListView.Items) { object key = parms.GroupByColumn.GetGroupKey(olvi.RowObject); if (!map.ContainsKey(key)) map[key] = new List(); map[key].Add(olvi); } // Sort the items within each group (unless specifically turned off) OLVColumn sortColumn = parms.SortItemsByPrimaryColumn ? parms.ListView.GetColumn(0) : parms.PrimarySort; if (sortColumn != null && parms.PrimarySortOrder != SortOrder.None) { IComparer itemSorter = parms.ItemComparer ?? new ColumnComparer(sortColumn, parms.PrimarySortOrder, parms.SecondarySort, parms.SecondarySortOrder); foreach (object key in map.Keys) { map[key].Sort(itemSorter); } } // Make a list of the required groups List groups = new List(); foreach (object key in map.Keys) { string title = parms.GroupByColumn.ConvertGroupKeyToTitle(key); if (!String.IsNullOrEmpty(parms.TitleFormat)) { int count = map[key].Count; string format = (count == 1 ? parms.TitleSingularFormat : parms.TitleFormat); try { title = String.Format(format, title, count); } catch (FormatException) { title = "Invalid group format: " + format; } } OLVGroup lvg = new OLVGroup(title); lvg.Collapsible = HasCollapsibleGroups; lvg.Key = key; lvg.SortValue = key as IComparable; lvg.Items = map[key]; if (parms.GroupByColumn.GroupFormatter != null) parms.GroupByColumn.GroupFormatter(lvg, parms); groups.Add(lvg); } // Sort the groups if (parms.GroupByOrder != SortOrder.None) groups.Sort(parms.GroupComparer ?? new OLVGroupComparer(parms.GroupByOrder)); return groups; } /// /// Build/rebuild all the list view items in the list, preserving as much state as is possible /// public virtual void BuildList() { if (InvokeRequired) Invoke(new MethodInvoker(BuildList)); else BuildList(true); } private readonly Dictionary _listItemLookup = new(); /// /// Build/rebuild all the list view items in the list /// /// If this is true, the control will try to preserve the selection, /// focused item, and the scroll position (see Remarks) /// /// /// /// Use this method in situations were the contents of the list is basically the same /// as previously. /// /// public virtual void BuildList(bool shouldPreserveState) { if (Frozen || IsDisposed || Disposing) return; //Stopwatch sw = Stopwatch.StartNew(); try { ApplyExtendedStyles(); ClearHotItem(); int previousTopIndex = TopItemIndex; Point currentScrollPosition = LowLevelScrollPosition; IList previousSelection = new ArrayList(); Object previousFocus = null; if (shouldPreserveState && objects != null) { previousSelection = SelectedObjects; if (FocusedItem is OLVListItem focusedItem) previousFocus = focusedItem.RowObject; } IEnumerable objectsToDisplay = FilteredObjects; BeginUpdate(); try { _listItemLookup.Clear(); Items.Clear(); ListViewItemSorter = null; if (objectsToDisplay != null) { // Build a list of all our items and then display them. (Building // a list and then doing one AddRange is about 10-15% faster than individual adds) List itemList = new List(); // use ListViewItem to avoid co-variant conversion foreach (object rowObject in objectsToDisplay) { OLVListItem lvi = new OLVListItem(rowObject); FillInValues(lvi, rowObject); _listItemLookup.Add(rowObject, lvi); itemList.Add(lvi); } Items.AddRange(itemList.ToArray()); Sort(); if (shouldPreserveState) { SelectedObjects = previousSelection; FocusedItem = ModelToItem(previousFocus); } } } finally { EndUpdate(); } RefreshHotItem(); // We can only restore the scroll position after the EndUpdate() because // of caching that the ListView does internally during a BeginUpdate/EndUpdate pair. if (shouldPreserveState) { // Restore the scroll position. TopItemIndex is best, but doesn't work // when the control is grouped. if (ShowGroups) LowLevelScroll(currentScrollPosition.X, currentScrollPosition.Y); else TopItemIndex = previousTopIndex; } } catch (ObjectDisposedException) { } // System.Diagnostics.Debug.WriteLine(String.Format("PERF - Building list for {2} objects took {0}ms / {1} ticks", sw.ElapsedMilliseconds, sw.ElapsedTicks, this.GetItemCount())); } /// /// Clear any cached info this list may have been using /// public virtual void ClearCachedInfo() { // ObjectListView doesn't currently cache information but subclass do (or might) } /// /// Apply all required extended styles to our control. /// /// /// /// Whenever .NET code sets an extended style, it erases all other extended styles /// that it doesn't use. So, we have to explicit reapply the styles that we have /// added. /// /// /// Normally, we would override CreateParms property and update /// the ExStyle member, but ListView seems to ignore all ExStyles that /// it doesn't already know about. Worse, when we set the LVS_EX_HEADERINALLVIEWS /// value, bad things happen (the control crashes!). /// /// protected virtual void ApplyExtendedStyles() { const int LVS_EX_SUBITEMIMAGES = 0x00000002; //const int LVS_EX_TRANSPARENTBKGND = 0x00400000; const int LVS_EX_HEADERINALLVIEWS = 0x02000000; const int STYLE_MASK = LVS_EX_SUBITEMIMAGES | LVS_EX_HEADERINALLVIEWS; int style = 0; if (ShowImagesOnSubItems && !VirtualMode) style ^= LVS_EX_SUBITEMIMAGES; if (ShowHeaderInAllViews) style ^= LVS_EX_HEADERINALLVIEWS; NativeMethods.SetExtendedStyle(this, style, STYLE_MASK); } /// /// Give the listview a reasonable size of its tiles, based on the number of lines of /// information that each tile is going to display. /// public virtual void CalculateReasonableTileSize() { if (Columns.Count <= 0) return; List columns = AllColumns.FindAll(delegate (OLVColumn x) { return (x.Index == 0) || x.IsTileViewColumn; }); int imageHeight = (LargeImageList == null ? 16 : LargeImageList.ImageSize.Height); int dataHeight = (Font.Height + 1) * columns.Count; int tileWidth = (TileSize.Width == 0 ? 200 : TileSize.Width); int tileHeight = Math.Max(TileSize.Height, Math.Max(imageHeight, dataHeight)); TileSize = new Size(tileWidth, tileHeight); } /// /// Rebuild this list for the given view /// /// public virtual void ChangeToFilteredColumns(View view) { // Store the state SuspendSelectionEvents(); IList previousSelection = SelectedObjects; int previousTopIndex = TopItemIndex; Freeze(); Clear(); List columns = GetFilteredColumns(view); if (view == View.Details || ShowHeaderInAllViews) { // Make sure all columns have a reasonable LastDisplayIndex for (int index = 0; index < columns.Count; index++) { if (columns[index].LastDisplayIndex == -1) columns[index].LastDisplayIndex = index; } // ListView will ignore DisplayIndex FOR ALL COLUMNS if there are any errors, // e.g. duplicates (two columns with the same DisplayIndex) or gaps. // LastDisplayIndex isn't guaranteed to be unique, so we just sort the columns by // the last position they were displayed and use that to generate a sequence // we can use for the DisplayIndex values. List columnsInDisplayOrder = new List(columns); columnsInDisplayOrder.Sort(delegate (OLVColumn x, OLVColumn y) { return (x.LastDisplayIndex - y.LastDisplayIndex); }); int i = 0; foreach (OLVColumn col in columnsInDisplayOrder) col.DisplayIndex = i++; } // ReSharper disable once CoVariantArrayConversion Columns.AddRange(columns.ToArray()); if (view == View.Details || ShowHeaderInAllViews) ShowSortIndicator(); UpdateFiltering(); Unfreeze(); // Restore the state SelectedObjects = previousSelection; TopItemIndex = previousTopIndex; ResumeSelectionEvents(); } /// /// Remove all items from this list /// /// This method can safely be called from background threads. public virtual void ClearObjects() { if (InvokeRequired) Invoke(new MethodInvoker(ClearObjects)); else SetObjects(null); } /// /// Reset the memory of which URLs have been visited /// public virtual void ClearUrlVisited() { visitedUrlMap = new Dictionary(); } /// /// Copy a text and html representation of the selected rows onto the clipboard. /// /// Be careful when using this with virtual lists. If the user has selected /// 10,000,000 rows, this method will faithfully try to copy all of them to the clipboard. /// From the user's point of view, your program will appear to have hung. public virtual void CopySelectionToClipboard() { IList selection = SelectedObjects; if (selection.Count == 0) return; // Use the DragSource object to create the data object, if so configured. // This relies on the assumption that DragSource will handle the selected objects only. // It is legal for StartDrag to return null. object data = null; if (CopySelectionOnControlCUsesDragSource && DragSource != null) data = DragSource.StartDrag(this, MouseButtons.Left, ModelToItem(selection[0])); Clipboard.SetDataObject(data ?? new OLVDataObject(this, selection)); } /// /// Copy a text and html representation of the given objects onto the clipboard. /// public virtual void CopyObjectsToClipboard(IList objectsToCopy) { if (objectsToCopy.Count == 0) return; // We don't know where these objects came from, so we can't use the DragSource to create // the data object, like we do with CopySelectionToClipboard() above. OLVDataObject dataObject = new OLVDataObject(this, objectsToCopy); dataObject.CreateTextFormats(); Clipboard.SetDataObject(dataObject); } /// /// Return a html representation of the given objects /// public virtual string ObjectsToHtml(IList objectsToConvert) { if (objectsToConvert.Count == 0) return String.Empty; OLVExporter exporter = new OLVExporter(this, objectsToConvert); return exporter.ExportTo(OLVExporter.ExportFormat.HTML); } /// /// Deselect all rows in the listview /// public virtual void DeselectAll() { NativeMethods.DeselectAllItems(this); } /// /// Return the ListViewItem that appears immediately after the given item. /// If the given item is null, the first item in the list will be returned. /// Return null if the given item is the last item. /// /// The item that is before the item that is returned, or null /// A ListViewItem public virtual OLVListItem GetNextItem(OLVListItem itemToFind) { if (ShowGroups) { bool isFound = (itemToFind == null); foreach (ListViewGroup group in Groups) { foreach (OLVListItem olvi in group.Items) { if (isFound) return olvi; isFound = (itemToFind == olvi); } } return null; } if (GetItemCount() == 0) return null; if (itemToFind == null) return GetItem(0); if (itemToFind.Index == GetItemCount() - 1) return null; return GetItem(itemToFind.Index + 1); } /// /// Return the last item in the order they are shown to the user. /// If the control is not grouped, the display order is the same as the /// sorted list order. But if the list is grouped, the display order is different. /// /// public virtual OLVListItem GetLastItemInDisplayOrder() { if (!ShowGroups) return GetItem(GetItemCount() - 1); if (Groups.Count > 0) { ListViewGroup lastGroup = Groups[Groups.Count - 1]; if (lastGroup.Items.Count > 0) return (OLVListItem)lastGroup.Items[lastGroup.Items.Count - 1]; } return null; } /// /// Return the n'th item (0-based) in the order they are shown to the user. /// If the control is not grouped, the display order is the same as the /// sorted list order. But if the list is grouped, the display order is different. /// /// /// public virtual OLVListItem GetNthItemInDisplayOrder(int n) { if (!ShowGroups || Groups.Count == 0) return GetItem(n); foreach (ListViewGroup group in Groups) { if (n < group.Items.Count) return (OLVListItem)group.Items[n]; n -= group.Items.Count; } return null; } /// /// Return the display index of the given listviewitem index. /// If the control is not grouped, the display order is the same as the /// sorted list order. But if the list is grouped, the display order is different. /// /// /// public virtual int GetDisplayOrderOfItemIndex(int itemIndex) { if (!ShowGroups || Groups.Count == 0) return itemIndex; // TODO: This could be optimized int i = 0; foreach (ListViewGroup lvg in Groups) { foreach (ListViewItem lvi in lvg.Items) { if (lvi.Index == itemIndex) return i; i++; } } return -1; } private int GetDisplayOrderOfItemIndex(ListViewItem listViewItem) { if (!ShowGroups || Groups.Count == 0) return listViewItem.Index; int i = 0; foreach (ListViewGroup lvg in Groups) { foreach (ListViewItem lvi in lvg.Items) { if (lvi == listViewItem) return i; i++; } } return -1; } /// /// Return the ListViewItem that appears immediately before the given item. /// If the given item is null, the last item in the list will be returned. /// Return null if the given item is the first item. /// /// The item that is before the item that is returned /// A ListViewItem public virtual OLVListItem GetPreviousItem(OLVListItem itemToFind) { if (ShowGroups) { OLVListItem previousItem = null; foreach (ListViewGroup group in Groups) { foreach (OLVListItem lvi in group.Items) { if (lvi == itemToFind) return previousItem; previousItem = lvi; } } return itemToFind == null ? previousItem : null; } if (GetItemCount() == 0) return null; if (itemToFind == null) return GetItem(GetItemCount() - 1); if (itemToFind.Index == 0) return null; return GetItem(itemToFind.Index - 1); } /// /// Insert the given collection of objects before the given position /// /// Where to insert the objects /// The objects to be inserted /// /// /// This operation only makes sense of non-sorted, non-grouped /// lists, since any subsequent sort/group operation will rearrange /// the list. /// /// This method only works on ObjectListViews and FastObjectListViews. /// public virtual void InsertObjects(int index, ICollection modelObjects) { if (InvokeRequired) { Invoke((MethodInvoker)delegate () { InsertObjects(index, modelObjects); }); return; } if (modelObjects == null) return; BeginUpdate(); try { // Give the world a chance to cancel or change the added objects ItemsAddingEventArgs args = new ItemsAddingEventArgs(modelObjects); OnItemsAdding(args); if (args.Canceled) return; modelObjects = args.ObjectsToAdd; TakeOwnershipOfObjects(); ArrayList ourObjects = EnumerableToArray(Objects, false); // If we are filtering the list, there is no way to efficiently // insert the objects, so just put them into our collection and rebuild. if (IsFiltering) { index = Math.Max(0, Math.Min(index, ourObjects.Count)); ourObjects.InsertRange(index, modelObjects); BuildList(true); } else { ListViewItemSorter = null; index = Math.Max(0, Math.Min(index, GetItemCount())); int i = index; foreach (object modelObject in modelObjects) { if (modelObject != null) { ourObjects.Insert(i, modelObject); OLVListItem lvi = new OLVListItem(modelObject); FillInValues(lvi, modelObject); Items.Insert(i, lvi); i++; } } for (i = index; i < GetItemCount(); i++) { OLVListItem lvi = GetItem(i); SetSubItemImages(lvi.Index, lvi); } PostProcessRows(); } // Tell the world that the list has changed SubscribeNotifications(modelObjects); OnItemsChanged(new ItemsChangedEventArgs()); } finally { EndUpdate(); } } /// /// Return true if the row representing the given model is selected /// /// The model object to look for /// Is the row selected public bool IsSelected(object model) { OLVListItem item = ModelToItem(model); return item != null && item.Selected; } /// /// Has the given URL been visited? /// /// The string to be consider /// Has it been visited public virtual bool IsUrlVisited(string url) { return visitedUrlMap.ContainsKey(url); } /// /// Scroll the ListView by the given deltas. /// /// Horizontal delta /// Vertical delta public void LowLevelScroll(int dx, int dy) { NativeMethods.Scroll(this, dx, dy); } /// /// Return a point that represents the current horizontal and vertical scroll positions /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public Point LowLevelScrollPosition { get { return new Point(NativeMethods.GetScrollPosition(this, true), NativeMethods.GetScrollPosition(this, false)); } } /// /// Remember that the given URL has been visited /// /// The url to be remembered /// This does not cause the control be redrawn public virtual void MarkUrlVisited(string url) { visitedUrlMap[url] = true; } /// /// Move the given collection of objects to the given index. /// /// This operation only makes sense on non-grouped ObjectListViews. /// /// public virtual void MoveObjects(int index, ICollection modelObjects) { // We are going to remove all the given objects from our list // and then insert them at the given location TakeOwnershipOfObjects(); ArrayList ourObjects = EnumerableToArray(Objects, false); List indicesToRemove = new List(); foreach (object modelObject in modelObjects) { if (modelObject != null) { int i = IndexOf(modelObject); if (i >= 0) { indicesToRemove.Add(i); ourObjects.Remove(modelObject); if (i <= index) index--; } } } // Remove the objects in reverse order so earlier // deletes don't change the index of later ones indicesToRemove.Sort(); indicesToRemove.Reverse(); try { BeginUpdate(); foreach (int i in indicesToRemove) { Items.RemoveAt(i); } InsertObjects(index, modelObjects); } finally { EndUpdate(); } } /// /// Calculate what item is under the given point? /// /// /// /// public new ListViewHitTestInfo HitTest(int x, int y) { // Everything costs something. Playing with the layout of the header can cause problems // with the hit testing. If the header shrinks, the underlying control can throw a tantrum. try { return base.HitTest(x, y); } catch (ArgumentOutOfRangeException) { return new ListViewHitTestInfo(null, null, ListViewHitTestLocations.None); } } /// /// Perform a hit test using the Windows control's SUBITEMHITTEST message. /// This provides information about group hits that the standard ListView.HitTest() does not. /// /// /// /// protected OlvListViewHitTestInfo LowLevelHitTest(int x, int y) { // If it's not even in the control, don't bother with anything else if (!ClientRectangle.Contains(x, y)) return new OlvListViewHitTestInfo(null, null, 0, null, 0); // Is the point over the header? OlvListViewHitTestInfo.HeaderHitTestInfo headerHitTestInfo = HeaderControl.HitTest(x, y); if (headerHitTestInfo != null) return new OlvListViewHitTestInfo(this, headerHitTestInfo.ColumnIndex, headerHitTestInfo.IsOverCheckBox, headerHitTestInfo.OverDividerIndex); // Call the native hit test method, which is a little confusing. NativeMethods.LVHITTESTINFO lParam = new NativeMethods.LVHITTESTINFO(); lParam.pt_x = x; lParam.pt_y = y; int index = NativeMethods.HitTest(this, ref lParam); // Setup the various values we need to make our hit test structure bool isGroupHit = (lParam.flags & (int)HitTestLocationEx.LVHT_EX_GROUP) != 0; OLVListItem hitItem = isGroupHit || index == -1 ? null : GetItem(index); OLVListSubItem subItem = (View == View.Details && hitItem != null) ? hitItem.GetSubItem(lParam.iSubItem) : null; // Figure out which group is involved in the hit test. This is a little complicated: // If the list is virtual: // - the returned value is list view item index // - iGroup is the *index* of the hit group. // If the list is not virtual: // - iGroup is always -1. // - if the point is over a group, the returned value is the *id* of the hit group. // - if the point is not over a group, the returned value is list view item index. OLVGroup group = null; if (ShowGroups && OLVGroups != null) { if (VirtualMode) { group = lParam.iGroup >= 0 && lParam.iGroup < OLVGroups.Count ? OLVGroups[lParam.iGroup] : null; } else { if (isGroupHit) { foreach (OLVGroup olvGroup in OLVGroups) { if (olvGroup.GroupId == index) { group = olvGroup; break; } } } } } OlvListViewHitTestInfo olvListViewHitTest = new OlvListViewHitTestInfo(hitItem, subItem, lParam.flags, group, lParam.iSubItem); // System.Diagnostics.Debug.WriteLine(String.Format("HitTest({0}, {1})=>{2}", x, y, olvListViewHitTest)); return olvListViewHitTest; } /// /// What is under the given point? This takes the various parts of a cell into accout, including /// any custom parts that a custom renderer might use /// /// /// /// An information block about what is under the point public virtual OlvListViewHitTestInfo OlvHitTest(int x, int y) { OlvListViewHitTestInfo hti = LowLevelHitTest(x, y); // There is a bug/"feature" of the ListView concerning hit testing. // If FullRowSelect is false and the point is over cell 0 but not on // the text or icon, HitTest will not register a hit. We could turn // FullRowSelect on, do the HitTest, and then turn it off again, but // toggling FullRowSelect in that way messes up the tooltip in the // underlying control. So we have to find another way. // // It's too hard to try to write the hit test from scratch. Grouping (for // example) makes it just too complicated. So, we have to use HitTest // but try to get around its limits. // // First step is to determine if the point was within column 0. // If it was, then we only have to determine if there is an actual row // under the point. If there is, then we know that the point is over cell 0. // So we try a Battleship-style approach: is there a subcell to the right // of cell 0? This will return a false negative if column 0 is the rightmost column, // so we also check for a subcell to the left. But if only column 0 is visible, // then that will fail too, so we check for something at the very left of the // control. // // This will still fail under pathological conditions. If column 0 fills // the whole listview and no part of the text column 0 is visible // (because it is horizontally scrolled offscreen), then the hit test will fail. // Are we in the buggy context? Details view, not full row select, and // failing to find anything if (hti.Item == null && !FullRowSelect && View == View.Details) { // Is the point within the column 0? If it is, maybe it should have been a hit. // Let's test slightly to the right and then to left of column 0. Hopefully one // of those will hit a subitem Point sides = NativeMethods.GetScrolledColumnSides(this, 0); if (x >= sides.X && x <= sides.Y) { // We look for: // - any subitem to the right of cell 0? // - any subitem to the left of cell 0? // - cell 0 at the left edge of the screen hti = LowLevelHitTest(sides.Y + 4, y); if (hti.Item == null) hti = LowLevelHitTest(sides.X - 4, y); if (hti.Item == null) hti = LowLevelHitTest(4, y); if (hti.Item != null) { // We hit something! So, the original point must have been in cell 0 hti.ColumnIndex = 0; hti.SubItem = hti.Item.GetSubItem(0); hti.Location = ListViewHitTestLocations.None; hti.HitTestLocation = HitTestLocation.InCell; } } } if (OwnerDraw) CalculateOwnerDrawnHitTest(hti, x, y); else CalculateStandardHitTest(hti, x, y); return hti; } /// /// Perform a hit test when the control is not owner drawn /// /// /// /// protected virtual void CalculateStandardHitTest(OlvListViewHitTestInfo hti, int x, int y) { // Standard hit test works fine for the primary column if (View != View.Details || hti.ColumnIndex == 0 || hti.SubItem == null || hti.Column == null) return; Rectangle cellBounds = hti.SubItem.Bounds; bool hasImage = (GetActualImageIndex(hti.SubItem.ImageSelector) != -1); // Unless we say otherwise, it was an general incell hit hti.HitTestLocation = HitTestLocation.InCell; // Check if the point is over where an image should be. // If there is a checkbox or image there, tag it and exit. Rectangle r = cellBounds; r.Width = SmallImageSize.Width; if (r.Contains(x, y)) { if (hti.Column.CheckBoxes) { hti.HitTestLocation = HitTestLocation.CheckBox; return; } if (hasImage) { hti.HitTestLocation = HitTestLocation.Image; return; } } // Figure out where the text actually is and if the point is in it // The standard HitTest assumes that any point inside a subitem is // a hit on Text -- which is clearly not true. Rectangle textBounds = cellBounds; textBounds.X += 4; if (hasImage) textBounds.X += SmallImageSize.Width; Size proposedSize = new Size(textBounds.Width, textBounds.Height); Size textSize = TextRenderer.MeasureText(hti.SubItem.Text, Font, proposedSize, TextFormatFlags.EndEllipsis | TextFormatFlags.SingleLine | TextFormatFlags.NoPrefix); textBounds.Width = textSize.Width; switch (hti.Column.TextAlign) { case HorizontalAlignment.Center: textBounds.X += (cellBounds.Right - cellBounds.Left - textSize.Width) / 2; break; case HorizontalAlignment.Right: textBounds.X = cellBounds.Right - textSize.Width; break; } if (textBounds.Contains(x, y)) { hti.HitTestLocation = HitTestLocation.Text; } } /// /// Perform a hit test when the control is owner drawn. This hands off responsibility /// to the renderer. /// /// /// /// protected virtual void CalculateOwnerDrawnHitTest(OlvListViewHitTestInfo hti, int x, int y) { // If the click wasn't on an item, give up if (hti.Item == null) return; // If the list is showing column, but they clicked outside the columns, also give up if (View == View.Details && hti.Column == null) return; // Which renderer was responsible for drawing that point IRenderer renderer = View == View.Details ? GetCellRenderer(hti.RowObject, hti.Column) : ItemRenderer; // We can't decide who was responsible. Give up if (renderer == null) return; // Ask the responsible renderer what is at that point renderer.HitTest(hti, x, y); } /// /// Pause (or unpause) all animations in the list /// /// true to pause, false to unpause public virtual void PauseAnimations(bool isPause) { for (int i = 0; i < Columns.Count; i++) { OLVColumn col = GetColumn(i); if (col.Renderer is ImageRenderer renderer) renderer.Paused = isPause; } } /// /// Rebuild the columns based upon its current view and column visibility settings /// public virtual void RebuildColumns() { ChangeToFilteredColumns(View); } /// /// Remove the given model object from the ListView /// /// The model to be removed /// See RemoveObjects() for more details /// This method is thread-safe. /// public virtual void RemoveObject(object modelObject) { if (InvokeRequired) Invoke((MethodInvoker)delegate () { RemoveObject(modelObject); }); else RemoveObjects(new object[] { modelObject }); } /// /// Remove all of the given objects from the control. /// /// Collection of objects to be removed /// /// Nulls and model objects that are not in the ListView are silently ignored. /// This method is thread-safe. /// public virtual void RemoveObjects(ICollection modelObjects) { if (InvokeRequired) { Invoke((MethodInvoker)delegate () { RemoveObjects(modelObjects); }); return; } if (modelObjects == null) return; BeginUpdate(); try { // Give the world a chance to cancel or change the added objects ItemsRemovingEventArgs args = new ItemsRemovingEventArgs(modelObjects); OnItemsRemoving(args); if (args.Canceled) return; modelObjects = args.ObjectsToRemove; TakeOwnershipOfObjects(); ArrayList ourObjects = EnumerableToArray(Objects, false); foreach (object modelObject in modelObjects) { if (modelObject != null) { // ReSharper disable PossibleMultipleEnumeration int i = ourObjects.IndexOf(modelObject); if (i >= 0) ourObjects.RemoveAt(i); // ReSharper restore PossibleMultipleEnumeration i = IndexOf(modelObject); if (i >= 0) Items.RemoveAt(i); } } PostProcessRows(); // Tell the world that the list has changed UnsubscribeNotifications(modelObjects); OnItemsChanged(new ItemsChangedEventArgs()); } finally { EndUpdate(); } } /// /// Select all rows in the listview /// public virtual void SelectAll() { NativeMethods.SelectAllItems(this); } /// /// Set the given image to be fixed in the bottom right of the list view. /// This image will not scroll when the list view scrolls. /// /// /// /// This method uses ListView's native ability to display a background image. /// It has a few limitations: /// /// /// It doesn't work well with owner drawn mode. In owner drawn mode, each cell draws itself, /// including its background, which covers the background image. /// It doesn't look very good when grid lines are enabled, since the grid lines are drawn over the image. /// It does not work at all on XP. /// Obviously, it doesn't look good when alternate row background colors are enabled. /// /// /// If you can live with these limitations, native watermarks are quite neat. They are true backgrounds, not /// translucent overlays like the OverlayImage uses. They also have the decided advantage over overlays in that /// they work correctly even in MDI applications. /// /// Setting this clears any background image. /// /// The image to be drawn. If null, any existing image will be removed. public void SetNativeBackgroundWatermark(Image image) { NativeMethods.SetBackgroundImage(this, image, true, false, 0, 0); } /// /// Set the given image to be background of the ListView so that it appears at the given /// percentage offsets within the list. /// /// /// This has the same limitations as described in . Make sure those limitations /// are understood before using the method. /// This is very similar to setting the property of the standard .NET ListView, except that the standard /// BackgroundImage does not handle images with transparent areas properly -- it renders transparent areas as black. This /// method does not have that problem. /// Setting this clears any background watermark. /// /// The image to be drawn. If null, any existing image will be removed. /// The horizontal percentage where the image will be placed. 0 is absolute left, 100 is absolute right. /// The vertical percentage where the image will be placed. public void SetNativeBackgroundImage(Image image, int xOffset, int yOffset) { NativeMethods.SetBackgroundImage(this, image, false, false, xOffset, yOffset); } /// /// Set the given image to be the tiled background of the ListView. /// /// /// This has the same limitations as described in and . /// Make sure those limitations /// are understood before using the method. /// /// The image to be drawn. If null, any existing image will be removed. public void SetNativeBackgroundTiledImage(Image image) { NativeMethods.SetBackgroundImage(this, image, false, true, 0, 0); } /// /// Set the collection of objects that will be shown in this list view. /// /// This method can safely be called from background threads. /// The list is updated immediately /// The objects to be displayed public virtual void SetObjects(IEnumerable collection) { SetObjects(collection, false); } /// /// Set the collection of objects that will be shown in this list view. /// /// This method can safely be called from background threads. /// The list is updated immediately /// The objects to be displayed /// Should the state of the list be preserved as far as is possible. public virtual void SetObjects(IEnumerable collection, bool preserveState) { if (InvokeRequired) { Invoke((MethodInvoker)delegate { SetObjects(collection, preserveState); }); return; } // Give the world a chance to cancel or change the assigned collection ItemsChangingEventArgs args = new ItemsChangingEventArgs(objects, collection); OnItemsChanging(args); if (args.Canceled) return; collection = args.NewObjects; // If we own the current list and they change to another list, we don't own it anymore if (isOwnerOfObjects && !ReferenceEquals(objects, collection)) isOwnerOfObjects = false; objects = collection; BuildList(preserveState); // Tell the world that the list has changed UpdateNotificationSubscriptions(objects); OnItemsChanged(new ItemsChangedEventArgs()); } /// /// Update the given model object into the ListView. The model will be added if it doesn't already exist. /// /// The model to be updated /// /// /// See for more details /// /// This method is thread-safe. /// This method will cause the list to be resorted. /// This method only works on ObjectListViews and FastObjectListViews. /// public virtual void UpdateObject(object modelObject) { if (InvokeRequired) Invoke((MethodInvoker)delegate () { UpdateObject(modelObject); }); else UpdateObjects(new object[] { modelObject }); } /// /// Update the pre-existing models that are equal to the given objects. If any of the model doesn't /// already exist in the control, they will be added. /// /// Collection of objects to be updated/added /// /// This method will cause the list to be resorted. /// Nulls are silently ignored. /// This method is thread-safe. /// This method only works on ObjectListViews and FastObjectListViews. /// public virtual void UpdateObjects(ICollection modelObjects) { if (InvokeRequired) { Invoke((MethodInvoker)delegate () { UpdateObjects(modelObjects); }); return; } if (modelObjects == null || modelObjects.Count == 0) return; BeginUpdate(); try { UnsubscribeNotifications(modelObjects); ArrayList objectsToAdd = new ArrayList(); TakeOwnershipOfObjects(); ArrayList ourObjects = EnumerableToArray(Objects, false); foreach (object modelObject in modelObjects) { if (modelObject != null) { int i = ourObjects.IndexOf(modelObject); if (i < 0) objectsToAdd.Add(modelObject); else { ourObjects[i] = modelObject; OLVListItem olvi = ModelToItem(modelObject); if (olvi != null) { olvi.RowObject = modelObject; RefreshItem(olvi); } } } } PostProcessRows(); AddObjects(objectsToAdd); // Tell the world that the list has changed SubscribeNotifications(modelObjects); OnItemsChanged(new ItemsChangedEventArgs()); } finally { EndUpdate(); } } /// /// Change any subscriptions to INotifyPropertyChanged events on our current /// model objects so that we no longer listen for events on the old models /// and do listen for events on the given collection. /// /// This does nothing if UseNotifyPropertyChanged is false. /// protected virtual void UpdateNotificationSubscriptions(IEnumerable collection) { if (!UseNotifyPropertyChanged) return; // We could calculate a symmetric difference between the old models and the new models // except that we don't have the previous models at this point. UnsubscribeNotifications(null); SubscribeNotifications(collection ?? Objects); } /// /// Gets or sets whether or not ObjectListView should subscribe to INotifyPropertyChanged /// events on the model objects that it is given. /// /// /// /// This should be set before calling SetObjects(). If you set this to false, /// ObjectListView will unsubscribe to all current model objects. /// /// If you set this to true on a virtual list, the ObjectListView will /// walk all the objects in the list trying to subscribe to change notifications. /// If you have 10,000,000 items in your virtual list, this may take some time. /// [Category("ObjectListView"), Description("Should ObjectListView listen for property changed events on the model objects?"), DefaultValue(false)] public bool UseNotifyPropertyChanged { get { return useNotifyPropertyChanged; } set { if (useNotifyPropertyChanged == value) return; useNotifyPropertyChanged = value; if (value) SubscribeNotifications(Objects); else UnsubscribeNotifications(null); } } private bool useNotifyPropertyChanged; /// /// Subscribe to INotifyPropertyChanges on the given collection of objects. /// /// protected void SubscribeNotifications(IEnumerable models) { if (!UseNotifyPropertyChanged || models == null) return; foreach (object x in models) { if (x is INotifyPropertyChanged notifier && !subscribedModels.ContainsKey(notifier)) { notifier.PropertyChanged += HandleModelOnPropertyChanged; subscribedModels[notifier] = notifier; } } } /// /// Unsubscribe from INotifyPropertyChanges on the given collection of objects. /// If the given collection is null, unsubscribe from all current subscriptions /// /// protected void UnsubscribeNotifications(IEnumerable models) { if (models == null) { foreach (INotifyPropertyChanged notifier in subscribedModels.Keys) { notifier.PropertyChanged -= HandleModelOnPropertyChanged; } subscribedModels = new Hashtable(); } else { foreach (object x in models) { if (x is INotifyPropertyChanged notifier) { notifier.PropertyChanged -= HandleModelOnPropertyChanged; subscribedModels.Remove(notifier); } } } } private void HandleModelOnPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs) { // System.Diagnostics.Debug.WriteLine(String.Format("PropertyChanged: '{0}' on '{1}", propertyChangedEventArgs.PropertyName, sender)); RefreshObject(sender); } private Hashtable subscribedModels = new(); #endregion #region Save/Restore State /// /// Return a byte array that represents the current state of the ObjectListView, such /// that the state can be restored by RestoreState() /// /// /// The state of an ObjectListView includes the attributes that the user can modify: /// /// current view (i.e. Details, Tile, Large Icon...) /// sort column and direction /// column order /// column widths /// column visibility /// /// /// /// It does not include selection or the scroll position. /// /// /// A byte array representing the state of the ObjectListView public virtual byte[] SaveState() { ObjectListViewState olvState = new ObjectListViewState(); olvState.VersionNumber = 1; olvState.NumberOfColumns = AllColumns.Count; olvState.CurrentView = View; // If we have a sort column, it is possible that it is not currently being shown, in which // case, it's Index will be -1. So we calculate its index directly. Technically, the sort // column does not even have to a member of AllColumns, in which case IndexOf will return -1, // which is works fine since we have no way of restoring such a column anyway. if (PrimarySortColumn != null) olvState.SortColumn = AllColumns.IndexOf(PrimarySortColumn); olvState.LastSortOrder = PrimarySortOrder; olvState.IsShowingGroups = ShowGroups; if (AllColumns.Count > 0 && AllColumns[0].LastDisplayIndex == -1) RememberDisplayIndicies(); foreach (OLVColumn column in AllColumns) { olvState.ColumnIsVisible.Add(column.IsVisible); olvState.ColumnDisplayIndicies.Add(column.LastDisplayIndex); olvState.ColumnWidths.Add(column.Width); } // Now that we have stored our state, convert it to a byte array using (MemoryStream ms = new MemoryStream()) { var serializer = new XmlSerializer(typeof(ObjectListViewState)); #pragma warning disable SYSLIB0011 serializer.Serialize(ms, olvState); #pragma warning restore SYSLIB0011 return ms.ToArray(); } } /// /// Restore the state of the control from the given string, which must have been /// produced by SaveState() /// /// A byte array returned from SaveState() /// Returns true if the state was restored public virtual bool RestoreState(byte[] state) { using (MemoryStream ms = new MemoryStream(state)) { var deserializer = new XmlSerializer(typeof(ObjectListViewState)); ObjectListViewState olvState; try { #pragma warning disable SYSLIB0011 olvState = deserializer.Deserialize(ms) as ObjectListViewState; #pragma warning restore SYSLIB0011 } catch (System.Runtime.Serialization.SerializationException) { return false; } // The number of columns has changed. We have no way to match old // columns to the new ones, so we just give up. if (olvState == null || olvState.NumberOfColumns != AllColumns.Count) return false; if (olvState.SortColumn == -1) { PrimarySortColumn = null; PrimarySortOrder = SortOrder.None; } else { PrimarySortColumn = AllColumns[olvState.SortColumn]; PrimarySortOrder = olvState.LastSortOrder; } for (int i = 0; i < olvState.NumberOfColumns; i++) { OLVColumn column = AllColumns[i]; column.Width = (int)olvState.ColumnWidths[i]; column.IsVisible = (bool)olvState.ColumnIsVisible[i]; column.LastDisplayIndex = (int)olvState.ColumnDisplayIndicies[i]; } // ReSharper disable RedundantCheckBeforeAssignment if (olvState.IsShowingGroups != ShowGroups) // ReSharper restore RedundantCheckBeforeAssignment ShowGroups = olvState.IsShowingGroups; if (View == olvState.CurrentView) RebuildColumns(); else View = olvState.CurrentView; } return true; } /// /// Instances of this class are used to store the state of an ObjectListView. /// [Serializable] public class ObjectListViewState { // ReSharper disable NotAccessedField.Global public int VersionNumber = 1; // ReSharper restore NotAccessedField.Global public int NumberOfColumns = 1; public View CurrentView; public int SortColumn = -1; public bool IsShowingGroups; public SortOrder LastSortOrder = SortOrder.None; // ReSharper disable FieldCanBeMadeReadOnly.Global public ArrayList ColumnIsVisible = new(); public ArrayList ColumnDisplayIndicies = new(); public ArrayList ColumnWidths = new(); // ReSharper restore FieldCanBeMadeReadOnly.Global } #endregion #region Event handlers /// /// The application is idle. Trigger a SelectionChanged event. /// /// /// protected virtual void HandleApplicationIdle(object sender, EventArgs e) { // Remove the handler before triggering the event Application.Idle -= new EventHandler(HandleApplicationIdle); hasIdleHandler = false; OnSelectionChanged(new EventArgs()); } /// /// The application is idle. Handle the column resizing event. /// /// /// protected virtual void HandleApplicationIdleResizeColumns(object sender, EventArgs e) { // Remove the handler before triggering the event Application.Idle -= new EventHandler(HandleApplicationIdleResizeColumns); hasResizeColumnsHandler = false; ResizeFreeSpaceFillingColumns(); } /// /// Handle the BeginScroll listview notification /// /// /// True if the event was completely handled protected virtual bool HandleBeginScroll(ref Message m) { //System.Diagnostics.Debug.WriteLine("LVN_BEGINSCROLL"); NativeMethods.NMLVSCROLL nmlvscroll = (NativeMethods.NMLVSCROLL)m.GetLParam(typeof(NativeMethods.NMLVSCROLL)); if (nmlvscroll.dx != 0) { int scrollPositionH = NativeMethods.GetScrollPosition(this, true); ScrollEventArgs args = new ScrollEventArgs(ScrollEventType.EndScroll, scrollPositionH - nmlvscroll.dx, scrollPositionH, ScrollOrientation.HorizontalScroll); OnScroll(args); // Force any empty list msg to redraw when the list is scrolled horizontally if (GetItemCount() == 0) Invalidate(); } if (nmlvscroll.dy != 0) { int scrollPositionV = NativeMethods.GetScrollPosition(this, false); ScrollEventArgs args = new ScrollEventArgs(ScrollEventType.EndScroll, scrollPositionV - nmlvscroll.dy, scrollPositionV, ScrollOrientation.VerticalScroll); OnScroll(args); } return false; } /// /// Handle the EndScroll listview notification /// /// /// True if the event was completely handled protected virtual bool HandleEndScroll(ref Message m) { //System.Diagnostics.Debug.WriteLine("LVN_BEGINSCROLL"); // There is a bug in ListView under XP that causes the gridlines to be incorrectly scrolled // when the left button is clicked to scroll. This is supposedly documented at // KB 813791, but I couldn't find it anywhere. You can follow this thread to see the discussion // http://www.ureader.com/msg/1484143.aspx if (!IsVistaOrLater && IsLeftMouseDown && GridLines) { Invalidate(); Update(); } return false; } /// /// Handle the LinkClick listview notification /// /// /// True if the event was completely handled protected virtual bool HandleLinkClick(ref Message m) { //System.Diagnostics.Debug.WriteLine("HandleLinkClick"); NativeMethods.NMLVLINK nmlvlink = (NativeMethods.NMLVLINK)m.GetLParam(typeof(NativeMethods.NMLVLINK)); // Find the group that was clicked and trigger an event foreach (OLVGroup x in OLVGroups) { if (x.GroupId == nmlvlink.iSubItem) { OnGroupTaskClicked(new GroupTaskClickedEventArgs(x)); return true; } } return false; } /// /// The cell tooltip control wants information about the tool tip that it should show. /// /// /// protected virtual void HandleCellToolTipShowing(object sender, ToolTipShowingEventArgs e) { BuildCellEvent(e, PointToClient(Cursor.Position)); if (e.Item != null) { e.Text = GetCellToolTip(e.ColumnIndex, e.RowIndex); OnCellToolTip(e); } } /// /// Allow the HeaderControl to call back into HandleHeaderToolTipShowing without making that method public /// /// /// internal void HeaderToolTipShowingCallback(object sender, ToolTipShowingEventArgs e) { HandleHeaderToolTipShowing(sender, e); } /// /// The header tooltip control wants information about the tool tip that it should show. /// /// /// protected virtual void HandleHeaderToolTipShowing(object sender, ToolTipShowingEventArgs e) { e.ColumnIndex = HeaderControl.ColumnIndexUnderCursor; if (e.ColumnIndex < 0) return; e.RowIndex = -1; e.Model = null; e.Column = GetColumn(e.ColumnIndex); e.Text = GetHeaderToolTip(e.ColumnIndex); e.ListView = this; OnHeaderToolTip(e); } /// /// Event handler for the column click event /// protected virtual void HandleColumnClick(object sender, ColumnClickEventArgs e) { if (!PossibleFinishCellEditing()) return; // Toggle the sorting direction on successive clicks on the same column if (PrimarySortColumn != null && e.Column == PrimarySortColumn.Index) PrimarySortOrder = (PrimarySortOrder == SortOrder.Descending ? SortOrder.Ascending : SortOrder.Descending); else PrimarySortOrder = SortOrder.Ascending; BeginUpdate(); try { Sort(e.Column); } finally { if (!IsDisposed && !Disposing) EndUpdate(); } } #endregion #region Low level Windows Message handling /// /// Override the basic message pump for this control /// /// protected override void WndProc(ref Message m) { try { // System.Diagnostics.Debug.WriteLine(m.Msg); switch (m.Msg) { case 2: // WM_DESTROY if (!HandleDestroy(ref m)) base.WndProc(ref m); break; //case 0x14: // WM_ERASEBKGND // Can't do anything here since, when the control is double buffered, anything // done here is immediately over-drawn // break; case 0x0F: // WM_PAINT if (!HandlePaint(ref m)) base.WndProc(ref m); break; case 0x46: // WM_WINDOWPOSCHANGING if (PossibleFinishCellEditing() && !HandleWindowPosChanging(ref m)) base.WndProc(ref m); break; case 0x4E: // WM_NOTIFY if (!HandleNotify(ref m)) base.WndProc(ref m); break; case 0x0100: // WM_KEY_DOWN if (!HandleKeyDown(ref m)) base.WndProc(ref m); break; case 0x0102: // WM_CHAR if (!HandleChar(ref m)) base.WndProc(ref m); break; case 0x0200: // WM_MOUSEMOVE if (!HandleMouseMove(ref m)) base.WndProc(ref m); break; case 0x0201: // WM_LBUTTONDOWN if (PossibleFinishCellEditing() && !HandleLButtonDown(ref m)) base.WndProc(ref m); break; case 0x202: // WM_LBUTTONUP if (PossibleFinishCellEditing() && !HandleLButtonUp(ref m)) base.WndProc(ref m); break; case 0x0203: // WM_LBUTTONDBLCLK if (PossibleFinishCellEditing() && !HandleLButtonDoubleClick(ref m)) base.WndProc(ref m); break; case 0x0204: // WM_RBUTTONDOWN if (PossibleFinishCellEditing() && !HandleRButtonDown(ref m)) base.WndProc(ref m); break; case 0x0206: // WM_RBUTTONDBLCLK if (PossibleFinishCellEditing() && !HandleRButtonDoubleClick(ref m)) base.WndProc(ref m); break; case 0x204E: // WM_REFLECT_NOTIFY if (!HandleReflectNotify(ref m)) base.WndProc(ref m); break; case 0x114: // WM_HSCROLL: case 0x115: // WM_VSCROLL: //System.Diagnostics.Debug.WriteLine("WM_VSCROLL"); if (PossibleFinishCellEditing()) base.WndProc(ref m); break; case 0x20A: // WM_MOUSEWHEEL: case 0x20E: // WM_MOUSEHWHEEL: if (PossibleFinishCellEditing()) base.WndProc(ref m); break; case 0x7B: // WM_CONTEXTMENU if (!HandleContextMenu(ref m)) base.WndProc(ref m); break; case 0x1000 + 18: // LVM_HITTEST: //System.Diagnostics.Debug.WriteLine("LVM_HITTEST"); if (skipNextHitTest) { //System.Diagnostics.Debug.WriteLine("SKIPPING LVM_HITTEST"); skipNextHitTest = false; } else { base.WndProc(ref m); } break; default: base.WndProc(ref m); break; } } catch (ArgumentOutOfRangeException) { // Catch error 0x80070459 in PtrToStructure - No mapping for the Unicode character exists in the target multi-byte code page // It can happen on some Japanese systems, it's better to have some ui glitching than crashing base.WndProc(ref m); } catch (ArgumentNullException e) when (e.ParamName == "owningItem") { // Bug in <= .NET 5.0.5 forms // https://github.com/dotnet/winforms/pull/4764 } } /// /// Handle the search for item m if possible. /// /// The m to be processed /// bool to indicate if the msg has been handled protected virtual bool HandleChar(ref Message m) { // Trigger a normal KeyPress event, which listeners can handle if they want. // Handling the event stops ObjectListView's fancy search-by-typing. if (ProcessKeyEventArgs(ref m)) return true; const int MILLISECONDS_BETWEEN_KEYPRESSES = 1000; // What character did the user type and was it part of a longer string? char character = (char)m.WParam.ToInt32(); //TODO: Will this work on 64 bit or MBCS? if (character == (char)Keys.Back) { // Backspace forces the next key to be considered the start of a new search timeLastCharEvent = 0; return true; } if (Environment.TickCount < (timeLastCharEvent + MILLISECONDS_BETWEEN_KEYPRESSES)) lastSearchString += character; else lastSearchString = character.ToString(CultureInfo.InvariantCulture); // If this control is showing checkboxes, we want to ignore single space presses, // since they are used to toggle the selected checkboxes. if (CheckBoxes && lastSearchString == " ") { timeLastCharEvent = 0; return true; } // Where should the search start? int start = 0; ListViewItem focused = FocusedItem; if (focused != null) { start = GetDisplayOrderOfItemIndex(focused.Index); // If the user presses a single key, we search from after the focused item, // being careful not to march past the end of the list if (lastSearchString.Length == 1) { start += 1; if (start == GetItemCount()) start = 0; } } // Give the world a chance to fiddle with or completely avoid the searching process BeforeSearchingEventArgs args = new BeforeSearchingEventArgs(lastSearchString, start); OnBeforeSearching(args); if (args.Canceled) return true; // The parameters of the search may have been changed string searchString = args.StringToFind; start = args.StartSearchFrom; // Do the actual search int found = FindMatchingRow(searchString, start, SearchDirectionHint.Down); if (found >= 0) { // Select and focus on the found item BeginUpdate(); try { SelectedIndices.Clear(); OLVListItem lvi = GetNthItemInDisplayOrder(found); if (lvi != null) { if (lvi.Enabled) lvi.Selected = true; lvi.Focused = true; EnsureVisible(lvi.Index); } } finally { EndUpdate(); } } // Tell the world that a search has occurred AfterSearchingEventArgs args2 = new AfterSearchingEventArgs(searchString, found); OnAfterSearching(args2); if (!args2.Handled) { if (found < 0) System.Media.SystemSounds.Beep.Play(); } // When did this event occur? timeLastCharEvent = Environment.TickCount; return true; } private int timeLastCharEvent; private string lastSearchString; /// /// The user wants to see the context menu. /// /// The windows m /// A bool indicating if this m has been handled /// /// We want to ignore context menu requests that are triggered by right clicks on the header /// protected virtual bool HandleContextMenu(ref Message m) { // Don't try to handle context menu commands at design time. if (DesignMode) return false; // If the context menu command was generated by the keyboard, LParam will be -1. // We don't want to process these. if (m.LParam == minusOne) return false; // If the context menu came from somewhere other than the header control, // we also don't want to ignore it if (m.WParam != HeaderControl.Handle) return false; // OK. Looks like a right click in the header if (!PossibleFinishCellEditing()) return true; int columnIndex = HeaderControl.ColumnIndexUnderCursor; return HandleHeaderRightClick(columnIndex); } private readonly IntPtr minusOne = new(-1); /// /// Handle the Custom draw series of notifications /// /// The message /// True if the message has been handled protected virtual bool HandleCustomDraw(ref Message m) { const int CDDS_PREPAINT = 1; const int CDDS_POSTPAINT = 2; const int CDDS_PREERASE = 3; const int CDDS_POSTERASE = 4; //const int CDRF_NEWFONT = 2; //const int CDRF_SKIPDEFAULT = 4; const int CDDS_ITEM = 0x00010000; const int CDDS_SUBITEM = 0x00020000; const int CDDS_ITEMPREPAINT = (CDDS_ITEM | CDDS_PREPAINT); const int CDDS_ITEMPOSTPAINT = (CDDS_ITEM | CDDS_POSTPAINT); const int CDDS_ITEMPREERASE = (CDDS_ITEM | CDDS_PREERASE); const int CDDS_ITEMPOSTERASE = (CDDS_ITEM | CDDS_POSTERASE); const int CDDS_SUBITEMPREPAINT = (CDDS_SUBITEM | CDDS_ITEMPREPAINT); const int CDDS_SUBITEMPOSTPAINT = (CDDS_SUBITEM | CDDS_ITEMPOSTPAINT); const int CDRF_NOTIFYPOSTPAINT = 0x10; //const int CDRF_NOTIFYITEMDRAW = 0x20; //const int CDRF_NOTIFYSUBITEMDRAW = 0x20; // same value as above! const int CDRF_NOTIFYPOSTERASE = 0x40; // There is a bug in owner drawn virtual lists which causes lots of custom draw messages // to be sent to the control *outside* of a WmPaint event. AFAIK, these custom draw events // are spurious and only serve to make the control flicker annoyingly. // So, we ignore messages that are outside of a paint event. if (!isInWmPaintEvent) return true; // One more complication! Sometimes with owner drawn virtual lists, the act of drawing // the overlays triggers a second attempt to paint the control -- which makes an annoying // flicker. So, we only do the custom drawing once per WmPaint event. if (!shouldDoCustomDrawing) return true; NativeMethods.NMLVCUSTOMDRAW nmcustomdraw = (NativeMethods.NMLVCUSTOMDRAW)m.GetLParam(typeof(NativeMethods.NMLVCUSTOMDRAW)); //System.Diagnostics.Debug.WriteLine(String.Format("cd: {0:x}, {1}, {2}", nmcustomdraw.nmcd.dwDrawStage, nmcustomdraw.dwItemType, nmcustomdraw.nmcd.dwItemSpec)); // Ignore drawing of group items if (nmcustomdraw.dwItemType == 1) { // This is the basis of an idea about how to owner draw group headers //nmcustomdraw.clrText = ColorTranslator.ToWin32(Color.DeepPink); //nmcustomdraw.clrFace = ColorTranslator.ToWin32(Color.DeepPink); //nmcustomdraw.clrTextBk = ColorTranslator.ToWin32(Color.DeepPink); //Marshal.StructureToPtr(nmcustomdraw, m.LParam, false); //using (Graphics g = Graphics.FromHdc(nmcustomdraw.nmcd.hdc)) { // g.DrawRectangle(Pens.Red, Rectangle.FromLTRB(nmcustomdraw.rcText.left, nmcustomdraw.rcText.top, nmcustomdraw.rcText.right, nmcustomdraw.rcText.bottom)); //} //m.Result = (IntPtr)((int)m.Result | CDRF_SKIPDEFAULT); return true; } switch (nmcustomdraw.nmcd.dwDrawStage) { case CDDS_PREPAINT: //System.Diagnostics.Debug.WriteLine("CDDS_PREPAINT"); // Remember which items were drawn during this paint cycle if (prePaintLevel == 0) drawnItems = new List(); // If there are any items, we have to wait until at least one has been painted // before we draw the overlays. If there aren't any items, there will never be any // item paint events, so we can draw the overlays whenever isAfterItemPaint = (GetItemCount() == 0); prePaintLevel++; base.WndProc(ref m); // Make sure that we get postpaint notifications m.Result = (IntPtr)((int)m.Result | CDRF_NOTIFYPOSTPAINT | CDRF_NOTIFYPOSTERASE); return true; case CDDS_POSTPAINT: //System.Diagnostics.Debug.WriteLine("CDDS_POSTPAINT"); prePaintLevel--; // When in group view, we have two problems. On XP, the control sends // a whole heap of PREPAINT/POSTPAINT messages before drawing any items. // We have to wait until after the first item paint before we draw overlays. // On Vista, we have a different problem. On Vista, the control nests calls // to PREPAINT and POSTPAINT. We only want to draw overlays on the outermost // POSTPAINT. if (prePaintLevel == 0 && (isMarqueSelecting || isAfterItemPaint)) { shouldDoCustomDrawing = false; // Draw our overlays after everything has been drawn using (Graphics g = Graphics.FromHdc(nmcustomdraw.nmcd.hdc)) { DrawAllDecorations(g, drawnItems); } } break; case CDDS_ITEMPREPAINT: //System.Diagnostics.Debug.WriteLine("CDDS_ITEMPREPAINT"); // When in group view on XP, the control send a whole heap of PREPAINT/POSTPAINT // messages before drawing any items. // We have to wait until after the first item paint before we draw overlays isAfterItemPaint = true; // This scheme of catching custom draw msgs works fine, except // for Tile view. Something in .NET's handling of Tile view causes lots // of invalidates and erases. So, we just ignore completely // .NET's handling of Tile view and let the underlying control // do its stuff. Strangely, if the Tile view is // completely owner drawn, those erasures don't happen. if (View == View.Tile) { if (OwnerDraw && ItemRenderer != null) base.WndProc(ref m); } else { base.WndProc(ref m); } m.Result = (IntPtr)((int)m.Result | CDRF_NOTIFYPOSTPAINT | CDRF_NOTIFYPOSTERASE); return true; case CDDS_ITEMPOSTPAINT: //System.Diagnostics.Debug.WriteLine("CDDS_ITEMPOSTPAINT"); // Remember which items have been drawn so we can draw any decorations for them // once all other painting is finished if (Columns.Count > 0) { OLVListItem olvi = GetItem((int)nmcustomdraw.nmcd.dwItemSpec); if (olvi != null) drawnItems.Add(olvi); } break; case CDDS_SUBITEMPREPAINT: //System.Diagnostics.Debug.WriteLine(String.Format("CDDS_SUBITEMPREPAINT ({0},{1})", (int)nmcustomdraw.nmcd.dwItemSpec, nmcustomdraw.iSubItem)); // There is a bug in the .NET framework which appears when column 0 of an owner drawn listview // is dragged to another column position. // The bounds calculation always returns the left edge of column 0 as being 0. // The effects of this bug become apparent // when the listview is scrolled horizontally: the control can think that column 0 // is no longer visible (the horizontal scroll position is subtracted from the bounds, giving a // rectangle that is offscreen). In those circumstances, column 0 is not redraw because // the control thinks it is not visible and so does not trigger a DrawSubItem event. // To fix this problem, we have to detected the situation -- owner drawing column 0 in any column except 0 -- // trigger our own DrawSubItem, and then prevent the default processing from occuring. // Are we owner drawing column 0 when it's in any column except 0? if (!OwnerDraw) return false; int columnIndex = nmcustomdraw.iSubItem; if (columnIndex != 0) return false; int displayIndex = Columns[0].DisplayIndex; if (displayIndex == 0) return false; int rowIndex = (int)nmcustomdraw.nmcd.dwItemSpec; OLVListItem item = GetItem(rowIndex); if (item == null) return false; // OK. We have the error condition, so lets do what the .NET framework should do. // Trigger an event to draw column 0 when it is not at display index 0 using (Graphics g = Graphics.FromHdc(nmcustomdraw.nmcd.hdc)) { // Correctly calculate the bounds of cell 0 Rectangle r = item.GetSubItemBounds(0); // We can hardcode "0" here since we know we are only doing this for column 0 DrawListViewSubItemEventArgs args = new DrawListViewSubItemEventArgs(g, r, item, item.SubItems[0], rowIndex, 0, Columns[0], (ListViewItemStates)nmcustomdraw.nmcd.uItemState); OnDrawSubItem(args); // If the event handler wants to do the default processing (i.e. DrawDefault = true), we are stuck. // There is no way we can force the default drawing because of the bug in .NET we are trying to get around. Trace.Assert(!args.DrawDefault, "Default drawing is impossible in this situation"); } m.Result = (IntPtr)4; return true; case CDDS_SUBITEMPOSTPAINT: //System.Diagnostics.Debug.WriteLine("CDDS_SUBITEMPOSTPAINT"); break; // I have included these stages, but it doesn't seem that they are sent for ListViews. // http://www.tech-archive.net/Archive/VC/microsoft.public.vc.mfc/2006-08/msg00220.html case CDDS_PREERASE: //System.Diagnostics.Debug.WriteLine("CDDS_PREERASE"); break; case CDDS_POSTERASE: //System.Diagnostics.Debug.WriteLine("CDDS_POSTERASE"); break; case CDDS_ITEMPREERASE: //System.Diagnostics.Debug.WriteLine("CDDS_ITEMPREERASE"); break; case CDDS_ITEMPOSTERASE: //System.Diagnostics.Debug.WriteLine("CDDS_ITEMPOSTERASE"); break; } return false; } private bool isAfterItemPaint; private List drawnItems; /// /// Handle the underlying control being destroyed /// /// /// protected virtual bool HandleDestroy(ref Message m) { //System.Diagnostics.Debug.WriteLine(String.Format("WM_DESTROY: Disposing={0}, IsDisposed={1}, VirtualMode={2}", Disposing, IsDisposed, VirtualMode)); // Recreate the header control when the listview control is destroyed headerControl = null; // When the underlying control is destroyed, we need to recreate and reconfigure its tooltip if (cellToolTip != null) { cellToolTip.PushSettings(); BeginInvoke((MethodInvoker)delegate { UpdateCellToolTipHandle(); cellToolTip.PopSettings(); }); } return false; } /// /// Handle the search for item m if possible. /// /// The m to be processed /// bool to indicate if the msg has been handled protected virtual bool HandleFindItem(ref Message m) { // NOTE: As far as I can see, this message is never actually sent to the control, making this // method redundant! const int LVFI_STRING = 0x0002; NativeMethods.LVFINDINFO findInfo = (NativeMethods.LVFINDINFO)m.GetLParam(typeof(NativeMethods.LVFINDINFO)); // We can only handle string searches if ((findInfo.flags & LVFI_STRING) != LVFI_STRING) return false; int start = m.WParam.ToInt32(); m.Result = (IntPtr)FindMatchingRow(findInfo.psz, start, SearchDirectionHint.Down); return true; } /// /// Find the first row after the given start in which the text value in the /// comparison column begins with the given text. The comparison column is column 0, /// unless IsSearchOnSortColumn is true, in which case the current sort column is used. /// /// The text to be prefix matched /// The index of the first row to consider /// Which direction should be searched? /// The index of the first row that matched, or -1 /// The text comparison is a case-insensitive, prefix match. The search will /// search the every row until a match is found, wrapping at the end if needed. public virtual int FindMatchingRow(string text, int start, SearchDirectionHint direction) { // We also can't do anything if we don't have data int rowCount = GetItemCount(); if (rowCount == 0) return -1; // Which column are we going to use for our comparing? OLVColumn column = GetColumn(0); if (IsSearchOnSortColumn && View == View.Details && PrimarySortColumn != null) column = PrimarySortColumn; // Do two searches if necessary to find a match. The second search is the wrap-around part of searching int i; if (direction == SearchDirectionHint.Down) { i = FindMatchInRange(text, start, rowCount - 1, column); if (i == -1 && start > 0) i = FindMatchInRange(text, 0, start - 1, column); } else { i = FindMatchInRange(text, start, 0, column); if (i == -1 && start != rowCount) i = FindMatchInRange(text, rowCount - 1, start + 1, column); } return i; } /// /// Find the first row in the given range of rows that prefix matches the string value of the given column. /// /// /// /// /// /// The index of the matched row, or -1 protected virtual int FindMatchInRange(string text, int first, int last, OLVColumn column) { if (first <= last) { for (int i = first; i <= last; i++) { string data = column.GetStringValue(GetNthItemInDisplayOrder(i).RowObject); if (data.StartsWith(text, StringComparison.CurrentCultureIgnoreCase)) return i; } } else { for (int i = first; i >= last; i--) { string data = column.GetStringValue(GetNthItemInDisplayOrder(i).RowObject); if (data.StartsWith(text, StringComparison.CurrentCultureIgnoreCase)) return i; } } return -1; } /// /// Handle the Group Info series of notifications /// /// The message /// True if the message has been handled protected virtual bool HandleGroupInfo(ref Message m) { NativeMethods.NMLVGROUP nmlvgroup = (NativeMethods.NMLVGROUP)m.GetLParam(typeof(NativeMethods.NMLVGROUP)); //System.Diagnostics.Debug.WriteLine(String.Format("group: {0}, old state: {1}, new state: {2}", // nmlvgroup.iGroupId, OLVGroup.StateToString(nmlvgroup.uOldState), OLVGroup.StateToString(nmlvgroup.uNewState))); // Ignore state changes that aren't related to selection, focus or collapsedness const uint INTERESTING_STATES = (uint)(GroupState.LVGS_COLLAPSED | GroupState.LVGS_FOCUSED | GroupState.LVGS_SELECTED); if ((nmlvgroup.uOldState & INTERESTING_STATES) == (nmlvgroup.uNewState & INTERESTING_STATES)) return false; foreach (OLVGroup group in OLVGroups) { if (group.GroupId == nmlvgroup.iGroupId) { GroupStateChangedEventArgs args = new GroupStateChangedEventArgs(group, (GroupState)nmlvgroup.uOldState, (GroupState)nmlvgroup.uNewState); OnGroupStateChanged(args); break; } } return false; } //private static string StateToString(uint state) //{ // if (state == 0) // return Enum.GetName(typeof(GroupState), 0); // List names = new List(); // foreach (int value in Enum.GetValues(typeof(GroupState))) // { // if (value != 0 && (state & value) == value) // { // names.Add(Enum.GetName(typeof(GroupState), value)); // } // } // return names.Count == 0 ? state.ToString("x") : String.Join("|", names.ToArray()); //} /// /// Handle a key down message /// /// /// True if the msg has been handled protected virtual bool HandleKeyDown(ref Message m) { // If this is a checkbox list, toggle the selected rows when the user presses Space if (CheckBoxes && m.WParam.ToInt32() == (int)Keys.Space && SelectedIndices.Count > 0) { ToggleSelectedRowCheckBoxes(); return true; } // Remember the scroll position so we can decide if the listview has scrolled in the // handling of the event. int scrollPositionH = NativeMethods.GetScrollPosition(this, true); int scrollPositionV = NativeMethods.GetScrollPosition(this, false); base.WndProc(ref m); // It's possible that the processing in base.WndProc has actually destroyed this control if (IsDisposed) return true; // If the keydown processing changed the scroll position, trigger a Scroll event int newScrollPositionH = NativeMethods.GetScrollPosition(this, true); int newScrollPositionV = NativeMethods.GetScrollPosition(this, false); if (scrollPositionH != newScrollPositionH) { ScrollEventArgs args = new ScrollEventArgs(ScrollEventType.EndScroll, scrollPositionH, newScrollPositionH, ScrollOrientation.HorizontalScroll); OnScroll(args); } if (scrollPositionV != newScrollPositionV) { ScrollEventArgs args = new ScrollEventArgs(ScrollEventType.EndScroll, scrollPositionV, newScrollPositionV, ScrollOrientation.VerticalScroll); OnScroll(args); } if (scrollPositionH != newScrollPositionH || scrollPositionV != newScrollPositionV) RefreshHotItem(); return true; } /// /// Toggle the checkedness of the selected rows /// /// /// /// Actually, this doesn't actually toggle all rows. It toggles the first row, and /// all other rows get the check state of that first row. This is actually a much /// more useful behaviour. /// /// /// If no rows are selected, this method does nothing. /// /// public void ToggleSelectedRowCheckBoxes() { if (SelectedIndices.Count == 0) return; Object primaryModel = GetItem(SelectedIndices[0]).RowObject; ToggleCheckObject(primaryModel); CheckState? state = GetCheckState(primaryModel); if (state.HasValue) { foreach (Object x in SelectedObjects) SetObjectCheckedness(x, state.Value); } } /// /// Catch the Left Button down event. /// /// The m to be processed /// bool to indicate if the msg has been handled protected virtual bool HandleLButtonDown(ref Message m) { // We have to intercept this low level message rather than the more natural // overridding of OnMouseDown, since ListCtrl's internal mouse down behavior // is to select (or deselect) rows when the mouse is released. We don't // want the selection to change when the user checks or unchecks a checkbox, so if the // mouse down event was to check/uncheck, we have to hide this mouse // down event from the control. int x = m.LParam.ToInt32() & 0xFFFF; int y = (m.LParam.ToInt32() >> 16) & 0xFFFF; return ProcessLButtonDown(OlvHitTest(x, y)); } /// /// Handle a left mouse down at the given hit test location /// /// Subclasses can override this to do something unique /// /// True if the message has been handled protected virtual bool ProcessLButtonDown(OlvListViewHitTestInfo hti) { if (hti.Item == null) return false; // If the click occurs on a button, ignore it so the row isn't selected if (hti.HitTestLocation == HitTestLocation.Button) { Invalidate(); return true; } // If they didn't click checkbox, we can just return if (hti.HitTestLocation != HitTestLocation.CheckBox) return false; // Disabled rows cannot change checkboxes if (!hti.Item.Enabled) return true; // Did they click a sub item checkbox? if (hti.Column != null && hti.Column.Index > 0) { if (hti.Column.IsEditable && hti.Item.Enabled) ToggleSubItemCheckBox(hti.RowObject, hti.Column); return true; } // They must have clicked the primary checkbox ToggleCheckObject(hti.RowObject); // If they change the checkbox of a selected row, all the rows in the selection // should be given the same state if (hti.Item.Selected) { CheckState? state = GetCheckState(hti.RowObject); if (state.HasValue) { foreach (Object x in SelectedObjects) SetObjectCheckedness(x, state.Value); } } return true; } /// /// Catch the Left Button up event. /// /// The m to be processed /// bool to indicate if the msg has been handled protected virtual bool HandleLButtonUp(ref Message m) { if (MouseMoveHitTest == null) return false; int x = m.LParam.ToInt32() & 0xFFFF; int y = (m.LParam.ToInt32() >> 16) & 0xFFFF; // Did they click an enabled, non-empty button? if (MouseMoveHitTest.HitTestLocation == HitTestLocation.Button) { // If a button was hit, Item and Column must be non-null if (MouseMoveHitTest.Item.Enabled || MouseMoveHitTest.Column.EnableButtonWhenItemIsDisabled) { string buttonText = MouseMoveHitTest.Column.GetStringValue(MouseMoveHitTest.RowObject); if (!String.IsNullOrEmpty(buttonText)) { Invalidate(); CellClickEventArgs args = new CellClickEventArgs(); BuildCellEvent(args, new Point(x, y), MouseMoveHitTest); OnButtonClick(args); return true; } } } // Are they trying to expand/collapse a group? if (MouseMoveHitTest.HitTestLocation == HitTestLocation.GroupExpander) { if (TriggerGroupExpandCollapse(MouseMoveHitTest.Group)) return true; } if (IsVistaOrLater && HasCollapsibleGroups) base.DefWndProc(ref m); return false; } /// /// Trigger a GroupExpandCollapse event and return true if the action was cancelled /// /// /// protected virtual bool TriggerGroupExpandCollapse(OLVGroup group) { GroupExpandingCollapsingEventArgs args = new GroupExpandingCollapsingEventArgs(group); OnGroupExpandingCollapsing(args); return args.Canceled; } /// /// Catch the Right Button down event. /// /// The m to be processed /// bool to indicate if the msg has been handled protected virtual bool HandleRButtonDown(ref Message m) { int x = m.LParam.ToInt32() & 0xFFFF; int y = (m.LParam.ToInt32() >> 16) & 0xFFFF; return ProcessRButtonDown(OlvHitTest(x, y)); } /// /// Handle a left mouse down at the given hit test location /// /// Subclasses can override this to do something unique /// /// True if the message has been handled protected virtual bool ProcessRButtonDown(OlvListViewHitTestInfo hti) { if (hti.Item == null) return false; // Ignore clicks on checkboxes return (hti.HitTestLocation == HitTestLocation.CheckBox); } /// /// Catch the Left Button double click event. /// /// The m to be processed /// bool to indicate if the msg has been handled protected virtual bool HandleLButtonDoubleClick(ref Message m) { int x = m.LParam.ToInt32() & 0xFFFF; int y = (m.LParam.ToInt32() >> 16) & 0xFFFF; return ProcessLButtonDoubleClick(OlvHitTest(x, y)); } /// /// Handle a mouse double click at the given hit test location /// /// Subclasses can override this to do something unique /// /// True if the message has been handled protected virtual bool ProcessLButtonDoubleClick(OlvListViewHitTestInfo hti) { // If the user double clicked on a checkbox, ignore it return (hti.HitTestLocation == HitTestLocation.CheckBox); } /// /// Catch the right Button double click event. /// /// The m to be processed /// bool to indicate if the msg has been handled protected virtual bool HandleRButtonDoubleClick(ref Message m) { int x = m.LParam.ToInt32() & 0xFFFF; int y = (m.LParam.ToInt32() >> 16) & 0xFFFF; return ProcessRButtonDoubleClick(OlvHitTest(x, y)); } /// /// Handle a right mouse double click at the given hit test location /// /// Subclasses can override this to do something unique /// /// True if the message has been handled protected virtual bool ProcessRButtonDoubleClick(OlvListViewHitTestInfo hti) { // If the user double clicked on a checkbox, ignore it return (hti.HitTestLocation == HitTestLocation.CheckBox); } /// /// Catch the MouseMove event. /// /// The m to be processed /// bool to indicate if the msg has been handled protected virtual bool HandleMouseMove(ref Message m) { //int x = m.LParam.ToInt32() & 0xFFFF; //int y = (m.LParam.ToInt32() >> 16) & 0xFFFF; //this.lastMouseMoveX = x; //this.lastMouseMoveY = y; return false; } //private int lastMouseMoveX = -1; //private int lastMouseMoveY = -1; /// /// Handle notifications that have been reflected back from the parent window /// /// The m to be processed /// bool to indicate if the msg has been handled protected virtual bool HandleReflectNotify(ref Message m) { const int NM_CLICK = -2; const int NM_DBLCLK = -3; const int NM_RDBLCLK = -6; const int NM_CUSTOMDRAW = -12; const int NM_RELEASEDCAPTURE = -16; const int LVN_FIRST = -100; const int LVN_ITEMCHANGED = LVN_FIRST - 1; const int LVN_ITEMCHANGING = LVN_FIRST - 0; const int LVN_HOTTRACK = LVN_FIRST - 21; const int LVN_MARQUEEBEGIN = LVN_FIRST - 56; const int LVN_GETINFOTIP = LVN_FIRST - 58; const int LVN_GETDISPINFO = LVN_FIRST - 77; const int LVN_BEGINSCROLL = LVN_FIRST - 80; const int LVN_ENDSCROLL = LVN_FIRST - 81; const int LVN_LINKCLICK = LVN_FIRST - 84; const int LVN_GROUPINFO = LVN_FIRST - 88; // undocumented const int LVIF_STATE = 8; //const int LVIS_FOCUSED = 1; const int LVIS_SELECTED = 2; bool isMsgHandled = false; // TODO: Don't do any logic in this method. Create separate methods for each message NativeMethods.NMHDR nmhdr = (NativeMethods.NMHDR)m.GetLParam(typeof(NativeMethods.NMHDR)); //System.Diagnostics.Debug.WriteLine(String.Format("rn: {0}", nmhdr->code)); switch (nmhdr.code) { case NM_CLICK: // The standard ListView does some strange stuff here when the list has checkboxes. // If you shift click on non-primary columns when FullRowSelect is true, the // checkedness of the selected rows changes. // We can't just not do the base class stuff because it sets up state that is used to // determine mouse up events later on. // So, we sabotage the base class's process of the click event. The base class does a HITTEST // in order to determine which row was clicked -- if that fails, the base class does nothing. // So when we get a CLICK, we know that the base class is going to send a HITTEST very soon, // so we ignore the next HITTEST message, which will cause the click processing to fail. //System.Diagnostics.Debug.WriteLine("NM_CLICK"); skipNextHitTest = true; break; case LVN_BEGINSCROLL: //System.Diagnostics.Debug.WriteLine("LVN_BEGINSCROLL"); isMsgHandled = HandleBeginScroll(ref m); break; case LVN_ENDSCROLL: isMsgHandled = HandleEndScroll(ref m); break; case LVN_LINKCLICK: isMsgHandled = HandleLinkClick(ref m); break; case LVN_MARQUEEBEGIN: //System.Diagnostics.Debug.WriteLine("LVN_MARQUEEBEGIN"); isMarqueSelecting = true; break; case LVN_GETINFOTIP: //System.Diagnostics.Debug.WriteLine("LVN_GETINFOTIP"); // When virtual lists are in SmallIcon view, they generates tooltip message with invalid item indicies. NativeMethods.NMLVGETINFOTIP nmGetInfoTip = (NativeMethods.NMLVGETINFOTIP)m.GetLParam(typeof(NativeMethods.NMLVGETINFOTIP)); isMsgHandled = nmGetInfoTip.iItem >= GetItemCount(); break; case NM_RELEASEDCAPTURE: //System.Diagnostics.Debug.WriteLine("NM_RELEASEDCAPTURE"); isMarqueSelecting = false; Invalidate(); break; case NM_CUSTOMDRAW: //System.Diagnostics.Debug.WriteLine("NM_CUSTOMDRAW"); isMsgHandled = HandleCustomDraw(ref m); break; case NM_DBLCLK: // The default behavior of a .NET ListView with checkboxes is to toggle the checkbox on // double-click. That's just silly, if you ask me :) if (CheckBoxes) { // How do we make ListView not do that silliness? We could just ignore the message // but the last part of the base code sets up state information, and without that // state, the ListView doesn't trigger MouseDoubleClick events. So we fake a // right button double click event, which sets up the same state, but without // toggling the checkbox. nmhdr.code = NM_RDBLCLK; Marshal.StructureToPtr(nmhdr, m.LParam, false); } break; case LVN_ITEMCHANGED: //System.Diagnostics.Debug.WriteLine("LVN_ITEMCHANGED"); NativeMethods.NMLISTVIEW nmlistviewPtr2 = (NativeMethods.NMLISTVIEW)m.GetLParam(typeof(NativeMethods.NMLISTVIEW)); if ((nmlistviewPtr2.uChanged & LVIF_STATE) != 0) { CheckState currentValue = CalculateCheckState(nmlistviewPtr2.uOldState); CheckState newCheckValue = CalculateCheckState(nmlistviewPtr2.uNewState); if (currentValue != newCheckValue) { // Remove the state indicies so that we don't trigger the OnItemChecked method // when we call our base method after exiting this method nmlistviewPtr2.uOldState &= 0x0FFF; nmlistviewPtr2.uNewState &= 0x0FFF; Marshal.StructureToPtr(nmlistviewPtr2, m.LParam, false); } else { bool isSelected = (nmlistviewPtr2.uNewState & LVIS_SELECTED) == LVIS_SELECTED; if (isSelected) { // System.Diagnostics.Debug.WriteLine(String.Format("Selected: {0}", nmlistviewPtr2.iItem)); bool isShiftDown = (ModifierKeys & Keys.Shift) == Keys.Shift; // -1 indicates that all rows are to be selected -- in fact, they already have been. // We now have to deselect all the disabled objects. if (nmlistviewPtr2.iItem == -1 || isShiftDown) { Stopwatch sw = Stopwatch.StartNew(); foreach (object disabledModel in DisabledObjects) { int modelIndex = IndexOf(disabledModel); if (modelIndex >= 0) NativeMethods.DeselectOneItem(this, modelIndex); } Debug.WriteLine(String.Format("PERF - Deselecting took {0}ms / {1} ticks", sw.ElapsedMilliseconds, sw.ElapsedTicks)); } else { // If the object just selected is disabled, explicitly de-select it OLVListItem olvi = GetItem(nmlistviewPtr2.iItem); if (olvi != null && !olvi.Enabled) NativeMethods.DeselectOneItem(this, nmlistviewPtr2.iItem); } } } } break; case LVN_ITEMCHANGING: //System.Diagnostics.Debug.WriteLine("LVN_ITEMCHANGING"); NativeMethods.NMLISTVIEW nmlistviewPtr = (NativeMethods.NMLISTVIEW)m.GetLParam(typeof(NativeMethods.NMLISTVIEW)); if ((nmlistviewPtr.uChanged & LVIF_STATE) != 0) { CheckState currentValue = CalculateCheckState(nmlistviewPtr.uOldState); CheckState newCheckValue = CalculateCheckState(nmlistviewPtr.uNewState); if (currentValue != newCheckValue) { // Prevent the base method from seeing the state change, // since we handled it elsewhere nmlistviewPtr.uChanged &= ~LVIF_STATE; Marshal.StructureToPtr(nmlistviewPtr, m.LParam, false); } } break; case LVN_HOTTRACK: break; case LVN_GETDISPINFO: break; case LVN_GROUPINFO: //System.Diagnostics.Debug.WriteLine("reflect notify: GROUP INFO"); isMsgHandled = HandleGroupInfo(ref m); break; //default: //System.Diagnostics.Debug.WriteLine(String.Format("reflect notify: {0}", nmhdr.code)); //break; } return isMsgHandled; } private bool skipNextHitTest; private CheckState CalculateCheckState(int state) { switch ((state & 0xf000) >> 12) { case 1: return CheckState.Unchecked; case 2: return CheckState.Checked; case 3: return CheckState.Indeterminate; default: return CheckState.Checked; } } /// /// In the notification messages, we handle attempts to change the width of our columns /// /// The m to be processed /// bool to indicate if the msg has been handled protected bool HandleNotify(ref Message m) { bool isMsgHandled = false; const int NM_CUSTOMDRAW = -12; const int HDN_FIRST = (0 - 300); const int HDN_ITEMCHANGINGA = (HDN_FIRST - 0); const int HDN_ITEMCHANGINGW = (HDN_FIRST - 20); const int HDN_ITEMCLICKA = (HDN_FIRST - 2); const int HDN_ITEMCLICKW = (HDN_FIRST - 22); const int HDN_DIVIDERDBLCLICKA = (HDN_FIRST - 5); const int HDN_DIVIDERDBLCLICKW = (HDN_FIRST - 25); const int HDN_BEGINTRACKA = (HDN_FIRST - 6); const int HDN_BEGINTRACKW = (HDN_FIRST - 26); const int HDN_ENDTRACKA = (HDN_FIRST - 7); const int HDN_ENDTRACKW = (HDN_FIRST - 27); const int HDN_TRACKA = (HDN_FIRST - 8); const int HDN_TRACKW = (HDN_FIRST - 28); // Handle the notification, remembering to handle both ANSI and Unicode versions NativeMethods.NMHEADER nmheader = (NativeMethods.NMHEADER)m.GetLParam(typeof(NativeMethods.NMHEADER)); //System.Diagnostics.Debug.WriteLine(String.Format("not: {0}", nmhdr->code)); //if (nmhdr.code < HDN_FIRST) // System.Diagnostics.Debug.WriteLine(nmhdr.code); // In KB Article #183258, MS states that when a header control has the HDS_FULLDRAG style, it will receive // ITEMCHANGING events rather than TRACK events. Under XP SP2 (at least) this is not always true, which may be // why MS has withdrawn that particular KB article. It is true that the header is always given the HDS_FULLDRAG // style. But even while window style set, the control doesn't always received ITEMCHANGING events. // The controlling setting seems to be the Explorer option "Show Window Contents While Dragging"! // In the category of "truly bizarre side effects", if the this option is turned on, we will receive // ITEMCHANGING events instead of TRACK events. But if it is turned off, we receive lots of TRACK events and // only one ITEMCHANGING event at the very end of the process. // If we receive HDN_TRACK messages, it's harder to control the resizing process. If we return a result of 1, we // cancel the whole drag operation, not just that particular track event, which is clearly not what we want. // If we are willing to compile with unsafe code enabled, we can modify the size of the column in place, using the // commented out code below. But without unsafe code, the best we can do is allow the user to drag the column to // any width, and then spring it back to within bounds once they release the mouse button. UI-wise it's very ugly. switch (nmheader.nhdr.code) { case NM_CUSTOMDRAW: if (!OwnerDrawnHeader) isMsgHandled = HeaderControl.HandleHeaderCustomDraw(ref m); break; case HDN_ITEMCLICKA: case HDN_ITEMCLICKW: if (!PossibleFinishCellEditing()) { m.Result = (IntPtr)1; // prevent the change from happening isMsgHandled = true; } break; case HDN_DIVIDERDBLCLICKA: case HDN_DIVIDERDBLCLICKW: case HDN_BEGINTRACKA: case HDN_BEGINTRACKW: if (!PossibleFinishCellEditing()) { m.Result = (IntPtr)1; // prevent the change from happening isMsgHandled = true; break; } if (nmheader.iItem >= 0 && nmheader.iItem < Columns.Count) { OLVColumn column = GetColumn(nmheader.iItem); // Space filling columns can't be dragged or double-click resized if (column.FillsFreeSpace) { m.Result = (IntPtr)1; // prevent the change from happening isMsgHandled = true; } } break; case HDN_ENDTRACKA: case HDN_ENDTRACKW: //if (this.ShowGroups) // this.ResizeLastGroup(); break; case HDN_TRACKA: case HDN_TRACKW: if (nmheader.iItem >= 0 && nmheader.iItem < Columns.Count) { NativeMethods.HDITEM hditem = (NativeMethods.HDITEM)Marshal.PtrToStructure(nmheader.pHDITEM, typeof(NativeMethods.HDITEM)); OLVColumn column = GetColumn(nmheader.iItem); if (hditem.cxy < column.MinimumWidth) hditem.cxy = column.MinimumWidth; else if (column.MaximumWidth != -1 && hditem.cxy > column.MaximumWidth) hditem.cxy = column.MaximumWidth; Marshal.StructureToPtr(hditem, nmheader.pHDITEM, false); } break; case HDN_ITEMCHANGINGA: case HDN_ITEMCHANGINGW: nmheader = (NativeMethods.NMHEADER)m.GetLParam(typeof(NativeMethods.NMHEADER)); if (nmheader.iItem >= 0 && nmheader.iItem < Columns.Count) { NativeMethods.HDITEM hditem = (NativeMethods.HDITEM)Marshal.PtrToStructure(nmheader.pHDITEM, typeof(NativeMethods.HDITEM)); OLVColumn column = GetColumn(nmheader.iItem); // Check the mask to see if the width field is valid, and if it is, make sure it's within range if ((hditem.mask & 1) == 1) { if (hditem.cxy < column.MinimumWidth || (column.MaximumWidth != -1 && hditem.cxy > column.MaximumWidth)) { m.Result = (IntPtr)1; // prevent the change from happening isMsgHandled = true; } } } break; case ToolTipControl.TTN_SHOW: //System.Diagnostics.Debug.WriteLine("olv TTN_SHOW"); if (CellToolTip.Handle == nmheader.nhdr.hwndFrom) isMsgHandled = CellToolTip.HandleShow(ref m); break; case ToolTipControl.TTN_POP: //System.Diagnostics.Debug.WriteLine("olv TTN_POP"); if (CellToolTip.Handle == nmheader.nhdr.hwndFrom) isMsgHandled = CellToolTip.HandlePop(ref m); break; case ToolTipControl.TTN_GETDISPINFO: //System.Diagnostics.Debug.WriteLine("olv TTN_GETDISPINFO"); if (CellToolTip.Handle == nmheader.nhdr.hwndFrom) isMsgHandled = CellToolTip.HandleGetDispInfo(ref m); break; // default: // System.Diagnostics.Debug.WriteLine(String.Format("notify: {0}", nmheader.nhdr.code)); // break; } return isMsgHandled; } /// /// Create a ToolTipControl to manage the tooltip control used by the listview control /// protected virtual void CreateCellToolTip() { cellToolTip = new ToolTipControl(); cellToolTip.AssignHandle(NativeMethods.GetTooltipControl(this)); cellToolTip.Showing += new EventHandler(HandleCellToolTipShowing); cellToolTip.SetMaxWidth(); NativeMethods.MakeTopMost(cellToolTip); } /// /// Update the handle used by our cell tooltip to be the tooltip used by /// the underlying Windows listview control. /// protected virtual void UpdateCellToolTipHandle() { if (cellToolTip != null && cellToolTip.Handle == IntPtr.Zero) cellToolTip.AssignHandle(NativeMethods.GetTooltipControl(this)); } /// /// Handle the WM_PAINT event /// /// /// Return true if the msg has been handled and nothing further should be done protected virtual bool HandlePaint(ref Message m) { //System.Diagnostics.Debug.WriteLine("> WMPAINT"); // We only want to custom draw the control within WmPaint message and only // once per paint event. We use these bools to insure this. isInWmPaintEvent = true; shouldDoCustomDrawing = true; prePaintLevel = 0; ShowOverlays(); HandlePrePaint(); base.WndProc(ref m); HandlePostPaint(); isInWmPaintEvent = false; //System.Diagnostics.Debug.WriteLine("< WMPAINT"); return true; } private int prePaintLevel; /// /// Perform any steps needed before painting the control /// protected virtual void HandlePrePaint() { // When we get a WM_PAINT msg, remember the rectangle that is being updated. // We can't get this information later, since the BeginPaint call wipes it out. // this.lastUpdateRectangle = NativeMethods.GetUpdateRect(this); // we no longer need this, but keep the code so we can see it later //// When the list is empty, we want to handle the drawing of the control by ourselves. //// Unfortunately, there is no easy way to tell our superclass that we want to do this. //// So we resort to guile and deception. We validate the list area of the control, which //// effectively tells our superclass that this area does not need to be painted. //// Our superclass will then not paint the control, leaving us free to do so ourselves. //// Without doing this trickery, the superclass will draw the list as empty, //// and then moments later, we will draw the empty list msg, giving a nasty flicker //if (this.GetItemCount() == 0 && this.HasEmptyListMsg) // NativeMethods.ValidateRect(this, this.ClientRectangle); } /// /// Perform any steps needed after painting the control /// protected virtual void HandlePostPaint() { // This message is no longer necessary, but we keep it for compatibility } /// /// Handle the window position changing. /// /// The m to be processed /// bool to indicate if the msg has been handled protected virtual bool HandleWindowPosChanging(ref Message m) { const int SWP_NOSIZE = 1; NativeMethods.WINDOWPOS pos = (NativeMethods.WINDOWPOS)m.GetLParam(typeof(NativeMethods.WINDOWPOS)); if ((pos.flags & SWP_NOSIZE) == 0) { if (pos.cx < Bounds.Width) // only when shrinking // pos.cx is the window width, not the client area width, so we have to subtract the border widths ResizeFreeSpaceFillingColumns(pos.cx - (Bounds.Width - ClientSize.Width)); } return false; } #endregion #region Column header clicking, column hiding and resizing /// /// The user has right clicked on the column headers. Do whatever is required /// /// Return true if this event has been handle protected virtual bool HandleHeaderRightClick(int columnIndex) { ColumnClickEventArgs eventArgs = new ColumnClickEventArgs(columnIndex); OnColumnRightClick(eventArgs); // TODO: Allow users to say they have handled this event return ShowHeaderRightClickMenu(columnIndex, Cursor.Position); } /// /// Show a menu that is appropriate when the given column header is clicked. /// /// The index of the header that was clicked. This /// can be -1, indicating that the header was clicked outside of a column /// Where should the menu be shown /// True if a menu was displayed protected virtual bool ShowHeaderRightClickMenu(int columnIndex, Point pt) { ToolStripDropDown m = MakeHeaderRightClickMenu(columnIndex); if (m.Items.Count > 0) { m.Show(pt); return true; } return false; } /// /// Create the menu that should be displayed when the user right clicks /// on the given column header. /// /// Index of the column that was right clicked. /// This can be negative, which indicates a click outside of any header. /// The toolstrip that should be displayed protected virtual ToolStripDropDown MakeHeaderRightClickMenu(int columnIndex) { ToolStripDropDown m = new ContextMenuStrip(); if (columnIndex >= 0 && UseFiltering && ShowFilterMenuOnRightClick) m = MakeFilteringMenu(m, columnIndex); if (columnIndex >= 0 && ShowCommandMenuOnRightClick) m = MakeColumnCommandMenu(m, columnIndex); if (SelectColumnsOnRightClickBehaviour != ColumnSelectBehaviour.None) { m = MakeColumnSelectMenu(m); } return m; } /// /// The user has right clicked on the column headers. Do whatever is required /// /// Return true if this event has been handle [Obsolete("Use HandleHeaderRightClick(int) instead")] protected virtual bool HandleHeaderRightClick() { return false; } /// /// Show a popup menu at the given point which will allow the user to choose which columns /// are visible on this listview /// /// Where should the menu be placed [Obsolete("Use ShowHeaderRightClickMenu instead")] protected virtual void ShowColumnSelectMenu(Point pt) { ToolStripDropDown m = MakeColumnSelectMenu(new ContextMenuStrip()); m.Show(pt); } /// /// Show a popup menu at the given point which will allow the user to choose which columns /// are visible on this listview /// /// /// Where should the menu be placed [Obsolete("Use ShowHeaderRightClickMenu instead")] protected virtual void ShowColumnCommandMenu(int columnIndex, Point pt) { ToolStripDropDown m = MakeColumnCommandMenu(new ContextMenuStrip(), columnIndex); if (SelectColumnsOnRightClick) { if (m.Items.Count > 0) m.Items.Add(new ToolStripSeparator()); MakeColumnSelectMenu(m); } m.Show(pt); } /// /// Gets or set the text to be used for the sorting ascending command /// [Category("Labels - ObjectListView"), DefaultValue("Sort ascending by '{0}'"), Localizable(true)] public string MenuLabelSortAscending { get { return menuLabelSortAscending; } set { menuLabelSortAscending = value; } } private string menuLabelSortAscending = "Sort ascending by '{0}'"; /// /// /// [Category("Labels - ObjectListView"), DefaultValue("Sort descending by '{0}'"), Localizable(true)] public string MenuLabelSortDescending { get { return menuLabelSortDescending; } set { menuLabelSortDescending = value; } } private string menuLabelSortDescending = "Sort descending by '{0}'"; /// /// /// [Category("Labels - ObjectListView"), DefaultValue("Group by '{0}'"), Localizable(true)] public string MenuLabelGroupBy { get { return menuLabelGroupBy; } set { menuLabelGroupBy = value; } } private string menuLabelGroupBy = "Group by '{0}'"; /// /// /// [Category("Labels - ObjectListView"), DefaultValue("Lock grouping on '{0}'"), Localizable(true)] public string MenuLabelLockGroupingOn { get { return menuLabelLockGroupingOn; } set { menuLabelLockGroupingOn = value; } } private string menuLabelLockGroupingOn = "Lock grouping on '{0}'"; /// /// /// [Category("Labels - ObjectListView"), DefaultValue("Unlock grouping from '{0}'"), Localizable(true)] public string MenuLabelUnlockGroupingOn { get { return menuLabelUnlockGroupingOn; } set { menuLabelUnlockGroupingOn = value; } } private string menuLabelUnlockGroupingOn = "Unlock grouping from '{0}'"; /// /// /// [Category("Labels - ObjectListView"), DefaultValue("Turn off groups"), Localizable(true)] public string MenuLabelTurnOffGroups { get { return menuLabelTurnOffGroups; } set { menuLabelTurnOffGroups = value; } } private string menuLabelTurnOffGroups = "Turn off groups"; /// /// /// [Category("Labels - ObjectListView"), DefaultValue("Unsort"), Localizable(true)] public string MenuLabelUnsort { get { return menuLabelUnsort; } set { menuLabelUnsort = value; } } private string menuLabelUnsort = "Unsort"; /// /// /// [Category("Labels - ObjectListView"), DefaultValue("Columns"), Localizable(true)] public string MenuLabelColumns { get { return menuLabelColumns; } set { menuLabelColumns = value; } } private string menuLabelColumns = "Columns"; /// /// /// [Category("Labels - ObjectListView"), DefaultValue("Select Columns..."), Localizable(true)] public string MenuLabelSelectColumns { get { return menuLabelSelectColumns; } set { menuLabelSelectColumns = value; } } private string menuLabelSelectColumns = "Select Columns..."; /// /// Gets or sets the image that will be place next to the Sort Ascending command /// public static Bitmap SortAscendingImage = Properties.Resources.SortAscending; /// /// Gets or sets the image that will be placed next to the Sort Descending command /// public static Bitmap SortDescendingImage = Properties.Resources.SortDescending; /// /// Append the column selection menu items to the given menu strip. /// /// The menu to which the items will be added. /// /// Return the menu to which the items were added public virtual ToolStripDropDown MakeColumnCommandMenu(ToolStripDropDown strip, int columnIndex) { OLVColumn column = GetColumn(columnIndex); if (column == null) return strip; if (strip.Items.Count > 0) strip.Items.Add(new ToolStripSeparator()); string label = String.Format(MenuLabelSortAscending, column.Text); if (column.Sortable && !String.IsNullOrEmpty(label)) { strip.Items.Add(label, SortAscendingImage, (EventHandler)delegate (object sender, EventArgs args) { Sort(column, SortOrder.Ascending); }); } label = String.Format(MenuLabelSortDescending, column.Text); if (column.Sortable && !String.IsNullOrEmpty(label)) { strip.Items.Add(label, SortDescendingImage, (EventHandler)delegate (object sender, EventArgs args) { Sort(column, SortOrder.Descending); }); } if (CanShowGroups) { label = String.Format(MenuLabelGroupBy, column.Text); if (column.Groupable && !String.IsNullOrEmpty(label)) { strip.Items.Add(label, null, (EventHandler)delegate (object sender, EventArgs args) { ShowGroups = true; PrimarySortColumn = column; PrimarySortOrder = SortOrder.Ascending; BuildList(); }); } } if (ShowGroups) { if (AlwaysGroupByColumn == column) { label = String.Format(MenuLabelUnlockGroupingOn, column.Text); if (!String.IsNullOrEmpty(label)) { strip.Items.Add(label, null, (EventHandler)delegate (object sender, EventArgs args) { AlwaysGroupByColumn = null; AlwaysGroupBySortOrder = SortOrder.None; BuildList(); }); } } else { label = String.Format(MenuLabelLockGroupingOn, column.Text); if (column.Groupable && !String.IsNullOrEmpty(label)) { strip.Items.Add(label, null, (EventHandler)delegate (object sender, EventArgs args) { ShowGroups = true; AlwaysGroupByColumn = column; AlwaysGroupBySortOrder = SortOrder.Ascending; BuildList(); }); } } label = String.Format(MenuLabelTurnOffGroups, column.Text); if (!String.IsNullOrEmpty(label)) { strip.Items.Add(label, null, (EventHandler)delegate (object sender, EventArgs args) { ShowGroups = false; BuildList(); }); } } else { label = String.Format(MenuLabelUnsort, column.Text); if (column.Sortable && !String.IsNullOrEmpty(label) && PrimarySortOrder != SortOrder.None) { strip.Items.Add(label, null, (EventHandler)delegate (object sender, EventArgs args) { Unsort(); }); } } return strip; } /// /// Append the column selection menu items to the given menu strip. /// /// The menu to which the items will be added. /// Return the menu to which the items were added public virtual ToolStripDropDown MakeColumnSelectMenu(ToolStripDropDown strip) { Debug.Assert(SelectColumnsOnRightClickBehaviour != ColumnSelectBehaviour.None); // Append a separator if the menu isn't empty and the last item isn't already a separator if (strip.Items.Count > 0 && (!(strip.Items[strip.Items.Count - 1] is ToolStripSeparator))) strip.Items.Add(new ToolStripSeparator()); if (AllColumns.Count > 0 && AllColumns[0].LastDisplayIndex == -1) RememberDisplayIndicies(); if (SelectColumnsOnRightClickBehaviour == ColumnSelectBehaviour.ModelDialog) { strip.Items.Add(MenuLabelSelectColumns, null, delegate (object sender, EventArgs args) { (new ColumnSelectionForm()).OpenOn(this); }); } if (SelectColumnsOnRightClickBehaviour == ColumnSelectBehaviour.Submenu) { ToolStripMenuItem menu = new ToolStripMenuItem(MenuLabelColumns); menu.DropDownItemClicked += new ToolStripItemClickedEventHandler(ColumnSelectMenuItemClicked); strip.Items.Add(menu); AddItemsToColumnSelectMenu(menu.DropDownItems); } if (SelectColumnsOnRightClickBehaviour == ColumnSelectBehaviour.InlineMenu) { strip.ItemClicked += new ToolStripItemClickedEventHandler(ColumnSelectMenuItemClicked); strip.Closing += new ToolStripDropDownClosingEventHandler(ColumnSelectMenuClosing); AddItemsToColumnSelectMenu(strip.Items); } return strip; } /// /// Create the menu items that will allow columns to be choosen and add them to the /// given collection /// /// protected void AddItemsToColumnSelectMenu(ToolStripItemCollection items) { // Sort columns by display order List columns = new List(AllColumns); columns.Sort(delegate (OLVColumn x, OLVColumn y) { return (x.LastDisplayIndex - y.LastDisplayIndex); }); // Build menu from sorted columns foreach (OLVColumn col in columns) { ToolStripMenuItem mi = new ToolStripMenuItem(col.Text); mi.Checked = col.IsVisible; mi.Tag = col; // The 'Index' property returns -1 when the column is not visible, so if the // column isn't visible we have to enable the item. Also the first column can't be turned off mi.Enabled = !col.IsVisible || col.CanBeHidden; items.Add(mi); } } private void ColumnSelectMenuItemClicked(object sender, ToolStripItemClickedEventArgs e) { contextMenuStaysOpen = false; if (e.ClickedItem is not ToolStripMenuItem menuItemClicked) return; if (menuItemClicked.Tag is not OLVColumn col) return; menuItemClicked.Checked = !menuItemClicked.Checked; col.IsVisible = menuItemClicked.Checked; contextMenuStaysOpen = SelectColumnsMenuStaysOpen; BeginInvoke(new MethodInvoker(RebuildColumns)); } private bool contextMenuStaysOpen; private void ColumnSelectMenuClosing(object sender, ToolStripDropDownClosingEventArgs e) { e.Cancel = contextMenuStaysOpen && e.CloseReason == ToolStripDropDownCloseReason.ItemClicked; contextMenuStaysOpen = false; } /// /// Create a Filtering menu /// /// /// /// public virtual ToolStripDropDown MakeFilteringMenu(ToolStripDropDown strip, int columnIndex) { OLVColumn column = GetColumn(columnIndex); if (column == null) return strip; FilterMenuBuilder strategy = FilterMenuBuildStrategy; if (strategy == null) return strip; return strategy.MakeFilterMenu(strip, this, column); } /// /// Override the OnColumnReordered method to do what we want /// /// protected override void OnColumnReordered(ColumnReorderedEventArgs e) { base.OnColumnReordered(e); // The internal logic of the .NET code behind a ENDDRAG event means that, // at this point, the DisplayIndex's of the columns are not yet as they are // going to be. So we have to invoke a method to run later that will remember // what the real DisplayIndex's are. BeginInvoke(new MethodInvoker(RememberDisplayIndicies)); } private void RememberDisplayIndicies() { // Remember the display indexes so we can put them back at a later date foreach (OLVColumn x in AllColumns) x.LastDisplayIndex = x.DisplayIndex; } /// /// When the column widths are changing, resize the space filling columns /// /// /// protected virtual void HandleColumnWidthChanging(object sender, ColumnWidthChangingEventArgs e) { if (UpdateSpaceFillingColumnsWhenDraggingColumnDivider && !GetColumn(e.ColumnIndex).FillsFreeSpace) { // If the width of a column is increasing, resize any space filling columns allowing the extra // space that the new column width is going to consume int oldWidth = GetColumn(e.ColumnIndex).Width; if (e.NewWidth > oldWidth) ResizeFreeSpaceFillingColumns(ClientSize.Width - (e.NewWidth - oldWidth)); else ResizeFreeSpaceFillingColumns(); } } /// /// When the column widths change, resize the space filling columns /// /// /// protected virtual void HandleColumnWidthChanged(object sender, ColumnWidthChangedEventArgs e) { if (!GetColumn(e.ColumnIndex).FillsFreeSpace) ResizeFreeSpaceFillingColumns(); } /// /// When the size of the control changes, we have to resize our space filling columns. /// /// /// protected virtual void HandleLayout(object sender, LayoutEventArgs e) { // We have to delay executing the recalculation of the columns, since virtual lists // get terribly confused if we resize the column widths during this event. if (!hasResizeColumnsHandler) { hasResizeColumnsHandler = true; RunWhenIdle(HandleApplicationIdleResizeColumns); } } private void RunWhenIdle(EventHandler eventHandler) { Application.Idle += eventHandler; if (!CanUseApplicationIdle) { SynchronizationContext.Current.Post(delegate (object x) { Application.RaiseIdle(EventArgs.Empty); }, null); } } /// /// Resize our space filling columns so they fill any unoccupied width in the control /// protected virtual void ResizeFreeSpaceFillingColumns() { ResizeFreeSpaceFillingColumns(ClientSize.Width); } /// /// Resize our space filling columns so they fill any unoccupied width in the control /// protected virtual void ResizeFreeSpaceFillingColumns(int freeSpace) { // It's too confusing to dynamically resize columns at design time. if (DesignMode) return; if (Frozen) return; // Calculate the free space available int totalProportion = 0; List spaceFillingColumns = new List(); for (int i = 0; i < Columns.Count; i++) { OLVColumn col = GetColumn(i); if (col.FillsFreeSpace) { spaceFillingColumns.Add(col); totalProportion += col.FreeSpaceProportion; } else freeSpace -= col.Width; } freeSpace = Math.Max(0, freeSpace); // Any space filling column that would hit it's Minimum or Maximum // width must be treated as a fixed column. foreach (OLVColumn col in spaceFillingColumns.ToArray()) { int newWidth = (freeSpace * col.FreeSpaceProportion) / totalProportion; if (col.MinimumWidth != -1 && newWidth < col.MinimumWidth) newWidth = col.MinimumWidth; else if (col.MaximumWidth != -1 && newWidth > col.MaximumWidth) newWidth = col.MaximumWidth; else newWidth = 0; if (newWidth > 0) { col.Width = newWidth; freeSpace -= newWidth; totalProportion -= col.FreeSpaceProportion; spaceFillingColumns.Remove(col); } } // Distribute the free space between the columns foreach (OLVColumn col in spaceFillingColumns) { col.Width = (freeSpace * col.FreeSpaceProportion) / totalProportion; } } #endregion #region Checkboxes /// /// Check all rows /// public virtual void CheckAll() { CheckedObjects = EnumerableToArray(Objects, false); } /// /// Check the checkbox in the given column header /// /// If the given columns header check box is linked to the cell check boxes, /// then checkboxes in all cells will also be checked. /// public virtual void CheckHeaderCheckBox(OLVColumn column) { if (column == null) return; ChangeHeaderCheckBoxState(column, CheckState.Checked); } /// /// Mark the checkbox in the given column header as having an indeterminate value /// /// public virtual void CheckIndeterminateHeaderCheckBox(OLVColumn column) { if (column == null) return; ChangeHeaderCheckBoxState(column, CheckState.Indeterminate); } /// /// Mark the given object as indeterminate check state /// /// The model object to be marked indeterminate public virtual void CheckIndeterminateObject(object modelObject) { SetObjectCheckedness(modelObject, CheckState.Indeterminate); } /// /// Mark the given object as checked in the list /// /// The model object to be checked public virtual void CheckObject(object modelObject) { SetObjectCheckedness(modelObject, CheckState.Checked); } /// /// Mark the given objects as checked in the list /// /// The model object to be checked public virtual void CheckObjects(IEnumerable modelObjects) { foreach (object model in modelObjects) CheckObject(model); } /// /// Put a check into the check box at the given cell /// /// /// public virtual void CheckSubItem(object rowObject, OLVColumn column) { if (column == null || rowObject == null || !column.CheckBoxes) return; column.PutCheckState(rowObject, CheckState.Checked); RefreshObject(rowObject); } /// /// Put an indeterminate check into the check box at the given cell /// /// /// public virtual void CheckIndeterminateSubItem(object rowObject, OLVColumn column) { if (column == null || rowObject == null || !column.CheckBoxes) return; column.PutCheckState(rowObject, CheckState.Indeterminate); RefreshObject(rowObject); } /// /// Return true of the given object is checked /// /// The model object whose checkedness is returned /// Is the given object checked? /// If the given object is not in the list, this method returns false. public virtual bool IsChecked(object modelObject) { return GetCheckState(modelObject) == CheckState.Checked; } /// /// Return true of the given object is indeterminately checked /// /// The model object whose checkedness is returned /// Is the given object indeterminately checked? /// If the given object is not in the list, this method returns false. public virtual bool IsCheckedIndeterminate(object modelObject) { return GetCheckState(modelObject) == CheckState.Indeterminate; } /// /// Is there a check at the check box at the given cell /// /// /// public virtual bool IsSubItemChecked(object rowObject, OLVColumn column) { if (column == null || rowObject == null || !column.CheckBoxes) return false; return (column.GetCheckState(rowObject) == CheckState.Checked); } /// /// Get the checkedness of an object from the model. Returning null means the /// model does not know and the value from the control will be used. /// /// /// protected virtual CheckState? GetCheckState(Object modelObject) { if (CheckStateGetter != null) return CheckStateGetter(modelObject); return PersistentCheckBoxes ? GetPersistentCheckState(modelObject) : (CheckState?)null; } /// /// Record the change of checkstate for the given object in the model. /// This does not update the UI -- only the model /// /// /// /// The check state that was recorded and that should be used to update /// the control. protected virtual CheckState PutCheckState(Object modelObject, CheckState state) { if (CheckStatePutter != null) return CheckStatePutter(modelObject, state); return PersistentCheckBoxes ? SetPersistentCheckState(modelObject, state) : state; } /// /// Change the check state of the given object to be the given state. /// /// /// If the given model object isn't in the list, we still try to remember /// its state, in case it is referenced in the future. /// /// /// True if the checkedness of the model changed protected virtual bool SetObjectCheckedness(object modelObject, CheckState state) { if (GetCheckState(modelObject) == state) return false; OLVListItem olvi = ModelToItem(modelObject); // If we didn't find the given, we still try to record the check state. if (olvi == null) { PutCheckState(modelObject, state); return true; } // Trigger checkbox changing event ItemCheckEventArgs ice = new ItemCheckEventArgs(olvi.Index, state, olvi.CheckState); OnItemCheck(ice); if (ice.NewValue == olvi.CheckState) return false; olvi.CheckState = PutCheckState(modelObject, state); RefreshItem(olvi); // Trigger check changed event OnItemChecked(new ItemCheckedEventArgs(olvi)); return true; } /// /// Toggle the checkedness of the given object. A checked object becomes /// unchecked; an unchecked or indeterminate object becomes checked. /// If the list has tristate checkboxes, the order is: /// unchecked -> checked -> indeterminate -> unchecked ... /// /// The model object to be checked public virtual void ToggleCheckObject(object modelObject) { OLVListItem olvi = ModelToItem(modelObject); if (olvi == null) return; CheckState newState = CheckState.Checked; if (olvi.CheckState == CheckState.Checked) { newState = TriStateCheckBoxes ? CheckState.Indeterminate : CheckState.Unchecked; } else { if (olvi.CheckState == CheckState.Indeterminate && TriStateCheckBoxes) newState = CheckState.Unchecked; } SetObjectCheckedness(modelObject, newState); } /// /// Toggle the checkbox in the header of the given column /// /// Obviously, this is only useful if the column actually has a header checkbox. /// public virtual void ToggleHeaderCheckBox(OLVColumn column) { if (column == null) return; CheckState newState = CalculateToggledCheckState(column.HeaderCheckState, column.HeaderTriStateCheckBox, column.HeaderCheckBoxDisabled); ChangeHeaderCheckBoxState(column, newState); } private void ChangeHeaderCheckBoxState(OLVColumn column, CheckState newState) { // Tell the world the checkbox was clicked HeaderCheckBoxChangingEventArgs args = new HeaderCheckBoxChangingEventArgs(); args.Column = column; args.NewCheckState = newState; OnHeaderCheckBoxChanging(args); if (args.Cancel || column.HeaderCheckState == args.NewCheckState) return; Stopwatch sw = Stopwatch.StartNew(); column.HeaderCheckState = args.NewCheckState; HeaderControl.Invalidate(column); if (column.HeaderCheckBoxUpdatesRowCheckBoxes) { if (column.Index == 0) UpdateAllPrimaryCheckBoxes(column); else UpdateAllSubItemCheckBoxes(column); } Debug.WriteLine(String.Format("PERF - Changing row checkboxes on {2} objects took {0}ms / {1} ticks", sw.ElapsedMilliseconds, sw.ElapsedTicks, GetItemCount())); } private void UpdateAllPrimaryCheckBoxes(OLVColumn column) { if (!CheckBoxes || column.HeaderCheckState == CheckState.Indeterminate) return; if (column.HeaderCheckState == CheckState.Checked) CheckAll(); else UncheckAll(); } private void UpdateAllSubItemCheckBoxes(OLVColumn column) { if (!column.CheckBoxes || column.HeaderCheckState == CheckState.Indeterminate) return; foreach (object model in Objects) column.PutCheckState(model, column.HeaderCheckState); BuildList(true); } /// /// Toggle the check at the check box of the given cell /// /// /// public virtual void ToggleSubItemCheckBox(object rowObject, OLVColumn column) { CheckState currentState = column.GetCheckState(rowObject); CheckState newState = CalculateToggledCheckState(currentState, column.TriStateCheckBoxes, false); SubItemCheckingEventArgs args = new SubItemCheckingEventArgs(column, ModelToItem(rowObject), column.Index, currentState, newState); OnSubItemChecking(args); if (args.Canceled) return; switch (args.NewValue) { case CheckState.Checked: CheckSubItem(rowObject, column); break; case CheckState.Indeterminate: CheckIndeterminateSubItem(rowObject, column); break; case CheckState.Unchecked: UncheckSubItem(rowObject, column); break; } } /// /// Uncheck all rows /// public virtual void UncheckAll() { CheckedObjects = null; } /// /// Mark the given object as unchecked in the list /// /// The model object to be unchecked public virtual void UncheckObject(object modelObject) { SetObjectCheckedness(modelObject, CheckState.Unchecked); } /// /// Mark the given objects as unchecked in the list /// /// The model object to be checked public virtual void UncheckObjects(IEnumerable modelObjects) { foreach (object model in modelObjects) UncheckObject(model); } /// /// Uncheck the checkbox in the given column header /// /// public virtual void UncheckHeaderCheckBox(OLVColumn column) { if (column == null) return; ChangeHeaderCheckBoxState(column, CheckState.Unchecked); } /// /// Uncheck the check at the given cell /// /// /// public virtual void UncheckSubItem(object rowObject, OLVColumn column) { if (column == null || rowObject == null || !column.CheckBoxes) return; column.PutCheckState(rowObject, CheckState.Unchecked); RefreshObject(rowObject); } #endregion #region OLV accessing /// /// Return the column at the given index /// /// Index of the column to be returned /// An OLVColumn public virtual OLVColumn GetColumn(int index) { return (OLVColumn)Columns[index]; } /// /// Return the column at the given title. /// /// Name of the column to be returned /// An OLVColumn public virtual OLVColumn GetColumn(string name) { foreach (ColumnHeader column in Columns) { if (column.Text == name) return (OLVColumn)column; } return null; } /// /// Return a collection of columns that are visible to the given view. /// Only Tile and Details have columns; all other views have 0 columns. /// /// Which view are the columns being calculate for? /// A list of columns public virtual List GetFilteredColumns(View view) { // For both detail and tile view, the first column must be included. Normally, we would // use the ColumnHeader.Index property, but if the header is not currently part of a ListView // that property returns -1. So, we track the index of // the column header, and always include the first header. int index = 0; return AllColumns.FindAll(delegate (OLVColumn x) { return (index++ == 0) || x.IsVisible; }); } /// /// Return the number of items in the list /// /// the number of items in the list /// If a filter is installed, this will return the number of items that match the filter. public virtual int GetItemCount() { return Items.Count; } /// /// Return the item at the given index /// /// Index of the item to be returned /// An OLVListItem public virtual OLVListItem GetItem(int index) { if (index < 0 || index >= GetItemCount()) return null; return (OLVListItem)Items[index]; } /// /// Return the model object at the given index /// /// Index of the model object to be returned /// A model object public virtual object GetModelObject(int index) { OLVListItem item = GetItem(index); return item == null ? null : item.RowObject; } /// /// Find the item and column that are under the given co-ords /// /// X co-ord /// Y co-ord /// The column under the given point /// The item under the given point. Can be null. public virtual OLVListItem GetItemAt(int x, int y, out OLVColumn hitColumn) { hitColumn = null; ListViewHitTestInfo info = HitTest(x, y); if (info.Item == null) return null; if (info.SubItem != null) { int subItemIndex = info.Item.SubItems.IndexOf(info.SubItem); hitColumn = GetColumn(subItemIndex); } return (OLVListItem)info.Item; } /// /// Return the sub item at the given index/column /// /// Index of the item to be returned /// Index of the subitem to be returned /// An OLVListSubItem public virtual OLVListSubItem GetSubItem(int index, int columnIndex) { OLVListItem olvi = GetItem(index); return olvi == null ? null : olvi.GetSubItem(columnIndex); } #endregion #region Object manipulation /// /// Scroll the listview so that the given group is at the top. /// /// The group to be revealed /// /// If the group is already visible, the list will still be scrolled to move /// the group to the top, if that is possible. /// /// This only works when the list is showing groups (obviously). /// This does not work on virtual lists, since virtual lists don't use ListViewGroups /// for grouping. Use instead. /// public virtual void EnsureGroupVisible(ListViewGroup lvg) { if (!ShowGroups || lvg == null) return; int groupIndex = Groups.IndexOf(lvg); if (groupIndex <= 0) { // There is no easy way to scroll back to the beginning of the list int delta = 0 - NativeMethods.GetScrollPosition(this, false); NativeMethods.Scroll(this, 0, delta); } else { // Find the display rectangle of the last item in the previous group ListViewGroup previousGroup = Groups[groupIndex - 1]; ListViewItem lastItemInGroup = previousGroup.Items[previousGroup.Items.Count - 1]; Rectangle r = GetItemRect(lastItemInGroup.Index); // Scroll so that the last item of the previous group is just out of sight, // which will make the desired group header visible. int delta = r.Y + r.Height / 2; NativeMethods.Scroll(this, 0, delta); } } /// /// Ensure that the given model object is visible /// /// The model object to be revealed public virtual void EnsureModelVisible(Object modelObject) { int index = IndexOf(modelObject); if (index >= 0) EnsureVisible(index); } /// /// Return the model object of the row that is selected or null if there is no selection or more than one selection /// /// Model object or null [Obsolete("Use SelectedObject property instead of this method")] public virtual object GetSelectedObject() { return SelectedObject; } /// /// Return the model objects of the rows that are selected or an empty collection if there is no selection /// /// ArrayList [Obsolete("Use SelectedObjects property instead of this method")] public virtual ArrayList GetSelectedObjects() { return EnumerableToArray(SelectedObjects, false); } /// /// Return the model object of the row that is checked or null if no row is checked /// or more than one row is checked /// /// Model object or null /// Use CheckedObject property instead of this method [Obsolete("Use CheckedObject property instead of this method")] public virtual object GetCheckedObject() { return CheckedObject; } /// /// Get the collection of model objects that are checked. /// /// Use CheckedObjects property instead of this method [Obsolete("Use CheckedObjects property instead of this method")] public virtual ArrayList GetCheckedObjects() { return EnumerableToArray(CheckedObjects, false); } /// /// Find the given model object within the listview and return its index /// /// The model object to be found /// The index of the object. -1 means the object was not present public virtual int IndexOf(Object modelObject) { for (int i = 0; i < GetItemCount(); i++) { if (GetModelObject(i).Equals(modelObject)) return i; } return -1; } /// /// Rebuild the given ListViewItem with the data from its associated model. /// /// This method does not resort or regroup the view. It simply updates /// the displayed data of the given item public virtual void RefreshItem(OLVListItem olvi) { olvi.UseItemStyleForSubItems = true; olvi.SubItems.Clear(); FillInValues(olvi, olvi.RowObject); PostProcessOneRow(olvi.Index, GetDisplayOrderOfItemIndex(olvi), olvi); } /// /// Rebuild the data on the row that is showing the given object. /// /// /// /// This method does not resort or regroup the view. /// /// /// The given object is *not* used as the source of data for the rebuild. /// It is only used to locate the matching model in the collection, /// then that matching model is used as the data source. This distinction is /// only important in model classes that have overridden the Equals() method. /// /// /// If you want the given model object to replace the pre-existing model, /// use . /// /// public virtual void RefreshObject(object modelObject) { RefreshObjects(new object[] { modelObject }); } /// /// Update the rows that are showing the given objects /// /// /// This method does not resort or regroup the view. /// This method can safely be called from background threads. /// public virtual void RefreshObjects(IList modelObjects) { if (InvokeRequired) { Invoke((MethodInvoker)delegate { RefreshObjects(modelObjects); }); return; } foreach (object modelObject in modelObjects) { OLVListItem olvi = ModelToItem(modelObject); if (olvi != null) { ReplaceModel(olvi, modelObject); RefreshItem(olvi); } } } private void ReplaceModel(OLVListItem olvi, object newModel) { if (ReferenceEquals(olvi.RowObject, newModel)) return; TakeOwnershipOfObjects(); ArrayList array = EnumerableToArray(Objects, false); int i = array.IndexOf(olvi.RowObject); if (i >= 0) array[i] = newModel; olvi.RowObject = newModel; } /// /// Update the rows that are selected /// /// This method does not resort or regroup the view. public virtual void RefreshSelectedObjects() { foreach (ListViewItem lvi in SelectedItems) RefreshItem((OLVListItem)lvi); } /// /// Select the row that is displaying the given model object, in addition to any current selection. /// /// The object to be selected /// Use the property to deselect all other rows public virtual void SelectObject(object modelObject) { SelectObject(modelObject, false); } /// /// Select the row that is displaying the given model object, in addition to any current selection. /// /// The object to be selected /// Should the object be focused as well? /// Use the property to deselect all other rows public virtual void SelectObject(object modelObject, bool setFocus) { OLVListItem olvi = ModelToItem(modelObject); if (olvi != null && olvi.Enabled) { olvi.Selected = true; if (setFocus) olvi.Focused = true; } } /// /// Select the rows that is displaying any of the given model object. All other rows are deselected. /// /// A collection of model objects public virtual void SelectObjects(IList modelObjects) { SelectedIndices.Clear(); if (modelObjects == null) return; foreach (object modelObject in modelObjects) { OLVListItem olvi = ModelToItem(modelObject); if (olvi != null && olvi.Enabled) olvi.Selected = true; } } #endregion #region Freezing/Suspending /// /// Get or set whether or not the listview is frozen. When the listview is /// frozen, it will not update itself. /// /// The Frozen property is similar to the methods Freeze()/Unfreeze() /// except that setting Frozen property to false immediately unfreezes the control /// regardless of the number of Freeze() calls outstanding. /// objectListView1.Frozen = false; // unfreeze the control now! /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual bool Frozen { get { return freezeCount > 0; } set { if (value) Freeze(); else if (freezeCount > 0) { freezeCount = 1; Unfreeze(); } } } private int freezeCount; /// /// Freeze the listview so that it no longer updates itself. /// /// Freeze()/Unfreeze() calls nest correctly public virtual void Freeze() { if (freezeCount == 0) DoFreeze(); freezeCount++; OnFreezing(new FreezeEventArgs(freezeCount)); } /// /// Unfreeze the listview. If this call is the outermost Unfreeze(), /// the contents of the listview will be rebuilt. /// /// Freeze()/Unfreeze() calls nest correctly public virtual void Unfreeze() { if (freezeCount <= 0) return; freezeCount--; if (freezeCount == 0) DoUnfreeze(); OnFreezing(new FreezeEventArgs(freezeCount)); } /// /// Do the actual work required when the listview is frozen /// protected virtual void DoFreeze() { BeginUpdate(); } /// /// Do the actual work required when the listview is unfrozen /// protected virtual void DoUnfreeze() { EndUpdate(); ResizeFreeSpaceFillingColumns(); BuildList(); } /// /// Returns true if selection events are currently suspended. /// While selection events are suspended, neither SelectedIndexChanged /// or SelectionChanged events will be raised. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] protected bool SelectionEventsSuspended { get { return suspendSelectionEventCount > 0; } } /// /// Suspend selection events until a matching ResumeSelectionEvents() /// is called. /// /// Calls to this method nest correctly. Every call to SuspendSelectionEvents() /// must have a matching ResumeSelectionEvents(). protected void SuspendSelectionEvents() { suspendSelectionEventCount++; } /// /// Resume raising selection events. /// protected void ResumeSelectionEvents() { Debug.Assert(SelectionEventsSuspended, "Mismatched called to ResumeSelectionEvents()"); suspendSelectionEventCount--; } /// /// Returns a disposable that will disable selection events /// during a using() block. /// /// protected IDisposable SuspendSelectionEventsDuring() { return new SuspendSelectionDisposable(this); } /// /// Implementation only class that suspends and resumes selection /// events on instance creation and disposal. /// private class SuspendSelectionDisposable : IDisposable { public SuspendSelectionDisposable(ObjectListView objectListView) { this.objectListView = objectListView; this.objectListView.SuspendSelectionEvents(); } public void Dispose() { objectListView.ResumeSelectionEvents(); } private readonly ObjectListView objectListView; } #endregion #region Column sorting /// /// Sort the items by the last sort column and order /// public new void Sort() { Sort(PrimarySortColumn, PrimarySortOrder); } /// /// Sort the items in the list view by the values in the given column and the last sort order /// /// The name of the column whose values will be used for the sorting public virtual void Sort(string columnToSortName) { Sort(GetColumn(columnToSortName), PrimarySortOrder); } /// /// Sort the items in the list view by the values in the given column and the last sort order /// /// The index of the column whose values will be used for the sorting public virtual void Sort(int columnToSortIndex) { if (columnToSortIndex >= 0 && columnToSortIndex < Columns.Count) Sort(GetColumn(columnToSortIndex), PrimarySortOrder); } /// /// Sort the items in the list view by the values in the given column and the last sort order /// /// The column whose values will be used for the sorting public virtual void Sort(OLVColumn columnToSort) { if (InvokeRequired) { Invoke((MethodInvoker)delegate { Sort(columnToSort); }); } else { Sort(columnToSort, PrimarySortOrder); } } /// /// Sort the items in the list view by the values in the given column and by the given order. /// /// The column whose values will be used for the sorting. /// If null, the first column will be used. /// The ordering to be used for sorting. If this is None, /// this.Sorting and then SortOrder.Ascending will be used /// If ShowGroups is true, the rows will be grouped by the given column. /// If AlwaysGroupsByColumn is not null, the rows will be grouped by that column, /// and the rows within each group will be sorted by the given column. public virtual void Sort(OLVColumn columnToSort, SortOrder order) { if (InvokeRequired) { Invoke((MethodInvoker)delegate { Sort(columnToSort, order); }); } else { DoSort(columnToSort, order); PostProcessRows(); } } private void DoSort(OLVColumn columnToSort, SortOrder order) { // Sanity checks if (GetItemCount() == 0 || Columns.Count == 0) return; // Fill in default values, if the parameters don't make sense if (ShowGroups) { columnToSort ??= GetColumn(0); if (order == SortOrder.None) { order = Sorting; if (order == SortOrder.None) order = SortOrder.Ascending; } } // Give the world a chance to fiddle with or completely avoid the sorting process BeforeSortingEventArgs args = BuildBeforeSortingEventArgs(columnToSort, order); OnBeforeSorting(args); if (args.Canceled) return; // Virtual lists don't preserve selection, so we have to do it specifically // THINK: Do we need to preserve focus too? IList selection = VirtualMode ? SelectedObjects : null; SuspendSelectionEvents(); ClearHotItem(); // Finally, do the work of sorting, unless an event handler has already done the sorting for us if (!args.Handled) { // Sanity checks if (args.ColumnToSort != null && args.SortOrder != SortOrder.None) { if (ShowGroups) BuildGroups(args.ColumnToGroupBy, args.GroupByOrder, args.ColumnToSort, args.SortOrder, args.SecondaryColumnToSort, args.SecondarySortOrder); else if (CustomSorter != null) CustomSorter(args.ColumnToSort, args.SortOrder); else ListViewItemSorter = new ColumnComparer(args.ColumnToSort, args.SortOrder, args.SecondaryColumnToSort, args.SecondarySortOrder); } } if (ShowSortIndicators) ShowSortIndicator(args.ColumnToSort, args.SortOrder); PrimarySortColumn = args.ColumnToSort; PrimarySortOrder = args.SortOrder; if (selection != null && selection.Count > 0) SelectedObjects = selection; ResumeSelectionEvents(); RefreshHotItem(); OnAfterSorting(new AfterSortingEventArgs(args)); } /// /// Put a sort indicator next to the text of the sort column /// public virtual void ShowSortIndicator() { if (ShowSortIndicators && PrimarySortOrder != SortOrder.None) ShowSortIndicator(PrimarySortColumn, PrimarySortOrder); } /// /// Put a sort indicator next to the text of the given given column /// /// The column to be marked /// The sort order in effect on that column protected virtual void ShowSortIndicator(OLVColumn columnToSort, SortOrder sortOrder) { int imageIndex = -1; if (!NativeMethods.HasBuiltinSortIndicators()) { // If we can't use builtin image, we have to make and then locate the index of the // sort indicator we want to use. SortOrder.None doesn't show an image. if (SmallImageList == null || !SmallImageList.Images.ContainsKey(SORT_INDICATOR_UP_KEY)) MakeSortIndicatorImages(); if (SmallImageList != null) { string key = sortOrder == SortOrder.Ascending ? SORT_INDICATOR_UP_KEY : SORT_INDICATOR_DOWN_KEY; imageIndex = SmallImageList.Images.IndexOfKey(key); } } // Set the image for each column for (int i = 0; i < Columns.Count; i++) { if (columnToSort != null && i == columnToSort.Index) NativeMethods.SetColumnImage(this, i, sortOrder, imageIndex); else NativeMethods.SetColumnImage(this, i, SortOrder.None, -1); } } /// /// The name of the image used when a column is sorted ascending /// /// This image is only used on pre-XP systems. System images are used for XP and later public const string SORT_INDICATOR_UP_KEY = "sort-indicator-up"; /// /// The name of the image used when a column is sorted descending /// /// This image is only used on pre-XP systems. System images are used for XP and later public const string SORT_INDICATOR_DOWN_KEY = "sort-indicator-down"; /// /// If the sort indicator images don't already exist, this method will make and install them /// protected virtual void MakeSortIndicatorImages() { // Don't mess with the image list in design mode if (DesignMode) return; ImageList il = SmallImageList; if (il == null) { il = new ImageList(); il.ImageSize = new Size(16, 16); il.ColorDepth = ColorDepth.Depth32Bit; } // This arrangement of points works well with (16,16) images, and OK with others int midX = il.ImageSize.Width / 2; int midY = (il.ImageSize.Height / 2) - 1; int deltaX = midX - 2; int deltaY = deltaX / 2; if (il.Images.IndexOfKey(SORT_INDICATOR_UP_KEY) == -1) { Point pt1 = new Point(midX - deltaX, midY + deltaY); Point pt2 = new Point(midX, midY - deltaY - 1); Point pt3 = new Point(midX + deltaX, midY + deltaY); il.Images.Add(SORT_INDICATOR_UP_KEY, MakeTriangleBitmap(il.ImageSize, new Point[] { pt1, pt2, pt3 })); } if (il.Images.IndexOfKey(SORT_INDICATOR_DOWN_KEY) == -1) { Point pt1 = new Point(midX - deltaX, midY - deltaY); Point pt2 = new Point(midX, midY + deltaY); Point pt3 = new Point(midX + deltaX, midY - deltaY); il.Images.Add(SORT_INDICATOR_DOWN_KEY, MakeTriangleBitmap(il.ImageSize, new Point[] { pt1, pt2, pt3 })); } SmallImageList = il; } private Bitmap MakeTriangleBitmap(Size sz, Point[] pts) { Bitmap bm = new Bitmap(sz.Width, sz.Height); Graphics g = Graphics.FromImage(bm); g.FillPolygon(new SolidBrush(Color.Gray), pts); return bm; } /// /// Remove any sorting and revert to the given order of the model objects /// public virtual void Unsort() { ShowGroups = false; PrimarySortColumn = null; PrimarySortOrder = SortOrder.None; BuildList(); } #endregion #region Utilities private static CheckState CalculateToggledCheckState(CheckState currentState, bool isTriState, bool isDisabled) { if (isDisabled) return currentState; switch (currentState) { case CheckState.Checked: return isTriState ? CheckState.Indeterminate : CheckState.Unchecked; case CheckState.Indeterminate: return CheckState.Unchecked; default: return CheckState.Checked; } } /// /// Do the actual work of creating the given list of groups /// /// protected virtual void CreateGroups(IEnumerable groups) { Groups.Clear(); // The group must be added before it is given items, otherwise an exception is thrown (is this documented?) foreach (OLVGroup group in groups) { group.InsertGroupOldStyle(this); group.SetItemsOldStyle(); } } /// /// For some reason, UseItemStyleForSubItems doesn't work for the colors /// when owner drawing the list, so we have to specifically give each subitem /// the desired colors /// /// The item whose subitems are to be corrected /// Cells drawn via BaseRenderer don't need this, but it is needed /// when an owner drawn cell uses DrawDefault=true protected virtual void CorrectSubItemColors(ListViewItem olvi) { } /// /// Fill in the given OLVListItem with values of the given row /// /// the OLVListItem that is to be stuff with values /// the model object from which values will be taken protected virtual void FillInValues(OLVListItem lvi, object rowObject) { if (Columns.Count == 0) return; OLVListSubItem subItem = MakeSubItem(rowObject, GetColumn(0)); lvi.SubItems[0] = subItem; lvi.ImageSelector = subItem.ImageSelector; // Give the item the same font/colors as the control lvi.Font = Font; lvi.BackColor = BackColor; lvi.ForeColor = ForeColor; // Should the row be selectable? lvi.Enabled = !IsDisabled(rowObject); // Only Details and Tile views have subitems switch (View) { case View.Details: for (int i = 1; i < Columns.Count; i++) { lvi.SubItems.Add(MakeSubItem(rowObject, GetColumn(i))); } break; case View.Tile: for (int i = 1; i < Columns.Count; i++) { OLVColumn column = GetColumn(i); if (column.IsTileViewColumn) lvi.SubItems.Add(MakeSubItem(rowObject, column)); } break; } // Should the row be selectable? if (!lvi.Enabled) { lvi.UseItemStyleForSubItems = false; ApplyRowStyle(lvi, DisabledItemStyle ?? DefaultDisabledItemStyle); } // Set the check state of the row, if we are showing check boxes if (CheckBoxes) { CheckState? state = GetCheckState(lvi.RowObject); if (state.HasValue) lvi.CheckState = state.Value; } // Give the RowFormatter a chance to mess with the item if (RowFormatter != null) { RowFormatter(lvi); } } private OLVListSubItem MakeSubItem(object rowObject, OLVColumn column) { object cellValue = column.GetValue(rowObject); OLVListSubItem subItem = new OLVListSubItem(cellValue, column.ValueToString(cellValue), column.GetImage(rowObject)); if (UseHyperlinks && column.Hyperlink) { IsHyperlinkEventArgs args = new IsHyperlinkEventArgs(); args.ListView = this; args.Model = rowObject; args.Column = column; args.Text = subItem.Text; args.Url = subItem.Text; args.IsHyperlink = !IsDisabled(rowObject); OnIsHyperlink(args); subItem.Url = args.IsHyperlink ? args.Url : null; } return subItem; } private void ApplyHyperlinkStyle(OLVListItem olvi) { for (int i = 0; i < Columns.Count; i++) { OLVListSubItem subItem = olvi.GetSubItem(i); if (subItem == null) continue; OLVColumn column = GetColumn(i); if (column.Hyperlink && !String.IsNullOrEmpty(subItem.Url)) ApplyCellStyle(olvi, i, IsUrlVisited(subItem.Url) ? HyperlinkStyle.Visited : HyperlinkStyle.Normal); } } /// /// Make sure the ListView has the extended style that says to display subitem images. /// /// This method must be called after any .NET call that update the extended styles /// since they seem to erase this setting. protected virtual void ForceSubItemImagesExStyle() { // Virtual lists can't show subitem images natively, so don't turn on this flag if (!VirtualMode) NativeMethods.ForceSubItemImagesExStyle(this); } /// /// Convert the given image selector to an index into our image list. /// Return -1 if that's not possible /// /// /// Index of the image in the imageList, or -1 protected virtual int GetActualImageIndex(Object imageSelector) { if (imageSelector == null) return -1; if (imageSelector is Int32) return (int)imageSelector; if (imageSelector is string imageSelectorAsString && SmallImageList != null) return SmallImageList.Images.IndexOfKey(imageSelectorAsString); return -1; } /// /// Return the tooltip that should be shown when the mouse is hovered over the given column /// /// The column index whose tool tip is to be fetched /// A string or null if no tool tip is to be shown public virtual String GetHeaderToolTip(int columnIndex) { OLVColumn column = GetColumn(columnIndex); if (column == null) return null; String tooltip = column.ToolTipText; if (HeaderToolTipGetter != null) tooltip = HeaderToolTipGetter(column); return tooltip; } /// /// Return the tooltip that should be shown when the mouse is hovered over the given cell /// /// The column index whose tool tip is to be fetched /// The row index whose tool tip is to be fetched /// A string or null if no tool tip is to be shown public virtual String GetCellToolTip(int columnIndex, int rowIndex) { if (CellToolTipGetter != null) return CellToolTipGetter(GetColumn(columnIndex), GetModelObject(rowIndex)); // Show the URL in the tooltip if it's different to the text if (columnIndex >= 0) { OLVListSubItem subItem = GetSubItem(rowIndex, columnIndex); if (subItem != null && !String.IsNullOrEmpty(subItem.Url) && subItem.Url != subItem.Text && HotCellHitLocation == HitTestLocation.Text) return subItem.Url; } return null; } /// /// Return the OLVListItem that displays the given model object /// /// The modelObject whose item is to be found /// The OLVListItem that displays the model, or null /// This method has O(n) performance. public virtual OLVListItem ModelToItem(object modelObject) { if (modelObject == null) return null; if (_listItemLookup.TryGetValue(modelObject, out var oli)) return oli; /* for (int i = 0; i < this.Items.Count; i++) { var olvi = this.Items[i] as OLVListItem; Debug.Assert(olvi != null, "olvi != null"); var rowObject = olvi.RowObject; if (rowObject != null && rowObject == modelObject) return olvi; } */ return null; } /// /// Do the work required after the items in a listview have been created /// protected virtual void PostProcessRows() { // If this method is called during a BeginUpdate/EndUpdate pair, changes to the // Items collection are cached. Getting the Count flushes that cache. #pragma warning disable 168 // ReSharper disable once UnusedVariable int count = Items.Count; #pragma warning restore 168 int i = 0; if (ShowGroups) { foreach (ListViewGroup group in Groups) { foreach (OLVListItem olvi in group.Items) { PostProcessOneRow(olvi.Index, i, olvi); i++; } } } else { foreach (OLVListItem olvi in Items) { PostProcessOneRow(olvi.Index, i, olvi); i++; } } } /// /// Do the work required after one item in a listview have been created /// protected virtual void PostProcessOneRow(int rowIndex, int displayIndex, OLVListItem olvi) { if (UseAlternatingBackColors && View == View.Details && olvi.Enabled) { olvi.UseItemStyleForSubItems = true; olvi.BackColor = displayIndex % 2 == 1 ? AlternateRowBackColorOrDefault : BackColor; } if (ShowImagesOnSubItems && !VirtualMode) SetSubItemImages(rowIndex, olvi); bool needToTriggerFormatCellEvents = TriggerFormatRowEvent(rowIndex, displayIndex, olvi); // We only need cell level events if we are in details view if (View != View.Details) return; // If we're going to have per cell formatting, we need to copy the formatting // of the item into each cell, before triggering the cell format events if (needToTriggerFormatCellEvents) { PropagateFormatFromRowToCells(olvi); TriggerFormatCellEvents(rowIndex, displayIndex, olvi); } // Similarly, if any cell in the row has hyperlinks, we have to copy formatting // from the item into each cell before applying the hyperlink style if (UseHyperlinks && olvi.HasAnyHyperlinks) { PropagateFormatFromRowToCells(olvi); ApplyHyperlinkStyle(olvi); } } /// /// Prepare the listview to show alternate row backcolors /// /// We cannot rely on lvi.Index in this method. /// In a straight list, lvi.Index is the display index, and can be used to determine /// whether the row should be colored. But when organised by groups, lvi.Index is not /// useable because it still refers to the position in the overall list, not the display order. /// [Obsolete("This method is no longer used. Override PostProcessOneRow() to achieve a similar result")] protected virtual void PrepareAlternateBackColors() { } /// /// Setup all subitem images on all rows /// [Obsolete("This method is not longer maintained and will be removed", false)] protected virtual void SetAllSubItemImages() { //if (!this.ShowImagesOnSubItems || this.OwnerDraw) // return; //this.ForceSubItemImagesExStyle(); //for (int rowIndex = 0; rowIndex < this.GetItemCount(); rowIndex++) // SetSubItemImages(rowIndex, this.GetItem(rowIndex)); } /// /// Tell the underlying list control which images to show against the subitems /// /// the index at which the item occurs /// the item whose subitems are to be set protected virtual void SetSubItemImages(int rowIndex, OLVListItem item) { SetSubItemImages(rowIndex, item, false); } /// /// Tell the underlying list control which images to show against the subitems /// /// the index at which the item occurs /// the item whose subitems are to be set /// will existing images be cleared if no new image is provided? protected virtual void SetSubItemImages(int rowIndex, OLVListItem item, bool shouldClearImages) { if (!ShowImagesOnSubItems || OwnerDraw) return; for (int i = 1; i < item.SubItems.Count; i++) { SetSubItemImage(rowIndex, i, item.GetSubItem(i), shouldClearImages); } } /// /// Set the subitem image natively /// /// /// /// /// public virtual void SetSubItemImage(int rowIndex, int subItemIndex, OLVListSubItem subItem, bool shouldClearImages) { int imageIndex = GetActualImageIndex(subItem.ImageSelector); if (shouldClearImages || imageIndex != -1) NativeMethods.SetSubItemImage(this, rowIndex, subItemIndex, imageIndex); } /// /// Take ownership of the 'objects' collection. This separats our collection from the source. /// /// /// /// This method /// separates the 'objects' instance variable from its source, so that any AddObject/RemoveObject /// calls will modify our collection and not the original colleciton. /// /// /// This method has the intentional side-effect of converting our list of objects to an ArrayList. /// /// protected virtual void TakeOwnershipOfObjects() { if (isOwnerOfObjects) return; isOwnerOfObjects = true; objects = EnumerableToArray(objects, true); } /// /// Trigger FormatRow and possibly FormatCell events for the given item /// /// /// /// protected virtual bool TriggerFormatRowEvent(int rowIndex, int displayIndex, OLVListItem olvi) { FormatRowEventArgs args = new FormatRowEventArgs(); args.ListView = this; args.RowIndex = rowIndex; args.DisplayIndex = displayIndex; args.Item = olvi; args.UseCellFormatEvents = UseCellFormatEvents; OnFormatRow(args); return args.UseCellFormatEvents; } /// /// Trigger FormatCell events for the given item /// /// /// /// protected virtual void TriggerFormatCellEvents(int rowIndex, int displayIndex, OLVListItem olvi) { PropagateFormatFromRowToCells(olvi); // Fire one event per cell FormatCellEventArgs args2 = new FormatCellEventArgs(); args2.ListView = this; args2.RowIndex = rowIndex; args2.DisplayIndex = displayIndex; args2.Item = olvi; for (int i = 0; i < Columns.Count; i++) { args2.ColumnIndex = i; args2.Column = GetColumn(i); args2.SubItem = olvi.GetSubItem(i); OnFormatCell(args2); } } private static void PropagateFormatFromRowToCells(OLVListItem olvi) { // If a cell isn't given its own colors, it *should* use the colors of the item. // However, there is a bug in the .NET framework where the cell are given // the colors of the ListView instead of the colors of the row. // If we've already done this, don't do it again if (olvi.UseItemStyleForSubItems == false) return; // So we have to explicitly give each cell the fore and back colors and the font that it should have. olvi.UseItemStyleForSubItems = false; Color backColor = olvi.BackColor; Color foreColor = olvi.ForeColor; Font font = olvi.Font; foreach (OLVListSubItem subitem in olvi.SubItems) { subitem.BackColor = backColor; subitem.ForeColor = foreColor; subitem.Font = font; } } /// /// Make the list forget everything -- all rows and all columns /// /// Use if you want to remove just the rows. public virtual void Reset() { Clear(); AllColumns.Clear(); ClearObjects(); PrimarySortColumn = null; SecondarySortColumn = null; ClearDisabledObjects(); ClearPersistentCheckState(); ClearUrlVisited(); ClearHotItem(); } #endregion #region ISupportInitialize Members void ISupportInitialize.BeginInit() { Frozen = true; } void ISupportInitialize.EndInit() { if (RowHeight != -1) { SmallImageList = SmallImageList; if (CheckBoxes) InitializeStateImageList(); } if (UseSubItemCheckBoxes || (VirtualMode && CheckBoxes)) SetupSubItemCheckBoxes(); Frozen = false; } #endregion #region Image list manipulation /// /// Update our externally visible image list so it holds the same images as our shadow list, but sized correctly /// private void SetupBaseImageList() { // If a row height hasn't been set, or an image list has been give which is the required size, just assign it if (rowHeight == -1 || View != View.Details || (shadowedImageList != null && shadowedImageList.ImageSize.Height == rowHeight)) BaseSmallImageList = shadowedImageList; else { int width = (shadowedImageList == null ? 16 : shadowedImageList.ImageSize.Width); BaseSmallImageList = MakeResizedImageList(width, rowHeight, shadowedImageList); } } /// /// Return a copy of the given source image list, where each image has been resized to be height x height in size. /// If source is null, an empty image list of the given size is returned /// /// Height and width of the new images /// Height and width of the new images /// Source of the images (can be null) /// A new image list private ImageList MakeResizedImageList(int width, int height, ImageList source) { ImageList il = new ImageList(); il.ImageSize = new Size(width, height); // If there's nothing to copy, just return the new list if (source == null) return il; il.TransparentColor = source.TransparentColor; il.ColorDepth = source.ColorDepth; // Fill the imagelist with resized copies from the source for (int i = 0; i < source.Images.Count; i++) { Bitmap bm = MakeResizedImage(width, height, source.Images[i], source.TransparentColor); il.Images.Add(bm); } // Give each image the same key it has in the original foreach (String key in source.Images.Keys) { il.Images.SetKeyName(source.Images.IndexOfKey(key), key); } return il; } /// /// Return a bitmap of the given height x height, which shows the given image, centred. /// /// Height and width of new bitmap /// Height and width of new bitmap /// Image to be centred /// The background color /// A new bitmap private Bitmap MakeResizedImage(int width, int height, Image image, Color transparent) { Bitmap bm = new Bitmap(width, height); Graphics g = Graphics.FromImage(bm); g.Clear(transparent); int x = Math.Max(0, (bm.Size.Width - image.Size.Width) / 2); int y = Math.Max(0, (bm.Size.Height - image.Size.Height) / 2); g.DrawImage(image, x, y, image.Size.Width, image.Size.Height); return bm; } /// /// Initialize the state image list with the required checkbox images /// protected virtual void InitializeStateImageList() { if (DesignMode) return; if (!CheckBoxes) return; if (StateImageList == null) { StateImageList = new ImageList(); StateImageList.ImageSize = new Size(16, RowHeight == -1 ? 16 : RowHeight); StateImageList.ColorDepth = ColorDepth.Depth32Bit; } if (RowHeight != -1 && View == View.Details && StateImageList.ImageSize.Height != RowHeight) { StateImageList = new ImageList(); StateImageList.ImageSize = new Size(16, RowHeight); StateImageList.ColorDepth = ColorDepth.Depth32Bit; } // The internal logic of ListView cycles through the state images when the primary // checkbox is clicked. So we have to get exactly the right number of images in the // image list. if (StateImageList.Images.Count == 0) AddCheckStateBitmap(StateImageList, UNCHECKED_KEY, CheckBoxState.UncheckedNormal); if (StateImageList.Images.Count <= 1) AddCheckStateBitmap(StateImageList, CHECKED_KEY, CheckBoxState.CheckedNormal); if (TriStateCheckBoxes && StateImageList.Images.Count <= 2) AddCheckStateBitmap(StateImageList, INDETERMINATE_KEY, CheckBoxState.MixedNormal); else { if (StateImageList.Images.ContainsKey(INDETERMINATE_KEY)) StateImageList.Images.RemoveByKey(INDETERMINATE_KEY); } } /// /// The name of the image used when a check box is checked /// public const string CHECKED_KEY = "checkbox-checked"; /// /// The name of the image used when a check box is unchecked /// public const string UNCHECKED_KEY = "checkbox-unchecked"; /// /// The name of the image used when a check box is Indeterminate /// public const string INDETERMINATE_KEY = "checkbox-indeterminate"; /// /// Setup this control so it can display check boxes on subitems /// (or primary checkboxes in virtual mode) /// /// This gives the ListView a small image list, if it doesn't already have one. public virtual void SetupSubItemCheckBoxes() { ShowImagesOnSubItems = true; if (SmallImageList == null || !SmallImageList.Images.ContainsKey(CHECKED_KEY)) InitializeSubItemCheckBoxImages(); } /// /// Make sure the small image list for this control has checkbox images /// (used for sub-item checkboxes). /// /// /// /// This gives the ListView a small image list, if it doesn't already have one. /// /// /// ObjectListView has to manage checkboxes on subitems separate from the checkboxes on each row. /// The underlying ListView knows about the per-row checkboxes, and to make them work, OLV has to /// correctly configure the StateImageList. However, the ListView cannot do checkboxes in subitems, /// so ObjectListView has to handle them in a differnt fashion. So, per-row checkboxes are controlled /// by images in the StateImageList, but per-cell checkboxes are handled by images in the SmallImageList. /// /// protected virtual void InitializeSubItemCheckBoxImages() { // Don't mess with the image list in design mode if (DesignMode) return; ImageList il = SmallImageList; if (il == null) { il = new ImageList(); il.ImageSize = new Size(16, 16); il.ColorDepth = ColorDepth.Depth32Bit; } AddCheckStateBitmap(il, CHECKED_KEY, CheckBoxState.CheckedNormal); AddCheckStateBitmap(il, UNCHECKED_KEY, CheckBoxState.UncheckedNormal); AddCheckStateBitmap(il, INDETERMINATE_KEY, CheckBoxState.MixedNormal); SmallImageList = il; } private void AddCheckStateBitmap(ImageList il, string key, CheckBoxState boxState) { Bitmap b = new Bitmap(il.ImageSize.Width, il.ImageSize.Height); Graphics g = Graphics.FromImage(b); g.Clear(il.TransparentColor); Point location = new Point(b.Width / 2 - 5, b.Height / 2 - 6); CheckBoxRenderer.DrawCheckBox(g, location, boxState); il.Images.Add(key, b); } #endregion #region Owner drawing /// /// Owner draw the column header /// /// protected override void OnDrawColumnHeader(DrawListViewColumnHeaderEventArgs e) { e.DrawDefault = true; base.OnDrawColumnHeader(e); } /// /// Owner draw the item /// /// protected override void OnDrawItem(DrawListViewItemEventArgs e) { if (View == View.Details) e.DrawDefault = false; else { if (ItemRenderer == null) e.DrawDefault = true; else { Object row = ((OLVListItem)e.Item).RowObject; e.DrawDefault = !ItemRenderer.RenderItem(e, e.Graphics, e.Bounds, row); } } if (e.DrawDefault) base.OnDrawItem(e); } /// /// Owner draw a single subitem /// /// protected override void OnDrawSubItem(DrawListViewSubItemEventArgs e) { //System.Diagnostics.Debug.WriteLine(String.Format("OnDrawSubItem ({0}, {1})", e.ItemIndex, e.ColumnIndex)); // Don't try to do owner drawing at design time if (DesignMode) { e.DrawDefault = true; return; } object rowObject = ((OLVListItem)e.Item).RowObject; // Calculate where the subitem should be drawn Rectangle r = e.Bounds; // Get the special renderer for this column. If there isn't one, use the default draw mechanism. OLVColumn column = GetColumn(e.ColumnIndex); IRenderer renderer = GetCellRenderer(rowObject, column); // Get a graphics context for the renderer to use. // But we have more complications. Virtual lists have a nasty habit of drawing column 0 // whenever there is any mouse move events over a row, and doing it in an un-double-buffered manner, // which results in nasty flickers! There are also some unbuffered draw when a mouse is first // hovered over column 0 of a normal row. So, to avoid all complications, // we always manually double-buffer the drawing. // Except with Mono, which doesn't seem to handle double buffering at all :-( BufferedGraphics buffer = BufferedGraphicsManager.Current.Allocate(e.Graphics, r); Graphics g = buffer.Graphics; g.TextRenderingHint = TextRenderingHint; g.SmoothingMode = SmoothingMode; // Finally, give the renderer a chance to draw something e.DrawDefault = !renderer.RenderSubItem(e, g, r, rowObject); if (!e.DrawDefault) buffer.Render(); buffer.Dispose(); } #endregion #region OnEvent Handling /// /// We need the click count in the mouse up event, but that is always 1. /// So we have to remember the click count from the preceding mouse down event. /// /// protected override void OnMouseDown(MouseEventArgs e) { lastMouseDownClickCount = e.Clicks; base.OnMouseDown(e); } private int lastMouseDownClickCount; /// /// When the mouse leaves the control, remove any hot item highlighting /// /// protected override void OnMouseLeave(EventArgs e) { base.OnMouseLeave(e); if (!Created) return; UpdateHotItem(new Point(-1, -1)); } // We could change the hot item on the mouse hover event, but it looks wrong. //protected override void OnMouseHover(EventArgs e) { // System.Diagnostics.Debug.WriteLine(String.Format("OnMouseHover")); // base.OnMouseHover(e); // this.UpdateHotItem(this.PointToClient(Cursor.Position)); //} /// /// When the mouse moves, we might need to change the hot item. /// /// protected override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); if (Created) HandleMouseMove(e.Location); } internal void HandleMouseMove(Point pt) { //System.Diagnostics.Debug.WriteLine(String.Format("HandleMouseMove: {0}", pt)); /* Prevent excessive redrawing when mouse is hovering over the listview. Doesn't seem to break anything important. CellOverEventArgs args = new CellOverEventArgs(); this.BuildCellEvent(args, pt); this.OnCellOver(args); this.MouseMoveHitTest = args.HitTest; if (!args.Handled) this.UpdateHotItem(args.HitTest);*/ } /// /// Check to see if we need to start editing a cell /// /// protected override void OnMouseUp(MouseEventArgs e) { //System.Diagnostics.Debug.WriteLine(String.Format("OnMouseUp")); base.OnMouseUp(e); if (!Created) return; if (e.Button == MouseButtons.Right) { OnRightMouseUp(e); return; } // What event should we listen for to start cell editing? // ------------------------------------------------------ // // We can't use OnMouseClick, OnMouseDoubleClick, OnClick, or OnDoubleClick // since they are not triggered for clicks on subitems without Full Row Select. // // We could use OnMouseDown, but selecting rows is done in OnMouseUp. This means // that if we start the editing during OnMouseDown, the editor will automatically // lose focus when mouse up happens. // // Tell the world about a cell click. If someone handles it, don't do anything else CellClickEventArgs args = new CellClickEventArgs(); BuildCellEvent(args, e.Location); args.ClickCount = lastMouseDownClickCount; OnCellClick(args); if (args.Handled) return; // Did the user click a hyperlink? if (UseHyperlinks && args.HitTest.HitTestLocation == HitTestLocation.Text && args.SubItem != null && !String.IsNullOrEmpty(args.SubItem.Url)) { // We have to delay the running of this process otherwise we can generate // a series of MouseUp events (don't ask me why) BeginInvoke((MethodInvoker)delegate { ProcessHyperlinkClicked(args); }); } // No one handled it so check to see if we should start editing. if (!ShouldStartCellEdit(e)) return; // We only start the edit if the user clicked on the image or text. if (args.HitTest.HitTestLocation == HitTestLocation.Nothing) return; // We don't edit the primary column by single clicks -- only subitems. if (CellEditActivation == CellEditActivateMode.SingleClick && args.ColumnIndex <= 0) return; // Don't start a cell edit operation when the user clicks on the background of a checkbox column -- it just looks wrong. // If the user clicks on the actual checkbox, changing the checkbox state is handled elsewhere. if (args.Column != null && args.Column.CheckBoxes) return; EditSubItem(args.Item, args.ColumnIndex); } /// /// Tell the world that a hyperlink was clicked and if the event isn't handled, /// do the default processing. /// /// protected virtual void ProcessHyperlinkClicked(CellClickEventArgs e) { HyperlinkClickedEventArgs args = new HyperlinkClickedEventArgs(); args.HitTest = e.HitTest; args.ListView = this; args.Location = new Point(-1, -1); args.Item = e.Item; args.SubItem = e.SubItem; args.Model = e.Model; args.ColumnIndex = e.ColumnIndex; args.Column = e.Column; args.RowIndex = e.RowIndex; args.ModifierKeys = ModifierKeys; args.Url = e.SubItem.Url; OnHyperlinkClicked(args); if (!args.Handled) { StandardHyperlinkClickedProcessing(args); } } /// /// Do the default processing for a hyperlink clicked event, which /// is to try and open the url. /// /// protected virtual void StandardHyperlinkClickedProcessing(HyperlinkClickedEventArgs args) { Cursor originalCursor = Cursor; try { Cursor = Cursors.WaitCursor; Process.Start(new ProcessStartInfo(args.Url) { UseShellExecute = true }); } catch (Win32Exception) { System.Media.SystemSounds.Beep.Play(); // ignore it } finally { Cursor = originalCursor; } MarkUrlVisited(args.Url); RefreshHotItem(); } /// /// The user right clicked on the control /// /// protected virtual void OnRightMouseUp(MouseEventArgs e) { CellRightClickEventArgs args = new CellRightClickEventArgs(); BuildCellEvent(args, e.Location); OnCellRightClick(args); if (!args.Handled) { if (args.MenuStrip != null) { args.MenuStrip.Show(this, args.Location); } } } internal void BuildCellEvent(CellEventArgs args, Point location) { BuildCellEvent(args, location, OlvHitTest(location.X, location.Y)); } internal void BuildCellEvent(CellEventArgs args, Point location, OlvListViewHitTestInfo hitTest) { args.HitTest = hitTest; args.ListView = this; args.Location = location; args.Item = hitTest.Item; args.SubItem = hitTest.SubItem; args.Model = hitTest.RowObject; args.ColumnIndex = hitTest.ColumnIndex; args.Column = hitTest.Column; if (hitTest.Item != null) args.RowIndex = hitTest.Item.Index; args.ModifierKeys = ModifierKeys; // In non-details view, we want any hit on an item to act as if it was a hit // on column 0 -- which, effectively, it was. if (args.Item != null && args.ListView.View != View.Details) { args.ColumnIndex = 0; args.Column = args.ListView.GetColumn(0); args.SubItem = args.Item.GetSubItem(0); } } /// /// This method is called every time a row is selected or deselected. This can be /// a pain if the user shift-clicks 100 rows. We override this method so we can /// trigger one event for any number of select/deselects that come from one user action /// /// protected override void OnSelectedIndexChanged(EventArgs e) { if (SelectionEventsSuspended) return; base.OnSelectedIndexChanged(e); // If we haven't already scheduled an event, schedule it to be triggered // By using idle time, we will wait until all select events for the same // user action have finished before triggering the event. if (!hasIdleHandler) { hasIdleHandler = true; RunWhenIdle(HandleApplicationIdle); } } /// /// Called when the handle of the underlying control is created /// /// protected override void OnHandleCreated(EventArgs e) { //Debug.WriteLine("OnHandleCreated"); base.OnHandleCreated(e); Invoke((MethodInvoker)OnControlCreated); } /// /// This method is called after the control has been fully created. /// protected virtual void OnControlCreated() { //Debug.WriteLine("OnControlCreated"); // Force the header control to be created when the listview handle is HeaderControl hc = HeaderControl; hc.WordWrap = HeaderWordWrap; // Make sure any overlays that are set on the hot item style take effect HotItemStyle = HotItemStyle; // Arrange for any group images to be installed after the control is created NativeMethods.SetGroupImageList(this, GroupImageList); UseExplorerTheme = UseExplorerTheme; RememberDisplayIndicies(); SetGroupSpacing(); if (VirtualMode) ApplyExtendedStyles(); } #endregion #region Cell editing /// /// Should we start editing the cell in response to the given mouse button event? /// /// /// protected virtual bool ShouldStartCellEdit(MouseEventArgs e) { if (IsCellEditing) return false; if (e.Button != MouseButtons.Left && e.Button != MouseButtons.Right) return false; if ((ModifierKeys & (Keys.Shift | Keys.Control | Keys.Alt)) != 0) return false; if (lastMouseDownClickCount == 1 && ( CellEditActivation == CellEditActivateMode.SingleClick || CellEditActivation == CellEditActivateMode.SingleClickAlways)) return true; return (lastMouseDownClickCount == 2 && CellEditActivation == CellEditActivateMode.DoubleClick); } /// /// Handle a key press on this control. We specifically look for F2 which edits the primary column, /// or a Tab character during an edit operation, which tries to start editing on the next (or previous) cell. /// /// /// protected override bool ProcessDialogKey(Keys keyData) { if (IsCellEditing) return CellEditKeyEngine.HandleKey(this, keyData); // Treat F2 as a request to edit the primary column if (keyData == Keys.F2) { EditSubItem((OLVListItem)FocusedItem, 0); return base.ProcessDialogKey(keyData); } // Treat Ctrl-C as Copy To Clipboard. if (CopySelectionOnControlC && keyData == (Keys.C | Keys.Control)) { CopySelectionToClipboard(); return true; } // Treat Ctrl-A as Select All. if (SelectAllOnControlA && keyData == (Keys.A | Keys.Control)) { SelectAll(); return true; } return base.ProcessDialogKey(keyData); } /// /// Start an editing operation on the first editable column of the given model. /// /// /// /// /// If the model doesn't exist, or there are no editable columns, this method /// will do nothing. /// /// This will start an edit operation regardless of CellActivationMode. /// /// public virtual void EditModel(object rowModel) { OLVListItem olvItem = ModelToItem(rowModel); if (olvItem == null) return; for (int i = 0; i < olvItem.SubItems.Count; i++) { if (GetColumn(i).IsEditable) { StartCellEdit(olvItem, i); return; } } } /// /// Begin an edit operation on the given cell. /// /// This performs various sanity checks and passes off the real work to StartCellEdit(). /// The row to be edited /// The index of the cell to be edited public virtual void EditSubItem(OLVListItem item, int subItemIndex) { if (item == null) return; if (subItemIndex < 0 && subItemIndex >= item.SubItems.Count) return; if (CellEditActivation == CellEditActivateMode.None) return; if (!GetColumn(subItemIndex).IsEditable) return; if (!item.Enabled) return; StartCellEdit(item, subItemIndex); } /// /// Really start an edit operation on a given cell. The parameters are assumed to be sane. /// /// The row to be edited /// The index of the cell to be edited public virtual void StartCellEdit(OLVListItem item, int subItemIndex) { OLVColumn column = GetColumn(subItemIndex); Control c = GetCellEditor(item, subItemIndex); Rectangle cellBounds = CalculateCellBounds(item, subItemIndex); c.Bounds = CalculateCellEditorBounds(item, subItemIndex, c.PreferredSize); // Try to align the control as the column is aligned. Not all controls support this property Munger.PutProperty(c, "TextAlign", column.TextAlign); // Give the control the value from the model SetControlValue(c, column.GetValue(item.RowObject), column.GetStringValue(item.RowObject)); // Give the outside world the chance to munge with the process CellEditEventArgs = new CellEditEventArgs(column, c, cellBounds, item, subItemIndex); OnCellEditStarting(CellEditEventArgs); if (CellEditEventArgs.Cancel) return; // The event handler may have completely changed the control, so we need to remember it cellEditor = CellEditEventArgs.Control; Invalidate(); Controls.Add(cellEditor); ConfigureControl(); PauseAnimations(true); } private Control cellEditor; internal CellEditEventArgs CellEditEventArgs; /// /// Calculate the bounds of the edit control for the given item/column /// /// /// /// /// public Rectangle CalculateCellEditorBounds(OLVListItem item, int subItemIndex, Size preferredSize) { Rectangle r = CalculateCellBounds(item, subItemIndex); // Calculate the width of the cell's current contents return OwnerDraw ? CalculateCellEditorBoundsOwnerDrawn(item, subItemIndex, r, preferredSize) : CalculateCellEditorBoundsStandard(item, subItemIndex, r, preferredSize); } /// /// Calculate the bounds of the edit control for the given item/column, when the listview /// is being owner drawn. /// /// /// /// /// /// A rectangle that is the bounds of the cell editor protected Rectangle CalculateCellEditorBoundsOwnerDrawn(OLVListItem item, int subItemIndex, Rectangle r, Size preferredSize) { IRenderer renderer = View == View.Details ? GetCellRenderer(item.RowObject, GetColumn(subItemIndex)) : ItemRenderer; if (renderer == null) return r; using (Graphics g = CreateGraphics()) { return renderer.GetEditRectangle(g, r, item, subItemIndex, preferredSize); } } /// /// Calculate the bounds of the edit control for the given item/column, when the listview /// is not being owner drawn. /// /// /// /// /// /// A rectangle that is the bounds of the cell editor protected Rectangle CalculateCellEditorBoundsStandard(OLVListItem item, int subItemIndex, Rectangle cellBounds, Size preferredSize) { if (View == View.Tile) return cellBounds; // Center the editor vertically if (cellBounds.Height != preferredSize.Height) cellBounds.Y += (cellBounds.Height - preferredSize.Height) / 2; // Only Details view needs more processing if (View != View.Details) return cellBounds; // Allow for image (if there is one). int offset = 0; object imageSelector = null; if (subItemIndex == 0) imageSelector = item.ImageSelector; else { // We only check for subitem images if we are owner drawn or showing subitem images if (OwnerDraw || ShowImagesOnSubItems) imageSelector = item.GetSubItem(subItemIndex).ImageSelector; } if (GetActualImageIndex(imageSelector) != -1) { offset += SmallImageSize.Width + 2; } // Allow for checkbox if (CheckBoxes && StateImageList != null && subItemIndex == 0) { offset += StateImageList.ImageSize.Width + 2; } // Allow for indent (first column only) if (subItemIndex == 0 && item.IndentCount > 0) { offset += (SmallImageSize.Width * item.IndentCount); } // Do the adjustment if (offset > 0) { cellBounds.X += offset; cellBounds.Width -= offset; } return cellBounds; } /// /// Try to give the given value to the provided control. Fall back to assigning a string /// if the value assignment fails. /// /// A control /// The value to be given to the control /// The string to be given if the value doesn't work protected virtual void SetControlValue(Control control, Object value, String stringValue) { // Handle combobox explicitly if (control is ComboBox cb) { if (cb.Created) cb.SelectedValue = value; else BeginInvoke(new MethodInvoker(delegate { cb.SelectedValue = value; })); return; } if (Munger.PutProperty(control, "Value", value)) return; // There wasn't a Value property, or we couldn't set it, so set the text instead try { String valueAsString = value as String; control.Text = valueAsString ?? stringValue; } catch (ArgumentOutOfRangeException) { // The value couldn't be set via the Text property. } } /// /// Setup the given control to be a cell editor /// protected virtual void ConfigureControl() { cellEditor.Validating += new CancelEventHandler(CellEditor_Validating); cellEditor.Select(); } /// /// Return the value that the given control is showing /// /// /// protected virtual Object GetControlValue(Control control) { if (control == null) return null; if (control is TextBox box) return box.Text; if (control is ComboBox comboBox) return comboBox.SelectedValue; if (control is CheckBox checkBox) return checkBox.Checked; try { return control.GetType().InvokeMember("Value", BindingFlags.GetProperty, null, control, null); } catch (MissingMethodException) { // Microsoft throws this return control.Text; } catch (MissingFieldException) { // Mono throws this return control.Text; } } /// /// Called when the cell editor could be about to lose focus. Time to commit the change /// /// /// protected virtual void CellEditor_Validating(object sender, CancelEventArgs e) { CellEditEventArgs.Cancel = false; CellEditEventArgs.NewValue = GetControlValue(cellEditor); OnCellEditorValidating(CellEditEventArgs); if (CellEditEventArgs.Cancel) { CellEditEventArgs.Control.Select(); e.Cancel = true; } else FinishCellEdit(); } /// /// Return the bounds of the given cell /// /// The row to be edited /// The index of the cell to be edited /// A Rectangle public virtual Rectangle CalculateCellBounds(OLVListItem item, int subItemIndex) { // It seems on Win7, GetSubItemBounds() does not have the same problems with // column 0 that it did previously. // TODO - Check on XP if (View != View.Details) return GetItemRect(item.Index, ItemBoundsPortion.Label); Rectangle r = item.GetSubItemBounds(subItemIndex); r.Width -= 1; r.Height -= 1; return r; // We use ItemBoundsPortion.Label rather than ItemBoundsPortion.Item // since Label extends to the right edge of the cell, whereas Item gives just the // current text width. //return this.CalculateCellBounds(item, subItemIndex, ItemBoundsPortion.Label); } /// /// Return the bounds of the given cell only until the edge of the current text /// /// The row to be edited /// The index of the cell to be edited /// A Rectangle public virtual Rectangle CalculateCellTextBounds(OLVListItem item, int subItemIndex) { return CalculateCellBounds(item, subItemIndex, ItemBoundsPortion.ItemOnly); } private Rectangle CalculateCellBounds(OLVListItem item, int subItemIndex, ItemBoundsPortion portion) { // SubItem.Bounds works for every subitem, except the first. if (subItemIndex > 0) return item.GetSubItemBounds(subItemIndex); // For non detail views, we just use the requested portion Rectangle r = GetItemRect(item.Index, portion); if (r.Y < -10000000 || r.Y > 10000000) { r.Y = item.Bounds.Y; } if (View != View.Details) return r; // Finding the bounds of cell 0 should not be a difficult task, but it is. Problems: // 1) item.SubItem[0].Bounds is always the full bounds of the entire row, not just cell 0. // 2) if column 0 has been dragged to some other position, the bounds always has a left edge of 0. // We avoid both these problems by using the position of sides the column header to calculate // the sides of the cell Point sides = NativeMethods.GetScrolledColumnSides(this, 0); r.X = sides.X + 4; r.Width = sides.Y - sides.X - 5; return r; } /// /// Calculate the visible bounds of the given column. The column's bottom edge is /// either the bottom of the last row or the bottom of the control. /// /// The bounds of the control itself /// The column /// A Rectangle /// This returns an empty rectnage if the control isn't in Details mode, /// OR has doesn't have any rows, OR if the given column is hidden. public virtual Rectangle CalculateColumnVisibleBounds(Rectangle bounds, OLVColumn column) { // Sanity checks if (column == null || View != View.Details || GetItemCount() == 0 || !column.IsVisible) return Rectangle.Empty; Point sides = NativeMethods.GetScrolledColumnSides(this, column.Index); if (sides.X == -1) return Rectangle.Empty; Rectangle columnBounds = new Rectangle(sides.X, bounds.Top, sides.Y - sides.X, bounds.Bottom); // Find the bottom of the last item. The column only extends to there. OLVListItem lastItem = GetLastItemInDisplayOrder(); if (lastItem != null) { Rectangle lastItemBounds = lastItem.Bounds; if (!lastItemBounds.IsEmpty && lastItemBounds.Bottom < columnBounds.Bottom) columnBounds.Height = lastItemBounds.Bottom - columnBounds.Top; } return columnBounds; } /// /// Return a control that can be used to edit the value of the given cell. /// /// The row to be edited /// The index of the cell to be edited /// A Control to edit the given cell protected virtual Control GetCellEditor(OLVListItem item, int subItemIndex) { OLVColumn column = GetColumn(subItemIndex); Object value = column.GetValue(item.RowObject) ?? GetFirstNonNullValue(column); // TODO: What do we do if value is still null here? // Ask the registry for an instance of the appropriate editor. // Use a default editor if the registry can't create one for us. Control editor = EditorRegistry.GetEditor(item.RowObject, column, value) ?? MakeDefaultCellEditor(column); return editor; } /// /// Get the first non-null value of the given column. /// At most 1000 rows will be considered. /// /// /// The first non-null value, or null if no non-null values were found internal object GetFirstNonNullValue(OLVColumn column) { for (int i = 0; i < Math.Min(GetItemCount(), 1000); i++) { object value = column.GetValue(GetModelObject(i)); if (value != null) return value; } return null; } /// /// Return a TextBox that can be used as a default cell editor. /// /// What column does the cell belong to? /// protected virtual Control MakeDefaultCellEditor(OLVColumn column) { TextBox tb = new TextBox(); if (column.AutoCompleteEditor) ConfigureAutoComplete(tb, column); return tb; } /// /// Configure the given text box to autocomplete unique values /// from the given column. At most 1000 rows will be considered. /// /// The textbox to configure /// The column used to calculate values public void ConfigureAutoComplete(TextBox tb, OLVColumn column) { ConfigureAutoComplete(tb, column, 1000); } /// /// Configure the given text box to autocomplete unique values /// from the given column. At most 1000 rows will be considered. /// /// The textbox to configure /// The column used to calculate values /// Consider only this many rows public void ConfigureAutoComplete(TextBox tb, OLVColumn column, int maxRows) { // Don't consider more rows than we actually have maxRows = Math.Min(GetItemCount(), maxRows); // Reset any existing autocomplete tb.AutoCompleteCustomSource.Clear(); // CONSIDER: Should we use ClusteringStrategy here? // Build a list of unique values, to be used as autocomplete on the editor Dictionary alreadySeen = new Dictionary(); List values = new List(); for (int i = 0; i < maxRows; i++) { string valueAsString = column.GetStringValue(GetModelObject(i)); if (!String.IsNullOrEmpty(valueAsString) && !alreadySeen.ContainsKey(valueAsString)) { values.Add(valueAsString); alreadySeen[valueAsString] = true; } } tb.AutoCompleteCustomSource.AddRange(values.ToArray()); tb.AutoCompleteSource = AutoCompleteSource.CustomSource; tb.AutoCompleteMode = column.AutoCompleteEditorMode; } /// /// Stop editing a cell and throw away any changes. /// public virtual void CancelCellEdit() { if (!IsCellEditing) return; // Let the world know that the user has cancelled the edit operation CellEditEventArgs.Cancel = true; CellEditEventArgs.NewValue = GetControlValue(cellEditor); OnCellEditFinishing(CellEditEventArgs); // Now cleanup the editing process CleanupCellEdit(false, CellEditEventArgs.AutoDispose); } /// /// If a cell edit is in progress, finish the edit. /// /// Returns false if the finishing process was cancelled /// (i.e. the cell editor is still on screen) /// This method does not guarantee that the editing will finish. The validation /// process can cause the finishing to be aborted. Developers should check the return value /// or use IsCellEditing property after calling this method to see if the user is still /// editing a cell. public virtual bool PossibleFinishCellEditing() { // BCU doesn't use cell editing, so this can be skipped for performance //return this.PossibleFinishCellEditing(false); return true; } /// /// If a cell edit is in progress, finish the edit. /// /// Returns false if the finishing process was cancelled /// (i.e. the cell editor is still on screen) /// This method does not guarantee that the editing will finish. The validation /// process can cause the finishing to be aborted. Developers should check the return value /// or use IsCellEditing property after calling this method to see if the user is still /// editing a cell. /// True if it is likely that another cell is going to be /// edited immediately after this cell finishes editing public virtual bool PossibleFinishCellEditing(bool expectingCellEdit) { if (!IsCellEditing) return true; CellEditEventArgs.Cancel = false; CellEditEventArgs.NewValue = GetControlValue(cellEditor); OnCellEditorValidating(CellEditEventArgs); if (CellEditEventArgs.Cancel) return false; FinishCellEdit(expectingCellEdit); return true; } /// /// Finish the cell edit operation, writing changed data back to the model object /// /// This method does not trigger a Validating event, so it always finishes /// the cell edit. public virtual void FinishCellEdit() { FinishCellEdit(false); } /// /// Finish the cell edit operation, writing changed data back to the model object /// /// This method does not trigger a Validating event, so it always finishes /// the cell edit. /// True if it is likely that another cell is going to be /// edited immediately after this cell finishes editing public virtual void FinishCellEdit(bool expectingCellEdit) { if (!IsCellEditing) return; CellEditEventArgs.Cancel = false; CellEditEventArgs.NewValue = GetControlValue(cellEditor); OnCellEditFinishing(CellEditEventArgs); // If someone doesn't cancel the editing process, write the value back into the model if (!CellEditEventArgs.Cancel) { CellEditEventArgs.Column.PutValue(CellEditEventArgs.RowObject, CellEditEventArgs.NewValue); RefreshItem(CellEditEventArgs.ListViewItem); } CleanupCellEdit(expectingCellEdit, CellEditEventArgs.AutoDispose); // Tell the world that the cell has been edited OnCellEditFinished(CellEditEventArgs); } /// /// Remove all trace of any existing cell edit operation /// /// True if it is likely that another cell is going to be /// edited immediately after this cell finishes editing /// True if the cell editor should be disposed protected virtual void CleanupCellEdit(bool expectingCellEdit, bool disposeOfCellEditor) { if (cellEditor == null) return; cellEditor.Validating -= new CancelEventHandler(CellEditor_Validating); Control soonToBeOldCellEditor = cellEditor; cellEditor = null; // Delay cleaning up the cell editor so that if we are immediately going to // start a new cell edit (because the user pressed Tab) the new cell editor // has a chance to grab the focus. Without this, the ListView gains focus // momentarily (after the cell editor is remove and before the new one is created) // causing the list's selection to flash momentarily. EventHandler toBeRun = null; toBeRun = delegate (object sender, EventArgs e) { Application.Idle -= toBeRun; Controls.Remove(soonToBeOldCellEditor); if (disposeOfCellEditor) soonToBeOldCellEditor.Dispose(); Invalidate(); if (!IsCellEditing) { if (Focused) Select(); PauseAnimations(false); } }; // We only want to delay the removal of the control if we are expecting another cell // to be edited. Otherwise, we remove the control immediately. if (expectingCellEdit) RunWhenIdle(toBeRun); else toBeRun(null, null); } #endregion #region Hot row and cell handling /// /// Force the hot item to be recalculated /// public virtual void ClearHotItem() { if (IsDisposed || Disposing) return; UpdateHotItem(new Point(-1, -1)); } /// /// Force the hot item to be recalculated /// public virtual void RefreshHotItem() { if (IsDisposed || Disposing) return; UpdateHotItem(PointToClient(Cursor.Position)); } /// /// The mouse has moved to the given pt. See if the hot item needs to be updated /// /// Where is the mouse? /// This is the main entry point for hot item handling protected virtual void UpdateHotItem(Point pt) { UpdateHotItem(OlvHitTest(pt.X, pt.Y)); } /// /// The mouse has moved to the given pt. See if the hot item needs to be updated /// /// /// This is the main entry point for hot item handling protected virtual void UpdateHotItem(OlvListViewHitTestInfo hti) { // We only need to do the work of this method when the list has hot parts // (i.e. some element whose visual appearance changes when under the mouse)? // Hot item decorations and hyperlinks are obvious, but if we have checkboxes // or buttons, those are also "hot". It's difficult to quickly detect if there are any // columns that have checkboxes or buttons, so we just abdicate responsibililty and // provide a property (UseHotControls) which lets the programmer say whether to do // the hot processing or not. if (!UseHotItem && !UseHyperlinks && !UseHotControls) return; int newHotRow = hti.RowIndex; int newHotColumn = hti.ColumnIndex; HitTestLocation newHotCellHitLocation = hti.HitTestLocation; HitTestLocationEx newHotCellHitLocationEx = hti.HitTestLocationEx; OLVGroup newHotGroup = hti.Group; // In non-details view, we treat any hit on a row as if it were a hit // on column 0 -- which (effectively) it is! if (newHotRow >= 0 && View != View.Details) newHotColumn = 0; if (HotRowIndex == newHotRow && HotColumnIndex == newHotColumn && HotCellHitLocation == newHotCellHitLocation && HotCellHitLocationEx == newHotCellHitLocationEx && HotGroup == newHotGroup) { return; } // Trigger the hotitem changed event HotItemChangedEventArgs args = new HotItemChangedEventArgs(); args.HotCellHitLocation = newHotCellHitLocation; args.HotCellHitLocationEx = newHotCellHitLocationEx; args.HotColumnIndex = newHotColumn; args.HotRowIndex = newHotRow; args.HotGroup = newHotGroup; args.OldHotCellHitLocation = HotCellHitLocation; args.OldHotCellHitLocationEx = HotCellHitLocationEx; args.OldHotColumnIndex = HotColumnIndex; args.OldHotRowIndex = HotRowIndex; args.OldHotGroup = HotGroup; OnHotItemChanged(args); // Update the state of the control HotRowIndex = newHotRow; HotColumnIndex = newHotColumn; HotCellHitLocation = newHotCellHitLocation; HotCellHitLocationEx = newHotCellHitLocationEx; HotGroup = newHotGroup; // If the event handler handled it complete, don't do anything else if (args.Handled) return; // System.Diagnostics.Debug.WriteLine(String.Format("Changed hot item: {0}", args)); BeginUpdate(); try { Invalidate(); if (args.OldHotRowIndex != -1) UnapplyHotItem(args.OldHotRowIndex); if (HotRowIndex != -1) { // Virtual lists apply hot item style when fetching their rows if (VirtualMode) { ClearCachedInfo(); RedrawItems(HotRowIndex, HotRowIndex, true); } else { UpdateHotRow(HotRowIndex, HotColumnIndex, HotCellHitLocation, hti.Item); } } if (UseHotItem && HotItemStyleOrDefault.Overlay != null) { RefreshOverlays(); } } finally { EndUpdate(); } } /// /// Update the given row using the current hot item information /// /// protected virtual void UpdateHotRow(OLVListItem olvi) { UpdateHotRow(HotRowIndex, HotColumnIndex, HotCellHitLocation, olvi); } /// /// Update the given row using the given hot item information /// /// /// /// /// protected virtual void UpdateHotRow(int rowIndex, int columnIndex, HitTestLocation hitLocation, OLVListItem olvi) { if (rowIndex < 0 || columnIndex < 0) return; // System.Diagnostics.Debug.WriteLine(String.Format("UpdateHotRow: {0}, {1}, {2}", rowIndex, columnIndex, hitLocation)); if (UseHyperlinks) { OLVColumn column = GetColumn(columnIndex); OLVListSubItem subItem = olvi.GetSubItem(columnIndex); if (column.Hyperlink && hitLocation == HitTestLocation.Text && !String.IsNullOrEmpty(subItem.Url)) { ApplyCellStyle(olvi, columnIndex, HyperlinkStyle.Over); Cursor = HyperlinkStyle.OverCursor ?? Cursors.Default; } else { Cursor = Cursors.Default; } } if (UseHotItem) { if (!olvi.Selected && olvi.Enabled) { ApplyRowStyle(olvi, HotItemStyleOrDefault); } } } /// /// Apply a style to the given row /// /// /// public virtual void ApplyRowStyle(OLVListItem olvi, IItemStyle style) { if (style == null) return; Font font = style.Font ?? olvi.Font; if (style.FontStyle != FontStyle.Regular) font = new Font(font ?? Font, style.FontStyle); if (!Equals(font, olvi.Font)) { if (olvi.UseItemStyleForSubItems) olvi.Font = font; else { foreach (ListViewItem.ListViewSubItem x in olvi.SubItems) x.Font = font; } } if (!style.ForeColor.IsEmpty) { if (olvi.UseItemStyleForSubItems) olvi.ForeColor = style.ForeColor; else { foreach (ListViewItem.ListViewSubItem x in olvi.SubItems) x.ForeColor = style.ForeColor; } } if (!style.BackColor.IsEmpty) { if (olvi.UseItemStyleForSubItems) olvi.BackColor = style.BackColor; else { foreach (ListViewItem.ListViewSubItem x in olvi.SubItems) x.BackColor = style.BackColor; } } } /// /// Apply a style to a cell /// /// /// /// protected virtual void ApplyCellStyle(OLVListItem olvi, int columnIndex, IItemStyle style) { if (style == null) return; // Don't apply formatting to subitems when not in Details view if (View != View.Details && columnIndex > 0) return; olvi.UseItemStyleForSubItems = false; ListViewItem.ListViewSubItem subItem = olvi.SubItems[columnIndex]; if (style.Font != null) subItem.Font = style.Font; if (style.FontStyle != FontStyle.Regular) subItem.Font = new Font(subItem.Font ?? olvi.Font ?? Font, style.FontStyle); if (!style.ForeColor.IsEmpty) subItem.ForeColor = style.ForeColor; if (!style.BackColor.IsEmpty) subItem.BackColor = style.BackColor; } /// /// Remove hot item styling from the given row /// /// protected virtual void UnapplyHotItem(int index) { Cursor = Cursors.Default; // Virtual lists will apply the appropriate formatting when the row is fetched if (VirtualMode) { if (index < VirtualListSize) RedrawItems(index, index, true); } else { OLVListItem olvi = GetItem(index); if (olvi != null) { //this.PostProcessOneRow(index, index, olvi); RefreshItem(olvi); } } } #endregion #region Drag and drop /// /// /// /// protected override void OnItemDrag(ItemDragEventArgs e) { base.OnItemDrag(e); if (DragSource == null) return; Object data = DragSource.StartDrag(this, e.Button, (OLVListItem)e.Item); if (data != null) { DragDropEffects effect = DoDragDrop(data, DragSource.GetAllowedEffects(data)); DragSource.EndDrag(data, effect); } } /// /// /// /// protected override void OnDragEnter(DragEventArgs args) { base.OnDragEnter(args); if (DropSink != null) DropSink.Enter(args); } /// /// /// /// protected override void OnDragOver(DragEventArgs args) { base.OnDragOver(args); if (DropSink != null) DropSink.Over(args); } /// /// /// /// protected override void OnDragDrop(DragEventArgs args) { base.OnDragDrop(args); if (DropSink != null) DropSink.Drop(args); } /// /// /// /// protected override void OnDragLeave(EventArgs e) { base.OnDragLeave(e); if (DropSink != null) DropSink.Leave(); } /// /// /// /// protected override void OnGiveFeedback(GiveFeedbackEventArgs args) { base.OnGiveFeedback(args); if (DropSink != null) DropSink.GiveFeedback(args); } /// /// /// /// protected override void OnQueryContinueDrag(QueryContinueDragEventArgs args) { base.OnQueryContinueDrag(args); if (DropSink != null) DropSink.QueryContinue(args); } #endregion #region Decorations and Overlays /// /// Add the given decoration to those on this list and make it appear /// /// The decoration /// /// A decoration scrolls with the listview. An overlay stays fixed in place. /// public virtual void AddDecoration(IDecoration decoration) { if (decoration == null) return; Decorations.Add(decoration); Invalidate(); } /// /// Add the given overlay to those on this list and make it appear /// /// The overlay public virtual void AddOverlay(IOverlay overlay) { if (overlay == null) return; Overlays.Add(overlay); Invalidate(); } /// /// Draw all the decorations /// /// A Graphics /// The items that were redrawn and whose decorations should also be redrawn protected virtual void DrawAllDecorations(Graphics g, List itemsThatWereRedrawn) { g.TextRenderingHint = TextRenderingHint; g.SmoothingMode = SmoothingMode; Rectangle contentRectangle = ContentRectangle; if (HasEmptyListMsg && GetItemCount() == 0) { EmptyListMsgOverlay.Draw(this, g, contentRectangle); } // Let the drop sink draw whatever feedback it likes if (DropSink != null) { DropSink.DrawFeedback(g, contentRectangle); } // Draw our item and subitem decorations foreach (OLVListItem olvi in itemsThatWereRedrawn) { if (olvi.HasDecoration) { foreach (IDecoration d in olvi.Decorations) { d.ListItem = olvi; d.SubItem = null; d.Draw(this, g, contentRectangle); } } foreach (OLVListSubItem subItem in olvi.SubItems.OfType()) { if (subItem.HasDecoration) { foreach (IDecoration d in subItem.Decorations) { d.ListItem = olvi; d.SubItem = subItem; d.Draw(this, g, contentRectangle); } } } if (SelectedRowDecoration != null && olvi.Selected && olvi.Enabled) { SelectedRowDecoration.ListItem = olvi; SelectedRowDecoration.SubItem = null; SelectedRowDecoration.Draw(this, g, contentRectangle); } } // Now draw the specifically registered decorations foreach (IDecoration decoration in Decorations) { decoration.ListItem = null; decoration.SubItem = null; decoration.Draw(this, g, contentRectangle); } // Finally, draw any hot item decoration if (UseHotItem) { IDecoration hotItemDecoration = HotItemStyleOrDefault.Decoration; if (hotItemDecoration != null) { hotItemDecoration.ListItem = GetItem(HotRowIndex); if (hotItemDecoration.ListItem == null || hotItemDecoration.ListItem.Enabled) { hotItemDecoration.SubItem = hotItemDecoration.ListItem == null ? null : hotItemDecoration.ListItem.GetSubItem(HotColumnIndex); hotItemDecoration.Draw(this, g, contentRectangle); } } } // If we are in design mode, we don't want to use the glass panels, // so we draw the background overlays here if (DesignMode) { foreach (IOverlay overlay in Overlays) { overlay.Draw(this, g, contentRectangle); } } } /// /// Is the given decoration shown on this list /// /// The overlay public virtual bool HasDecoration(IDecoration decoration) { return Decorations.Contains(decoration); } /// /// Is the given overlay shown on this list? /// /// The overlay public virtual bool HasOverlay(IOverlay overlay) { return Overlays.Contains(overlay); } /// /// Hide any overlays. /// /// /// This is only a temporary hiding -- the overlays will be shown /// the next time the ObjectListView redraws. /// public virtual void HideOverlays() { foreach (GlassPanelForm glassPanel in glassPanels) { glassPanel.HideGlass(); } } /// /// Create and configure the empty list msg overlay /// protected virtual void InitializeEmptyListMsgOverlay() { TextOverlay overlay = new TextOverlay(); overlay.Alignment = System.Drawing.ContentAlignment.MiddleCenter; overlay.TextColor = SystemColors.ControlDarkDark; overlay.BackColor = Color.BlanchedAlmond; overlay.BorderColor = SystemColors.ControlDark; overlay.BorderWidth = 2.0f; EmptyListMsgOverlay = overlay; } /// /// Initialize the standard image and text overlays /// protected virtual void InitializeStandardOverlays() { OverlayImage = new ImageOverlay(); AddOverlay(OverlayImage); OverlayText = new TextOverlay(); AddOverlay(OverlayText); } /// /// Make sure that any overlays are visible. /// public virtual void ShowOverlays() { // If we shouldn't show overlays, then don't create glass panels if (!ShouldShowOverlays()) return; // Make sure that each overlay has its own glass panels if (Overlays.Count != glassPanels.Count) { foreach (IOverlay overlay in Overlays) { GlassPanelForm glassPanel = FindGlassPanelForOverlay(overlay); if (glassPanel == null) { glassPanel = new GlassPanelForm(); glassPanel.Bind(this, overlay); glassPanels.Add(glassPanel); } } } foreach (GlassPanelForm glassPanel in glassPanels) { glassPanel.ShowGlass(); } } private bool ShouldShowOverlays() { // If we are in design mode, we dont show the overlays if (DesignMode) return false; // If we are explicitly not using overlays, also don't show them if (!UseOverlays) return false; // If there are no overlays, guess... if (!HasOverlays) return false; // If we don't have 32-bit display, alpha blending doesn't work, so again, no overlays // TODO: This should actually figure out which screen(s) the control is on, and make sure // that each one is 32-bit. if (Screen.PrimaryScreen.BitsPerPixel < 32) return false; // Finally, we can show the overlays return true; } private GlassPanelForm FindGlassPanelForOverlay(IOverlay overlay) { return glassPanels.Find(delegate (GlassPanelForm x) { return x.Overlay == overlay; }); } /// /// Refresh the display of the overlays /// public virtual void RefreshOverlays() { foreach (GlassPanelForm glassPanel in glassPanels) { glassPanel.Invalidate(); } } /// /// Refresh the display of just one overlays /// public virtual void RefreshOverlay(IOverlay overlay) { GlassPanelForm glassPanel = FindGlassPanelForOverlay(overlay); if (glassPanel != null) glassPanel.Invalidate(); } /// /// Remove the given decoration from this list /// /// The decoration to remove public virtual void RemoveDecoration(IDecoration decoration) { if (decoration == null) return; Decorations.Remove(decoration); Invalidate(); } /// /// Remove the given overlay to those on this list /// /// The overlay public virtual void RemoveOverlay(IOverlay overlay) { if (overlay == null) return; Overlays.Remove(overlay); GlassPanelForm glassPanel = FindGlassPanelForOverlay(overlay); if (glassPanel != null) { glassPanels.Remove(glassPanel); glassPanel.Unbind(); glassPanel.Dispose(); } } #endregion #region Filtering /// /// Create a filter that will enact all the filtering currently installed /// on the visible columns. /// public virtual IModelFilter CreateColumnFilter() { List filters = new List(); foreach (OLVColumn column in Columns) { IModelFilter filter = column.ValueBasedFilter; if (filter != null) filters.Add(filter); } return (filters.Count == 0) ? null : new CompositeAllFilter(filters); } /// /// Do the actual work of filtering /// /// /// /// /// protected virtual IEnumerable FilterObjects(IEnumerable originalObjects, IModelFilter aModelFilter, IListFilter aListFilter) { // Being cautious originalObjects ??= new ArrayList(); // Tell the world to filter the objects. If they do so, don't do anything else // ReSharper disable PossibleMultipleEnumeration FilterEventArgs args = new FilterEventArgs(originalObjects); OnFilter(args); if (args.FilteredObjects != null) return args.FilteredObjects; // Apply a filter to the list as a whole if (aListFilter != null) originalObjects = aListFilter.Filter(originalObjects); // Apply the object filter if there is one if (aModelFilter != null) { ArrayList filteredObjects = new ArrayList(); foreach (object model in originalObjects) { if (aModelFilter.Filter(model)) filteredObjects.Add(model); } originalObjects = filteredObjects; } return originalObjects; // ReSharper restore PossibleMultipleEnumeration } /// /// Remove all column filtering. /// public virtual void ResetColumnFiltering() { foreach (OLVColumn column in Columns) { column.ValuesChosenForFiltering.Clear(); } UpdateColumnFiltering(); } /// /// Update the filtering of this ObjectListView based on the value filtering /// defined in each column /// public virtual void UpdateColumnFiltering() { //List filters = new List(); //IModelFilter columnFilter = this.CreateColumnFilter(); //if (columnFilter != null) // filters.Add(columnFilter); //if (this.AdditionalFilter != null) // filters.Add(this.AdditionalFilter); //this.ModelFilter = filters.Count == 0 ? null : new CompositeAllFilter(filters); if (IsDisposed || Disposing) return; if (AdditionalFilter == null) ModelFilter = CreateColumnFilter(); else { IModelFilter columnFilter = CreateColumnFilter(); if (columnFilter == null) ModelFilter = AdditionalFilter; else { List filters = new List(); filters.Add(columnFilter); filters.Add(AdditionalFilter); ModelFilter = new CompositeAllFilter(filters); } } } /// /// When some setting related to filtering changes, this method is called. /// protected virtual void UpdateFiltering() { BuildList(true); } /// /// Update all renderers with the currently installed model filter /// protected virtual void NotifyNewModelFilter() { if (DefaultRenderer is IFilterAwareRenderer filterAware) filterAware.Filter = ModelFilter; foreach (OLVColumn column in AllColumns) { filterAware = column.Renderer as IFilterAwareRenderer; if (filterAware != null) filterAware.Filter = ModelFilter; } } #endregion #region Persistent check state /// /// Gets the checkedness of the given model. /// /// The model /// The checkedness of the model. Defaults to unchecked. protected virtual CheckState GetPersistentCheckState(object model) { if (model != null && CheckStateMap.TryGetValue(model, out CheckState state)) return state; return CheckState.Unchecked; } /// /// Remember the check state of the given model object /// /// The model to be remembered /// The model's checkedness /// The state given to the method protected virtual CheckState SetPersistentCheckState(object model, CheckState state) { if (model == null) return CheckState.Unchecked; CheckStateMap[model] = state; return state; } /// /// Forget any persistent checkbox state /// protected virtual void ClearPersistentCheckState() { CheckStateMap = null; } #endregion private float origFontSize; protected override void RescaleConstantsForDpi(int deviceDpiOld, int deviceDpiNew) { base.RescaleConstantsForDpi(deviceDpiOld, deviceDpiNew); SuspendLayout(); BeginUpdate(); // Storing the font size because the Font property gets changed at weird times // which corrupts the size after a few DPI switches since scaling is sometimes applied twice if (origFontSize == 0) origFontSize = Font.Size; var scalingRatio = DeviceDpi / 96f; //e.DeviceDpiNew / (double)e.DeviceDpiOld; //Debug.WriteLine($"DPI CHANGE: {deviceDpiOld} > {deviceDpiNew}"); Font = new Font(Font.FontFamily, MathF.Round(origFontSize * scalingRatio, 1)); // Can't use foreach since it can throw an InvalidOperationException when the ListView is in virtual mode for (var i = 0; i < Items.Count; i++) { var listViewItem = (OLVListItem)Items[i]; RefreshItem(listViewItem); } AutoResizeColumns(); EndUpdate(); ResumeLayout(); } #region Implementation variables private bool isOwnerOfObjects; // does this ObjectListView own the Objects collection? private bool hasIdleHandler; // has an Idle handler already been installed? private bool hasResizeColumnsHandler; // has an idle handler been installed which will handle column resizing? private bool isInWmPaintEvent; // is a WmPaint event currently being handled? private bool shouldDoCustomDrawing; // should the list do its custom drawing? private bool isMarqueSelecting; // Is a marque selection in progress? private int suspendSelectionEventCount; // How many unmatched SuspendSelectionEvents() calls have been made? private readonly List glassPanels = new(); // The transparent panel that draws overlays private Dictionary visitedUrlMap = new(); // Which urls have been visited? // TODO //private CheckBoxSettings checkBoxSettings = new CheckBoxSettings(); #endregion } } ================================================ FILE: source/ObjectListView/ObjectListView.csproj ================================================  Library BrightIdeasSoftware ObjectListView false false 1 True True Resources.resx ResXFileCodeGenerator Resources.Designer.cs ================================================ FILE: source/ObjectListView/ObjectListView.shfb ================================================  All ObjectListView appears in this namespace ObjectListViewDemo demonstrates helpful techniques when using an ObjectListView Summary, Parameter, Returns, AutoDocumentCtors, Namespace InheritedMembers, Protected, SealedProtected .\Help\ True True HtmlHelp1x True False 2.0.50727 True False True False ObjectListView Reference Documentation en-US (c) Copyright 2006-2008 Phillip Piper All Rights Reserved phillip.piper@gmail.com Local Msdn Blank Prototype Guid CSharp False AboveNamespaces ================================================ FILE: source/ObjectListView/Properties/AssemblyInfo.cs ================================================ using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Runtime.InteropServices; [assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "Windows-only app")] // 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("ObjectListView")] [assembly: AssemblyDescription("A much easier to use ListView and friends")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Bright Ideas Software")] [assembly: AssemblyProduct("ObjectListView")] [assembly: AssemblyCopyright("Copyright © 2006-2016")] [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("ef28c7a8-77ae-442d-abc3-bb023fa31e57")] // 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 Revision and Build Numbers // by using the '*' as shown below: [assembly: AssemblyVersion("2.10.0.0")] [assembly: AssemblyFileVersion("2.9.1.0")] [assembly: AssemblyInformationalVersion("2.9.1")] [assembly: System.CLSCompliant(true)] ================================================ FILE: source/ObjectListView/Properties/Resources.Designer.cs ================================================ //------------------------------------------------------------------------------ // // This code was generated by a tool. // Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ namespace BrightIdeasSoftware.Properties { using System; /// /// A strongly-typed resource class, for looking up localized strings, etc. /// // This class was auto-generated by the StronglyTypedResourceBuilder // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { private static global::System.Resources.ResourceManager resourceMan; private static global::System.Globalization.CultureInfo resourceCulture; [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] internal Resources() { } /// /// Returns the cached ResourceManager instance used by this class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("BrightIdeasSoftware.Properties.Resources", typeof(Resources).Assembly); resourceMan = temp; } return resourceMan; } } /// /// Overrides the current thread's CurrentUICulture property for all /// resource lookups using this strongly typed resource class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Globalization.CultureInfo Culture { get { return resourceCulture; } set { resourceCulture = value; } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap ClearFiltering { get { object obj = ResourceManager.GetObject("ClearFiltering", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap ColumnFilterIndicator { get { object obj = ResourceManager.GetObject("ColumnFilterIndicator", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap Filtering { get { object obj = ResourceManager.GetObject("Filtering", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap SortAscending { get { object obj = ResourceManager.GetObject("SortAscending", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap SortDescending { get { object obj = ResourceManager.GetObject("SortDescending", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } } } ================================================ FILE: source/ObjectListView/Properties/Resources.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ..\Resources\clear-filter.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\filter-icons3.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\filter.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\sort-ascending.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\sort-descending.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ================================================ FILE: source/ObjectListView/Rendering/Adornments.cs ================================================ /* * Adornments - Adornments are the basis for overlays and decorations -- things that can be rendered over the top of a ListView * * Author: Phillip Piper * Date: 16/08/2009 1:02 AM * * Change log: * v2.6 * 2012-08-18 JPP - Correctly dispose of brush and pen resources * v2.3 * 2009-09-22 JPP - Added Wrap property to TextAdornment, to allow text wrapping to be disabled * - Added ShrinkToWidth property to ImageAdornment * 2009-08-17 JPP - Initial version * * To do: * - Use IPointLocator rather than Corners * - Add RotationCenter property ratherr than always using middle center * * Copyright (C) 2009-2014 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System; using System.ComponentModel; using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Imaging; namespace BrightIdeasSoftware { /// /// An adorment is the common base for overlays and decorations. /// public class GraphicAdornment { #region Public properties /// /// Gets or sets the corner of the adornment that will be positioned at the reference corner /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public ContentAlignment AdornmentCorner { get { return adornmentCorner; } set { adornmentCorner = value; } } private ContentAlignment adornmentCorner = ContentAlignment.MiddleCenter; /// /// Gets or sets location within the reference rectange where the adornment will be drawn /// /// This is a simplied interface to ReferenceCorner and AdornmentCorner [Category("ObjectListView"), Description("How will the adornment be aligned"), DefaultValue(ContentAlignment.BottomRight), NotifyParentProperty(true)] public ContentAlignment Alignment { get { return alignment; } set { alignment = value; ReferenceCorner = value; AdornmentCorner = value; } } private ContentAlignment alignment = ContentAlignment.BottomRight; /// /// Gets or sets the offset by which the position of the adornment will be adjusted /// [Category("ObjectListView"), Description("The offset by which the position of the adornment will be adjusted"), DefaultValue(typeof(Size), "0,0")] public Size Offset { get { return offset; } set { offset = value; } } private Size offset = new(); /// /// Gets or sets the point of the reference rectangle to which the adornment will be aligned. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public ContentAlignment ReferenceCorner { get { return referenceCorner; } set { referenceCorner = value; } } private ContentAlignment referenceCorner = ContentAlignment.MiddleCenter; /// /// Gets or sets the degree of rotation by which the adornment will be transformed. /// The centre of rotation will be the center point of the adornment. /// [Category("ObjectListView"), Description("The degree of rotation that will be applied to the adornment."), DefaultValue(0), NotifyParentProperty(true)] public int Rotation { get { return rotation; } set { rotation = value; } } private int rotation; /// /// Gets or sets the transparency of the overlay. /// 0 is completely transparent, 255 is completely opaque. /// [Category("ObjectListView"), Description("The transparency of this adornment. 0 is completely transparent, 255 is completely opaque."), DefaultValue(128)] public int Transparency { get { return transparency; } set { transparency = Math.Min(255, Math.Max(0, value)); } } private int transparency = 128; #endregion #region Calculations /// /// Calculate the location of rectangle of the given size, /// so that it's indicated corner would be at the given point. /// /// The point /// /// Which corner will be positioned at the reference point /// /// CalculateAlignedPosition(new Point(50, 100), new Size(10, 20), System.Drawing.ContentAlignment.TopLeft) -> Point(50, 100) /// CalculateAlignedPosition(new Point(50, 100), new Size(10, 20), System.Drawing.ContentAlignment.MiddleCenter) -> Point(45, 90) /// CalculateAlignedPosition(new Point(50, 100), new Size(10, 20), System.Drawing.ContentAlignment.BottomRight) -> Point(40, 80) public virtual Point CalculateAlignedPosition(Point pt, Size size, ContentAlignment corner) { switch (corner) { case ContentAlignment.TopLeft: return pt; case ContentAlignment.TopCenter: return new Point(pt.X - (size.Width / 2), pt.Y); case ContentAlignment.TopRight: return new Point(pt.X - size.Width, pt.Y); case ContentAlignment.MiddleLeft: return new Point(pt.X, pt.Y - (size.Height / 2)); case ContentAlignment.MiddleCenter: return new Point(pt.X - (size.Width / 2), pt.Y - (size.Height / 2)); case ContentAlignment.MiddleRight: return new Point(pt.X - size.Width, pt.Y - (size.Height / 2)); case ContentAlignment.BottomLeft: return new Point(pt.X, pt.Y - size.Height); case ContentAlignment.BottomCenter: return new Point(pt.X - (size.Width / 2), pt.Y - size.Height); case ContentAlignment.BottomRight: return new Point(pt.X - size.Width, pt.Y - size.Height); } // Should never reach here return pt; } /// /// Calculate a rectangle that has the given size which is positioned so that /// its alignment point is at the reference location of the given rect. /// /// /// /// public virtual Rectangle CreateAlignedRectangle(Rectangle r, Size sz) { return CreateAlignedRectangle(r, sz, ReferenceCorner, AdornmentCorner, Offset); } /// /// Create a rectangle of the given size which is positioned so that /// its indicated corner is at the indicated corner of the reference rect. /// /// /// /// /// /// /// /// /// Creates a rectangle so that its bottom left is at the centre of the reference: /// corner=BottomLeft, referenceCorner=MiddleCenter /// This is a powerful concept that takes some getting used to, but is /// very neat once you understand it. /// public virtual Rectangle CreateAlignedRectangle(Rectangle r, Size sz, ContentAlignment corner, ContentAlignment referenceCorner, Size offset) { Point referencePt = CalculateCorner(r, referenceCorner); Point topLeft = CalculateAlignedPosition(referencePt, sz, corner); return new Rectangle(topLeft + offset, sz); } /// /// Return the point at the indicated corner of the given rectangle (it doesn't /// have to be a corner, but a named location) /// /// The reference rectangle /// Which point of the rectangle should be returned? /// A point /// CalculateReferenceLocation(new Rectangle(0, 0, 50, 100), System.Drawing.ContentAlignment.TopLeft) -> Point(0, 0) /// CalculateReferenceLocation(new Rectangle(0, 0, 50, 100), System.Drawing.ContentAlignment.MiddleCenter) -> Point(25, 50) /// CalculateReferenceLocation(new Rectangle(0, 0, 50, 100), System.Drawing.ContentAlignment.BottomRight) -> Point(50, 100) public virtual Point CalculateCorner(Rectangle r, ContentAlignment corner) { switch (corner) { case ContentAlignment.TopLeft: return new Point(r.Left, r.Top); case ContentAlignment.TopCenter: return new Point(r.X + (r.Width / 2), r.Top); case ContentAlignment.TopRight: return new Point(r.Right, r.Top); case ContentAlignment.MiddleLeft: return new Point(r.Left, r.Top + (r.Height / 2)); case ContentAlignment.MiddleCenter: return new Point(r.X + (r.Width / 2), r.Top + (r.Height / 2)); case ContentAlignment.MiddleRight: return new Point(r.Right, r.Top + (r.Height / 2)); case ContentAlignment.BottomLeft: return new Point(r.Left, r.Bottom); case ContentAlignment.BottomCenter: return new Point(r.X + (r.Width / 2), r.Bottom); case ContentAlignment.BottomRight: return new Point(r.Right, r.Bottom); } // Should never reach here return r.Location; } /// /// Given the item and the subitem, calculate its bounds. /// /// /// /// public virtual Rectangle CalculateItemBounds(OLVListItem item, OLVListSubItem subItem) { if (item == null) return Rectangle.Empty; if (subItem == null) return item.Bounds; return item.GetSubItemBounds(item.SubItems.IndexOf(subItem)); } #endregion #region Commands /// /// Apply any specified rotation to the Graphic content. /// /// The Graphics to be transformed /// The rotation will be around the centre of this rect protected virtual void ApplyRotation(Graphics g, Rectangle r) { if (Rotation == 0) return; // THINK: Do we want to reset the transform? I think we want to push a new transform g.ResetTransform(); Matrix m = new Matrix(); m.RotateAt(Rotation, new Point(r.Left + r.Width / 2, r.Top + r.Height / 2)); g.Transform = m; } /// /// Reverse the rotation created by ApplyRotation() /// /// protected virtual void UnapplyRotation(Graphics g) { if (Rotation != 0) g.ResetTransform(); } #endregion } /// /// An overlay that will draw an image over the top of the ObjectListView /// public class ImageAdornment : GraphicAdornment { #region Public properties /// /// Gets or sets the image that will be drawn /// [Category("ObjectListView"), Description("The image that will be drawn"), DefaultValue(null), NotifyParentProperty(true)] public Image Image { get { return image; } set { image = value; } } private Image image; /// /// Gets or sets if the image will be shrunk to fit with its horizontal bounds /// [Category("ObjectListView"), Description("Will the image be shrunk to fit within its width?"), DefaultValue(false)] public bool ShrinkToWidth { get { return shrinkToWidth; } set { shrinkToWidth = value; } } private bool shrinkToWidth; #endregion #region Commands /// /// Draw the image in its specified location /// /// The Graphics used for drawing /// The bounds of the rendering public virtual void DrawImage(Graphics g, Rectangle r) { if (ShrinkToWidth) DrawScaledImage(g, r, Image, Transparency); else DrawImage(g, r, Image, Transparency); } /// /// Draw the image in its specified location /// /// The image to be drawn /// The Graphics used for drawing /// The bounds of the rendering /// How transparent should the image be (0 is completely transparent, 255 is opaque) public virtual void DrawImage(Graphics g, Rectangle r, Image image, int transparency) { if (image != null) DrawImage(g, r, image, image.Size, transparency); } /// /// Draw the image in its specified location /// /// The image to be drawn /// The Graphics used for drawing /// The bounds of the rendering /// How big should the image be? /// How transparent should the image be (0 is completely transparent, 255 is opaque) public virtual void DrawImage(Graphics g, Rectangle r, Image image, Size sz, int transparency) { if (image == null) return; Rectangle adornmentBounds = CreateAlignedRectangle(r, sz); try { ApplyRotation(g, adornmentBounds); DrawTransparentBitmap(g, adornmentBounds, image, transparency); } finally { UnapplyRotation(g); } } /// /// Draw the image in its specified location, scaled so that it is not wider /// than the given rectangle. Height is scaled proportional to the width. /// /// The image to be drawn /// The Graphics used for drawing /// The bounds of the rendering /// How transparent should the image be (0 is completely transparent, 255 is opaque) public virtual void DrawScaledImage(Graphics g, Rectangle r, Image image, int transparency) { if (image == null) return; // If the image is too wide to be drawn in the space provided, proportionally scale it down. // Too tall images are not scaled. Size size = image.Size; if (image.Width > r.Width) { float scaleRatio = (float)r.Width / (float)image.Width; size.Height = (int)((float)image.Height * scaleRatio); size.Width = r.Width - 1; } DrawImage(g, r, image, size, transparency); } /// /// Utility to draw a bitmap transparenly. /// /// /// /// /// protected virtual void DrawTransparentBitmap(Graphics g, Rectangle r, Image image, int transparency) { ImageAttributes imageAttributes = null; if (transparency != 255) { imageAttributes = new ImageAttributes(); float a = (float)transparency / 255.0f; float[][] colorMatrixElements = { new float[] {1, 0, 0, 0, 0}, new float[] {0, 1, 0, 0, 0}, new float[] {0, 0, 1, 0, 0}, new float[] {0, 0, 0, a, 0}, new float[] {0, 0, 0, 0, 1}}; imageAttributes.SetColorMatrix(new ColorMatrix(colorMatrixElements)); } g.DrawImage(image, r, // destination rectangle 0, 0, image.Size.Width, image.Size.Height, // source rectangle GraphicsUnit.Pixel, imageAttributes); } #endregion } /// /// An adornment that will draw text /// public class TextAdornment : GraphicAdornment { #region Public properties /// /// Gets or sets the background color of the text /// Set this to Color.Empty to not draw a background /// [Category("ObjectListView"), Description("The background color of the text"), DefaultValue(typeof(Color), "")] public Color BackColor { get { return backColor; } set { backColor = value; } } private Color backColor = Color.Empty; /// /// Gets the brush that will be used to paint the text /// [Browsable(false)] public Brush BackgroundBrush { get { return new SolidBrush(Color.FromArgb(workingTransparency, BackColor)); } } /// /// Gets or sets the color of the border around the billboard. /// Set this to Color.Empty to remove the border /// [Category("ObjectListView"), Description("The color of the border around the text"), DefaultValue(typeof(Color), "")] public Color BorderColor { get { return borderColor; } set { borderColor = value; } } private Color borderColor = Color.Empty; /// /// Gets the brush that will be used to paint the text /// [Browsable(false)] public Pen BorderPen { get { return new Pen(Color.FromArgb(workingTransparency, BorderColor), BorderWidth); } } /// /// Gets or sets the width of the border around the text /// [Category("ObjectListView"), Description("The width of the border around the text"), DefaultValue(0.0f)] public float BorderWidth { get { return borderWidth; } set { borderWidth = value; } } private float borderWidth; /// /// How rounded should the corners of the border be? 0 means no rounding. /// /// If this value is too large, the edges of the border will appear odd. [Category("ObjectListView"), Description("How rounded should the corners of the border be? 0 means no rounding."), DefaultValue(16.0f), NotifyParentProperty(true)] public float CornerRounding { get { return cornerRounding; } set { cornerRounding = value; } } private float cornerRounding = 16.0f; /// /// Gets or sets the font that will be used to draw the text /// [Category("ObjectListView"), Description("The font that will be used to draw the text"), DefaultValue(null), NotifyParentProperty(true)] public Font Font { get { return font; } set { font = value; } } private Font font; /// /// Gets the font that will be used to draw the text or a reasonable default /// [Browsable(false)] public Font FontOrDefault { get { return Font ?? new Font("Tahoma", 16); } } /// /// Does this text have a background? /// [Browsable(false)] public bool HasBackground { get { return BackColor != Color.Empty; } } /// /// Does this overlay have a border? /// [Browsable(false)] public bool HasBorder { get { return BorderColor != Color.Empty && BorderWidth > 0; } } /// /// Gets or sets the maximum width of the text. Text longer than this will wrap. /// 0 means no maximum. /// [Category("ObjectListView"), Description("The maximum width the text (0 means no maximum). Text longer than this will wrap"), DefaultValue(0)] public int MaximumTextWidth { get { return maximumTextWidth; } set { maximumTextWidth = value; } } private int maximumTextWidth; /// /// Gets or sets the formatting that should be used on the text /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual StringFormat StringFormat { get { if (stringFormat == null) { stringFormat = new StringFormat(); stringFormat.Alignment = StringAlignment.Center; stringFormat.LineAlignment = StringAlignment.Center; stringFormat.Trimming = StringTrimming.EllipsisCharacter; if (!Wrap) stringFormat.FormatFlags = StringFormatFlags.NoWrap; } return stringFormat; } set { stringFormat = value; } } private StringFormat stringFormat; /// /// Gets or sets the text that will be drawn /// [Category("ObjectListView"), Description("The text that will be drawn over the top of the ListView"), DefaultValue(null), NotifyParentProperty(true), Localizable(true)] public string Text { get { return text; } set { text = value; } } private string text; /// /// Gets the brush that will be used to paint the text /// [Browsable(false)] public Brush TextBrush { get { return new SolidBrush(Color.FromArgb(workingTransparency, TextColor)); } } /// /// Gets or sets the color of the text /// [Category("ObjectListView"), Description("The color of the text"), DefaultValue(typeof(Color), "DarkBlue"), NotifyParentProperty(true)] public Color TextColor { get { return textColor; } set { textColor = value; } } private Color textColor = Color.DarkBlue; /// /// Gets or sets whether the text will wrap when it exceeds its bounds /// [Category("ObjectListView"), Description("Will the text wrap?"), DefaultValue(true)] public bool Wrap { get { return wrap; } set { wrap = value; } } private bool wrap = true; #endregion #region Implementation /// /// Draw our text with our stored configuration in relation to the given /// reference rectangle /// /// The Graphics used for drawing /// The reference rectangle in relation to which the text will be drawn public virtual void DrawText(Graphics g, Rectangle r) { DrawText(g, r, Text, Transparency); } /// /// Draw the given text with our stored configuration /// /// The Graphics used for drawing /// The reference rectangle in relation to which the text will be drawn /// The text to draw /// How opaque should be text be public virtual void DrawText(Graphics g, Rectangle r, string s, int transparency) { if (String.IsNullOrEmpty(s)) return; Rectangle textRect = CalculateTextBounds(g, r, s); DrawBorderedText(g, textRect, s, transparency); } /// /// Draw the text with a border /// /// The Graphics used for drawing /// The bounds within which the text should be drawn /// The text to draw /// How opaque should be text be protected virtual void DrawBorderedText(Graphics g, Rectangle textRect, string text, int transparency) { Rectangle borderRect = textRect; borderRect.Inflate((int)BorderWidth / 2, (int)BorderWidth / 2); borderRect.Y -= 1; // Looker better a little higher try { ApplyRotation(g, textRect); using (GraphicsPath path = GetRoundedRect(borderRect, CornerRounding)) { workingTransparency = transparency; if (HasBackground) { using (Brush b = BackgroundBrush) g.FillPath(b, path); } using (Brush b = TextBrush) g.DrawString(text, FontOrDefault, b, textRect, StringFormat); if (HasBorder) { using (Pen p = BorderPen) g.DrawPath(p, path); } } } finally { UnapplyRotation(g); } } /// /// Return the rectangle that will be the precise bounds of the displayed text /// /// /// /// /// The bounds of the text protected virtual Rectangle CalculateTextBounds(Graphics g, Rectangle r, string s) { int maxWidth = MaximumTextWidth <= 0 ? r.Width : MaximumTextWidth; SizeF sizeF = g.MeasureString(s, FontOrDefault, maxWidth, StringFormat); Size size = new Size(1 + (int)sizeF.Width, 1 + (int)sizeF.Height); return CreateAlignedRectangle(r, size); } /// /// Return a GraphicPath that is a round cornered rectangle /// /// The rectangle /// The diameter of the corners /// A round cornered rectagle path /// If I could rely on people using C# 3.0+, this should be /// an extension method of GraphicsPath. protected virtual GraphicsPath GetRoundedRect(Rectangle rect, float diameter) { GraphicsPath path = new GraphicsPath(); if (diameter > 0) { RectangleF arc = new RectangleF(rect.X, rect.Y, diameter, diameter); path.AddArc(arc, 180, 90); arc.X = rect.Right - diameter; path.AddArc(arc, 270, 90); arc.Y = rect.Bottom - diameter; path.AddArc(arc, 0, 90); arc.X = rect.Left; path.AddArc(arc, 90, 90); path.CloseFigure(); } else { path.AddRectangle(rect); } return path; } #endregion private int workingTransparency; } } ================================================ FILE: source/ObjectListView/Rendering/Decorations.cs ================================================ /* * Decorations - Images, text or other things that can be rendered onto an ObjectListView * * Author: Phillip Piper * Date: 19/08/2009 10:56 PM * * Change log: * 2011-04-04 JPP - Added ability to have a gradient background on BorderDecoration * v2.4 * 2010-04-15 JPP - Tweaked LightBoxDecoration a little * v2.3 * 2009-09-23 JPP - Added LeftColumn and RightColumn to RowBorderDecoration * 2009-08-23 JPP - Added LightBoxDecoration * 2009-08-19 JPP - Initial version. Separated from Overlays.cs * * To do: * * Copyright (C) 2009-2014 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System.Drawing; using System.Drawing.Drawing2D; using System.Windows.Forms; namespace BrightIdeasSoftware { /// /// A decoration is an overlay that draws itself in relation to a given row or cell. /// Decorations scroll when the listview scrolls. /// public interface IDecoration : IOverlay { /// /// Gets or sets the row that is to be decorated /// OLVListItem ListItem { get; set; } /// /// Gets or sets the subitem that is to be decorated /// OLVListSubItem SubItem { get; set; } } /// /// An AbstractDecoration is a safe do-nothing implementation of the IDecoration interface /// public class AbstractDecoration : IDecoration { #region IDecoration Members /// /// Gets or sets the row that is to be decorated /// public OLVListItem ListItem { get { return listItem; } set { listItem = value; } } private OLVListItem listItem; /// /// Gets or sets the subitem that is to be decorated /// public OLVListSubItem SubItem { get { return subItem; } set { subItem = value; } } private OLVListSubItem subItem; #endregion #region Public properties /// /// Gets the bounds of the decorations row /// public Rectangle RowBounds { get { if (ListItem == null) return Rectangle.Empty; else return ListItem.Bounds; } } /// /// Get the bounds of the decorations cell /// public Rectangle CellBounds { get { if (ListItem == null || SubItem == null) return Rectangle.Empty; else return ListItem.GetSubItemBounds(ListItem.SubItems.IndexOf(SubItem)); } } #endregion #region IOverlay Members /// /// Draw the decoration /// /// /// /// public virtual void Draw(ObjectListView olv, Graphics g, Rectangle r) { } #endregion } /// /// This decoration draws a slight tint over a column of the /// owning listview. If no column is explicitly set, the selected /// column in the listview will be used. /// The selected column is normally the sort column, but does not have to be. /// public class TintedColumnDecoration : AbstractDecoration { #region Constructors /// /// Create a TintedColumnDecoration /// public TintedColumnDecoration() { Tint = Color.FromArgb(15, Color.Blue); } /// /// Create a TintedColumnDecoration /// /// public TintedColumnDecoration(OLVColumn column) : this() { ColumnToTint = column; } #endregion #region Properties /// /// Gets or sets the column that will be tinted /// public OLVColumn ColumnToTint { get { return columnToTint; } set { columnToTint = value; } } private OLVColumn columnToTint; /// /// Gets or sets the color that will be 'tinted' over the selected column /// public Color Tint { get { return tint; } set { if (tint == value) return; if (tintBrush != null) { tintBrush.Dispose(); tintBrush = null; } tint = value; tintBrush = new SolidBrush(tint); } } private Color tint; private SolidBrush tintBrush; #endregion #region IOverlay Members /// /// Draw a slight colouring over our tinted column /// /// /// This overlay only works when: /// - the list is in Details view /// - there is at least one row /// - there is a selected column (or a specified tint column) /// /// /// /// public override void Draw(ObjectListView olv, Graphics g, Rectangle r) { if (olv.View != View.Details) return; if (olv.GetItemCount() == 0) return; OLVColumn column = ColumnToTint ?? olv.SelectedColumn; if (column == null) return; Point sides = NativeMethods.GetScrolledColumnSides(olv, column.Index); if (sides.X == -1) return; Rectangle columnBounds = new Rectangle(sides.X, r.Top, sides.Y - sides.X, r.Bottom); // Find the bottom of the last item. The tinting should extend only to there. OLVListItem lastItem = olv.GetLastItemInDisplayOrder(); if (lastItem != null) { Rectangle lastItemBounds = lastItem.Bounds; if (!lastItemBounds.IsEmpty && lastItemBounds.Bottom < columnBounds.Bottom) columnBounds.Height = lastItemBounds.Bottom - columnBounds.Top; } g.FillRectangle(tintBrush, columnBounds); } #endregion } /// /// This decoration draws an optionally filled border around a rectangle. /// Subclasses must override CalculateBounds(). /// public class BorderDecoration : AbstractDecoration { #region Constructors /// /// Create a BorderDecoration /// public BorderDecoration() : this(new Pen(Color.FromArgb(64, Color.Blue), 1)) { } /// /// Create a BorderDecoration /// /// The pen used to draw the border public BorderDecoration(Pen borderPen) { BorderPen = borderPen; } /// /// Create a BorderDecoration /// /// The pen used to draw the border /// The brush used to fill the rectangle public BorderDecoration(Pen borderPen, Brush fill) { BorderPen = borderPen; FillBrush = fill; } #endregion #region Properties /// /// Gets or sets the pen that will be used to draw the border /// public Pen BorderPen { get { return borderPen; } set { borderPen = value; } } private Pen borderPen; /// /// Gets or sets the padding that will be added to the bounds of the item /// before drawing the border and fill. /// public Size BoundsPadding { get { return boundsPadding; } set { boundsPadding = value; } } private Size boundsPadding = new(-1, 2); /// /// How rounded should the corners of the border be? 0 means no rounding. /// /// If this value is too large, the edges of the border will appear odd. public float CornerRounding { get { return cornerRounding; } set { cornerRounding = value; } } private float cornerRounding = 16.0f; /// /// Gets or sets the brush that will be used to fill the border /// /// This value is ignored when using gradient brush public Brush FillBrush { get { return fillBrush; } set { fillBrush = value; } } private Brush fillBrush = new SolidBrush(Color.FromArgb(64, Color.Blue)); /// /// Gets or sets the color that will be used as the start of a gradient fill. /// /// This and FillGradientTo must be given value to show a gradient public Color? FillGradientFrom { get { return fillGradientFrom; } set { fillGradientFrom = value; } } private Color? fillGradientFrom; /// /// Gets or sets the color that will be used as the end of a gradient fill. /// /// This and FillGradientFrom must be given value to show a gradient public Color? FillGradientTo { get { return fillGradientTo; } set { fillGradientTo = value; } } private Color? fillGradientTo; /// /// Gets or sets the fill mode that will be used for the gradient. /// public LinearGradientMode FillGradientMode { get { return fillGradientMode; } set { fillGradientMode = value; } } private LinearGradientMode fillGradientMode = LinearGradientMode.Vertical; #endregion #region IOverlay Members /// /// Draw a filled border /// /// /// /// public override void Draw(ObjectListView olv, Graphics g, Rectangle r) { Rectangle bounds = CalculateBounds(); if (!bounds.IsEmpty) DrawFilledBorder(g, bounds); } #endregion #region Subclass responsibility /// /// Subclasses should override this to say where the border should be drawn /// /// protected virtual Rectangle CalculateBounds() { return Rectangle.Empty; } #endregion #region Implementation utlities /// /// Do the actual work of drawing the filled border /// /// /// protected void DrawFilledBorder(Graphics g, Rectangle bounds) { bounds.Inflate(BoundsPadding); GraphicsPath path = GetRoundedRect(bounds, CornerRounding); if (FillGradientFrom != null && FillGradientTo != null) { if (FillBrush != null) FillBrush.Dispose(); FillBrush = new LinearGradientBrush(bounds, FillGradientFrom.Value, FillGradientTo.Value, FillGradientMode); } if (FillBrush != null) g.FillPath(FillBrush, path); if (BorderPen != null) g.DrawPath(BorderPen, path); } /// /// Create a GraphicsPath that represents a round cornered rectangle. /// /// /// If this is 0 or less, the rectangle will not be rounded. /// protected GraphicsPath GetRoundedRect(RectangleF rect, float diameter) { GraphicsPath path = new GraphicsPath(); if (diameter <= 0.0f) { path.AddRectangle(rect); } else { RectangleF arc = new RectangleF(rect.X, rect.Y, diameter, diameter); path.AddArc(arc, 180, 90); arc.X = rect.Right - diameter; path.AddArc(arc, 270, 90); arc.Y = rect.Bottom - diameter; path.AddArc(arc, 0, 90); arc.X = rect.Left; path.AddArc(arc, 90, 90); path.CloseFigure(); } return path; } #endregion } /// /// Instances of this class draw a border around the decorated row /// public class RowBorderDecoration : BorderDecoration { /// /// Gets or sets the index of the left most column to be used for the border /// public int LeftColumn { get { return leftColumn; } set { leftColumn = value; } } private int leftColumn = -1; /// /// Gets or sets the index of the right most column to be used for the border /// public int RightColumn { get { return rightColumn; } set { rightColumn = value; } } private int rightColumn = -1; /// /// Calculate the boundaries of the border /// /// protected override Rectangle CalculateBounds() { Rectangle bounds = RowBounds; if (ListItem == null) return bounds; if (LeftColumn >= 0) { Rectangle leftCellBounds = ListItem.GetSubItemBounds(LeftColumn); if (!leftCellBounds.IsEmpty) { bounds.Width = bounds.Right - leftCellBounds.Left; bounds.X = leftCellBounds.Left; } } if (RightColumn >= 0) { Rectangle rightCellBounds = ListItem.GetSubItemBounds(RightColumn); if (!rightCellBounds.IsEmpty) { bounds.Width = rightCellBounds.Right - bounds.Left; } } return bounds; } } /// /// Instances of this class draw a border around the decorated subitem. /// public class CellBorderDecoration : BorderDecoration { /// /// Calculate the boundaries of the border /// /// protected override Rectangle CalculateBounds() { return CellBounds; } } /// /// This decoration puts a border around the cell being edited and /// optionally "lightboxes" the cell (makes the rest of the control dark). /// public class EditingCellBorderDecoration : BorderDecoration { #region Life and death /// /// Create a EditingCellBorderDecoration /// public EditingCellBorderDecoration() { FillBrush = null; BorderPen = new Pen(Color.DarkBlue, 2); CornerRounding = 8; BoundsPadding = new Size(10, 8); } /// /// Create a EditingCellBorderDecoration /// /// Should the decoration use a lighbox display style? public EditingCellBorderDecoration(bool useLightBox) : this() { UseLightbox = useLightBox; } #endregion #region Configuration properties /// /// Gets or set whether the decoration should make the rest of /// the control dark when a cell is being edited /// /// If this is true, FillBrush is used to overpaint /// the control. public bool UseLightbox { get { return useLightbox; } set { if (useLightbox == value) return; useLightbox = value; if (useLightbox) { if (FillBrush == null) FillBrush = new SolidBrush(Color.FromArgb(64, Color.Black)); } } } private bool useLightbox; #endregion #region Implementation /// /// Draw the decoration /// /// /// /// public override void Draw(ObjectListView olv, Graphics g, Rectangle r) { if (!olv.IsCellEditing) return; Rectangle bounds = olv.CellEditor.Bounds; if (bounds.IsEmpty) return; bounds.Inflate(BoundsPadding); GraphicsPath path = GetRoundedRect(bounds, CornerRounding); if (FillBrush != null) { if (UseLightbox) { using (Region newClip = new Region(r)) { newClip.Exclude(path); Region originalClip = g.Clip; g.Clip = newClip; g.FillRectangle(FillBrush, r); g.Clip = originalClip; } } else { g.FillPath(FillBrush, path); } } if (BorderPen != null) g.DrawPath(BorderPen, path); } #endregion } /// /// This decoration causes everything *except* the row under the mouse to be overpainted /// with a tint, making the row under the mouse stand out in comparison. /// The darker and more opaque the fill color, the more obvious the /// decorated row becomes. /// public class LightBoxDecoration : BorderDecoration { /// /// Create a LightBoxDecoration /// public LightBoxDecoration() { BoundsPadding = new Size(-1, 4); CornerRounding = 8.0f; FillBrush = new SolidBrush(Color.FromArgb(72, Color.Black)); } /// /// Draw a tint over everything in the ObjectListView except the /// row under the mouse. /// /// /// /// public override void Draw(ObjectListView olv, Graphics g, Rectangle r) { if (!r.Contains(olv.PointToClient(Cursor.Position))) return; Rectangle bounds = RowBounds; if (bounds.IsEmpty) { if (olv.View == View.Tile) g.FillRectangle(FillBrush, r); return; } using (Region newClip = new Region(r)) { bounds.Inflate(BoundsPadding); newClip.Exclude(GetRoundedRect(bounds, CornerRounding)); Region originalClip = g.Clip; g.Clip = newClip; g.FillRectangle(FillBrush, r); g.Clip = originalClip; } } } /// /// Instances of this class put an Image over the row/cell that it is decorating /// public class ImageDecoration : ImageAdornment, IDecoration { #region Constructors /// /// Create an image decoration /// public ImageDecoration() { Alignment = ContentAlignment.MiddleRight; } /// /// Create an image decoration /// /// public ImageDecoration(Image image) : this() { Image = image; } /// /// Create an image decoration /// /// /// public ImageDecoration(Image image, int transparency) : this() { Image = image; Transparency = transparency; } /// /// Create an image decoration /// /// /// public ImageDecoration(Image image, ContentAlignment alignment) : this() { Image = image; Alignment = alignment; } /// /// Create an image decoration /// /// /// /// public ImageDecoration(Image image, int transparency, ContentAlignment alignment) : this() { Image = image; Transparency = transparency; Alignment = alignment; } #endregion #region IDecoration Members /// /// Gets or sets the item being decorated /// public OLVListItem ListItem { get { return listItem; } set { listItem = value; } } private OLVListItem listItem; /// /// Gets or sets the sub item being decorated /// public OLVListSubItem SubItem { get { return subItem; } set { subItem = value; } } private OLVListSubItem subItem; #endregion #region Commands /// /// Draw this decoration /// /// The ObjectListView being decorated /// The Graphics used for drawing /// The bounds of the rendering public virtual void Draw(ObjectListView olv, Graphics g, Rectangle r) { DrawImage(g, CalculateItemBounds(ListItem, SubItem)); } #endregion } /// /// Instances of this class draw some text over the row/cell that they are decorating /// public class TextDecoration : TextAdornment, IDecoration { #region Constructors /// /// Create a TextDecoration /// public TextDecoration() { Alignment = ContentAlignment.MiddleRight; } /// /// Create a TextDecoration /// /// public TextDecoration(string text) : this() { Text = text; } /// /// Create a TextDecoration /// /// /// public TextDecoration(string text, int transparency) : this() { Text = text; Transparency = transparency; } /// /// Create a TextDecoration /// /// /// public TextDecoration(string text, ContentAlignment alignment) : this() { Text = text; Alignment = alignment; } /// /// Create a TextDecoration /// /// /// /// public TextDecoration(string text, int transparency, ContentAlignment alignment) : this() { Text = text; Transparency = transparency; Alignment = alignment; } #endregion #region IDecoration Members /// /// Gets or sets the item being decorated /// public OLVListItem ListItem { get { return listItem; } set { listItem = value; } } private OLVListItem listItem; /// /// Gets or sets the sub item being decorated /// public OLVListSubItem SubItem { get { return subItem; } set { subItem = value; } } private OLVListSubItem subItem; #endregion #region Commands /// /// Draw this decoration /// /// The ObjectListView being decorated /// The Graphics used for drawing /// The bounds of the rendering public virtual void Draw(ObjectListView olv, Graphics g, Rectangle r) { DrawText(g, CalculateItemBounds(ListItem, SubItem)); } #endregion } } ================================================ FILE: source/ObjectListView/Rendering/Overlays.cs ================================================ /* * Overlays - Images, text or other things that can be rendered over the top of a ListView * * Author: Phillip Piper * Date: 14/04/2009 4:36 PM * * Change log: * v2.3 * 2009-08-17 JPP - Overlays now use Adornments * - Added ITransparentOverlay interface. Overlays can now have separate transparency levels * 2009-08-10 JPP - Moved decoration related code to new file * v2.2.1 * 200-07-24 JPP - TintedColumnDecoration now works when last item is a member of a collapsed * group (well, it no longer crashes). * v2.2 * 2009-06-01 JPP - Make sure that TintedColumnDecoration reaches to the last item in group view * 2009-05-05 JPP - Unified BillboardOverlay text rendering with that of TextOverlay * 2009-04-30 JPP - Added TintedColumnDecoration * 2009-04-14 JPP - Initial version * * To do: * * Copyright (C) 2009-2014 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System; using System.ComponentModel; using System.Drawing; namespace BrightIdeasSoftware { /// /// The interface for an object which can draw itself over the top of /// an ObjectListView. /// public interface IOverlay { /// /// Draw this overlay /// /// The ObjectListView that is being overlaid /// The Graphics onto the given OLV /// The content area of the OLV void Draw(ObjectListView olv, Graphics g, Rectangle r); } /// /// An interface for an overlay that supports variable levels of transparency /// public interface ITransparentOverlay : IOverlay { /// /// Gets or sets the transparency of the overlay. /// 0 is completely transparent, 255 is completely opaque. /// int Transparency { get; set; } } /// /// A null implementation of the IOverlay interface /// public class AbstractOverlay : ITransparentOverlay { #region IOverlay Members /// /// Draw this overlay /// /// The ObjectListView that is being overlaid /// The Graphics onto the given OLV /// The content area of the OLV public virtual void Draw(ObjectListView olv, Graphics g, Rectangle r) { } #endregion #region ITransparentOverlay Members /// /// How transparent should this overlay be? /// [Category("ObjectListView"), Description("How transparent should this overlay be"), DefaultValue(128), NotifyParentProperty(true)] public int Transparency { get { return transparency; } set { transparency = Math.Min(255, Math.Max(0, value)); } } private int transparency = 128; #endregion } /// /// An overlay that will draw an image over the top of the ObjectListView /// [TypeConverter("BrightIdeasSoftware.Design.OverlayConverter")] public class ImageOverlay : ImageAdornment, ITransparentOverlay { /// /// Create an ImageOverlay /// public ImageOverlay() { Alignment = ContentAlignment.BottomRight; } #region Public properties /// /// Gets or sets the horizontal inset by which the position of the overlay will be adjusted /// [Category("ObjectListView"), Description("The horizontal inset by which the position of the overlay will be adjusted"), DefaultValue(20), NotifyParentProperty(true)] public int InsetX { get { return insetX; } set { insetX = Math.Max(0, value); } } private int insetX = 20; /// /// Gets or sets the vertical inset by which the position of the overlay will be adjusted /// [Category("ObjectListView"), Description("Gets or sets the vertical inset by which the position of the overlay will be adjusted"), DefaultValue(20), NotifyParentProperty(true)] public int InsetY { get { return insetY; } set { insetY = Math.Max(0, value); } } private int insetY = 20; #endregion #region Commands /// /// Draw this overlay /// /// The ObjectListView being decorated /// The Graphics used for drawing /// The bounds of the rendering public virtual void Draw(ObjectListView olv, Graphics g, Rectangle r) { Rectangle insetRect = r; insetRect.Inflate(-InsetX, -InsetY); // We hard code a transparency of 255 here since transparency is handled by the glass panel DrawImage(g, insetRect, Image, 255); } #endregion } /// /// An overlay that will draw text over the top of the ObjectListView /// [TypeConverter("BrightIdeasSoftware.Design.OverlayConverter")] public class TextOverlay : TextAdornment, ITransparentOverlay { /// /// Create a TextOverlay /// public TextOverlay() { Alignment = ContentAlignment.BottomRight; } #region Public properties /// /// Gets or sets the horizontal inset by which the position of the overlay will be adjusted /// [Category("ObjectListView"), Description("The horizontal inset by which the position of the overlay will be adjusted"), DefaultValue(20), NotifyParentProperty(true)] public int InsetX { get { return insetX; } set { insetX = Math.Max(0, value); } } private int insetX = 20; /// /// Gets or sets the vertical inset by which the position of the overlay will be adjusted /// [Category("ObjectListView"), Description("Gets or sets the vertical inset by which the position of the overlay will be adjusted"), DefaultValue(20), NotifyParentProperty(true)] public int InsetY { get { return insetY; } set { insetY = Math.Max(0, value); } } private int insetY = 20; /// /// Gets or sets whether the border will be drawn with rounded corners /// [Browsable(false), Obsolete("Use CornerRounding instead", false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool RoundCorneredBorder { get { return CornerRounding > 0; } set { if (value) CornerRounding = 16.0f; else CornerRounding = 0.0f; } } #endregion #region Commands /// /// Draw this overlay /// /// The ObjectListView being decorated /// The Graphics used for drawing /// The bounds of the rendering public virtual void Draw(ObjectListView olv, Graphics g, Rectangle r) { if (String.IsNullOrEmpty(Text)) return; Rectangle insetRect = r; insetRect.Inflate(-InsetX, -InsetY); // We hard code a transparency of 255 here since transparency is handled by the glass panel DrawText(g, insetRect, Text, 255); } #endregion } /// /// A Billboard overlay is a TextOverlay positioned at an absolute point /// public class BillboardOverlay : TextOverlay { /// /// Create a BillboardOverlay /// public BillboardOverlay() { Transparency = 255; BackColor = Color.PeachPuff; TextColor = Color.Black; BorderColor = Color.Empty; Font = new Font("Tahoma", 10); } /// /// Gets or sets where should the top left of the billboard be placed /// public Point Location { get { return location; } set { location = value; } } private Point location; /// /// Draw this overlay /// /// The ObjectListView being decorated /// The Graphics used for drawing /// The bounds of the rendering public override void Draw(ObjectListView olv, Graphics g, Rectangle r) { if (String.IsNullOrEmpty(Text)) return; // Calculate the bounds of the text, and then move it to where it should be Rectangle textRect = CalculateTextBounds(g, r, Text); textRect.Location = Location; // Make sure the billboard is within the bounds of the List, as far as is possible if (textRect.Right > r.Width) textRect.X = Math.Max(r.Left, r.Width - textRect.Width); if (textRect.Bottom > r.Height) textRect.Y = Math.Max(r.Top, r.Height - textRect.Height); DrawBorderedText(g, textRect, Text, 255); } } } ================================================ FILE: source/ObjectListView/Rendering/Renderers.cs ================================================ /* * Renderers - A collection of useful renderers that are used to owner draw a cell in an ObjectListView * * Author: Phillip Piper * Date: 27/09/2008 9:15 AM * * Change log: * v2.9 * 2015-08-22 JPP - Allow selected row back/fore colours to be specified for each row * 2015-06-23 JPP - Added ColumnButtonRenderer plus general support for Buttons * 2015-06-22 JPP - Added BaseRenderer.ConfigureItem() and ConfigureSubItem() to easily allow * other renderers to be chained for use within a primary renderer. * - Lots of tightening of hit tests and edit rectangles * 2015-05-15 JPP - Handle renderering an Image when that Image is returned as an aspect. * v2.8 * 2014-09-26 JPP - Dispose of animation timer in a more robust fashion. * 2014-05-20 JPP - Handle rendering disabled rows * v2.7 * 2013-04-29 JPP - Fixed bug where Images were not vertically aligned * v2.6 * 2012-10-26 JPP - Hit detection will no longer report check box hits on columns without checkboxes. * 2012-07-13 JPP - [Breaking change] Added preferedSize parameter to IRenderer.GetEditRectangle(). * v2.5.1 * 2012-07-14 JPP - Added CellPadding to various places. Replaced DescribedTaskRenderer.CellPadding. * 2012-07-11 JPP - Added CellVerticalAlignment to various places allow cell contents to be vertically * aligned (rather than always being centered). * v2.5 * 2010-08-24 JPP - CheckBoxRenderer handles hot boxes and correctly vertically centers the box. * 2010-06-23 JPP - Major rework of HighlightTextRenderer. Now uses TextMatchFilter directly. * Draw highlighting underneath text to improve legibility. Works with new * TextMatchFilter capabilities. * v2.4 * 2009-10-30 JPP - Plugged possible resource leak by using using() with CreateGraphics() * v2.3 * 2009-09-28 JPP - Added DescribedTaskRenderer * 2009-09-01 JPP - Correctly handle an ImageRenderer's handling of an aspect that holds * the image to be displayed at Byte[]. * 2009-08-29 JPP - Fixed bug where some of a cell's background was not erased. * 2009-08-15 JPP - Correctly MeasureText() using the appropriate graphic context * - Handle translucent selection setting * v2.2.1 * 2009-07-24 JPP - Try to honour CanWrap setting when GDI rendering text. * 2009-07-11 JPP - Correctly calculate edit rectangle for subitems of a tree view * (previously subitems were indented in the same way as the primary column) * v2.2 * 2009-06-06 JPP - Tweaked text rendering so that column 0 isn't ellipsed unnecessarily. * 2009-05-05 JPP - Added Unfocused foreground and background colors * (thanks to Christophe Hosten) * 2009-04-21 JPP - Fixed off-by-1 error when calculating text widths. This caused * middle and right aligned columns to always wrap one character * when printed using ListViewPrinter (SF#2776634). * 2009-04-11 JPP - Correctly renderer checkboxes when RowHeight is non-standard * 2009-04-06 JPP - Allow for item indent when calculating edit rectangle * v2.1 * 2009-02-24 JPP - Work properly with ListViewPrinter again * 2009-01-26 JPP - AUSTRALIA DAY (why aren't I on holidays!) * - Major overhaul of renderers. Now uses IRenderer interface. * - ImagesRenderer and FlagsRenderer are now defunct. * The names are retained for backward compatibility. * 2009-01-23 JPP - Align bitmap AND text according to column alignment (previously * only text was aligned and bitmap was always to the left). * 2009-01-21 JPP - Changed to use TextRenderer rather than native GDI routines. * 2009-01-20 JPP - Draw images directly from image list if possible. 30% faster! * - Tweaked some spacings to look more like native ListView * - Text highlight for non FullRowSelect is now the right color * when the control doesn't have focus. * - Commented out experimental animations. Still needs work. * 2009-01-19 JPP - Changed to draw text using GDI routines. Looks more like * native control this way. Set UseGdiTextRendering to false to * revert to previous behavior. * 2009-01-15 JPP - Draw background correctly when control is disabled * - Render checkboxes using CheckBoxRenderer * v2.0.1 * 2008-12-29 JPP - Render text correctly when HideSelection is true. * 2008-12-26 JPP - BaseRenderer now works correctly in all Views * 2008-12-23 JPP - Fixed two small bugs in BarRenderer * v2.0 * 2008-10-26 JPP - Don't owner draw when in Design mode * 2008-09-27 JPP - Separated from ObjectListView.cs * * Copyright (C) 2006-2014 Phillip Piper * * TO DO: * - Hit detection on renderers doesn't change the controls standard selection behavior * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Imaging; using System.Globalization; using System.IO; using System.Threading; using System.Windows.Forms; using System.Windows.Forms.VisualStyles; using Timer = System.Threading.Timer; namespace BrightIdeasSoftware { /// /// Renderers are the mechanism used for owner drawing cells. As such, they can also handle /// hit detection and positioning of cell editing rectangles. /// public interface IRenderer { /// /// Render the whole item within an ObjectListView. This is only used in non-Details views. /// /// The event /// A Graphics for rendering /// The bounds of the item /// The model object to be drawn /// Return true to indicate that the event was handled and no further processing is needed. bool RenderItem(DrawListViewItemEventArgs e, Graphics g, Rectangle itemBounds, Object rowObject); /// /// Render one cell within an ObjectListView when it is in Details mode. /// /// The event /// A Graphics for rendering /// The bounds of the cell /// The model object to be drawn /// Return true to indicate that the event was handled and no further processing is needed. bool RenderSubItem(DrawListViewSubItemEventArgs e, Graphics g, Rectangle cellBounds, Object rowObject); /// /// What is under the given point? /// /// /// x co-ordinate /// y co-ordinate /// This method should only alter HitTestLocation and/or UserData. void HitTest(OlvListViewHitTestInfo hti, int x, int y); /// /// When the value in the given cell is to be edited, where should the edit rectangle be placed? /// /// /// /// /// /// /// Rectangle GetEditRectangle(Graphics g, Rectangle cellBounds, OLVListItem item, int subItemIndex, Size preferredSize); } /// /// Renderers that implement this interface will have the filter property updated, /// each time the filter on the ObjectListView is updated. /// public interface IFilterAwareRenderer { IModelFilter Filter { get; set; } } /// /// An AbstractRenderer is a do-nothing implementation of the IRenderer interface. /// [Browsable(true), ToolboxItem(false)] public class AbstractRenderer : Component, IRenderer { #region IRenderer Members /// /// Render the whole item within an ObjectListView. This is only used in non-Details views. /// /// The event /// A Graphics for rendering /// The bounds of the item /// The model object to be drawn /// Return true to indicate that the event was handled and no further processing is needed. public virtual bool RenderItem(DrawListViewItemEventArgs e, Graphics g, Rectangle itemBounds, object rowObject) { return true; } /// /// Render one cell within an ObjectListView when it is in Details mode. /// /// The event /// A Graphics for rendering /// The bounds of the cell /// The model object to be drawn /// Return true to indicate that the event was handled and no further processing is needed. public virtual bool RenderSubItem(DrawListViewSubItemEventArgs e, Graphics g, Rectangle cellBounds, object rowObject) { return false; } /// /// What is under the given point? /// /// /// x co-ordinate /// y co-ordinate /// This method should only alter HitTestLocation and/or UserData. public virtual void HitTest(OlvListViewHitTestInfo hti, int x, int y) {} /// /// When the value in the given cell is to be edited, where should the edit rectangle be placed? /// /// /// /// /// /// /// public virtual Rectangle GetEditRectangle(Graphics g, Rectangle cellBounds, OLVListItem item, int subItemIndex, Size preferredSize) { return cellBounds; } #endregion } /// /// This class provides compatibility for v1 RendererDelegates /// [ToolboxItem(false)] internal class Version1Renderer : AbstractRenderer { public Version1Renderer(RenderDelegate renderDelegate) { RenderDelegate = renderDelegate; } /// /// The renderer delegate that this renderer wraps /// public RenderDelegate RenderDelegate; #region IRenderer Members public override bool RenderSubItem(DrawListViewSubItemEventArgs e, Graphics g, Rectangle cellBounds, object rowObject) { if (RenderDelegate == null) return base.RenderSubItem(e, g, cellBounds, rowObject); else return RenderDelegate(e, g, cellBounds, rowObject); } #endregion } /// /// A BaseRenderer provides useful base level functionality for any custom renderer. /// /// /// Subclasses will normally override the Render or OptionalRender method, and use the other /// methods as helper functions. /// [Browsable(true), ToolboxItem(true)] public class BaseRenderer : AbstractRenderer { internal const TextFormatFlags NormalTextFormatFlags = TextFormatFlags.NoPrefix | TextFormatFlags.EndEllipsis | TextFormatFlags.PreserveGraphicsTranslateTransform; #region Configuration Properties /// /// Can the renderer wrap lines that do not fit completely within the cell? /// /// Wrapping text doesn't work with the GDI renderer. [Category("Appearance"), Description("Can the renderer wrap text that does not fit completely within the cell"), DefaultValue(false)] public bool CanWrap { get { return canWrap; } set { canWrap = value; if (canWrap) UseGdiTextRendering = false; } } private bool canWrap; /// /// Gets or sets how many pixels will be left blank around this cell /// /// /// /// This setting only takes effect when the control is owner drawn. /// /// for more details. /// [Category("ObjectListView"), Description("The number of pixels that renderer will leave empty around the edge of the cell"), DefaultValue(null)] public Rectangle? CellPadding { get { return cellPadding; } set { cellPadding = value; } } private Rectangle? cellPadding; /// /// Gets the horiztonal alignment of the column /// [Browsable(false)] public HorizontalAlignment CellHorizontalAlignment { get { return Column == null ? HorizontalAlignment.Left : Column.TextAlign; } } /// /// Gets or sets how cells drawn by this renderer will be vertically aligned. /// /// /// /// If this is not set, the value from the column or control itself will be used. /// /// [Category("ObjectListView"), Description("How will cell values be vertically aligned?"), DefaultValue(null)] public virtual StringAlignment? CellVerticalAlignment { get { return cellVerticalAlignment; } set { cellVerticalAlignment = value; } } private StringAlignment? cellVerticalAlignment; /// /// Gets the optional padding that this renderer should apply before drawing. /// This property considers all possible sources of padding /// [Browsable(false)] protected virtual Rectangle? EffectiveCellPadding { get { if (cellPadding.HasValue) return cellPadding.Value; if (OLVSubItem != null && OLVSubItem.CellPadding.HasValue) return OLVSubItem.CellPadding.Value; if (ListItem != null && ListItem.CellPadding.HasValue) return ListItem.CellPadding.Value; if (Column != null && Column.CellPadding.HasValue) return Column.CellPadding.Value; if (ListView != null && ListView.CellPadding.HasValue) return ListView.CellPadding.Value; return null; } } /// /// Gets the vertical cell alignment that should govern the rendering. /// This property considers all possible sources. /// [Browsable(false)] protected virtual StringAlignment EffectiveCellVerticalAlignment { get { if (cellVerticalAlignment.HasValue) return cellVerticalAlignment.Value; if (OLVSubItem != null && OLVSubItem.CellVerticalAlignment.HasValue) return OLVSubItem.CellVerticalAlignment.Value; if (ListItem != null && ListItem.CellVerticalAlignment.HasValue) return ListItem.CellVerticalAlignment.Value; if (Column != null && Column.CellVerticalAlignment.HasValue) return Column.CellVerticalAlignment.Value; if (ListView != null) return ListView.CellVerticalAlignment; return StringAlignment.Center; } } /// /// Gets or sets the image list from which keyed images will be fetched /// [Category("Appearance"), Description("The image list from which keyed images will be fetched for drawing. If this is not given, the small ImageList from the ObjectListView will be used"), DefaultValue(null)] public ImageList ImageList { get { return imageList; } set { imageList = value; } } private ImageList imageList; /// /// When rendering multiple images, how many pixels should be between each image? /// [Category("Appearance"), Description("When rendering multiple images, how many pixels should be between each image?"), DefaultValue(1)] public int Spacing { get { return spacing; } set { spacing = value; } } private int spacing = 1; /// /// Should text be rendered using GDI routines? This makes the text look more /// like a native List view control. /// [Category("Appearance"), Description("Should text be rendered using GDI routines?"), DefaultValue(true)] public virtual bool UseGdiTextRendering { get { // Can't use GDI routines on a GDI+ printer context return !IsPrinting && useGdiTextRendering; } set { useGdiTextRendering = value; } } private bool useGdiTextRendering = true; #endregion #region State Properties /// /// Get or set the aspect of the model object that this renderer should draw /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public Object Aspect { get { if (aspect == null) aspect = column.GetValue(rowObject); return aspect; } set { aspect = value; } } private Object aspect; /// /// What are the bounds of the cell that is being drawn? /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public Rectangle Bounds { get { return bounds; } set { bounds = value; } } private Rectangle bounds; /// /// Get or set the OLVColumn that this renderer will draw /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public OLVColumn Column { get { return column; } set { column = value; } } private OLVColumn column; /// /// Get/set the event that caused this renderer to be called /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public DrawListViewItemEventArgs DrawItemEvent { get { return drawItemEventArgs; } set { drawItemEventArgs = value; } } private DrawListViewItemEventArgs drawItemEventArgs; /// /// Get/set the event that caused this renderer to be called /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public DrawListViewSubItemEventArgs Event { get { return eventArgs; } set { eventArgs = value; } } private DrawListViewSubItemEventArgs eventArgs; /// /// Gets or sets the font to be used for text in this cell /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public Font Font { get { if (font != null || ListItem == null) return font; if (SubItem == null || ListItem.UseItemStyleForSubItems) return ListItem.Font; return SubItem.Font; } set { font = value; } } private Font font; /// /// Gets the image list from which keyed images will be fetched /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public ImageList ImageListOrDefault { get { return ImageList ?? ListView.SmallImageList; } } /// /// Should this renderer fill in the background before drawing? /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool IsDrawBackground { get { return !IsPrinting; } } /// /// Cache whether or not our item is selected /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool IsItemSelected { get { return isItemSelected; } set { isItemSelected = value; } } private bool isItemSelected; /// /// Is this renderer being used on a printer context? /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool IsPrinting { get { return isPrinting; } set { isPrinting = value; } } private bool isPrinting; /// /// Get or set the listitem that this renderer will be drawing /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public OLVListItem ListItem { get { return listItem; } set { listItem = value; } } private OLVListItem listItem; /// /// Get/set the listview for which the drawing is to be done /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public ObjectListView ListView { get { return objectListView; } set { objectListView = value; } } private ObjectListView objectListView; /// /// Get the specialized OLVSubItem that this renderer is drawing /// /// This returns null for column 0. [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public OLVListSubItem OLVSubItem { get { return listSubItem; } } /// /// Get or set the model object that this renderer should draw /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public Object RowObject { get { return rowObject; } set { rowObject = value; } } private Object rowObject; /// /// Get or set the list subitem that this renderer will be drawing /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public OLVListSubItem SubItem { get { return listSubItem; } set { listSubItem = value; } } private OLVListSubItem listSubItem; /// /// The brush that will be used to paint the text /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public Brush TextBrush { get { if (textBrush == null) return new SolidBrush(GetForegroundColor()); else return textBrush; } set { textBrush = value; } } private Brush textBrush; /// /// Will this renderer use the custom images from the parent ObjectListView /// to draw the checkbox images. /// /// /// /// If this is true, the renderer will use the images from the /// StateImageList to represent checkboxes. 0 - unchecked, 1 - checked, 2 - indeterminate. /// /// If this is false (the default), then the renderer will use .NET's standard /// CheckBoxRenderer. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool UseCustomCheckboxImages { get { return useCustomCheckboxImages; } set { useCustomCheckboxImages = value; } } private bool useCustomCheckboxImages; private void ClearState() { Event = null; DrawItemEvent = null; Aspect = null; Font = null; TextBrush = null; } #endregion #region Utilities /// /// Align the second rectangle with the first rectangle, /// according to the alignment of the column /// /// The cell's bounds /// The rectangle to be aligned within the bounds /// An aligned rectangle protected virtual Rectangle AlignRectangle(Rectangle outer, Rectangle inner) { Rectangle r = new Rectangle(outer.Location, inner.Size); // Align horizontally depending on the column alignment if (inner.Width < outer.Width) { r.X = AlignHorizontally(outer, inner); } // Align vertically too if (inner.Height < outer.Height) { r.Y = AlignVertically(outer, inner); } return r; } /// /// Calculate the left edge of the rectangle that aligns the outer rectangle with the inner one /// according to this renderer's horizontal alignment /// /// /// /// protected int AlignHorizontally(Rectangle outer, Rectangle inner) { HorizontalAlignment alignment = CellHorizontalAlignment; switch (alignment) { case HorizontalAlignment.Left: return outer.Left + 1; case HorizontalAlignment.Center: return outer.Left + ((outer.Width - inner.Width) / 2); case HorizontalAlignment.Right: return outer.Right - inner.Width - 1; default: throw new ArgumentOutOfRangeException(); } } /// /// Calculate the top of the rectangle that aligns the outer rectangle with the inner rectangle /// according to this renders vertical alignment /// /// /// /// protected int AlignVertically(Rectangle outer, Rectangle inner) { return AlignVertically(outer, inner.Height); } /// /// Calculate the top of the rectangle that aligns the outer rectangle with a rectangle of the given height /// according to this renderer's vertical alignment /// /// /// /// protected int AlignVertically(Rectangle outer, int innerHeight) { switch (EffectiveCellVerticalAlignment) { case StringAlignment.Near: return outer.Top + 1; case StringAlignment.Center: return outer.Top + ((outer.Height - innerHeight) / 2); case StringAlignment.Far: return outer.Bottom - innerHeight - 1; default: throw new ArgumentOutOfRangeException(); } } /// /// Calculate the space that our rendering will occupy and then align that space /// with the given rectangle, according to the Column alignment /// /// /// Pre-padded bounds of the cell /// protected virtual Rectangle CalculateAlignedRectangle(Graphics g, Rectangle r) { if (Column == null) return r; Rectangle contentRectangle = new Rectangle(Point.Empty, CalculateContentSize(g, r)); return AlignRectangle(r, contentRectangle); } /// /// Calculate the size of the content of this cell. /// /// /// Pre-padded bounds of the cell /// The width and height of the content protected virtual Size CalculateContentSize(Graphics g, Rectangle r) { Size checkBoxSize = CalculatePrimaryCheckBoxSize(g); Size imageSize = CalculateImageSize(g, GetImageSelector()); Size textSize = CalculateTextSize(g, GetText(), r.Width - (checkBoxSize.Width + imageSize.Width)); // If the combined width is greater than the whole cell, we just use the cell itself int width = Math.Min(r.Width, checkBoxSize.Width + imageSize.Width + textSize.Width); int componentMaxHeight = Math.Max(checkBoxSize.Height, Math.Max(imageSize.Height, textSize.Height)); int height = Math.Min(r.Height, componentMaxHeight); return new Size(width, height); } /// /// Calculate the bounds of a checkbox given the (pre-padded) cell bounds /// /// /// Pre-padded cell bounds /// protected Rectangle CalculateCheckBoxBounds(Graphics g, Rectangle cellBounds) { Size checkBoxSize = CalculateCheckBoxSize(g); return AlignRectangle(cellBounds, new Rectangle(0, 0, checkBoxSize.Width, checkBoxSize.Height)); } /// /// How much space will the check box for this cell occupy? /// /// Only column 0 can have check boxes. Sub item checkboxes are /// treated as images /// /// protected virtual Size CalculateCheckBoxSize(Graphics g) { if (UseCustomCheckboxImages && ListView.StateImageList != null) return ListView.StateImageList.ImageSize; return CheckBoxRenderer.GetGlyphSize(g, CheckBoxState.UncheckedNormal); } /// /// How much space will the check box for this row occupy? /// If the list doesn't have checkboxes, or this isn't the primary column, /// this returns an empty size. /// /// /// protected virtual Size CalculatePrimaryCheckBoxSize(Graphics g) { if (!ListView.CheckBoxes || !ColumnIsPrimary) return Size.Empty; Size size = CalculateCheckBoxSize(g); size.Width += 6; return size; } /// /// How much horizontal space will the image of this cell occupy? /// /// /// /// protected virtual int CalculateImageWidth(Graphics g, object imageSelector) { return CalculateImageSize(g, imageSelector).Width + 2; } /// /// How much vertical space will the image of this cell occupy? /// /// /// /// protected virtual int CalculateImageHeight(Graphics g, object imageSelector) { return CalculateImageSize(g, imageSelector).Height; } /// /// How much space will the image of this cell occupy? /// /// /// /// protected virtual Size CalculateImageSize(Graphics g, object imageSelector) { if (imageSelector == null || imageSelector == DBNull.Value) return Size.Empty; // Check for the image in the image list (most common case) ImageList il = ImageListOrDefault; if (il != null) { int selectorAsInt = -1; if (imageSelector is Int32) selectorAsInt = (Int32)imageSelector; else { if (imageSelector is string selectorAsString) selectorAsInt = il.Images.IndexOfKey(selectorAsString); } if (selectorAsInt >= 0) return il.ImageSize; } // Is the selector actually an image? if (imageSelector is Image image) return image.Size; return Size.Empty; } /// /// How much horizontal space will the text of this cell occupy? /// /// /// /// /// protected virtual int CalculateTextWidth(Graphics g, string txt, int width) { if (String.IsNullOrEmpty(txt)) return 0; return CalculateTextSize(g, txt, width).Width; } /// /// How much space will the text of this cell occupy? /// /// /// /// /// protected virtual Size CalculateTextSize(Graphics g, string txt, int width) { if (String.IsNullOrEmpty(txt)) return Size.Empty; if (UseGdiTextRendering) { Size proposedSize = new Size(width, Int32.MaxValue); return TextRenderer.MeasureText(g, txt, Font, proposedSize, NormalTextFormatFlags); } // Using GDI+ renderering using (StringFormat fmt = new StringFormat()) { fmt.Trimming = StringTrimming.EllipsisCharacter; SizeF sizeF = g.MeasureString(txt, Font, width, fmt); return new Size(1 + (int)sizeF.Width, 1 + (int)sizeF.Height); } } /// /// Return the Color that is the background color for this item's cell /// /// The background color of the subitem public virtual Color GetBackgroundColor() { if (!ListView.Enabled) return SystemColors.Control; if (IsItemSelected && !ListView.UseTranslucentSelection && ListView.FullRowSelect) return GetSelectedBackgroundColor(); if (SubItem == null || ListItem.UseItemStyleForSubItems) return ListItem.BackColor; return SubItem.BackColor; } /// /// Return the color of the background color when the item is selected /// /// The background color of the subitem public virtual Color GetSelectedBackgroundColor() { if (ListView.Focused) return ListItem.SelectedBackColor ?? ListView.SelectedBackColorOrDefault; if (!ListView.HideSelection) return ListView.UnfocusedSelectedBackColorOrDefault; return ListItem.BackColor; } /// /// Return the color to be used for text in this cell /// /// The text color of the subitem public virtual Color GetForegroundColor() { if (IsItemSelected && !ListView.UseTranslucentSelection && (ColumnIsPrimary || ListView.FullRowSelect)) return GetSelectedForegroundColor(); return SubItem == null || ListItem.UseItemStyleForSubItems ? ListItem.ForeColor : SubItem.ForeColor; } /// /// Return the color of the foreground color when the item is selected /// /// The foreground color of the subitem public virtual Color GetSelectedForegroundColor() { if (ListView.Focused) return ListItem.SelectedForeColor ?? ListView.SelectedForeColorOrDefault; if (!ListView.HideSelection) return ListView.UnfocusedSelectedForeColorOrDefault; return SubItem == null || ListItem.UseItemStyleForSubItems ? ListItem.ForeColor : SubItem.ForeColor; } /// /// Return the image that should be drawn against this subitem /// /// An Image or null if no image should be drawn. protected virtual Image GetImage() { return GetImage(GetImageSelector()); } /// /// Return the actual image that should be drawn when keyed by the given image selector. /// An image selector can be: /// an int, giving the index into the image list /// a string, giving the image key into the image list /// an Image, being the image itself /// /// /// The value that indicates the image to be used /// An Image or null protected virtual Image GetImage(Object imageSelector) { if (imageSelector == null || imageSelector == DBNull.Value) return null; ImageList il = ImageListOrDefault; if (il != null) { if (imageSelector is Int32) { Int32 index = (Int32) imageSelector; if (index < 0 || index >= il.Images.Count) return null; return il.Images[index]; } if (imageSelector is string str) { if (il.Images.ContainsKey(str)) return il.Images[str]; return null; } } return imageSelector as Image; } /// /// protected virtual Object GetImageSelector() { return ColumnIsPrimary ? ListItem.ImageSelector : OLVSubItem.ImageSelector; } /// /// Return the string that should be drawn within this /// /// protected virtual string GetText() { return SubItem == null ? ListItem.Text : SubItem.Text; } /// /// Return the Color that is the background color for this item's text /// /// The background color of the subitem's text [Obsolete("Use GetBackgroundColor() instead")] protected virtual Color GetTextBackgroundColor() { return Color.Red; // just so it shows up if it is used } #endregion #region IRenderer members /// /// Render the whole item in a non-details view. /// /// /// /// /// /// public override bool RenderItem(DrawListViewItemEventArgs e, Graphics g, Rectangle itemBounds, object model) { ConfigureItem(e, itemBounds, model); return OptionalRender(g, itemBounds); } /// /// Prepare this renderer to draw in response to the given event /// /// /// /// /// Use this if you want to chain a second renderer within a primary renderer. public virtual void ConfigureItem(DrawListViewItemEventArgs e, Rectangle itemBounds, object model) { ClearState(); DrawItemEvent = e; ListItem = (OLVListItem)e.Item; SubItem = null; ListView = (ObjectListView)ListItem.ListView; Column = ListView.GetColumn(0); RowObject = model; Bounds = itemBounds; IsItemSelected = ListItem.Selected && ListItem.Enabled; } /// /// Render one cell /// /// /// /// /// /// public override bool RenderSubItem(DrawListViewSubItemEventArgs e, Graphics g, Rectangle cellBounds, object model) { ConfigureSubItem(e, cellBounds, model); return OptionalRender(g, cellBounds); } /// /// Prepare this renderer to draw in response to the given event /// /// /// /// /// Use this if you want to chain a second renderer within a primary renderer. public virtual void ConfigureSubItem(DrawListViewSubItemEventArgs e, Rectangle cellBounds, object model) { ClearState(); Event = e; ListItem = (OLVListItem)e.Item; SubItem = (OLVListSubItem)e.SubItem; ListView = (ObjectListView)ListItem.ListView; Column = (OLVColumn)e.Header; RowObject = model; Bounds = cellBounds; IsItemSelected = ListItem.Selected && ListItem.Enabled; } /// /// Calculate which part of this cell was hit /// /// /// /// public override void HitTest(OlvListViewHitTestInfo hti, int x, int y) { ClearState(); ListView = hti.ListView; ListItem = hti.Item; SubItem = hti.SubItem; Column = hti.Column; RowObject = hti.RowObject; IsItemSelected = ListItem.Selected && ListItem.Enabled; if (SubItem == null) Bounds = ListItem.Bounds; else Bounds = ListItem.GetSubItemBounds(Column.Index); using (Graphics g = ListView.CreateGraphics()) { HandleHitTest(g, hti, x, y); } } /// /// Calculate the edit rectangle /// /// /// /// /// /// /// public override Rectangle GetEditRectangle(Graphics g, Rectangle cellBounds, OLVListItem item, int subItemIndex, Size preferredSize) { ClearState(); ListView = (ObjectListView) item.ListView; ListItem = item; SubItem = item.GetSubItem(subItemIndex); Column = ListView.GetColumn(subItemIndex); RowObject = item.RowObject; IsItemSelected = ListItem.Selected && ListItem.Enabled; Bounds = cellBounds; return HandleGetEditRectangle(g, cellBounds, item, subItemIndex, preferredSize); } #endregion #region IRenderer implementation // Subclasses will probably want to override these methods rather than the IRenderer // interface methods. /// /// Draw our data into the given rectangle using the given graphics context. /// /// /// Subclasses should override this method. /// The graphics context that should be used for drawing /// The bounds of the subitem cell /// Returns whether the rendering has already taken place. /// If this returns false, the default processing will take over. /// public virtual bool OptionalRender(Graphics g, Rectangle r) { if (ListView.View != View.Details) return false; Render(g, r); return true; } /// /// Draw our data into the given rectangle using the given graphics context. /// /// /// Subclasses should override this method if they never want /// to fall back on the default processing /// The graphics context that should be used for drawing /// The bounds of the subitem cell public virtual void Render(Graphics g, Rectangle r) { StandardRender(g, r); } /// /// Do the actual work of hit testing. Subclasses should override this rather than HitTest() /// /// /// /// /// protected virtual void HandleHitTest(Graphics g, OlvListViewHitTestInfo hti, int x, int y) { Rectangle r = CalculateAlignedRectangle(g, ApplyCellPadding(Bounds)); StandardHitTest(g, hti, r, x, y); } /// /// Handle a HitTest request after all state information has been initialized /// /// /// /// /// /// /// protected virtual Rectangle HandleGetEditRectangle(Graphics g, Rectangle cellBounds, OLVListItem item, int subItemIndex, Size preferredSize) { // MAINTAINER NOTE: This type testing is wrong (design-wise). The base class should return cell bounds, // and a more specialized class should return StandardGetEditRectangle(). But BaseRenderer is used directly // to draw most normal cells, as well as being directly subclassed for user implemented renderers. And this // method needs to return different bounds in each of those cases. We should have a StandardRenderer and make // BaseRenderer into an ABC -- but that would break too much existing code. And so we have this hack :( // If we are a standard renderer, return the position of the text, otherwise, use the whole cell. if (GetType() == typeof (BaseRenderer)) return StandardGetEditRectangle(g, cellBounds, preferredSize); // Center the editor vertically if (cellBounds.Height != preferredSize.Height) cellBounds.Y += (cellBounds.Height - preferredSize.Height) / 2; return cellBounds; } #endregion #region Standard IRenderer implementations /// /// Draw the standard "[checkbox] [image] [text]" cell after the state properties have been initialized. /// /// /// protected void StandardRender(Graphics g, Rectangle r) { DrawBackground(g, r); // Adjust the first columns rectangle to match the padding used by the native mode of the ListView if (ColumnIsPrimary && CellHorizontalAlignment == HorizontalAlignment.Left ) { r.X += 3; r.Width -= 1; } r = ApplyCellPadding(r); DrawAlignedImageAndText(g, r); // Show where the bounds of the cell padding are (debugging) if (ObjectListView.ShowCellPaddingBounds) g.DrawRectangle(Pens.Purple, r); } /// /// Change the bounds of the given rectangle to take any cell padding into account /// /// /// public virtual Rectangle ApplyCellPadding(Rectangle r) { Rectangle? padding = EffectiveCellPadding; if (!padding.HasValue) return r; // The two subtractions below look wrong, but are correct! Rectangle paddingRectangle = padding.Value; r.Width -= paddingRectangle.Right; r.Height -= paddingRectangle.Bottom; r.Offset(paddingRectangle.Location); return r; } /// /// Perform normal hit testing relative to the given aligned content bounds /// /// /// /// /// /// protected virtual void StandardHitTest(Graphics g, OlvListViewHitTestInfo hti, Rectangle alignedContentRectangle, int x, int y) { Rectangle r = alignedContentRectangle; // Match tweaking from renderer if (ColumnIsPrimary && CellHorizontalAlignment == HorizontalAlignment.Left && !(this is TreeListView.TreeRenderer)) { r.X += 3; r.Width -= 1; } int width = 0; // Did they hit a check box on the primary column? if (ColumnIsPrimary && ListView.CheckBoxes) { Size checkBoxSize = CalculateCheckBoxSize(g); int checkBoxTop = AlignVertically(r, checkBoxSize.Height); Rectangle r3 = new Rectangle(r.X, checkBoxTop, checkBoxSize.Width, checkBoxSize.Height); width = r3.Width + 6; // g.DrawRectangle(Pens.DarkGreen, r3); if (r3.Contains(x, y)) { hti.HitTestLocation = HitTestLocation.CheckBox; return; } } // Did they hit the image? If they hit the image of a // non-primary column that has a checkbox, it counts as a // checkbox hit r.X += width; r.Width -= width; width = CalculateImageWidth(g, GetImageSelector()); Rectangle rTwo = r; rTwo.Width = width; // g.DrawRectangle(Pens.Red, rTwo); if (rTwo.Contains(x, y)) { if (Column != null && (Column.Index > 0 && Column.CheckBoxes)) hti.HitTestLocation = HitTestLocation.CheckBox; else hti.HitTestLocation = HitTestLocation.Image; return; } // Did they hit the text? r.X += width; r.Width -= width; width = CalculateTextWidth(g, GetText(), r.Width); rTwo = r; rTwo.Width = width; // g.DrawRectangle(Pens.Blue, rTwo); if (rTwo.Contains(x, y)) { hti.HitTestLocation = HitTestLocation.Text; return; } hti.HitTestLocation = HitTestLocation.InCell; } /// /// This method calculates the bounds of the text within a standard layout /// (i.e. optional checkbox, optional image, text) /// /// This method only works correctly if the state of the renderer /// has been fully initialized (see BaseRenderer.GetEditRectangle) /// /// /// /// protected virtual Rectangle StandardGetEditRectangle(Graphics g, Rectangle cellBounds, Size preferredSize) { Size contentSize = CalculateContentSize(g, cellBounds); int contentWidth = Column.CellEditUseWholeCellEffective ? cellBounds.Width : contentSize.Width; Rectangle editControlBounds = CalculatePaddedAlignedBounds(g, cellBounds, new Size(contentWidth, preferredSize.Height)); Size checkBoxSize = CalculatePrimaryCheckBoxSize(g); int imageWidth = CalculateImageWidth(g, GetImageSelector()); int width = checkBoxSize.Width + imageWidth; // Indent the primary column by the required amount if (ListItem.IndentCount > 0) { int indentWidth = ListView.SmallImageSize.Width * ListItem.IndentCount; width += indentWidth; } editControlBounds.X += width; editControlBounds.Width -= width; if (editControlBounds.Width < 50) editControlBounds.Width = 50; if (editControlBounds.Right > cellBounds.Right) editControlBounds.Width = cellBounds.Right - editControlBounds.Left; return editControlBounds; } /// /// Apply any padding to the given bounds, and then align a rectangle of the given /// size within that padded area. /// /// /// /// /// protected Rectangle CalculatePaddedAlignedBounds(Graphics g, Rectangle cellBounds, Size preferredSize) { Rectangle r = ApplyCellPadding(cellBounds); r = AlignRectangle(r, new Rectangle(Point.Empty, preferredSize)); return r; } #endregion #region Drawing routines /// /// Draw the given image aligned horizontally within the column. /// /// /// Over tall images are scaled to fit. Over-wide images are /// truncated. This is by design! /// /// Graphics context to use for drawing /// Bounds of the cell /// The image to be drawn protected virtual void DrawAlignedImage(Graphics g, Rectangle r, Image image) { if (image == null) return; // By default, the image goes in the top left of the rectangle Rectangle imageBounds = new Rectangle(r.Location, image.Size); // If the image is too tall to be drawn in the space provided, proportionally scale it down. // Too wide images are not scaled. if (image.Height > r.Height) { float scaleRatio = (float) r.Height / (float) image.Height; imageBounds.Width = (int) ((float) image.Width * scaleRatio); imageBounds.Height = r.Height - 1; } // Align and draw our (possibly scaled) image Rectangle alignRectangle = AlignRectangle(r, imageBounds); if (ListItem.Enabled) g.DrawImage(image, alignRectangle); else ControlPaint.DrawImageDisabled(g, image, alignRectangle.X, alignRectangle.Y, GetBackgroundColor()); } /// /// Draw our subitems image and text /// /// Graphics context to use for drawing /// Pre-padded bounds of the cell protected virtual void DrawAlignedImageAndText(Graphics g, Rectangle r) { DrawImageAndText(g, r); //this.CalculateAlignedRectangle(g, r)); } /// /// Fill in the background of this cell /// /// Graphics context to use for drawing /// Bounds of the cell protected virtual void DrawBackground(Graphics g, Rectangle r) { if (!IsDrawBackground) return; Color backgroundColor = GetBackgroundColor(); using (Brush brush = new SolidBrush(backgroundColor)) { g.FillRectangle(brush, r.X - 1, r.Y - 1, r.Width + 2, r.Height + 2); } } /// /// Draw the primary check box of this row (checkboxes in other sub items use a different method) /// /// Graphics context to use for drawing /// The pre-aligned and padded target rectangle protected virtual int DrawCheckBox(Graphics g, Rectangle r) { // The odd constants are to match checkbox placement in native mode (on XP at least) // TODO: Unify this with CheckStateRenderer // The rectangle r is already horizontally aligned. We still need to align it vertically. Size checkBoxSize = CalculateCheckBoxSize(g); Point checkBoxLocation = new Point(r.X, AlignVertically(r, checkBoxSize.Height)); if (IsPrinting || UseCustomCheckboxImages) { int imageIndex = ListItem.StateImageIndex; if (ListView.StateImageList == null || imageIndex < 0 || imageIndex >= ListView.StateImageList.Images.Count) return 0; return DrawImage(g, new Rectangle(checkBoxLocation, checkBoxSize), ListView.StateImageList.Images[imageIndex]) + 4; } CheckBoxState boxState = GetCheckBoxState(ListItem.CheckState); CheckBoxRenderer.DrawCheckBox(g, checkBoxLocation, boxState); return checkBoxSize.Width; } /// /// Calculate the CheckBoxState we need to correctly draw the given state /// /// /// protected virtual CheckBoxState GetCheckBoxState(CheckState checkState) { // Should the checkbox be drawn as disabled? if (IsCheckBoxDisabled) { switch (checkState) { case CheckState.Checked: return CheckBoxState.CheckedDisabled; case CheckState.Unchecked: return CheckBoxState.UncheckedDisabled; default: return CheckBoxState.MixedDisabled; } } // Is the cursor currently over this checkbox? if (IsCheckboxHot) { switch (checkState) { case CheckState.Checked: return CheckBoxState.CheckedHot; case CheckState.Unchecked: return CheckBoxState.UncheckedHot; default: return CheckBoxState.MixedHot; } } // Not hot and not disabled -- just draw it normally switch (checkState) { case CheckState.Checked: return CheckBoxState.CheckedNormal; case CheckState.Unchecked: return CheckBoxState.UncheckedNormal; default: return CheckBoxState.MixedNormal; } } /// /// Should this checkbox be drawn as disabled? /// protected virtual bool IsCheckBoxDisabled { get { if (ListItem != null && !ListItem.Enabled) return true; if (!ListView.RenderNonEditableCheckboxesAsDisabled) return false; return (ListView.CellEditActivation == ObjectListView.CellEditActivateMode.None || (Column != null && !Column.IsEditable)); } } /// /// Is the current item hot (i.e. under the mouse)? /// protected bool IsCellHot { get { return ListView != null && ListView.HotRowIndex == ListItem.Index && ListView.HotColumnIndex == (Column == null ? 0 : Column.Index); } } /// /// Is the mouse over a checkbox in this cell? /// protected bool IsCheckboxHot { get { return IsCellHot && ListView.HotCellHitLocation == HitTestLocation.CheckBox; } } /// /// Draw the given text and optional image in the "normal" fashion /// /// Graphics context to use for drawing /// Bounds of the cell /// The optional image to be drawn protected virtual int DrawImage(Graphics g, Rectangle r, Object imageSelector) { if (imageSelector == null || imageSelector == DBNull.Value) return 0; // Draw from the image list (most common case) ImageList il = ImageListOrDefault; if (il != null) { // Try to translate our imageSelector into a valid ImageList index int selectorAsInt = -1; if (imageSelector is Int32) { selectorAsInt = (Int32) imageSelector; if (selectorAsInt >= il.Images.Count) selectorAsInt = -1; } else { if (imageSelector is string selectorAsString) selectorAsInt = il.Images.IndexOfKey(selectorAsString); } // If we found a valid index into the ImageList, draw it. // We want to draw using the native DrawImageList calls, since that let's us do some nice effects // But the native call does not work on PrinterDCs, so if we're printing we have to skip this bit. if (selectorAsInt >= 0) { if (!IsPrinting) { if (il.ImageSize.Height < r.Height) r.Y = AlignVertically(r, new Rectangle(Point.Empty, il.ImageSize)); // If we are not printing, it's probable that the given Graphics object is double buffered using a BufferedGraphics object. // But the ImageList.Draw method doesn't honor the Translation matrix that's probably in effect on the buffered // graphics. So we have to calculate our drawing rectangle, relative to the cells natural boundaries. // This effectively simulates the Translation matrix. Rectangle r2 = new Rectangle(r.X - Bounds.X, r.Y - Bounds.Y, r.Width, r.Height); NativeMethods.DrawImageList(g, il, selectorAsInt, r2.X, r2.Y, IsItemSelected, !ListItem.Enabled); return il.ImageSize.Width; } // For some reason, printing from an image list doesn't work onto a printer context // So get the image from the list and FALL THROUGH to the "print an image" case imageSelector = il.Images[selectorAsInt]; } } // Is the selector actually an image? if (imageSelector is not Image image) return 0; // no, give up if (image.Size.Height < r.Height) r.Y = AlignVertically(r, new Rectangle(Point.Empty, image.Size)); if (ListItem.Enabled) g.DrawImageUnscaled(image, r.X, r.Y); else ControlPaint.DrawImageDisabled(g, image, r.X, r.Y, GetBackgroundColor()); return image.Width; } /// /// Draw our subitems image and text /// /// Graphics context to use for drawing /// Bounds of the cell protected virtual void DrawImageAndText(Graphics g, Rectangle r) { int offset = 0; if (ListView.CheckBoxes && ColumnIsPrimary) { offset = DrawCheckBox(g, r) + 6; r.X += offset; r.Width -= offset; } offset = DrawImage(g, r, GetImageSelector()); r.X += offset; r.Width -= offset; DrawText(g, r, GetText()); } /// /// Draw the given collection of image selectors /// /// /// /// protected virtual int DrawImages(Graphics g, Rectangle r, ICollection imageSelectors) { // Collect the non-null images List images = new List(); foreach (Object selector in imageSelectors) { Image image = GetImage(selector); if (image != null) images.Add(image); } // Figure out how much space they will occupy int width = 0; int height = 0; foreach (Image image in images) { width += (image.Width + Spacing); height = Math.Max(height, image.Height); } // Align the collection of images within the cell Rectangle r2 = AlignRectangle(r, new Rectangle(0, 0, width, height)); // Finally, draw all the images in their correct location Color backgroundColor = GetBackgroundColor(); Point pt = r2.Location; foreach (Image image in images) { if (ListItem.Enabled) g.DrawImage(image, pt); else ControlPaint.DrawImageDisabled(g, image, pt.X, pt.Y, backgroundColor); pt.X += (image.Width + Spacing); } // Return the width that the images occupy return width; } /// /// Draw the given text and optional image in the "normal" fashion /// /// Graphics context to use for drawing /// Bounds of the cell /// The string to be drawn public virtual void DrawText(Graphics g, Rectangle r, String txt) { if (String.IsNullOrEmpty(txt)) return; if (UseGdiTextRendering) DrawTextGdi(g, r, txt); else DrawTextGdiPlus(g, r, txt); } /// /// Print the given text in the given rectangle using only GDI routines /// /// /// /// /// /// The native list control uses GDI routines to do its drawing, so using them /// here makes the owner drawn mode looks more natural. /// This method doesn't honour the CanWrap setting on the renderer. All /// text is single line /// protected virtual void DrawTextGdi(Graphics g, Rectangle r, String txt) { Color backColor = Color.Transparent; if (IsDrawBackground && IsItemSelected && ColumnIsPrimary && !ListView.FullRowSelect) backColor = GetSelectedBackgroundColor(); TextFormatFlags flags = NormalTextFormatFlags | CellVerticalAlignmentAsTextFormatFlag; // I think there is a bug in the TextRenderer. Setting or not setting SingleLine doesn't make // any difference -- it is always single line. if (!CanWrap) flags |= TextFormatFlags.SingleLine; TextRenderer.DrawText(g, txt, Font, r, GetForegroundColor(), backColor, flags); } private bool ColumnIsPrimary { get { return Column != null && Column.Index == 0; } } /// /// Gets the cell's vertical alignment as a TextFormatFlag /// /// protected TextFormatFlags CellVerticalAlignmentAsTextFormatFlag { get { switch (EffectiveCellVerticalAlignment) { case StringAlignment.Near: return TextFormatFlags.Top; case StringAlignment.Center: return TextFormatFlags.VerticalCenter; case StringAlignment.Far: return TextFormatFlags.Bottom; default: throw new ArgumentOutOfRangeException(); } } } /// /// Gets the StringFormat needed when drawing text using GDI+ /// protected virtual StringFormat StringFormatForGdiPlus { get { StringFormat fmt = new StringFormat(); fmt.LineAlignment = EffectiveCellVerticalAlignment; fmt.Trimming = StringTrimming.EllipsisCharacter; fmt.Alignment = Column == null ? StringAlignment.Near : Column.TextStringAlign; if (!CanWrap) fmt.FormatFlags = StringFormatFlags.NoWrap; return fmt; } } /// /// Print the given text in the given rectangle using normal GDI+ .NET methods /// /// Printing to a printer dc has to be done using this method. protected virtual void DrawTextGdiPlus(Graphics g, Rectangle r, String txt) { using (StringFormat fmt = StringFormatForGdiPlus) { // Draw the background of the text as selected, if it's the primary column // and it's selected and it's not in FullRowSelect mode. Font f = Font; if (IsDrawBackground && IsItemSelected && ColumnIsPrimary && !ListView.FullRowSelect) { SizeF size = g.MeasureString(txt, f, r.Width, fmt); Rectangle r2 = r; r2.Width = (int) size.Width + 1; using (Brush brush = new SolidBrush(GetSelectedBackgroundColor())) { g.FillRectangle(brush, r2); } } RectangleF rf = r; g.DrawString(txt, f, TextBrush, rf, fmt); } // We should put a focus rectangle around the column 0 text if it's selected -- // but we don't because: // - I really dislike this UI convention // - we are using buffered graphics, so the DrawFocusRecatangle method of the event doesn't work //if (this.ColumnIsPrimary) { // Size size = TextRenderer.MeasureText(this.SubItem.Text, this.ListView.ListFont); // if (r.Width > size.Width) // r.Width = size.Width; // this.Event.DrawFocusRectangle(r); //} } #endregion } /// /// This renderer highlights substrings that match a given text filter. /// public class HighlightTextRenderer : BaseRenderer, IFilterAwareRenderer { #region Life and death /// /// Create a HighlightTextRenderer /// public HighlightTextRenderer() { FramePen = Pens.DarkGreen; FillBrush = Brushes.Yellow; } /// /// Create a HighlightTextRenderer /// /// public HighlightTextRenderer(TextMatchFilter filter) : this() { Filter = filter; } /// /// Create a HighlightTextRenderer /// /// [Obsolete("Use HighlightTextRenderer(TextMatchFilter) instead", true)] public HighlightTextRenderer(string text) {} #endregion #region Configuration properties /// /// Gets or set how rounded will be the corners of the text match frame /// [Category("Appearance"), DefaultValue(3.0f), Description("How rounded will be the corners of the text match frame?")] public float CornerRoundness { get { return cornerRoundness; } set { cornerRoundness = value; } } private float cornerRoundness = 3.0f; /// /// Gets or set the brush will be used to paint behind the matched substrings. /// Set this to null to not fill the frame. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public Brush FillBrush { get { return fillBrush; } set { fillBrush = value; } } private Brush fillBrush; /// /// Gets or sets the filter that is filtering the ObjectListView and for /// which this renderer should highlight text /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public TextMatchFilter Filter { get { return filter; } set { filter = value; } } private TextMatchFilter filter; /// /// When a filter changes, keep track of the text matching filters /// IModelFilter IFilterAwareRenderer.Filter { get { return filter; } set { RegisterNewFilter(value); } } internal void RegisterNewFilter(IModelFilter newFilter) { if (newFilter is TextMatchFilter textFilter) { Filter = textFilter; return; } if (newFilter is CompositeFilter composite) { foreach (TextMatchFilter textSubFilter in composite.TextFilters) { Filter = textSubFilter; return; } } Filter = null; } /// /// Gets or set the pen will be used to frame the matched substrings. /// Set this to null to not draw a frame. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public Pen FramePen { get { return framePen; } set { framePen = value; } } private Pen framePen; /// /// Gets or sets whether the frame around a text match will have rounded corners /// [Category("Appearance"), DefaultValue(true), Description("Will the frame around a text match will have rounded corners?")] public bool UseRoundedRectangle { get { return useRoundedRectangle; } set { useRoundedRectangle = value; } } private bool useRoundedRectangle = true; #endregion #region Compatibility properties /// /// Gets or set the text that will be highlighted /// [Obsolete("Set the Filter directly rather than just the text", true)] [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public string TextToHighlight { get { return String.Empty; } set { } } /// /// Gets or sets the manner in which substring will be compared. /// /// /// Use this to control if substring matches are case sensitive or insensitive. [Obsolete("Set the Filter directly rather than just this setting", true)] [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public StringComparison StringComparison { get { return StringComparison.CurrentCultureIgnoreCase; } set { } } #endregion #region IRenderer interface overrides /// /// Handle a HitTest request after all state information has been initialized /// /// /// /// /// /// /// protected override Rectangle HandleGetEditRectangle(Graphics g, Rectangle cellBounds, OLVListItem item, int subItemIndex, Size preferredSize) { return StandardGetEditRectangle(g, cellBounds, preferredSize); } #endregion #region Rendering // This class has two implement two highlighting schemes: one for GDI, another for GDI+. // Naturally, GDI+ makes the task easier, but we have to provide something for GDI // since that it is what is normally used. /// /// Draw text using GDI /// /// /// /// protected override void DrawTextGdi(Graphics g, Rectangle r, string txt) { if (ShouldDrawHighlighting) DrawGdiTextHighlighting(g, r, txt); base.DrawTextGdi(g, r, txt); } /// /// Draw the highlighted text using GDI /// /// /// /// protected virtual void DrawGdiTextHighlighting(Graphics g, Rectangle r, string txt) { // TextRenderer puts horizontal padding around the strings, so we need to take // that into account when measuring strings const int paddingAdjustment = 6; // Cache the font Font f = Font; foreach (CharacterRange range in Filter.FindAllMatchedRanges(txt)) { // Measure the text that comes before our substring Size precedingTextSize = Size.Empty; if (range.First > 0) { string precedingText = txt.Substring(0, range.First); precedingTextSize = TextRenderer.MeasureText(g, precedingText, f, r.Size, NormalTextFormatFlags); precedingTextSize.Width -= paddingAdjustment; } // Measure the length of our substring (may be different each time due to case differences) string highlightText = txt.Substring(range.First, range.Length); Size textToHighlightSize = TextRenderer.MeasureText(g, highlightText, f, r.Size, NormalTextFormatFlags); textToHighlightSize.Width -= paddingAdjustment; float textToHighlightLeft = r.X + precedingTextSize.Width + 1; float textToHighlightTop = AlignVertically(r, textToHighlightSize.Height); // Draw a filled frame around our substring DrawSubstringFrame(g, textToHighlightLeft, textToHighlightTop, textToHighlightSize.Width, textToHighlightSize.Height); } } /// /// Draw an indication around the given frame that shows a text match /// /// /// /// /// /// protected virtual void DrawSubstringFrame(Graphics g, float x, float y, float width, float height) { if (UseRoundedRectangle) { using (GraphicsPath path = GetRoundedRect(x, y, width, height, 3.0f)) { if (FillBrush != null) g.FillPath(FillBrush, path); if (FramePen != null) g.DrawPath(FramePen, path); } } else { if (FillBrush != null) g.FillRectangle(FillBrush, x, y, width, height); if (FramePen != null) g.DrawRectangle(FramePen, x, y, width, height); } } /// /// Draw the text using GDI+ /// /// /// /// protected override void DrawTextGdiPlus(Graphics g, Rectangle r, string txt) { if (ShouldDrawHighlighting) DrawGdiPlusTextHighlighting(g, r, txt); base.DrawTextGdiPlus(g, r, txt); } /// /// Draw the highlighted text using GDI+ /// /// /// /// protected virtual void DrawGdiPlusTextHighlighting(Graphics g, Rectangle r, string txt) { // Find the substrings we want to highlight List ranges = new List(Filter.FindAllMatchedRanges(txt)); if (ranges.Count == 0) return; using (StringFormat fmt = StringFormatForGdiPlus) { RectangleF rf = r; fmt.SetMeasurableCharacterRanges(ranges.ToArray()); Region[] stringRegions = g.MeasureCharacterRanges(txt, Font, rf, fmt); foreach (Region region in stringRegions) { RectangleF bounds = region.GetBounds(g); DrawSubstringFrame(g, bounds.X - 1, bounds.Y - 1, bounds.Width + 2, bounds.Height); } } } #endregion #region Utilities /// /// Gets whether the renderer should actually draw highlighting /// protected bool ShouldDrawHighlighting { get { return Column == null || (Column.Searchable && Filter != null && Filter.HasComponents); } } /// /// Return a GraphicPath that is a round cornered rectangle /// /// A round cornered rectangle path /// If I could rely on people using C# 3.0+, this should be /// an extension method of GraphicsPath. /// /// /// /// /// protected GraphicsPath GetRoundedRect(float x, float y, float width, float height, float diameter) { return GetRoundedRect(new RectangleF(x, y, width, height), diameter); } /// /// Return a GraphicPath that is a round cornered rectangle /// /// The rectangle /// The diameter of the corners /// A round cornered rectangle path /// If I could rely on people using C# 3.0+, this should be /// an extension method of GraphicsPath. protected GraphicsPath GetRoundedRect(RectangleF rect, float diameter) { GraphicsPath path = new GraphicsPath(); if (diameter > 0) { RectangleF arc = new RectangleF(rect.X, rect.Y, diameter, diameter); path.AddArc(arc, 180, 90); arc.X = rect.Right - diameter; path.AddArc(arc, 270, 90); arc.Y = rect.Bottom - diameter; path.AddArc(arc, 0, 90); arc.X = rect.Left; path.AddArc(arc, 90, 90); path.CloseFigure(); } else { path.AddRectangle(rect); } return path; } #endregion } /// /// This class maps a data value to an image that should be drawn for that value. /// /// It is useful for drawing data that is represented as an enum or boolean. public class MappedImageRenderer : BaseRenderer { /// /// Return a renderer that draw boolean values using the given images /// /// Draw this when our data value is true /// Draw this when our data value is false /// A Renderer public static MappedImageRenderer Boolean(Object trueImage, Object falseImage) { return new MappedImageRenderer(true, trueImage, false, falseImage); } /// /// Return a renderer that draw tristate boolean values using the given images /// /// Draw this when our data value is true /// Draw this when our data value is false /// Draw this when our data value is null /// A Renderer public static MappedImageRenderer TriState(Object trueImage, Object falseImage, Object nullImage) { return new MappedImageRenderer(new Object[] {true, trueImage, false, falseImage, null, nullImage}); } /// /// Make a new empty renderer /// public MappedImageRenderer() { map = new Hashtable(); } /// /// Make a new renderer that will show the given image when the given key is the aspect value /// /// The data value to be matched /// The image to be shown when the key is matched public MappedImageRenderer(Object key, Object image) : this() { Add(key, image); } /// /// Make a new renderer that will show the given images when it receives the given keys /// /// /// /// /// public MappedImageRenderer(Object key1, Object image1, Object key2, Object image2) : this() { Add(key1, image1); Add(key2, image2); } /// /// Build a renderer from the given array of keys and their matching images /// /// An array of key/image pairs public MappedImageRenderer(Object[] keysAndImages) : this() { if ((keysAndImages.GetLength(0) % 2) != 0) throw new ArgumentException("Array must have key/image pairs"); for (int i = 0; i < keysAndImages.GetLength(0); i += 2) Add(keysAndImages[i], keysAndImages[i + 1]); } /// /// Register the image that should be drawn when our Aspect has the data value. /// /// Value that the Aspect must match /// An ImageSelector -- an int, string or image public void Add(Object value, Object image) { if (value == null) nullImage = image; else map[value] = image; } /// /// Render our value /// /// /// public override void Render(Graphics g, Rectangle r) { DrawBackground(g, r); r = ApplyCellPadding(r); if (Aspect is not ICollection aspectAsCollection) RenderOne(g, r, Aspect); else RenderCollection(g, r, aspectAsCollection); } /// /// Draw a collection of images /// /// /// /// protected void RenderCollection(Graphics g, Rectangle r, ICollection imageSelectors) { ArrayList images = new ArrayList(); Image image = null; foreach (Object selector in imageSelectors) { if (selector == null) image = GetImage(nullImage); else if (map.ContainsKey(selector)) image = GetImage(map[selector]); else image = null; if (image != null) images.Add(image); } DrawImages(g, r, images); } /// /// Draw one image /// /// /// /// protected void RenderOne(Graphics g, Rectangle r, Object selector) { Image image = null; if (selector == null) image = GetImage(nullImage); else if (map.ContainsKey(selector)) image = GetImage(map[selector]); if (image != null) DrawAlignedImage(g, r, image); } #region Private variables private Hashtable map; // Track the association between values and images private Object nullImage; // image to be drawn for null values (since null can't be a key) #endregion } /// /// This renderer draws just a checkbox to match the check state of our model object. /// public class CheckStateRenderer : BaseRenderer { /// /// Draw our cell /// /// /// public override void Render(Graphics g, Rectangle r) { DrawBackground(g, r); if (Column == null) return; r = ApplyCellPadding(r); CheckState state = Column.GetCheckState(RowObject); if (IsPrinting) { // Renderers don't work onto printer DCs, so we have to draw the image ourselves string key = ObjectListView.CHECKED_KEY; if (state == CheckState.Unchecked) key = ObjectListView.UNCHECKED_KEY; if (state == CheckState.Indeterminate) key = ObjectListView.INDETERMINATE_KEY; DrawAlignedImage(g, r, ImageListOrDefault.Images[key]); } else { r = CalculateCheckBoxBounds(g, r); CheckBoxRenderer.DrawCheckBox(g, r.Location, GetCheckBoxState(state)); } } /// /// Handle the GetEditRectangle request /// /// /// /// /// /// /// protected override Rectangle HandleGetEditRectangle(Graphics g, Rectangle cellBounds, OLVListItem item, int subItemIndex, Size preferredSize) { return CalculatePaddedAlignedBounds(g, cellBounds, preferredSize); } /// /// Handle the HitTest request /// /// /// /// /// protected override void HandleHitTest(Graphics g, OlvListViewHitTestInfo hti, int x, int y) { Rectangle r = CalculateCheckBoxBounds(g, Bounds); if (r.Contains(x, y)) hti.HitTestLocation = HitTestLocation.CheckBox; } } /// /// Render an image that comes from our data source. /// /// The image can be sourced from: /// /// a byte-array (normally when the image to be shown is /// stored as a value in a database) /// an int, which is treated as an index into the image list /// a string, which is treated first as a file name, and failing that as an index into the image list /// an ICollection of ints or strings, which will be drawn as consecutive images /// /// If an image is an animated GIF, it's state is stored in the SubItem object. /// By default, the image renderer does not render animations (it begins life with animations paused). /// To enable animations, you must call Unpause(). /// In the current implementation (2009-09), each column showing animated gifs must have a /// different instance of ImageRenderer assigned to it. You cannot share the same instance of /// an image renderer between two animated gif columns. If you do, only the last column will be /// animated. /// public class ImageRenderer : BaseRenderer { /// /// Make an empty image renderer /// public ImageRenderer() { stopwatch = new Stopwatch(); } /// /// Make an empty image renderer that begins life ready for animations /// public ImageRenderer(bool startAnimations) : this() { Paused = !startAnimations; } /// /// Finalizer /// protected override void Dispose(bool disposing) { Paused = true; base.Dispose(disposing); } #region Properties /// /// Should the animations in this renderer be paused? /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool Paused { get { return isPaused; } set { if (isPaused == value) return; isPaused = value; if (isPaused) { StopTickler(); stopwatch.Stop(); } else { Tickler.Change(1, Timeout.Infinite); stopwatch.Start(); } } } private bool isPaused = true; private void StopTickler() { if (tickler == null) return; tickler.Dispose(); tickler = null; } /// /// Gets a timer that can be used to trigger redraws on animations /// protected Timer Tickler { get { if (tickler == null) tickler = new Timer(new TimerCallback(OnTimer), null, Timeout.Infinite, Timeout.Infinite); return tickler; } } #endregion #region Commands /// /// Pause any animations /// public void Pause() { Paused = true; } /// /// Unpause any animations /// public void Unpause() { Paused = false; } #endregion #region Drawing /// /// Draw our image /// /// /// public override void Render(Graphics g, Rectangle r) { DrawBackground(g, r); if (Aspect == null || Aspect == DBNull.Value) return; r = ApplyCellPadding(r); if (Aspect is Byte[]) { DrawAlignedImage(g, r, GetImageFromAspect()); } else { if (Aspect is not ICollection imageSelectors) DrawAlignedImage(g, r, GetImageFromAspect()); else DrawImages(g, r, imageSelectors); } } /// /// Translate our Aspect into an image. /// /// The strategy is: /// If its a byte array, we treat it as an in-memory image /// If it's an int, we use that as an index into our image list /// If it's a string, we try to load a file by that name. If we can't, /// we use the string as an index into our image list. /// /// An image protected Image GetImageFromAspect() { // If we've already figured out the image, don't do it again if (OLVSubItem != null && OLVSubItem.ImageSelector is Image) { if (OLVSubItem.AnimationState == null) return (Image) OLVSubItem.ImageSelector; else return OLVSubItem.AnimationState.image; } // Try to convert our Aspect into an Image // If its a byte array, we treat it as an in-memory image // If it's an int, we use that as an index into our image list // If it's a string, we try to find a file by that name. // If we can't, we use the string as an index into our image list. Image image = Aspect as Image; if (image != null) { // Don't do anything else } else if (Aspect is Byte[]) { using (MemoryStream stream = new MemoryStream((Byte[]) Aspect)) { try { image = Image.FromStream(stream); } catch (ArgumentException) { // ignore } } } else if (Aspect is Int32) { image = GetImage(Aspect); } else { String str = Aspect as String; if (!String.IsNullOrEmpty(str)) { try { image = Image.FromFile(str); } catch (FileNotFoundException) { image = GetImage(Aspect); } catch (OutOfMemoryException) { image = GetImage(Aspect); } } } // If this image is an animation, initialize the animation process if (OLVSubItem != null && AnimationState.IsAnimation(image)) { OLVSubItem.AnimationState = new AnimationState(image); } // Cache the image so we don't repeat this dreary process if (OLVSubItem != null) OLVSubItem.ImageSelector = image; return image; } #endregion #region Events /// /// This is the method that is invoked by the timer. It basically switches control to the listview thread. /// /// not used public void OnTimer(Object state) { if (IsListViewDead) return; if (Paused) return; if (ListView.InvokeRequired) ListView.Invoke((MethodInvoker) delegate { OnTimer(state); }); else OnTimerInThread(); } private bool IsListViewDead { get { // Apply a whole heap of sanity checks, which basically ensure that the ListView is still alive return ListView == null || ListView.Disposing || ListView.IsDisposed || !ListView.IsHandleCreated; } } /// /// This is the OnTimer callback, but invoked in the same thread as the creator of the ListView. /// This method can use all of ListViews methods without creating a CrossThread exception. /// protected void OnTimerInThread() { // MAINTAINER NOTE: This method must renew the tickler. If it doesn't the animations will stop. // If this listview has been destroyed, we can't do anything, so we return without // renewing the tickler, effectively killing all animations on this renderer if (IsListViewDead) return; if (Paused) return; // If we're not in Detail view or our column has been removed from the list, // we can't do anything at the moment, but we still renew the tickler because the view may change later. if (ListView.View != View.Details || Column == null || Column.Index < 0) { Tickler.Change(1000, Timeout.Infinite); return; } long elapsedMilliseconds = stopwatch.ElapsedMilliseconds; int subItemIndex = Column.Index; long nextCheckAt = elapsedMilliseconds + 1000; // wait at most one second before checking again Rectangle updateRect = new Rectangle(); // what part of the view must be updated to draw the changed gifs? // Run through all the subitems in the view for our column, and for each one that // has an animation attached to it, see if the frame needs updating. for (int i = 0; i < ListView.GetItemCount(); i++) { OLVListItem lvi = ListView.GetItem(i); // Get the animation state from the subitem. If there isn't an animation state, skip this row. OLVListSubItem lvsi = lvi.GetSubItem(subItemIndex); AnimationState state = lvsi.AnimationState; if (state == null || !state.IsValid) continue; // Has this frame of the animation expired? if (elapsedMilliseconds >= state.currentFrameExpiresAt) { state.AdvanceFrame(elapsedMilliseconds); // Track the area of the view that needs to be redrawn to show the changed images if (updateRect.IsEmpty) updateRect = lvsi.Bounds; else updateRect = Rectangle.Union(updateRect, lvsi.Bounds); } // Remember the minimum time at which a frame is next due to change nextCheckAt = Math.Min(nextCheckAt, state.currentFrameExpiresAt); } // Update the part of the listview where frames have changed if (!updateRect.IsEmpty) ListView.Invalidate(updateRect); // Renew the tickler in time for the next frame change Tickler.Change(nextCheckAt - elapsedMilliseconds, Timeout.Infinite); } #endregion /// /// Instances of this class kept track of the animation state of a single image. /// internal class AnimationState { private const int PropertyTagTypeShort = 3; private const int PropertyTagTypeLong = 4; private const int PropertyTagFrameDelay = 0x5100; private const int PropertyTagLoopCount = 0x5101; /// /// Is the given image an animation /// /// The image to be tested /// Is the image an animation? public static bool IsAnimation(Image image) { if (image == null) return false; else return (new List(image.FrameDimensionsList)).Contains(FrameDimension.Time.Guid); } /// /// Create an AnimationState in a quiet state /// public AnimationState() { imageDuration = new List(); } /// /// Create an animation state for the given image, which may or may not /// be an animation /// /// The image to be rendered public AnimationState(Image image) : this() { if (!IsAnimation(image)) return; // How many frames in the animation? this.image = image; frameCount = this.image.GetFrameCount(FrameDimension.Time); // Find the delay between each frame. // The delays are stored an array of 4-byte ints. Each int is the // number of 1/100th of a second that should elapsed before the frame expires foreach (PropertyItem pi in this.image.PropertyItems) { if (pi.Id == PropertyTagFrameDelay) { for (int i = 0; i < pi.Len; i += 4) { //TODO: There must be a better way to convert 4-bytes to an int int delay = (pi.Value[i + 3] << 24) + (pi.Value[i + 2] << 16) + (pi.Value[i + 1] << 8) + pi.Value[i]; imageDuration.Add(delay * 10); // store delays as milliseconds } break; } } // There should be as many frame durations as frames Debug.Assert(imageDuration.Count == frameCount, "There should be as many frame durations as there are frames."); } /// /// Does this state represent a valid animation /// public bool IsValid { get { return (image != null && frameCount > 0); } } /// /// Advance our images current frame and calculate when it will expire /// public void AdvanceFrame(long millisecondsNow) { currentFrame = (currentFrame + 1) % frameCount; currentFrameExpiresAt = millisecondsNow + imageDuration[currentFrame]; image.SelectActiveFrame(FrameDimension.Time, currentFrame); } internal int currentFrame; internal long currentFrameExpiresAt; internal Image image; internal List imageDuration; internal int frameCount; } #region Private variables private Timer tickler; // timer used to tickle the animations private Stopwatch stopwatch; // clock used to time the animation frame changes #endregion } /// /// Render our Aspect as a progress bar /// public class BarRenderer : BaseRenderer { #region Constructors /// /// Make a BarRenderer /// public BarRenderer() : base() {} /// /// Make a BarRenderer for the given range of data values /// public BarRenderer(int minimum, int maximum) : this() { MinimumValue = minimum; MaximumValue = maximum; } /// /// Make a BarRenderer using a custom bar scheme /// public BarRenderer(Pen pen, Brush brush) : this() { Pen = pen; Brush = brush; UseStandardBar = false; } /// /// Make a BarRenderer using a custom bar scheme /// public BarRenderer(int minimum, int maximum, Pen pen, Brush brush) : this(minimum, maximum) { Pen = pen; Brush = brush; UseStandardBar = false; } /// /// Make a BarRenderer that uses a horizontal gradient /// public BarRenderer(Pen pen, Color start, Color end) : this() { Pen = pen; SetGradient(start, end); } /// /// Make a BarRenderer that uses a horizontal gradient /// public BarRenderer(int minimum, int maximum, Pen pen, Color start, Color end) : this(minimum, maximum) { Pen = pen; SetGradient(start, end); } #endregion #region Configuration Properties /// /// Should this bar be drawn in the system style? /// [Category("ObjectListView"), Description("Should this bar be drawn in the system style?"), DefaultValue(true)] public bool UseStandardBar { get { return useStandardBar; } set { useStandardBar = value; } } private bool useStandardBar = true; /// /// How many pixels in from our cell border will this bar be drawn /// [Category("ObjectListView"), Description("How many pixels in from our cell border will this bar be drawn"), DefaultValue(2)] public int Padding { get { return padding; } set { padding = value; } } private int padding = 2; /// /// What color will be used to fill the interior of the control before the /// progress bar is drawn? /// [Category("ObjectListView"), Description("The color of the interior of the bar"), DefaultValue(typeof (Color), "AliceBlue")] public Color BackgroundColor { get { return backgroundColor; } set { backgroundColor = value; } } private Color backgroundColor = Color.AliceBlue; /// /// What color should the frame of the progress bar be? /// [Category("ObjectListView"), Description("What color should the frame of the progress bar be"), DefaultValue(typeof (Color), "Black")] public Color FrameColor { get { return frameColor; } set { frameColor = value; } } private Color frameColor = Color.Black; /// /// How many pixels wide should the frame of the progress bar be? /// [Category("ObjectListView"), Description("How many pixels wide should the frame of the progress bar be"), DefaultValue(1.0f)] public float FrameWidth { get { return frameWidth; } set { frameWidth = value; } } private float frameWidth = 1.0f; /// /// What color should the 'filled in' part of the progress bar be? /// /// This is only used if GradientStartColor is Color.Empty [Category("ObjectListView"), Description("What color should the 'filled in' part of the progress bar be"), DefaultValue(typeof (Color), "BlueViolet")] public Color FillColor { get { return fillColor; } set { fillColor = value; } } private Color fillColor = Color.BlueViolet; /// /// Use a gradient to fill the progress bar starting with this color /// [Category("ObjectListView"), Description("Use a gradient to fill the progress bar starting with this color"), DefaultValue(typeof (Color), "CornflowerBlue")] public Color GradientStartColor { get { return startColor; } set { startColor = value; } } private Color startColor = Color.CornflowerBlue; /// /// Use a gradient to fill the progress bar ending with this color /// [Category("ObjectListView"), Description("Use a gradient to fill the progress bar ending with this color"), DefaultValue(typeof (Color), "DarkBlue")] public Color GradientEndColor { get { return endColor; } set { endColor = value; } } private Color endColor = Color.DarkBlue; /// /// Regardless of how wide the column become the progress bar will never be wider than this /// [Category("Behavior"), Description("The progress bar will never be wider than this"), DefaultValue(100)] public int MaximumWidth { get { return maximumWidth; } set { maximumWidth = value; } } private int maximumWidth = 100; /// /// Regardless of how high the cell is the progress bar will never be taller than this /// [Category("Behavior"), Description("The progress bar will never be taller than this"), DefaultValue(16)] public int MaximumHeight { get { return maximumHeight; } set { maximumHeight = value; } } private int maximumHeight = 16; /// /// The minimum data value expected. Values less than this will given an empty bar /// [Category("Behavior"), Description("The minimum data value expected. Values less than this will given an empty bar"), DefaultValue(0.0)] public double MinimumValue { get { return minimumValue; } set { minimumValue = value; } } private double minimumValue = 0.0; /// /// The maximum value for the range. Values greater than this will give a full bar /// [Category("Behavior"), Description("The maximum value for the range. Values greater than this will give a full bar"), DefaultValue(100.0)] public double MaximumValue { get { return maximumValue; } set { maximumValue = value; } } private double maximumValue = 100.0; #endregion #region Public Properties (non-IDE) /// /// The Pen that will draw the frame surrounding this bar /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public Pen Pen { get { if (pen == null && !FrameColor.IsEmpty) return new Pen(FrameColor, FrameWidth); else return pen; } set { pen = value; } } private Pen pen; /// /// The brush that will be used to fill the bar /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public Brush Brush { get { if (brush == null && !FillColor.IsEmpty) return new SolidBrush(FillColor); else return brush; } set { brush = value; } } private Brush brush; /// /// The brush that will be used to fill the background of the bar /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public Brush BackgroundBrush { get { if (backgroundBrush == null && !BackgroundColor.IsEmpty) return new SolidBrush(BackgroundColor); else return backgroundBrush; } set { backgroundBrush = value; } } private Brush backgroundBrush; #endregion /// /// Draw this progress bar using a gradient /// /// /// public void SetGradient(Color start, Color end) { GradientStartColor = start; GradientEndColor = end; } /// /// Draw our aspect /// /// /// public override void Render(Graphics g, Rectangle r) { DrawBackground(g, r); r = ApplyCellPadding(r); Rectangle frameRect = Rectangle.Inflate(r, 0 - Padding, 0 - Padding); frameRect.Width = Math.Min(frameRect.Width, MaximumWidth); frameRect.Height = Math.Min(frameRect.Height, MaximumHeight); frameRect = AlignRectangle(r, frameRect); // Convert our aspect to a numeric value if (Aspect is not IConvertible convertable) return; double aspectValue = convertable.ToDouble(NumberFormatInfo.InvariantInfo); Rectangle fillRect = Rectangle.Inflate(frameRect, -1, -1); if (aspectValue <= MinimumValue) fillRect.Width = 0; else if (aspectValue < MaximumValue) fillRect.Width = (int) (fillRect.Width * (aspectValue - MinimumValue) / MaximumValue); // MS-themed progress bars don't work when printing if (UseStandardBar && ProgressBarRenderer.IsSupported && !IsPrinting) { ProgressBarRenderer.DrawHorizontalBar(g, frameRect); ProgressBarRenderer.DrawHorizontalChunks(g, fillRect); } else { g.FillRectangle(BackgroundBrush, frameRect); if (fillRect.Width > 0) { // FillRectangle fills inside the given rectangle, so expand it a little fillRect.Width++; fillRect.Height++; if (GradientStartColor == Color.Empty) g.FillRectangle(Brush, fillRect); else { using (LinearGradientBrush gradient = new LinearGradientBrush(frameRect, GradientStartColor, GradientEndColor, LinearGradientMode.Horizontal)) { g.FillRectangle(gradient, fillRect); } } } g.DrawRectangle(Pen, frameRect); } } /// /// Handle the GetEditRectangle request /// /// /// /// /// /// /// protected override Rectangle HandleGetEditRectangle(Graphics g, Rectangle cellBounds, OLVListItem item, int subItemIndex, Size preferredSize) { return CalculatePaddedAlignedBounds(g, cellBounds, preferredSize); } } /// /// An ImagesRenderer draws zero or more images depending on the data returned by its Aspect. /// /// This renderer's Aspect must return a ICollection of ints, strings or Images, /// each of which will be drawn horizontally one after the other. /// As of v2.1, this functionality has been absorbed into ImageRenderer and this is now an /// empty shell, solely for backwards compatibility. /// [ToolboxItem(false)] public class ImagesRenderer : ImageRenderer {} /// /// A MultiImageRenderer draws the same image a number of times based on our data value /// /// The stars in the Rating column of iTunes is a good example of this type of renderer. public class MultiImageRenderer : BaseRenderer { /// /// Make a quiet renderer /// public MultiImageRenderer() : base() {} /// /// Make an image renderer that will draw the indicated image, at most maxImages times. /// /// /// /// /// public MultiImageRenderer(Object imageSelector, int maxImages, int minValue, int maxValue) : this() { ImageSelector = imageSelector; MaxNumberImages = maxImages; MinimumValue = minValue; MaximumValue = maxValue; } #region Configuration Properties /// /// The index of the image that should be drawn /// [Category("Behavior"), Description("The index of the image that should be drawn"), DefaultValue(-1)] public int ImageIndex { get { if (imageSelector is Int32) return (Int32) imageSelector; else return -1; } set { imageSelector = value; } } /// /// The name of the image that should be drawn /// [Category("Behavior"), Description("The index of the image that should be drawn"), DefaultValue(null)] public string ImageName { get { return imageSelector as String; } set { imageSelector = value; } } /// /// The image selector that will give the image to be drawn /// /// Like all image selectors, this can be an int, string or Image [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public Object ImageSelector { get { return imageSelector; } set { imageSelector = value; } } private Object imageSelector; /// /// What is the maximum number of images that this renderer should draw? /// [Category("Behavior"), Description("The maximum number of images that this renderer should draw"), DefaultValue(10)] public int MaxNumberImages { get { return maxNumberImages; } set { maxNumberImages = value; } } private int maxNumberImages = 10; /// /// Values less than or equal to this will have 0 images drawn /// [Category("Behavior"), Description("Values less than or equal to this will have 0 images drawn"), DefaultValue(0)] public int MinimumValue { get { return minimumValue; } set { minimumValue = value; } } private int minimumValue = 0; /// /// Values greater than or equal to this will have MaxNumberImages images drawn /// [Category("Behavior"), Description("Values greater than or equal to this will have MaxNumberImages images drawn"), DefaultValue(100)] public int MaximumValue { get { return maximumValue; } set { maximumValue = value; } } private int maximumValue = 100; #endregion /// /// Draw our data value /// /// /// public override void Render(Graphics g, Rectangle r) { DrawBackground(g, r); r = ApplyCellPadding(r); Image image = GetImage(ImageSelector); if (image == null) return; // Convert our aspect to a numeric value if (Aspect is not IConvertible convertable) return; double aspectValue = convertable.ToDouble(NumberFormatInfo.InvariantInfo); // Calculate how many images we need to draw to represent our aspect value int numberOfImages; if (aspectValue <= MinimumValue) numberOfImages = 0; else if (aspectValue < MaximumValue) numberOfImages = 1 + (int) (MaxNumberImages * (aspectValue - MinimumValue) / MaximumValue); else numberOfImages = MaxNumberImages; // If we need to shrink the image, what will its on-screen dimensions be? int imageScaledWidth = image.Width; int imageScaledHeight = image.Height; if (r.Height < image.Height) { imageScaledWidth = (int) ((float) image.Width * (float) r.Height / (float) image.Height); imageScaledHeight = r.Height; } // Calculate where the images should be drawn Rectangle imageBounds = r; imageBounds.Width = (MaxNumberImages * (imageScaledWidth + Spacing)) - Spacing; imageBounds.Height = imageScaledHeight; imageBounds = AlignRectangle(r, imageBounds); // Finally, draw the images Rectangle singleImageRect = new Rectangle(imageBounds.X, imageBounds.Y, imageScaledWidth, imageScaledHeight); Color backgroundColor = GetBackgroundColor(); for (int i = 0; i < numberOfImages; i++) { if (ListItem.Enabled) { DrawImage(g, singleImageRect, ImageSelector); } else ControlPaint.DrawImageDisabled(g, image, singleImageRect.X, singleImageRect.Y, backgroundColor); singleImageRect.X += (imageScaledWidth + Spacing); } } } /// /// A class to render a value that contains a bitwise-OR'ed collection of values. /// public class FlagRenderer : BaseRenderer { /// /// Register the given image to the given value /// /// When this flag is present... /// ...draw this image public void Add(Object key, Object imageSelector) { Int32 k2 = ((IConvertible) key).ToInt32(NumberFormatInfo.InvariantInfo); imageMap[k2] = imageSelector; keysInOrder.Remove(k2); keysInOrder.Add(k2); } /// /// Draw the flags /// /// /// public override void Render(Graphics g, Rectangle r) { DrawBackground(g, r); if (Aspect is not IConvertible convertable) return; r = ApplyCellPadding(r); Int32 v2 = convertable.ToInt32(NumberFormatInfo.InvariantInfo); ArrayList images = new ArrayList(); foreach (Int32 key in keysInOrder) { if ((v2 & key) == key) { Image image = GetImage(imageMap[key]); if (image != null) images.Add(image); } } if (images.Count > 0) DrawImages(g, r, images); } /// /// Do the actual work of hit testing. Subclasses should override this rather than HitTest() /// /// /// /// /// protected override void HandleHitTest(Graphics g, OlvListViewHitTestInfo hti, int x, int y) { if (Aspect is not IConvertible convertable) return; Int32 v2 = convertable.ToInt32(NumberFormatInfo.InvariantInfo); Point pt = Bounds.Location; foreach (Int32 key in keysInOrder) { if ((v2 & key) == key) { Image image = GetImage(imageMap[key]); if (image != null) { Rectangle imageRect = new Rectangle(pt, image.Size); if (imageRect.Contains(x, y)) { hti.UserData = key; return; } pt.X += (image.Width + Spacing); } } } } private List keysInOrder = new(); private Dictionary imageMap = new(); } /// /// This renderer draws an image, a single line title, and then multi-line description /// under the title. /// /// /// This class works best with FullRowSelect = true. /// It's not designed to work with cell editing -- it will work but will look odd. /// /// It's not RightToLeft friendly. /// /// public class DescribedTaskRenderer : BaseRenderer, IFilterAwareRenderer { private readonly StringFormat noWrapStringFormat; private readonly HighlightTextRenderer highlightTextRenderer = new(); /// /// Create a DescribedTaskRenderer /// public DescribedTaskRenderer() { noWrapStringFormat = new StringFormat(StringFormatFlags.NoWrap); noWrapStringFormat.Trimming = StringTrimming.EllipsisCharacter; noWrapStringFormat.Alignment = StringAlignment.Near; noWrapStringFormat.LineAlignment = StringAlignment.Near; highlightTextRenderer.CellVerticalAlignment = StringAlignment.Near; } #region Configuration properties /// /// Should text be rendered using GDI routines? This makes the text look more /// like a native List view control. /// public override bool UseGdiTextRendering { get { return base.UseGdiTextRendering; } set { base.UseGdiTextRendering = value; highlightTextRenderer.UseGdiTextRendering = value; } } /// /// Gets or set the font that will be used to draw the title of the task /// /// If this is null, the ListView's font will be used [Category("ObjectListView"), Description("The font that will be used to draw the title of the task"), DefaultValue(null)] public Font TitleFont { get { return titleFont; } set { titleFont = value; } } private Font titleFont; /// /// Return a font that has been set for the title or a reasonable default /// [Browsable(false)] public Font TitleFontOrDefault { get { return TitleFont ?? ListView.Font; } } /// /// Gets or set the color of the title of the task /// /// This color is used when the task is not selected or when the listview /// has a translucent selection mechanism. [Category("ObjectListView"), Description("The color of the title"), DefaultValue(typeof (Color), "")] public Color TitleColor { get { return titleColor; } set { titleColor = value; } } private Color titleColor; /// /// Return the color of the title of the task or a reasonable default /// [Browsable(false)] public Color TitleColorOrDefault { get { if (!ListItem.Enabled) return SubItem.ForeColor; if (IsItemSelected || TitleColor.IsEmpty) return GetForegroundColor(); return TitleColor; } } /// /// Gets or set the font that will be used to draw the description of the task /// /// If this is null, the ListView's font will be used [Category("ObjectListView"), Description("The font that will be used to draw the description of the task"), DefaultValue(null)] public Font DescriptionFont { get { return descriptionFont; } set { descriptionFont = value; } } private Font descriptionFont; /// /// Return a font that has been set for the title or a reasonable default /// [Browsable(false)] public Font DescriptionFontOrDefault { get { return DescriptionFont ?? ListView.Font; } } /// /// Gets or set the color of the description of the task /// /// This color is used when the task is not selected or when the listview /// has a translucent selection mechanism. [Category("ObjectListView"), Description("The color of the description"), DefaultValue(typeof (Color), "")] public Color DescriptionColor { get { return descriptionColor; } set { descriptionColor = value; } } private Color descriptionColor = Color.Empty; /// /// Return the color of the description of the task or a reasonable default /// [Browsable(false)] public Color DescriptionColorOrDefault { get { if (!ListItem.Enabled) return SubItem.ForeColor; if (IsItemSelected && !ListView.UseTranslucentSelection) return GetForegroundColor(); return DescriptionColor.IsEmpty ? defaultDescriptionColor : DescriptionColor; } } private static Color defaultDescriptionColor = Color.FromArgb(45, 46, 49); /// /// Gets or sets the number of pixels that will be left between the image and the text /// [Category("ObjectListView"), Description("The number of pixels that that will be left between the image and the text"), DefaultValue(4)] public int ImageTextSpace { get { return imageTextSpace; } set { imageTextSpace = value; } } private int imageTextSpace = 4; /// /// Gets or sets the number of pixels that will be left between the title and the description /// [Category("ObjectListView"), Description("The number of pixels that that will be left between the title and the description"), DefaultValue(2)] public int TitleDescriptionSpace { get { return titleDescriptionSpace; } set { titleDescriptionSpace = value; } } private int titleDescriptionSpace = 2; /// /// Gets or sets the name of the aspect of the model object that contains the task description /// [Category("ObjectListView"), Description("The name of the aspect of the model object that contains the task description"), DefaultValue(null)] public string DescriptionAspectName { get { return descriptionAspectName; } set { descriptionAspectName = value; } } private string descriptionAspectName; #endregion #region Text highlighting /// /// Gets or sets the filter that is filtering the ObjectListView and for /// which this renderer should highlight text /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public TextMatchFilter Filter { get { return highlightTextRenderer.Filter; } set { highlightTextRenderer.Filter = value; } } /// /// When a filter changes, keep track of the text matching filters /// IModelFilter IFilterAwareRenderer.Filter { get { return Filter; } set { highlightTextRenderer.RegisterNewFilter(value); } } #endregion #region Calculating /// /// Fetch the description from the model class /// /// /// public virtual string GetDescription(object model) { if (String.IsNullOrEmpty(DescriptionAspectName)) return String.Empty; if (descriptionGetter == null) descriptionGetter = new Munger(DescriptionAspectName); return descriptionGetter.GetValue(model) as string; } private Munger descriptionGetter; #endregion #region Rendering public override void ConfigureSubItem(DrawListViewSubItemEventArgs e, Rectangle cellBounds, object model) { base.ConfigureSubItem(e, cellBounds, model); highlightTextRenderer.ConfigureSubItem(e, cellBounds, model); } /// /// Draw our item /// /// /// public override void Render(Graphics g, Rectangle r) { DrawBackground(g, r); r = ApplyCellPadding(r); DrawDescribedTask(g, r, GetText(), GetDescription(RowObject), GetImageSelector()); } /// /// Draw the task /// /// /// /// /// /// protected virtual void DrawDescribedTask(Graphics g, Rectangle r, string title, string description, object imageSelector) { //Debug.WriteLine(String.Format("DrawDescribedTask({0}, {1}, {2}, {3})", r, title, description, imageSelector)); // Draw the image if one's been given Rectangle textBounds = r; if (imageSelector != null) { int imageWidth = DrawImage(g, r, imageSelector); int gapToText = imageWidth + ImageTextSpace; textBounds.X += gapToText; textBounds.Width -= gapToText; } // Draw the title if (!String.IsNullOrEmpty(title)) { using (SolidBrush b = new SolidBrush(TitleColorOrDefault)) { highlightTextRenderer.CanWrap = false; highlightTextRenderer.Font = TitleFontOrDefault; highlightTextRenderer.TextBrush = b; highlightTextRenderer.DrawText(g, textBounds, title); } // How tall was the title? SizeF size = g.MeasureString(title, TitleFontOrDefault, textBounds.Width, noWrapStringFormat); int pixelsToDescription = TitleDescriptionSpace + (int)size.Height; textBounds.Y += pixelsToDescription; textBounds.Height -= pixelsToDescription; } // Draw the description if (!String.IsNullOrEmpty(description)) { using (SolidBrush b = new SolidBrush(DescriptionColorOrDefault)) { highlightTextRenderer.CanWrap = true; highlightTextRenderer.Font = DescriptionFontOrDefault; highlightTextRenderer.TextBrush = b; highlightTextRenderer.DrawText(g, textBounds, description); } } //g.DrawRectangle(Pens.OrangeRed, r); } #endregion #region Hit Testing /// /// Handle the HitTest request /// /// /// /// /// protected override void HandleHitTest(Graphics g, OlvListViewHitTestInfo hti, int x, int y) { if (Bounds.Contains(x, y)) hti.HitTestLocation = HitTestLocation.Text; } #endregion } /// /// This renderer draws a functioning button in its cell /// public class ColumnButtonRenderer : BaseRenderer { #region Properties /// /// Gets or sets how each button will be sized /// [Category("ObjectListView"), Description("How each button will be sized"), DefaultValue(OLVColumn.ButtonSizingMode.TextBounds)] public OLVColumn.ButtonSizingMode SizingMode { get { return sizingMode; } set { sizingMode = value; } } private OLVColumn.ButtonSizingMode sizingMode = OLVColumn.ButtonSizingMode.TextBounds; /// /// Gets or sets the size of the button when the SizingMode is FixedBounds /// /// If this is not set, the bounds of the cell will be used [Category("ObjectListView"), Description("The size of the button when the SizingMode is FixedBounds"), DefaultValue(null)] public Size? ButtonSize { get { return buttonSize; } set { buttonSize = value; } } private Size? buttonSize; /// /// Gets or sets the extra space that surrounds the cell when the SizingMode is TextBounds /// [Category("ObjectListView"), Description("The extra space that surrounds the cell when the SizingMode is TextBounds")] [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public Size? ButtonPadding { get { return buttonPadding; } set { buttonPadding = value; } } private Size? buttonPadding = new Size(10, 10); private Size ButtonPaddingOrDefault { get { return ButtonPadding ?? new Size(10, 10); } } /// /// Gets or sets the maximum width that a button can occupy. /// -1 means there is no maximum width. /// /// This is only considered when the SizingMode is TextBounds [Category("ObjectListView"), Description("The maximum width that a button can occupy when the SizingMode is TextBounds"), DefaultValue(-1)] public int MaxButtonWidth { get { return maxButtonWidth; } set { maxButtonWidth = value; } } private int maxButtonWidth = -1; /// /// Gets or sets the minimum width that a button can occupy. /// -1 means there is no minimum width. /// /// This is only considered when the SizingMode is TextBounds [Category("ObjectListView"), Description("The minimum width that a button can be when the SizingMode is TextBounds"), DefaultValue(-1)] public int MinButtonWidth { get { return minButtonWidth; } set { minButtonWidth = value; } } private int minButtonWidth = -1; #endregion #region Rendering /// /// Calculate the size of the contents /// /// /// /// protected override Size CalculateContentSize(Graphics g, Rectangle r) { if (SizingMode == OLVColumn.ButtonSizingMode.CellBounds) return r.Size; if (SizingMode == OLVColumn.ButtonSizingMode.FixedBounds) return ButtonSize ?? r.Size; // Ok, SizingMode must be TextBounds. So figure out the size of the text Size textSize = CalculateTextSize(g, GetText(), r.Width); // Allow for padding and max width textSize.Height += ButtonPaddingOrDefault.Height * 2; textSize.Width += ButtonPaddingOrDefault.Width * 2; if (MaxButtonWidth != -1 && textSize.Width > MaxButtonWidth) textSize.Width = MaxButtonWidth; if (textSize.Width < MinButtonWidth) textSize.Width = MinButtonWidth; return textSize; } /// /// Draw the button /// /// /// protected override void DrawImageAndText(Graphics g, Rectangle r) { TextFormatFlags textFormatFlags = TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter | TextFormatFlags.EndEllipsis | TextFormatFlags.NoPadding | TextFormatFlags.SingleLine | TextFormatFlags.PreserveGraphicsTranslateTransform; if (ListView.RightToLeftLayout) textFormatFlags |= TextFormatFlags.RightToLeft; string buttonText = GetText(); if (!String.IsNullOrEmpty(buttonText)) ButtonRenderer.DrawButton(g, r, buttonText, Font, textFormatFlags, false, CalculatePushButtonState()); } /// /// What part of the control is under the given point? /// /// /// /// /// /// protected override void StandardHitTest(Graphics g, OlvListViewHitTestInfo hti, Rectangle bounds, int x, int y) { Rectangle r = ApplyCellPadding(bounds); if (r.Contains(x, y)) hti.HitTestLocation = HitTestLocation.Button; } /// /// What is the state of the button? /// /// protected PushButtonState CalculatePushButtonState() { if (!ListItem.Enabled && !Column.EnableButtonWhenItemIsDisabled) return PushButtonState.Disabled; if (IsButtonHot) return ObjectListView.IsLeftMouseDown ? PushButtonState.Pressed : PushButtonState.Hot; return PushButtonState.Normal; } /// /// Is the mouse over the button? /// protected bool IsButtonHot { get { return IsCellHot && ListView.HotCellHitLocation == HitTestLocation.Button; } } #endregion } } ================================================ FILE: source/ObjectListView/Rendering/Styles.cs ================================================ /* * Styles - A style is a group of formatting attributes that can be applied to a row or a cell * * Author: Phillip Piper * Date: 29/07/2009 23:09 * * Change log: * v2.4 * 2010-03-23 JPP - Added HeaderFormatStyle and support * v2.3 * 2009-08-15 JPP - Added Decoration and Overlay properties to HotItemStyle * 2009-07-29 JPP - Initial version * * To do: * - These should be more generally available. It should be possible to do something like this: * this.olv.GetItem(i).Style = new ItemStyle(); * this.olv.GetItem(i).GetSubItem(j).Style = new CellStyle(); * * Copyright (C) 2009-2014 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System.ComponentModel; using System.Drawing; using System.Windows.Forms; namespace BrightIdeasSoftware { /// /// The common interface supported by all style objects /// public interface IItemStyle { /// /// Gets or set the font that will be used by this style /// Font Font { get; set; } /// /// Gets or set the font style /// FontStyle FontStyle { get; set; } /// /// Gets or sets the ForeColor /// Color ForeColor { get; set; } /// /// Gets or sets the BackColor /// Color BackColor { get; set; } } /// /// Basic implementation of IItemStyle /// public class SimpleItemStyle : Component, IItemStyle { /// /// Gets or sets the font that will be applied by this style /// [DefaultValue(null)] public Font Font { get { return font; } set { font = value; } } private Font font; /// /// Gets or sets the style of font that will be applied by this style /// [DefaultValue(FontStyle.Regular)] public FontStyle FontStyle { get { return fontStyle; } set { fontStyle = value; } } private FontStyle fontStyle; /// /// Gets or sets the color of the text that will be applied by this style /// [DefaultValue(typeof (Color), "")] public Color ForeColor { get { return foreColor; } set { foreColor = value; } } private Color foreColor; /// /// Gets or sets the background color that will be applied by this style /// [DefaultValue(typeof (Color), "")] public Color BackColor { get { return backColor; } set { backColor = value; } } private Color backColor; } /// /// Instances of this class specify how should "hot items" (non-selected /// rows under the cursor) be renderered. /// public class HotItemStyle : SimpleItemStyle { /// /// Gets or sets the overlay that should be drawn as part of the hot item /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public IOverlay Overlay { get { return overlay; } set { overlay = value; } } private IOverlay overlay; /// /// Gets or sets the decoration that should be drawn as part of the hot item /// /// A decoration is different from an overlay in that an decoration /// scrolls with the listview contents, whilst an overlay does not. [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public IDecoration Decoration { get { return decoration; } set { decoration = value; } } private IDecoration decoration; } /// /// This class defines how a cell should be formatted /// [TypeConverter(typeof(ExpandableObjectConverter))] public class CellStyle : IItemStyle { /// /// Gets or sets the font that will be applied by this style /// public Font Font { get { return font; } set { font = value; } } private Font font; /// /// Gets or sets the style of font that will be applied by this style /// [DefaultValue(FontStyle.Regular)] public FontStyle FontStyle { get { return fontStyle; } set { fontStyle = value; } } private FontStyle fontStyle; /// /// Gets or sets the color of the text that will be applied by this style /// [DefaultValue(typeof(Color), "")] public Color ForeColor { get { return foreColor; } set { foreColor = value; } } private Color foreColor; /// /// Gets or sets the background color that will be applied by this style /// [DefaultValue(typeof(Color), "")] public Color BackColor { get { return backColor; } set { backColor = value; } } private Color backColor; } /// /// Instances of this class describe how hyperlinks will appear /// public class HyperlinkStyle : Component { /// /// Create a HyperlinkStyle /// public HyperlinkStyle() { Normal = new CellStyle(); Normal.ForeColor = Color.Blue; Over = new CellStyle(); Over.FontStyle = FontStyle.Underline; Visited = new CellStyle(); Visited.ForeColor = Color.Purple; OverCursor = Cursors.Hand; } /// /// What sort of formatting should be applied to hyperlinks in their normal state? /// [Category("Appearance"), Description("How should hyperlinks be drawn")] [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public CellStyle Normal { get { return normalStyle; } set { normalStyle = value; } } private CellStyle normalStyle; /// /// What sort of formatting should be applied to hyperlinks when the mouse is over them? /// [Category("Appearance"), Description("How should hyperlinks be drawn when the mouse is over them?")] [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public CellStyle Over { get { return overStyle; } set { overStyle = value; } } private CellStyle overStyle; /// /// What sort of formatting should be applied to hyperlinks after they have been clicked? /// [Category("Appearance"), Description("How should hyperlinks be drawn after they have been clicked")] [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public CellStyle Visited { get { return visitedStyle; } set { visitedStyle = value; } } private CellStyle visitedStyle; /// /// Gets or sets the cursor that should be shown when the mouse is over a hyperlink. /// [Category("Appearance"), Description("What cursor should be shown when the mouse is over a link?")] [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public Cursor OverCursor { get { return overCursor; } set { overCursor = value; } } private Cursor overCursor; } /// /// Instances of this class control one the styling of one particular state /// (normal, hot, pressed) of a header control /// [TypeConverter(typeof(ExpandableObjectConverter))] public class HeaderStateStyle { /// /// Gets or sets the font that will be applied by this style /// [DefaultValue(null)] public Font Font { get { return font; } set { font = value; } } private Font font; /// /// Gets or sets the color of the text that will be applied by this style /// [DefaultValue(typeof(Color), "")] public Color ForeColor { get { return foreColor; } set { foreColor = value; } } private Color foreColor; /// /// Gets or sets the background color that will be applied by this style /// [DefaultValue(typeof(Color), "")] public Color BackColor { get { return backColor; } set { backColor = value; } } private Color backColor; /// /// Gets or sets the color in which a frame will be drawn around the header for this column /// [DefaultValue(typeof(Color), "")] public Color FrameColor { get { return frameColor; } set { frameColor = value; } } private Color frameColor; /// /// Gets or sets the width of the frame that will be drawn around the header for this column /// [DefaultValue(0.0f)] public float FrameWidth { get { return frameWidth; } set { frameWidth = value; } } private float frameWidth; } /// /// This class defines how a header should be formatted in its various states. /// public class HeaderFormatStyle : Component { /// /// Create a new HeaderFormatStyle /// public HeaderFormatStyle() { Hot = new HeaderStateStyle(); Normal = new HeaderStateStyle(); Pressed = new HeaderStateStyle(); } /// /// What sort of formatting should be applied to a column header when the mouse is over it? /// [Category("Appearance"), Description("How should the header be drawn when the mouse is over it?")] [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public HeaderStateStyle Hot { get { return hotStyle; } set { hotStyle = value; } } private HeaderStateStyle hotStyle; /// /// What sort of formatting should be applied to a column header in its normal state? /// [Category("Appearance"), Description("How should a column header normally be drawn")] [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public HeaderStateStyle Normal { get { return normalStyle; } set { normalStyle = value; } } private HeaderStateStyle normalStyle; /// /// What sort of formatting should be applied to a column header when pressed? /// [Category("Appearance"), Description("How should a column header be drawn when it is pressed")] [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public HeaderStateStyle Pressed { get { return pressedStyle; } set { pressedStyle = value; } } private HeaderStateStyle pressedStyle; /// /// Set the font for all three states /// /// public void SetFont(Font font) { Normal.Font = font; Hot.Font = font; Pressed.Font = font; } /// /// Set the fore color for all three states /// /// public void SetForeColor(Color color) { Normal.ForeColor = color; Hot.ForeColor = color; Pressed.ForeColor = color; } /// /// Set the back color for all three states /// /// public void SetBackColor(Color color) { Normal.BackColor = color; Hot.BackColor = color; Pressed.BackColor = color; } } } ================================================ FILE: source/ObjectListView/Rendering/TreeRenderer.cs ================================================ /* * TreeRenderer - Draw the major column in a TreeListView * * Author: Phillip Piper * Date: 27/06/2015 * * Change log: * 2016-07-17 JPP - Added TreeRenderer.UseTriangles and IsShowGlyphs * 2015-06-27 JPP - Split out from TreeListView.cs * */ using System.Collections.Generic; using System.Drawing; using System.Windows.Forms; using System.Windows.Forms.VisualStyles; using System.Drawing.Drawing2D; using System.ComponentModel; namespace BrightIdeasSoftware { public partial class TreeListView { /// /// This class handles drawing the tree structure of the primary column. /// public class TreeRenderer : HighlightTextRenderer { /// /// Create a TreeRenderer /// public TreeRenderer() { LinePen = new Pen(Color.Blue, 1.0f); LinePen.DashStyle = DashStyle.Dot; } #region Configuration properties /// /// Should the renderer draw glyphs at the expansion points? /// /// The expansion points will still function to expand/collapse even if this is false. [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public bool IsShowGlyphs { get { return isShowGlyphs; } set { isShowGlyphs = value; } } private bool isShowGlyphs = true; /// /// Should the renderer draw lines connecting siblings? /// [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public bool IsShowLines { get { return isShowLines; } set { isShowLines = value; } } private bool isShowLines = true; /// /// Return the pen that will be used to draw the lines between branches /// [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public Pen LinePen { get { return linePen; } set { linePen = value; } } private Pen linePen; /// /// Should the renderer draw triangles as the expansion glyphs? /// /// /// This looks best with ShowLines = false /// [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public bool UseTriangles { get { return useTriangles; } set { useTriangles = value; } } private bool useTriangles = false; #endregion /// /// Return the branch that the renderer is currently drawing. /// private Branch Branch { get { return TreeListView.TreeModel.GetBranch(RowObject); } } /// /// Return the TreeListView for which the renderer is being used. /// public TreeListView TreeListView { get { return (TreeListView)ListView; } } /// /// How many pixels will be reserved for each level of indentation? /// public static int PIXELS_PER_LEVEL = 16 + 1; /// /// The real work of drawing the tree is done in this method /// /// /// public override void Render(Graphics g, Rectangle r) { DrawBackground(g, r); Branch br = Branch; Rectangle paddedRectangle = ApplyCellPadding(r); Rectangle expandGlyphRectangle = paddedRectangle; expandGlyphRectangle.Offset((br.Level - 1) * PIXELS_PER_LEVEL, 0); expandGlyphRectangle.Width = PIXELS_PER_LEVEL; expandGlyphRectangle.Height = PIXELS_PER_LEVEL; expandGlyphRectangle.Y = AlignVertically(paddedRectangle, expandGlyphRectangle); int expandGlyphRectangleMidVertical = expandGlyphRectangle.Y + (expandGlyphRectangle.Height/2); if (IsShowLines) DrawLines(g, r, LinePen, br, expandGlyphRectangleMidVertical); if (br.CanExpand && IsShowGlyphs) DrawExpansionGlyph(g, expandGlyphRectangle, br.IsExpanded); int indent = br.Level * PIXELS_PER_LEVEL; paddedRectangle.Offset(indent, 0); paddedRectangle.Width -= indent; DrawImageAndText(g, paddedRectangle); } /// /// Draw the expansion indicator /// /// /// /// protected virtual void DrawExpansionGlyph(Graphics g, Rectangle r, bool isExpanded) { if (UseStyles) { DrawExpansionGlyphStyled(g, r, isExpanded); } else { DrawExpansionGlyphManual(g, r, isExpanded); } } /// /// Gets whether or not we should render using styles /// protected virtual bool UseStyles { get { return !IsPrinting && Application.RenderWithVisualStyles; } } /// /// Draw the expansion indicator using styles /// /// /// /// protected virtual void DrawExpansionGlyphStyled(Graphics g, Rectangle r, bool isExpanded) { if (UseTriangles && IsShowLines) { using (SolidBrush b = new SolidBrush(GetBackgroundColor())) { Rectangle r2 = r; r2.Inflate(-2, -2); g.FillRectangle(b, r2); } } VisualStyleRenderer renderer = new VisualStyleRenderer(DecideVisualElement(isExpanded)); renderer.DrawBackground(g, r); } private VisualStyleElement DecideVisualElement(bool isExpanded) { string klass = UseTriangles ? "Explorer::TreeView" : "TREEVIEW"; int part = UseTriangles && IsExpansionHot ? 4 : 2; int state = isExpanded ? 2 : 1; return VisualStyleElement.CreateElement(klass, part, state); } /// /// Is the mouse over a checkbox in this cell? /// protected bool IsExpansionHot { get { return IsCellHot && ListView.HotCellHitLocation == HitTestLocation.ExpandButton; } } /// /// Draw the expansion indicator without using styles /// /// /// /// protected virtual void DrawExpansionGlyphManual(Graphics g, Rectangle r, bool isExpanded) { int h = 8; int w = 8; int x = r.X + 4; int y = r.Y + (r.Height / 2) - 4; g.DrawRectangle(new Pen(SystemBrushes.ControlDark), x, y, w, h); g.FillRectangle(Brushes.White, x + 1, y + 1, w - 1, h - 1); g.DrawLine(Pens.Black, x + 2, y + 4, x + w - 2, y + 4); if (!isExpanded) g.DrawLine(Pens.Black, x + 4, y + 2, x + 4, y + h - 2); } /// /// Draw the lines of the tree /// /// /// /// /// /// protected virtual void DrawLines(Graphics g, Rectangle r, Pen p, Branch br, int glyphMidVertical) { Rectangle r2 = r; r2.Width = PIXELS_PER_LEVEL; // Vertical lines have to start on even points, otherwise the dotted line looks wrong. // This is only needed if pen is dotted. int top = r2.Top; //if (p.DashStyle == DashStyle.Dot && (top & 1) == 0) // top += 1; // Draw lines for ancestors int midX; IList ancestors = br.Ancestors; foreach (Branch ancestor in ancestors) { if (!ancestor.IsLastChild && !ancestor.IsOnlyBranch) { midX = r2.Left + r2.Width / 2; g.DrawLine(p, midX, top, midX, r2.Bottom); } r2.Offset(PIXELS_PER_LEVEL, 0); } // Draw lines for this branch midX = r2.Left + r2.Width / 2; // Horizontal line first g.DrawLine(p, midX, glyphMidVertical, r2.Right, glyphMidVertical); // Vertical line second if (br.IsFirstBranch) { if (!br.IsLastChild && !br.IsOnlyBranch) g.DrawLine(p, midX, glyphMidVertical, midX, r2.Bottom); } else { if (br.IsLastChild) g.DrawLine(p, midX, top, midX, glyphMidVertical); else g.DrawLine(p, midX, top, midX, r2.Bottom); } } /// /// Do the hit test /// /// /// /// /// protected override void HandleHitTest(Graphics g, OlvListViewHitTestInfo hti, int x, int y) { Branch br = Branch; Rectangle r = ApplyCellPadding(Bounds); if (br.CanExpand) { r.Offset((br.Level - 1) * PIXELS_PER_LEVEL, 0); r.Width = PIXELS_PER_LEVEL; if (r.Contains(x, y)) { hti.HitTestLocation = HitTestLocation.ExpandButton; return; } } r = Bounds; int indent = br.Level * PIXELS_PER_LEVEL; r.X += indent; r.Width -= indent; // Ignore events in the indent zone if (x < r.Left) { hti.HitTestLocation = HitTestLocation.Nothing; } else { StandardHitTest(g, hti, r, x, y); } } /// /// Calculate the edit rect /// /// /// /// /// /// /// protected override Rectangle HandleGetEditRectangle(Graphics g, Rectangle cellBounds, OLVListItem item, int subItemIndex, Size preferredSize) { return StandardGetEditRectangle(g, cellBounds, preferredSize); } } } } ================================================ FILE: source/ObjectListView/SubControls/GlassPanelForm.cs ================================================ /* * GlassPanelForm - A transparent form that is placed over an ObjectListView * to allow flicker-free overlay images during scrolling. * * Author: Phillip Piper * Date: 14/04/2009 4:36 PM * * Change log: * 2010-08-18 JPP - Added WS_EX_TOOLWINDOW style so that the form won't appear in Alt-Tab list. * v2.4 * 2010-03-11 JPP - Work correctly in MDI applications -- more or less. Actually, less than more. * They don't crash but they don't correctly handle overlapping MDI children. * Overlays from one control are shown on top of other other windows. * 2010-03-09 JPP - Correctly Unbind() when the related ObjectListView is disposed. * 2009-10-28 JPP - Use FindForm() rather than TopMostControl, since the latter doesn't work * as I expected when the OLV is part of an MDI child window. Thanks to * wvd_vegt who tracked this down. * v2.3 * 2009-08-19 JPP - Only hide the glass pane on resize, not on move * - Each glass panel now only draws one overlays * v2.2 * 2009-06-05 JPP - Handle when owning window is a topmost window * 2009-04-14 JPP - Initial version * * To do: * * Copyright (C) 2009-2014 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System; using System.Collections.Generic; using System.Drawing; using System.Windows.Forms; namespace BrightIdeasSoftware { /// /// A GlassPanelForm sits transparently over an ObjectListView to show overlays. /// internal partial class GlassPanelForm : Form { public GlassPanelForm() { Name = "GlassPanelForm"; Text = "GlassPanelForm"; ClientSize = new Size(0, 0); ControlBox = false; FormBorderStyle = FormBorderStyle.None; SizeGripStyle = SizeGripStyle.Hide; StartPosition = FormStartPosition.Manual; MaximizeBox = false; MinimizeBox = false; ShowIcon = false; ShowInTaskbar = false; FormBorderStyle = FormBorderStyle.None; SetStyle(ControlStyles.Selectable, false); Opacity = 0.5f; BackColor = Color.FromArgb(255, 254, 254, 254); TransparencyKey = BackColor; HideGlass(); NativeMethods.ShowWithoutActivate(this); } protected override void Dispose(bool disposing) { if (disposing) Unbind(); base.Dispose(disposing); } #region Properties /// /// Get the low-level windows flag that will be given to CreateWindow. /// protected override CreateParams CreateParams { get { CreateParams cp = base.CreateParams; cp.ExStyle |= 0x20; // WS_EX_TRANSPARENT cp.ExStyle |= 0x80; // WS_EX_TOOLWINDOW return cp; } } #endregion #region Commands /// /// Attach this form to the given ObjectListView /// public void Bind(ObjectListView olv, IOverlay overlay) { if (objectListView != null) Unbind(); objectListView = olv; Overlay = overlay; mdiClient = null; mdiOwner = null; if (objectListView == null) return; // NOTE: If you listen to any events here, you *must* stop listening in Unbind() objectListView.Disposed += new EventHandler(objectListView_Disposed); objectListView.LocationChanged += new EventHandler(objectListView_LocationChanged); objectListView.SizeChanged += new EventHandler(objectListView_SizeChanged); objectListView.VisibleChanged += new EventHandler(objectListView_VisibleChanged); objectListView.ParentChanged += new EventHandler(objectListView_ParentChanged); // Collect our ancestors in the widget hierachy if (ancestors == null) ancestors = new List(); Control parent = objectListView.Parent; while (parent != null) { ancestors.Add(parent); parent = parent.Parent; } // Listen for changes in the hierachy foreach (Control ancestor in ancestors) { ancestor.ParentChanged += new EventHandler(objectListView_ParentChanged); if (ancestor is TabControl tabControl) { tabControl.Selected += new TabControlEventHandler(tabControl_Selected); } } // Listen for changes in our owning form Owner = objectListView.FindForm(); myOwner = Owner; if (Owner != null) { Owner.LocationChanged += new EventHandler(Owner_LocationChanged); Owner.SizeChanged += new EventHandler(Owner_SizeChanged); Owner.ResizeBegin += new EventHandler(Owner_ResizeBegin); Owner.ResizeEnd += new EventHandler(Owner_ResizeEnd); if (Owner.TopMost) { // We can't do this.TopMost = true; since that will activate the panel, // taking focus away from the owner of the listview NativeMethods.MakeTopMost(this); } // We need special code to handle MDI mdiOwner = Owner.MdiParent; if (mdiOwner != null) { mdiOwner.LocationChanged += new EventHandler(Owner_LocationChanged); mdiOwner.SizeChanged += new EventHandler(Owner_SizeChanged); mdiOwner.ResizeBegin += new EventHandler(Owner_ResizeBegin); mdiOwner.ResizeEnd += new EventHandler(Owner_ResizeEnd); // Find the MDIClient control, which houses all MDI children foreach (Control c in mdiOwner.Controls) { mdiClient = c as MdiClient; if (mdiClient != null) { break; } } if (mdiClient != null) { mdiClient.ClientSizeChanged += new EventHandler(myMdiClient_ClientSizeChanged); } } } UpdateTransparency(); } void myMdiClient_ClientSizeChanged(object sender, EventArgs e) { RecalculateBounds(); Invalidate(); } /// /// Made the overlay panel invisible /// public void HideGlass() { if (!isGlassShown) return; isGlassShown = false; Bounds = new Rectangle(-10000, -10000, 1, 1); } /// /// Show the overlay panel in its correctly location /// /// /// If the panel is always shown, this method does nothing. /// If the panel is being resized, this method also does nothing. /// public void ShowGlass() { if (isGlassShown || isDuringResizeSequence) return; isGlassShown = true; RecalculateBounds(); } /// /// Detach this glass panel from its previous ObjectListView /// /// /// You should unbind the overlay panel before making any changes to the /// widget hierarchy. /// public void Unbind() { if (objectListView != null) { objectListView.Disposed -= new EventHandler(objectListView_Disposed); objectListView.LocationChanged -= new EventHandler(objectListView_LocationChanged); objectListView.SizeChanged -= new EventHandler(objectListView_SizeChanged); objectListView.VisibleChanged -= new EventHandler(objectListView_VisibleChanged); objectListView.ParentChanged -= new EventHandler(objectListView_ParentChanged); objectListView = null; } if (ancestors != null) { foreach (Control parent in ancestors) { parent.ParentChanged -= new EventHandler(objectListView_ParentChanged); if (parent is TabControl tabControl) { tabControl.Selected -= new TabControlEventHandler(tabControl_Selected); } } ancestors = null; } if (myOwner != null) { myOwner.LocationChanged -= new EventHandler(Owner_LocationChanged); myOwner.SizeChanged -= new EventHandler(Owner_SizeChanged); myOwner.ResizeBegin -= new EventHandler(Owner_ResizeBegin); myOwner.ResizeEnd -= new EventHandler(Owner_ResizeEnd); myOwner = null; } if (mdiOwner != null) { mdiOwner.LocationChanged -= new EventHandler(Owner_LocationChanged); mdiOwner.SizeChanged -= new EventHandler(Owner_SizeChanged); mdiOwner.ResizeBegin -= new EventHandler(Owner_ResizeBegin); mdiOwner.ResizeEnd -= new EventHandler(Owner_ResizeEnd); mdiOwner = null; } if (mdiClient != null) { mdiClient.ClientSizeChanged -= new EventHandler(myMdiClient_ClientSizeChanged); mdiClient = null; } } #endregion #region Event Handlers void objectListView_Disposed(object sender, EventArgs e) { Unbind(); } /// /// Handle when the form that owns the ObjectListView begins to be resized /// /// /// void Owner_ResizeBegin(object sender, EventArgs e) { // When the top level window is being resized, we just want to hide // the overlay window. When the resizing finishes, we want to show // the overlay window, if it was shown before the resize started. isDuringResizeSequence = true; wasGlassShownBeforeResize = isGlassShown; } /// /// Handle when the form that owns the ObjectListView finished to be resized /// /// /// void Owner_ResizeEnd(object sender, EventArgs e) { isDuringResizeSequence = false; if (wasGlassShownBeforeResize) ShowGlass(); } /// /// The owning form has moved. Move the overlay panel too. /// /// /// void Owner_LocationChanged(object sender, EventArgs e) { if (mdiOwner != null) HideGlass(); else RecalculateBounds(); } /// /// The owning form is resizing. Hide our overlay panel until the resizing stops /// /// /// void Owner_SizeChanged(object sender, EventArgs e) { HideGlass(); } /// /// Handle when the bound OLV changes its location. The overlay panel must /// be moved too, IFF it is currently visible. /// /// /// void objectListView_LocationChanged(object sender, EventArgs e) { if (isGlassShown) { RecalculateBounds(); } } /// /// Handle when the bound OLV changes size. The overlay panel must /// resize too, IFF it is currently visible. /// /// /// void objectListView_SizeChanged(object sender, EventArgs e) { // This event is triggered in all sorts of places, and not always when the size changes. //if (this.isGlassShown) { // this.Size = this.objectListView.ClientSize; //} } /// /// Handle when the bound OLV is part of a TabControl and that /// TabControl changes tabs. The overlay panel is hidden. The /// first time the bound OLV is redrawn, the overlay panel will /// be shown again. /// /// /// void tabControl_Selected(object sender, TabControlEventArgs e) { HideGlass(); } /// /// Somewhere the parent of the bound OLV has changed. Update /// our events. /// /// /// void objectListView_ParentChanged(object sender, EventArgs e) { ObjectListView olv = objectListView; IOverlay overlay = Overlay; Unbind(); Bind(olv, overlay); } /// /// Handle when the bound OLV changes its visibility. /// The overlay panel should match the OLV's visibility. /// /// /// void objectListView_VisibleChanged(object sender, EventArgs e) { if (objectListView.Visible) ShowGlass(); else HideGlass(); } #endregion #region Implementation protected override void OnPaint(PaintEventArgs e) { if (objectListView == null || Overlay == null) return; Graphics g = e.Graphics; g.TextRenderingHint = ObjectListView.TextRenderingHint; g.SmoothingMode = ObjectListView.SmoothingMode; //g.DrawRectangle(new Pen(Color.Green, 4.0f), this.ClientRectangle); // If we are part of an MDI app, make sure we don't draw outside the bounds if (mdiClient != null) { Rectangle r = mdiClient.RectangleToScreen(mdiClient.ClientRectangle); Rectangle r2 = objectListView.RectangleToClient(r); g.SetClip(r2, System.Drawing.Drawing2D.CombineMode.Intersect); } Overlay.Draw(objectListView, g, objectListView.ClientRectangle); } protected void RecalculateBounds() { if (!isGlassShown) return; Rectangle rect = objectListView.ClientRectangle; rect.X = 0; rect.Y = 0; Bounds = objectListView.RectangleToScreen(rect); } internal void UpdateTransparency() { if (Overlay is not ITransparentOverlay transparentOverlay) Opacity = objectListView.OverlayTransparency / 255.0f; else Opacity = transparentOverlay.Transparency / 255.0f; } protected override void WndProc(ref Message m) { const int WM_NCHITTEST = 132; const int HTTRANSPARENT = -1; switch (m.Msg) { // Ignore all mouse interactions case WM_NCHITTEST: m.Result = (IntPtr)HTTRANSPARENT; break; } base.WndProc(ref m); } #endregion #region Implementation variables internal IOverlay Overlay; #endregion #region Private variables private ObjectListView objectListView; private bool isDuringResizeSequence; private bool isGlassShown; private bool wasGlassShownBeforeResize; // Cache these so we can unsubscribe from events even when the OLV has been disposed. private Form myOwner; private Form mdiOwner; private List ancestors; MdiClient mdiClient; #endregion } } ================================================ FILE: source/ObjectListView/SubControls/HeaderControl.cs ================================================ /* * HeaderControl - A limited implementation of HeaderControl * * Author: Phillip Piper * Date: 25/11/2008 17:15 * * Change log: * 2015-06-12 JPP - Use HeaderTextAlignOrDefault instead of HeaderTextAlign * 2014-09-07 JPP - Added ability to have checkboxes in headers * * 2011-05-11 JPP - Fixed bug that prevented columns from being resized in IDE Designer * by dragging the column divider * 2011-04-12 JPP - Added ability to draw filter indicator in a column's header * v2.4.1 * 2010-08-23 JPP - Added ability to draw header vertically (thanks to Mark Fenwick) * - Uses OLVColumn.HeaderTextAlign to decide how to align the column's header * 2010-08-08 JPP - Added ability to have image in header * v2.4 * 2010-03-22 JPP - Draw header using header styles * 2009-10-30 JPP - Plugged GDI resource leak, where font handles were created during custom * drawing, but never destroyed * v2.3 * 2009-10-03 JPP - Handle when ListView.HeaderFormatStyle is None * 2009-08-24 JPP - Handle the header being destroyed * v2.2.1 * 2009-08-16 JPP - Correctly handle header themes * 2009-08-15 JPP - Added formatting capabilities: font, color, word wrap * v2.2 * 2009-06-01 JPP - Use ToolTipControl * 2009-05-10 JPP - Removed all unsafe code * 2008-11-25 JPP - Initial version * * TO DO: * - Put drawing code into header style object, so that it can be easily customized. * * Copyright (C) 2006-2014 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System; using System.Drawing; using System.Windows.Forms; using System.Runtime.InteropServices; using System.Windows.Forms.VisualStyles; using System.Drawing.Drawing2D; using BrightIdeasSoftware.Properties; namespace BrightIdeasSoftware { /// /// Class used to capture window messages for the header of the list view /// control. /// public class HeaderControl : NativeWindow { /// /// Create a header control for the given ObjectListView. /// /// public HeaderControl(ObjectListView olv) { ListView = olv; AssignHandle(NativeMethods.GetHeaderControl(olv)); } #region Properties /// /// Return the index of the column under the current cursor position, /// or -1 if the cursor is not over a column /// /// Index of the column under the cursor, or -1 public int ColumnIndexUnderCursor { get { Point pt = ScrolledCursorPosition; return NativeMethods.GetColumnUnderPoint(Handle, pt); } } /// /// Return the Windows handle behind this control /// /// /// When an ObjectListView is initialized as part of a UserControl, the /// GetHeaderControl() method returns 0 until the UserControl is /// completely initialized. So the AssignHandle() call in the constructor /// doesn't work. So we override the Handle property so value is always /// current. /// public new IntPtr Handle { get { return NativeMethods.GetHeaderControl(ListView); } } //TODO: The Handle property may no longer be necessary. CHECK! 2008/11/28 /// /// Gets or sets a style that should be applied to the font of the /// column's header text when the mouse is over that column /// /// THIS IS EXPERIMENTAL. USE AT OWN RISK. August 2009 [Obsolete("Use HeaderStyle.Hot.FontStyle instead")] public FontStyle HotFontStyle { get { return FontStyle.Regular; } set { } } /// /// Gets the index of the column under the cursor if the cursor is over it's checkbox /// protected int GetColumnCheckBoxUnderCursor() { Point pt = ScrolledCursorPosition; int columnIndex = NativeMethods.GetColumnUnderPoint(Handle, pt); return IsPointOverHeaderCheckBox(columnIndex, pt) ? columnIndex : -1; } /// /// Gets the client rectangle for the header /// public Rectangle ClientRectangle { get { Rectangle r = new Rectangle(); NativeMethods.GetClientRect(Handle, ref r); return r; } } /// /// Return true if the given point is over the checkbox for the given column. /// /// /// /// protected bool IsPointOverHeaderCheckBox(int columnIndex, Point pt) { if (columnIndex < 0 || columnIndex >= ListView.Columns.Count) return false; OLVColumn column = ListView.GetColumn(columnIndex); if (!HasCheckBox(column)) return false; Rectangle r = GetCheckBoxBounds(column); r.Inflate(1, 1); // make the target slightly bigger return r.Contains(pt); } /// /// Gets whether the cursor is over a "locked" divider, i.e. /// one that cannot be dragged by the user. /// protected bool IsCursorOverLockedDivider { get { Point pt = ScrolledCursorPosition; int dividerIndex = NativeMethods.GetDividerUnderPoint(Handle, pt); if (dividerIndex >= 0 && dividerIndex < ListView.Columns.Count) { OLVColumn column = ListView.GetColumn(dividerIndex); return column.IsFixedWidth || column.FillsFreeSpace; } else return false; } } private Point ScrolledCursorPosition { get { Point pt = ListView.PointToClient(Cursor.Position); pt.X += ListView.LowLevelScrollPosition.X; return pt; } } /// /// Gets or sets the listview that this header belongs to /// protected ObjectListView ListView { get { return listView; } set { listView = value; } } private ObjectListView listView; /// /// Gets the maximum height of the header. -1 means no maximum. /// public int MaximumHeight { get { return ListView.HeaderMaximumHeight; } } /// /// Gets the minimum height of the header. -1 means no minimum. /// public int MinimumHeight { get { return ListView.HeaderMinimumHeight; } } /// /// Get or set the ToolTip that shows tips for the header /// public ToolTipControl ToolTip { get { if (toolTip == null) { CreateToolTip(); } return toolTip; } protected set { toolTip = value; } } private ToolTipControl toolTip; /// /// Gets or sets whether the text in column headers should be word /// wrapped when it is too long to fit within the column /// public bool WordWrap { get { return wordWrap; } set { wordWrap = value; } } private bool wordWrap; #endregion #region Commands /// /// Calculate how height the header needs to be /// /// Height in pixels protected int CalculateHeight(Graphics g) { TextFormatFlags flags = TextFormatFlags; int columnUnderCursor = ColumnIndexUnderCursor; float height = MinimumHeight; for (int i = 0; i < ListView.Columns.Count; i++) { OLVColumn column = ListView.GetColumn(i); height = Math.Max(height, CalculateColumnHeight(g, column, flags, columnUnderCursor == i, i)); } return MaximumHeight == -1 ? (int) height : Math.Min(MaximumHeight, (int) height); } private float CalculateColumnHeight(Graphics g, OLVColumn column, TextFormatFlags flags, bool isHot, int i) { Font f = CalculateFont(column, isHot, false); if (column.IsHeaderVertical) return TextRenderer.MeasureText(g, column.Text, f, new Size(10000, 10000), flags).Width; const int fudge = 9; // 9 is a magic constant that makes it perfectly match XP behavior if (!WordWrap) return f.Height + fudge; Rectangle r = GetHeaderDrawRect(i); if (HasNonThemedSortIndicator(column)) r.Width -= 16; if (column.HasHeaderImage) r.Width -= column.ImageList.ImageSize.Width + 3; if (HasFilterIndicator(column)) r.Width -= CalculateFilterIndicatorWidth(r); if (HasCheckBox(column)) r.Width -= CalculateCheckBoxBounds(g, r).Width; SizeF size = TextRenderer.MeasureText(g, column.Text, f, new Size(r.Width, 100), flags); return size.Height + fudge; } /// /// Get the bounds of the checkbox against the given column /// /// /// public Rectangle GetCheckBoxBounds(OLVColumn column) { Rectangle r = GetHeaderDrawRect(column.Index); using (Graphics g = ListView.CreateGraphics()) return CalculateCheckBoxBounds(g, r); } /// /// Should the given column be drawn with a checkbox against it? /// /// /// public bool HasCheckBox(OLVColumn column) { return column.HeaderCheckBox || column.HeaderTriStateCheckBox; } /// /// Should the given column show a sort indicator? /// /// /// protected bool HasSortIndicator(OLVColumn column) { if (!ListView.ShowSortIndicators) return false; return column == ListView.LastSortColumn && ListView.LastSortOrder != SortOrder.None; } /// /// Should the given column be drawn with a filter indicator against it? /// /// /// protected bool HasFilterIndicator(OLVColumn column) { return (ListView.UseFiltering && ListView.UseFilterIndicator && column.HasFilterIndicator); } /// /// Should the given column show a non-themed sort indicator? /// /// /// protected bool HasNonThemedSortIndicator(OLVColumn column) { if (!ListView.ShowSortIndicators) return false; if (VisualStyleRenderer.IsSupported) return !VisualStyleRenderer.IsElementDefined(VisualStyleElement.Header.SortArrow.SortedUp) && HasSortIndicator(column); else return HasSortIndicator(column); } /// /// Return the bounds of the item with the given index /// /// /// public Rectangle GetItemRect(int itemIndex) { const int HDM_FIRST = 0x1200; const int HDM_GETITEMRECT = HDM_FIRST + 7; NativeMethods.RECT r = new NativeMethods.RECT(); NativeMethods.SendMessageRECT(Handle, HDM_GETITEMRECT, itemIndex, ref r); return Rectangle.FromLTRB(r.left, r.top, r.right, r.bottom); } /// /// Return the bounds within which the given column will be drawn /// /// /// public Rectangle GetHeaderDrawRect(int itemIndex) { Rectangle r = GetItemRect(itemIndex); // Tweak the text rectangle a little to improve aethestics r.Inflate(-3, 0); r.Y -= 2; return r; } /// /// Force the header to redraw by invalidating it /// public void Invalidate() { NativeMethods.InvalidateRect(Handle, 0, true); } /// /// Force the header to redraw a single column by invalidating it /// public void Invalidate(OLVColumn column) { NativeMethods.InvalidateRect(Handle, 0, true); // todo } #endregion #region Tooltip /// /// Create a native tool tip control for this listview /// protected virtual void CreateToolTip() { ToolTip = new ToolTipControl(); ToolTip.Create(Handle); ToolTip.AddTool(this); ToolTip.Showing += new EventHandler(ListView.HeaderToolTipShowingCallback); } #endregion #region Windows messaging /// /// Override the basic message pump /// /// protected override void WndProc(ref Message m) { const int WM_DESTROY = 2; const int WM_SETCURSOR = 0x20; const int WM_NOTIFY = 0x4E; const int WM_MOUSEMOVE = 0x200; const int WM_LBUTTONDOWN = 0x201; const int WM_LBUTTONUP = 0x202; const int WM_MOUSELEAVE = 675; const int HDM_FIRST = 0x1200; const int HDM_LAYOUT = (HDM_FIRST + 5); // System.Diagnostics.Debug.WriteLine(String.Format("WndProc: {0}", m.Msg)); switch (m.Msg) { case WM_SETCURSOR: if (!HandleSetCursor(ref m)) return; break; case WM_NOTIFY: if (!HandleNotify(ref m)) return; break; case WM_MOUSEMOVE: if (!HandleMouseMove(ref m)) return; break; case WM_MOUSELEAVE: if (!HandleMouseLeave(ref m)) return; break; case HDM_LAYOUT: if (!HandleLayout(ref m)) return; break; case WM_DESTROY: if (!HandleDestroy(ref m)) return; break; case WM_LBUTTONDOWN: if (!HandleLButtonDown(ref m)) return; break; case WM_LBUTTONUP: if (!HandleLButtonUp(ref m)) return; break; } base.WndProc(ref m); } private bool HandleReflectNotify(ref Message m) { NativeMethods.NMHDR nmhdr = (NativeMethods.NMHDR)m.GetLParam(typeof(NativeMethods.NMHDR)); System.Diagnostics.Debug.WriteLine(String.Format("rn: {0}", nmhdr.code)); return true; } /// /// Handle the LButtonDown windows message /// /// /// protected bool HandleLButtonDown(ref Message m) { // Was there a header checkbox under the cursor? columnIndexCheckBoxMouseDown = GetColumnCheckBoxUnderCursor(); if (columnIndexCheckBoxMouseDown < 0) return true; // Redraw the header so the checkbox redraws Invalidate(); // Force the owning control to ignore this mouse click // We don't want to sort the listview when they click the checkbox m.Result = (IntPtr)1; return false; } private int columnIndexCheckBoxMouseDown = -1; /// /// Handle the LButtonUp windows message /// /// /// protected bool HandleLButtonUp(ref Message m) { //System.Diagnostics.Debug.WriteLine("WM_LBUTTONUP"); // Was the mouse released over a header checkbox? if (columnIndexCheckBoxMouseDown < 0) return true; // Was the mouse released over the same checkbox on which it was pressed? if (columnIndexCheckBoxMouseDown != GetColumnCheckBoxUnderCursor()) return true; // Toggle the header's checkbox OLVColumn column = ListView.GetColumn(columnIndexCheckBoxMouseDown); ListView.ToggleHeaderCheckBox(column); return true; } /// /// Handle the SetCursor windows message /// /// /// protected bool HandleSetCursor(ref Message m) { if (IsCursorOverLockedDivider) { m.Result = (IntPtr) 1; // Don't change the cursor return false; } return true; } /// /// Handle the MouseMove windows message /// /// /// protected bool HandleMouseMove(ref Message m) { // Forward the mouse move event to the ListView itself if (ListView.TriggerCellOverEventsWhenOverHeader) { int x = m.LParam.ToInt32() & 0xFFFF; int y = (m.LParam.ToInt32() >> 16) & 0xFFFF; ListView.HandleMouseMove(new Point(x, y)); } int columnIndex = ColumnIndexUnderCursor; // If the mouse has moved to a different header, pop the current tip (if any) // For some reason, references this.ToolTip when in design mode, causes the // columns to not be resizable by dragging the divider in the Designer. No idea why. if (columnIndex != columnShowingTip && !ListView.IsDesignMode) { ToolTip.PopToolTip(this); columnShowingTip = columnIndex; } // If the mouse has moved onto or away from a checkbox, we need to draw int checkBoxUnderCursor = GetColumnCheckBoxUnderCursor(); if (checkBoxUnderCursor != lastCheckBoxUnderCursor) { Invalidate(); lastCheckBoxUnderCursor = checkBoxUnderCursor; } return true; } private int columnShowingTip = -1; private int lastCheckBoxUnderCursor = -1; /// /// Handle the MouseLeave windows message /// /// /// protected bool HandleMouseLeave(ref Message m) { // Forward the mouse leave event to the ListView itself if (ListView.TriggerCellOverEventsWhenOverHeader) ListView.HandleMouseMove(new Point(-1, -1)); return true; } /// /// Handle the Notify windows message /// /// /// protected bool HandleNotify(ref Message m) { // Can this ever happen? JPP 2009-05-22 if (m.LParam == IntPtr.Zero) return false; NativeMethods.NMHDR nmhdr = (NativeMethods.NMHDR)m.GetLParam(typeof(NativeMethods.NMHDR)); switch (nmhdr.code) { case ToolTipControl.TTN_SHOW: //System.Diagnostics.Debug.WriteLine("hdr TTN_SHOW"); //System.Diagnostics.Trace.Assert(this.ToolTip.Handle == nmhdr.hwndFrom); return ToolTip.HandleShow(ref m); case ToolTipControl.TTN_POP: //System.Diagnostics.Debug.WriteLine("hdr TTN_POP"); //System.Diagnostics.Trace.Assert(this.ToolTip.Handle == nmhdr.hwndFrom); return ToolTip.HandlePop(ref m); case ToolTipControl.TTN_GETDISPINFO: //System.Diagnostics.Debug.WriteLine("hdr TTN_GETDISPINFO"); //System.Diagnostics.Trace.Assert(this.ToolTip.Handle == nmhdr.hwndFrom); return ToolTip.HandleGetDispInfo(ref m); } return false; } /// /// Handle the CustomDraw windows message /// /// /// internal virtual bool HandleHeaderCustomDraw(ref Message m) { const int CDRF_NEWFONT = 2; const int CDRF_SKIPDEFAULT = 4; const int CDRF_NOTIFYPOSTPAINT = 0x10; const int CDRF_NOTIFYITEMDRAW = 0x20; const int CDDS_PREPAINT = 1; const int CDDS_POSTPAINT = 2; const int CDDS_ITEM = 0x00010000; const int CDDS_ITEMPREPAINT = (CDDS_ITEM | CDDS_PREPAINT); const int CDDS_ITEMPOSTPAINT = (CDDS_ITEM | CDDS_POSTPAINT); NativeMethods.NMCUSTOMDRAW nmcustomdraw = (NativeMethods.NMCUSTOMDRAW) m.GetLParam(typeof (NativeMethods.NMCUSTOMDRAW)); //System.Diagnostics.Debug.WriteLine(String.Format("header cd: {0:x}, {1}, {2:x}", nmcustomdraw.dwDrawStage, nmcustomdraw.dwItemSpec, nmcustomdraw.uItemState)); switch (nmcustomdraw.dwDrawStage) { case CDDS_PREPAINT: cachedNeedsCustomDraw = NeedsCustomDraw(); m.Result = (IntPtr) CDRF_NOTIFYITEMDRAW; return true; case CDDS_ITEMPREPAINT: int columnIndex = nmcustomdraw.dwItemSpec.ToInt32(); OLVColumn column = ListView.GetColumn(columnIndex); // These don't work when visual styles are enabled //NativeMethods.SetBkColor(nmcustomdraw.hdc, ColorTranslator.ToWin32(Color.Red)); //NativeMethods.SetTextColor(nmcustomdraw.hdc, ColorTranslator.ToWin32(Color.Blue)); //m.Result = IntPtr.Zero; if (cachedNeedsCustomDraw) { using (Graphics g = Graphics.FromHdc(nmcustomdraw.hdc)) { g.TextRenderingHint = ObjectListView.TextRenderingHint; CustomDrawHeaderCell(g, columnIndex, nmcustomdraw.uItemState); } m.Result = (IntPtr) CDRF_SKIPDEFAULT; } else { const int CDIS_SELECTED = 1; bool isPressed = ((nmcustomdraw.uItemState & CDIS_SELECTED) == CDIS_SELECTED); // We don't need to modify this based on checkboxes, since there can't be checkboxes if we are here bool isHot = columnIndex == ColumnIndexUnderCursor; Font f = CalculateFont(column, isHot, isPressed); fontHandle = f.ToHfont(); NativeMethods.SelectObject(nmcustomdraw.hdc, fontHandle); m.Result = (IntPtr) (CDRF_NEWFONT | CDRF_NOTIFYPOSTPAINT); } return true; case CDDS_ITEMPOSTPAINT: if (fontHandle != IntPtr.Zero) { NativeMethods.DeleteObject(fontHandle); fontHandle = IntPtr.Zero; } break; } return false; } private bool cachedNeedsCustomDraw; private IntPtr fontHandle; /// /// The message divides a ListView's space between the header and the rows of the listview. /// The WINDOWPOS structure controls the headers bounds, the RECT controls the listview bounds. /// /// /// protected bool HandleLayout(ref Message m) { if (ListView.HeaderStyle == ColumnHeaderStyle.None) return true; NativeMethods.HDLAYOUT hdlayout = (NativeMethods.HDLAYOUT) m.GetLParam(typeof (NativeMethods.HDLAYOUT)); NativeMethods.RECT rect = (NativeMethods.RECT) Marshal.PtrToStructure(hdlayout.prc, typeof (NativeMethods.RECT)); NativeMethods.WINDOWPOS wpos = (NativeMethods.WINDOWPOS) Marshal.PtrToStructure(hdlayout.pwpos, typeof (NativeMethods.WINDOWPOS)); using (Graphics g = ListView.CreateGraphics()) { g.TextRenderingHint = ObjectListView.TextRenderingHint; int height = CalculateHeight(g); wpos.hwnd = Handle; wpos.hwndInsertAfter = IntPtr.Zero; wpos.flags = NativeMethods.SWP_FRAMECHANGED; wpos.x = rect.left; wpos.y = rect.top; wpos.cx = rect.right - rect.left; wpos.cy = height; rect.top = height; Marshal.StructureToPtr(rect, hdlayout.prc, false); Marshal.StructureToPtr(wpos, hdlayout.pwpos, false); } ListView.BeginInvoke((MethodInvoker) delegate { Invalidate(); ListView.Invalidate(); }); return false; } /// /// Handle when the underlying header control is destroyed /// /// /// protected bool HandleDestroy(ref Message m) { if (toolTip != null) { toolTip.Showing -= new EventHandler(ListView.HeaderToolTipShowingCallback); } return false; } #endregion #region Rendering /// /// Does this header need to be custom drawn? /// /// Word wrapping and colored text require custom drawning. Funnily enough, we /// can change the font natively. protected bool NeedsCustomDraw() { if (WordWrap) return true; if (ListView.HeaderUsesThemes) return false; if (NeedsCustomDraw(ListView.HeaderFormatStyle)) return true; foreach (OLVColumn column in ListView.Columns) { if (column.HasHeaderImage || !column.ShowTextInHeader || column.IsHeaderVertical || HasFilterIndicator(column) || HasCheckBox(column) || column.TextAlign != column.HeaderTextAlignOrDefault || (column.Index == 0 && column.HeaderTextAlignOrDefault != HorizontalAlignment.Left) || NeedsCustomDraw(column.HeaderFormatStyle)) return true; } return false; } private bool NeedsCustomDraw(HeaderFormatStyle style) { if (style == null) return false; return (NeedsCustomDraw(style.Normal) || NeedsCustomDraw(style.Hot) || NeedsCustomDraw(style.Pressed)); } private bool NeedsCustomDraw(HeaderStateStyle style) { if (style == null) return false; // If we want fancy colors or frames, we have to custom draw. Oddly enough, we // can handle font changes without custom drawing. if (!style.BackColor.IsEmpty) return true; if (style.FrameWidth > 0f && !style.FrameColor.IsEmpty) return true; return (!style.ForeColor.IsEmpty && style.ForeColor != Color.Black); } /// /// Draw one cell of the header /// /// /// /// protected void CustomDrawHeaderCell(Graphics g, int columnIndex, int itemState) { OLVColumn column = ListView.GetColumn(columnIndex); bool hasCheckBox = HasCheckBox(column); bool isMouseOverCheckBox = columnIndex == lastCheckBoxUnderCursor; bool isMouseDownOnCheckBox = isMouseOverCheckBox && Control.MouseButtons == MouseButtons.Left; bool isHot = (columnIndex == ColumnIndexUnderCursor) && (!(hasCheckBox && isMouseOverCheckBox)); const int CDIS_SELECTED = 1; bool isPressed = ((itemState & CDIS_SELECTED) == CDIS_SELECTED); // System.Diagnostics.Debug.WriteLine(String.Format("{2:hh:mm:ss.ff} - HeaderCustomDraw: {0}, {1}", columnIndex, itemState, DateTime.Now)); // Calculate which style should be used for the header HeaderStateStyle stateStyle = CalculateStateStyle(column, isHot, isPressed); // If there is an owner drawn delegate installed, give it a chance to draw the header Rectangle fullCellBounds = GetItemRect(columnIndex); if (column.HeaderDrawing != null) { if (!column.HeaderDrawing(g, fullCellBounds, columnIndex, column, isPressed, stateStyle)) return; } // Draw the background if (ListView.HeaderUsesThemes && VisualStyleRenderer.IsSupported && VisualStyleRenderer.IsElementDefined(VisualStyleElement.Header.Item.Normal)) DrawThemedBackground(g, fullCellBounds, columnIndex, isPressed, isHot); else DrawUnthemedBackground(g, fullCellBounds, columnIndex, isPressed, isHot, stateStyle); Rectangle r = GetHeaderDrawRect(columnIndex); // Draw the sort indicator if this column has one if (HasSortIndicator(column)) { if (ListView.HeaderUsesThemes && VisualStyleRenderer.IsSupported && VisualStyleRenderer.IsElementDefined(VisualStyleElement.Header.SortArrow.SortedUp)) DrawThemedSortIndicator(g, r); else r = DrawUnthemedSortIndicator(g, r); } if (HasFilterIndicator(column)) r = DrawFilterIndicator(g, r); if (hasCheckBox) r = DrawCheckBox(g, r, column.HeaderCheckState, column.HeaderCheckBoxDisabled, isMouseOverCheckBox, isMouseDownOnCheckBox); // Debugging - Where is the text going to be drawn // g.DrawRectangle(Pens.Blue, r); // Finally draw the text DrawHeaderImageAndText(g, r, column, stateStyle); } private Rectangle DrawCheckBox(Graphics g, Rectangle r, CheckState checkState, bool isDisabled, bool isHot, bool isPressed) { CheckBoxState checkBoxState = GetCheckBoxState(checkState, isDisabled, isHot, isPressed); Rectangle checkBoxBounds = CalculateCheckBoxBounds(g, r); CheckBoxRenderer.DrawCheckBox(g, checkBoxBounds.Location, checkBoxState); // Move the left edge without changing the right edge int newX = checkBoxBounds.Right + 3; r.Width -= (newX - r.X); r.X = newX; return r; } private Rectangle CalculateCheckBoxBounds(Graphics g, Rectangle cellBounds) { Size checkBoxSize = CheckBoxRenderer.GetGlyphSize(g, CheckBoxState.CheckedNormal); // Vertically center the checkbox int topOffset = (cellBounds.Height - checkBoxSize.Height)/2; return new Rectangle(cellBounds.X + 3, cellBounds.Y + topOffset, checkBoxSize.Width, checkBoxSize.Height); } private CheckBoxState GetCheckBoxState(CheckState checkState, bool isDisabled, bool isHot, bool isPressed) { // Should the checkbox be drawn as disabled? if (isDisabled) { switch (checkState) { case CheckState.Checked: return CheckBoxState.CheckedDisabled; case CheckState.Unchecked: return CheckBoxState.UncheckedDisabled; default: return CheckBoxState.MixedDisabled; } } // Is the mouse button currently down? if (isPressed) { switch (checkState) { case CheckState.Checked: return CheckBoxState.CheckedPressed; case CheckState.Unchecked: return CheckBoxState.UncheckedPressed; default: return CheckBoxState.MixedPressed; } } // Is the cursor currently over this checkbox? if (isHot) { switch (checkState) { case CheckState.Checked: return CheckBoxState.CheckedHot; case CheckState.Unchecked: return CheckBoxState.UncheckedHot; default: return CheckBoxState.MixedHot; } } // Not hot and not disabled -- just draw it normally switch (checkState) { case CheckState.Checked: return CheckBoxState.CheckedNormal; case CheckState.Unchecked: return CheckBoxState.UncheckedNormal; default: return CheckBoxState.MixedNormal; } } /// /// Draw a background for the header, without using Themes. /// /// /// /// /// /// /// protected void DrawUnthemedBackground(Graphics g, Rectangle r, int columnIndex, bool isPressed, bool isHot, HeaderStateStyle stateStyle) { if (stateStyle.BackColor.IsEmpty) // I know we're supposed to be drawing the unthemed background, but let's just see if we // can draw something more interesting than the dull raised block if (VisualStyleRenderer.IsSupported && VisualStyleRenderer.IsElementDefined(VisualStyleElement.Header.Item.Normal)) DrawThemedBackground(g, r, columnIndex, isPressed, isHot); else ControlPaint.DrawBorder3D(g, r, Border3DStyle.RaisedInner); else { using (Brush b = new SolidBrush(stateStyle.BackColor)) g.FillRectangle(b, r); } // Draw the frame if the style asks for one if (!stateStyle.FrameColor.IsEmpty && stateStyle.FrameWidth > 0f) { RectangleF r2 = r; r2.Inflate(-stateStyle.FrameWidth, -stateStyle.FrameWidth); using (Pen pen = new Pen(stateStyle.FrameColor, stateStyle.FrameWidth)) g.DrawRectangle(pen, r2.X, r2.Y, r2.Width, r2.Height); } } /// /// Draw a more-or-less pure themed header background. /// /// /// /// /// /// protected void DrawThemedBackground(Graphics g, Rectangle r, int columnIndex, bool isPressed, bool isHot) { int part = 1; // normal item if (columnIndex == 0 && VisualStyleRenderer.IsElementDefined(VisualStyleElement.Header.ItemLeft.Normal)) part = 2; // left item if (columnIndex == ListView.Columns.Count - 1 && VisualStyleRenderer.IsElementDefined(VisualStyleElement.Header.ItemRight.Normal)) part = 3; // right item int state = 1; // normal state if (isPressed) state = 3; // pressed else if (isHot) state = 2; // hot VisualStyleRenderer renderer = new VisualStyleRenderer("HEADER", part, state); renderer.DrawBackground(g, r); } /// /// Draw a sort indicator using themes /// /// /// protected void DrawThemedSortIndicator(Graphics g, Rectangle r) { VisualStyleRenderer renderer2 = null; if (ListView.LastSortOrder == SortOrder.Ascending) renderer2 = new VisualStyleRenderer(VisualStyleElement.Header.SortArrow.SortedUp); if (ListView.LastSortOrder == SortOrder.Descending) renderer2 = new VisualStyleRenderer(VisualStyleElement.Header.SortArrow.SortedDown); if (renderer2 != null) { Size sz = renderer2.GetPartSize(g, ThemeSizeType.True); Point pt = renderer2.GetPoint(PointProperty.Offset); // GetPoint() should work, but if it doesn't, put the arrow in the top middle if (pt.X == 0 && pt.Y == 0) pt = new Point(r.X + (r.Width/2) - (sz.Width/2), r.Y); renderer2.DrawBackground(g, new Rectangle(pt, sz)); } } /// /// Draw a sort indicator without using themes /// /// /// /// protected Rectangle DrawUnthemedSortIndicator(Graphics g, Rectangle r) { // No theme support for sort indicators. So, we draw a triangle at the right edge // of the column header. const int triangleHeight = 16; const int triangleWidth = 16; const int midX = triangleWidth/2; const int midY = (triangleHeight/2) - 1; const int deltaX = midX - 2; const int deltaY = deltaX/2; Point triangleLocation = new Point(r.Right - triangleWidth - 2, r.Top + (r.Height - triangleHeight)/2); Point[] pts = new Point[] {triangleLocation, triangleLocation, triangleLocation}; if (ListView.LastSortOrder == SortOrder.Ascending) { pts[0].Offset(midX - deltaX, midY + deltaY); pts[1].Offset(midX, midY - deltaY - 1); pts[2].Offset(midX + deltaX, midY + deltaY); } else { pts[0].Offset(midX - deltaX, midY - deltaY); pts[1].Offset(midX, midY + deltaY); pts[2].Offset(midX + deltaX, midY - deltaY); } g.FillPolygon(Brushes.SlateGray, pts); r.Width -= triangleWidth; return r; } /// /// Draw an indication that this column has a filter applied to it /// /// /// /// protected Rectangle DrawFilterIndicator(Graphics g, Rectangle r) { int width = CalculateFilterIndicatorWidth(r); if (width <= 0) return r; Image indicator = Resources.ColumnFilterIndicator; int x = r.Right - width; int y = r.Top + (r.Height - indicator.Height)/2; g.DrawImageUnscaled(indicator, x, y); r.Width -= width; return r; } private int CalculateFilterIndicatorWidth(Rectangle r) { if (Resources.ColumnFilterIndicator == null || r.Width < 48) return 0; return Resources.ColumnFilterIndicator.Width + 1; } /// /// Draw the header's image and text /// /// /// /// /// protected void DrawHeaderImageAndText(Graphics g, Rectangle r, OLVColumn column, HeaderStateStyle stateStyle) { TextFormatFlags flags = TextFormatFlags; flags |= TextFormatFlags.VerticalCenter; if (column.HeaderTextAlignOrDefault == HorizontalAlignment.Center) flags |= TextFormatFlags.HorizontalCenter; if (column.HeaderTextAlignOrDefault == HorizontalAlignment.Right) flags |= TextFormatFlags.Right; Font f = ListView.HeaderUsesThemes ? ListView.Font : stateStyle.Font ?? ListView.Font; Color color = ListView.HeaderUsesThemes ? Color.Black : stateStyle.ForeColor; if (color.IsEmpty) color = Color.Black; const int imageTextGap = 3; if (column.IsHeaderVertical) { DrawVerticalText(g, r, column, f, color); } else { // Does the column have a header image and is there space for it? if (column.HasHeaderImage && r.Width > column.ImageList.ImageSize.Width*2) DrawImageAndText(g, r, column, flags, f, color, imageTextGap); else DrawText(g, r, column, flags, f, color); } } private void DrawText(Graphics g, Rectangle r, OLVColumn column, TextFormatFlags flags, Font f, Color color) { if (column.ShowTextInHeader) TextRenderer.DrawText(g, column.Text, f, r, color, Color.Transparent, flags); } private void DrawImageAndText(Graphics g, Rectangle r, OLVColumn column, TextFormatFlags flags, Font f, Color color, int imageTextGap) { Rectangle textRect = r; textRect.X += (column.ImageList.ImageSize.Width + imageTextGap); textRect.Width -= (column.ImageList.ImageSize.Width + imageTextGap); Size textSize = Size.Empty; if (column.ShowTextInHeader) textSize = TextRenderer.MeasureText(g, column.Text, f, textRect.Size, flags); int imageY = r.Top + ((r.Height - column.ImageList.ImageSize.Height)/2); int imageX = textRect.Left; if (column.HeaderTextAlignOrDefault == HorizontalAlignment.Center) imageX = textRect.Left + ((textRect.Width - textSize.Width)/2); if (column.HeaderTextAlignOrDefault == HorizontalAlignment.Right) imageX = textRect.Right - textSize.Width; imageX -= (column.ImageList.ImageSize.Width + imageTextGap); column.ImageList.Draw(g, imageX, imageY, column.ImageList.Images.IndexOfKey(column.HeaderImageKey)); DrawText(g, textRect, column, flags, f, color); } private static void DrawVerticalText(Graphics g, Rectangle r, OLVColumn column, Font f, Color color) { try { // Create a matrix transformation that will rotate the text 90 degrees vertically // AND place the text in the middle of where it was previously. [Think of tipping // a box over by its bottom left edge -- you have to move it back a bit so it's // in the same place as it started] Matrix m = new Matrix(); m.RotateAt(-90, new Point(r.X, r.Bottom)); m.Translate(0, r.Height); g.Transform = m; StringFormat fmt = new StringFormat(StringFormatFlags.NoWrap); fmt.Alignment = StringAlignment.Near; fmt.LineAlignment = column.HeaderTextAlignAsStringAlignment; //fmt.Trimming = StringTrimming.EllipsisCharacter; // The drawing is rotated 90 degrees, so switch our text boundaries Rectangle textRect = r; textRect.Width = r.Height; textRect.Height = r.Width; using (Brush b = new SolidBrush(color)) g.DrawString(column.Text, f, b, textRect, fmt); } finally { g.ResetTransform(); } } /// /// Return the header format that should be used for the given column /// /// /// protected HeaderFormatStyle CalculateHeaderStyle(OLVColumn column) { return column.HeaderFormatStyle ?? ListView.HeaderFormatStyle ?? new HeaderFormatStyle(); } /// /// What style should be applied to the header? /// /// /// /// /// protected HeaderStateStyle CalculateStateStyle(OLVColumn column, bool isHot, bool isPressed) { HeaderFormatStyle headerStyle = CalculateHeaderStyle(column); if (ListView.IsDesignMode) return headerStyle.Normal; if (isPressed) return headerStyle.Pressed; if (isHot) return headerStyle.Hot; return headerStyle.Normal; } /// /// What font should be used to draw the header text? /// /// /// /// /// protected Font CalculateFont(OLVColumn column, bool isHot, bool isPressed) { HeaderStateStyle stateStyle = CalculateStateStyle(column, isHot, isPressed); return stateStyle.Font ?? ListView.Font; } /// /// What flags will be used when drawing text /// protected TextFormatFlags TextFormatFlags { get { TextFormatFlags flags = TextFormatFlags.EndEllipsis | TextFormatFlags.NoPrefix | TextFormatFlags.WordEllipsis | TextFormatFlags.PreserveGraphicsTranslateTransform; if (WordWrap) flags |= TextFormatFlags.WordBreak; else flags |= TextFormatFlags.SingleLine; if (ListView.RightToLeft == RightToLeft.Yes) flags |= TextFormatFlags.RightToLeft; return flags; } } /// /// Perform a HitTest for the header control /// /// /// /// Null if the given point isn't over the header internal OlvListViewHitTestInfo.HeaderHitTestInfo HitTest(int x, int y) { Rectangle r = ClientRectangle; if (!r.Contains(x, y)) return null; Point pt = new Point(x + ListView.LowLevelScrollPosition.X, y); OlvListViewHitTestInfo.HeaderHitTestInfo hti = new OlvListViewHitTestInfo.HeaderHitTestInfo(); hti.ColumnIndex = NativeMethods.GetColumnUnderPoint(Handle, pt); hti.IsOverCheckBox = IsPointOverHeaderCheckBox(hti.ColumnIndex, pt); hti.OverDividerIndex = NativeMethods.GetDividerUnderPoint(Handle, pt); return hti; } #endregion } } ================================================ FILE: source/ObjectListView/SubControls/ToolStripCheckedListBox.cs ================================================ /* * ToolStripCheckedListBox - Puts a CheckedListBox into a tool strip menu item * * Author: Phillip Piper * Date: 4-March-2011 11:59 pm * * Change log: * 2011-03-04 JPP - First version * * Copyright (C) 2011-2014 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System.Windows.Forms; using System.Drawing; using System.ComponentModel; namespace BrightIdeasSoftware { /// /// Instances of this class put a CheckedListBox into a tool strip menu item. /// public class ToolStripCheckedListBox : ToolStripControlHost { /// /// Create a ToolStripCheckedListBox /// public ToolStripCheckedListBox() : base(new CheckedListBox()) { CheckedListBoxControl.MaximumSize = new Size(400, 700); CheckedListBoxControl.ThreeDCheckBoxes = true; CheckedListBoxControl.CheckOnClick = true; CheckedListBoxControl.SelectionMode = SelectionMode.One; } /// /// Gets the control embedded in the menu /// public CheckedListBox CheckedListBoxControl { get { return Control as CheckedListBox; } } /// /// Gets the items shown in the checkedlistbox /// public CheckedListBox.ObjectCollection Items { get { return CheckedListBoxControl.Items; } } /// /// Gets or sets whether an item should be checked when it is clicked /// [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public bool CheckedOnClick { get { return CheckedListBoxControl.CheckOnClick; } set { CheckedListBoxControl.CheckOnClick = value; } } /// /// Gets a collection of the checked items /// public CheckedListBox.CheckedItemCollection CheckedItems { get { return CheckedListBoxControl.CheckedItems; } } /// /// Add a possibly checked item to the control /// /// /// public void AddItem(object item, bool isChecked) { Items.Add(item); if (isChecked) CheckedListBoxControl.SetItemChecked(Items.Count - 1, true); } /// /// Add an item with the given state to the control /// /// /// public void AddItem(object item, CheckState state) { Items.Add(item); CheckedListBoxControl.SetItemCheckState(Items.Count - 1, state); } /// /// Gets the checkedness of the i'th item /// /// /// public CheckState GetItemCheckState(int i) { return CheckedListBoxControl.GetItemCheckState(i); } /// /// Set the checkedness of the i'th item /// /// /// public void SetItemState(int i, CheckState checkState) { if (i >= 0 && i < Items.Count) CheckedListBoxControl.SetItemCheckState(i, checkState); } /// /// Check all the items in the control /// public void CheckAll() { for (int i = 0; i < Items.Count; i++) CheckedListBoxControl.SetItemChecked(i, true); } /// /// Unchecked all the items in the control /// public void UncheckAll() { for (int i = 0; i < Items.Count; i++) CheckedListBoxControl.SetItemChecked(i, false); } #region Events /// /// Listen for events on the underlying control /// /// protected override void OnSubscribeControlEvents(Control c) { base.OnSubscribeControlEvents(c); CheckedListBox control = (CheckedListBox)c; control.ItemCheck += new ItemCheckEventHandler(OnItemCheck); } /// /// Stop listening for events on the underlying control /// /// protected override void OnUnsubscribeControlEvents(Control c) { base.OnUnsubscribeControlEvents(c); CheckedListBox control = (CheckedListBox)c; control.ItemCheck -= new ItemCheckEventHandler(OnItemCheck); } /// /// Tell the world that an item was checked /// public event ItemCheckEventHandler ItemCheck; /// /// Trigger the ItemCheck event /// /// /// private void OnItemCheck(object sender, ItemCheckEventArgs e) { if (ItemCheck != null) { ItemCheck(this, e); } } #endregion } } ================================================ FILE: source/ObjectListView/SubControls/ToolTipControl.cs ================================================ /* * ToolTipControl - A limited wrapper around a Windows tooltip control * * For some reason, the ToolTip class in the .NET framework is implemented in a significantly * different manner to other controls. For our purposes, the worst of these problems * is that we cannot get the Handle, so we cannot send Windows level messages to the control. * * Author: Phillip Piper * Date: 2009-05-17 7:22PM * * Change log: * v2.3 * 2009-06-13 JPP - Moved ToolTipShowingEventArgs to Events.cs * v2.2 * 2009-06-06 JPP - Fixed some Vista specific problems * 2009-05-17 JPP - Initial version * * TO DO: * * Copyright (C) 2006-2014 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System; using System.Collections; using System.Drawing; using System.Runtime.InteropServices; using System.Windows.Forms; namespace BrightIdeasSoftware { /// /// A limited wrapper around a Windows tooltip window. /// public class ToolTipControl : NativeWindow { #region Constants /// /// These are the standard icons that a tooltip can display. /// public enum StandardIcons { /// /// No icon /// None = 0, /// /// Info /// Info = 1, /// /// Warning /// Warning = 2, /// /// Error /// Error = 3, /// /// Large info (Vista and later only) /// InfoLarge = 4, /// /// Large warning (Vista and later only) /// WarningLarge = 5, /// /// Large error (Vista and later only) /// ErrorLarge = 6 } const int GWL_STYLE = -16; const int WM_GETFONT = 0x31; const int WM_SETFONT = 0x30; const int WS_BORDER = 0x800000; const int WS_EX_TOPMOST = 8; const int TTM_ADDTOOL = 0x432; const int TTM_ADJUSTRECT = 0x400 + 31; const int TTM_DELTOOL = 0x433; const int TTM_GETBUBBLESIZE = 0x400 + 30; const int TTM_GETCURRENTTOOL = 0x400 + 59; const int TTM_GETTIPBKCOLOR = 0x400 + 22; const int TTM_GETTIPTEXTCOLOR = 0x400 + 23; const int TTM_GETDELAYTIME = 0x400 + 21; const int TTM_NEWTOOLRECT = 0x400 + 52; const int TTM_POP = 0x41c; const int TTM_SETDELAYTIME = 0x400 + 3; const int TTM_SETMAXTIPWIDTH = 0x400 + 24; const int TTM_SETTIPBKCOLOR = 0x400 + 19; const int TTM_SETTIPTEXTCOLOR = 0x400 + 20; const int TTM_SETTITLE = 0x400 + 33; const int TTM_SETTOOLINFO = 0x400 + 54; const int TTF_IDISHWND = 1; //const int TTF_ABSOLUTE = 0x80; const int TTF_CENTERTIP = 2; const int TTF_RTLREADING = 4; const int TTF_SUBCLASS = 0x10; //const int TTF_TRACK = 0x20; //const int TTF_TRANSPARENT = 0x100; const int TTF_PARSELINKS = 0x1000; const int TTS_NOPREFIX = 2; const int TTS_BALLOON = 0x40; const int TTS_USEVISUALSTYLE = 0x100; const int TTN_FIRST = -520; /// /// /// public const int TTN_SHOW = (TTN_FIRST - 1); /// /// /// public const int TTN_POP = (TTN_FIRST - 2); /// /// /// public const int TTN_LINKCLICK = (TTN_FIRST - 3); /// /// /// public const int TTN_GETDISPINFO = (TTN_FIRST - 10); const int TTDT_AUTOMATIC = 0; const int TTDT_RESHOW = 1; const int TTDT_AUTOPOP = 2; const int TTDT_INITIAL = 3; #endregion #region Properties /// /// Get or set if the style of the tooltip control /// internal int WindowStyle { get { return (int)NativeMethods.GetWindowLong(Handle, GWL_STYLE); } set { NativeMethods.SetWindowLong(Handle, GWL_STYLE, value); } } /// /// Get or set if the tooltip should be shown as a ballon /// public bool IsBalloon { get { return (WindowStyle & TTS_BALLOON) == TTS_BALLOON; } set { if (IsBalloon == value) return; int windowStyle = WindowStyle; if (value) { windowStyle |= (TTS_BALLOON | TTS_USEVISUALSTYLE); // On XP, a border makes the ballon look wrong if (!ObjectListView.IsVistaOrLater) windowStyle &= ~WS_BORDER; } else { windowStyle &= ~(TTS_BALLOON | TTS_USEVISUALSTYLE); if (!ObjectListView.IsVistaOrLater) { if (hasBorder) windowStyle |= WS_BORDER; else windowStyle &= ~WS_BORDER; } } WindowStyle = windowStyle; } } /// /// Get or set if the tooltip should be shown as a ballon /// public bool HasBorder { get { return hasBorder; } set { if (hasBorder == value) return; if (value) { WindowStyle |= WS_BORDER; } else { WindowStyle &= ~WS_BORDER; } } } private bool hasBorder = true; /// /// Get or set the background color of the tooltip /// public Color BackColor { get { int color = (int)NativeMethods.SendMessage(Handle, TTM_GETTIPBKCOLOR, 0, 0); return ColorTranslator.FromWin32(color); } set { // For some reason, setting the color fails on Vista and messes up later ops. // So we don't even try to set it. if (!ObjectListView.IsVistaOrLater) { int color = ColorTranslator.ToWin32(value); NativeMethods.SendMessage(Handle, TTM_SETTIPBKCOLOR, color, 0); //int x2 = Marshal.GetLastWin32Error(); } } } /// /// Get or set the color of the text and border on the tooltip. /// public Color ForeColor { get { int color = (int)NativeMethods.SendMessage(Handle, TTM_GETTIPTEXTCOLOR, 0, 0); return ColorTranslator.FromWin32(color); } set { // For some reason, setting the color fails on Vista and messes up later ops. // So we don't even try to set it. if (!ObjectListView.IsVistaOrLater) { int color = ColorTranslator.ToWin32(value); NativeMethods.SendMessage(Handle, TTM_SETTIPTEXTCOLOR, color, 0); } } } /// /// Get or set the title that will be shown on the tooltip. /// public string Title { get { return title; } set { if (String.IsNullOrEmpty(value)) title = String.Empty; else if (value.Length >= 100) title = value.Substring(0, 99); else title = value; NativeMethods.SendMessageString(Handle, TTM_SETTITLE, (int)standardIcon, title); } } private string title; /// /// Get or set the icon that will be shown on the tooltip. /// public StandardIcons StandardIcon { get { return standardIcon; } set { standardIcon = value; NativeMethods.SendMessageString(Handle, TTM_SETTITLE, (int)standardIcon, title); } } private StandardIcons standardIcon; /// /// Gets or sets the font that will be used to draw this control. /// is still. /// /// Setting this to null reverts to the default font. public Font Font { get { IntPtr hfont = NativeMethods.SendMessage(Handle, WM_GETFONT, 0, 0); if (hfont == IntPtr.Zero) return Control.DefaultFont; else return Font.FromHfont(hfont); } set { Font newFont = value ?? Control.DefaultFont; if (newFont == font) return; font = newFont; IntPtr hfont = font.ToHfont(); // THINK: When should we delete this hfont? NativeMethods.SendMessage(Handle, WM_SETFONT, hfont, 0); } } private Font font; /// /// Gets or sets how many milliseconds the tooltip will remain visible while the mouse /// is still. /// public int AutoPopDelay { get { return GetDelayTime(TTDT_AUTOPOP); } set { SetDelayTime(TTDT_AUTOPOP, value); } } /// /// Gets or sets how many milliseconds the mouse must be still before the tooltip is shown. /// public int InitialDelay { get { return GetDelayTime(TTDT_INITIAL); } set { SetDelayTime(TTDT_INITIAL, value); } } /// /// Gets or sets how many milliseconds the mouse must be still before the tooltip is shown again. /// public int ReshowDelay { get { return GetDelayTime(TTDT_RESHOW); } set { SetDelayTime(TTDT_RESHOW, value); } } private int GetDelayTime(int which) { return (int)NativeMethods.SendMessage(Handle, TTM_GETDELAYTIME, which, 0); } private void SetDelayTime(int which, int value) { NativeMethods.SendMessage(Handle, TTM_SETDELAYTIME, which, value); } #endregion #region Commands /// /// Create the underlying control. /// /// The parent of the tooltip /// This does nothing if the control has already been created public void Create(IntPtr parentHandle) { if (Handle != IntPtr.Zero) return; CreateParams cp = new CreateParams(); cp.ClassName = "tooltips_class32"; cp.Style = TTS_NOPREFIX; cp.ExStyle = WS_EX_TOPMOST; cp.Parent = parentHandle; CreateHandle(cp); // Ensure that multiline tooltips work correctly SetMaxWidth(); } /// /// Take a copy of the current settings and restore them when the /// tooltip is poppped. /// /// /// This call cannot be nested. Subsequent calls to this method will be ignored /// until PopSettings() is called. /// public void PushSettings() { // Ignore any nested calls if (settings != null) return; settings = new Hashtable(); settings["IsBalloon"] = IsBalloon; settings["HasBorder"] = HasBorder; settings["BackColor"] = BackColor; settings["ForeColor"] = ForeColor; settings["Title"] = Title; settings["StandardIcon"] = StandardIcon; settings["AutoPopDelay"] = AutoPopDelay; settings["InitialDelay"] = InitialDelay; settings["ReshowDelay"] = ReshowDelay; settings["Font"] = Font; } private Hashtable settings; /// /// Restore the settings of the tooltip as they were when PushSettings() /// was last called. /// public void PopSettings() { if (settings == null) return; IsBalloon = (bool)settings["IsBalloon"]; HasBorder = (bool)settings["HasBorder"]; BackColor = (Color)settings["BackColor"]; ForeColor = (Color)settings["ForeColor"]; Title = (string)settings["Title"]; StandardIcon = (StandardIcons)settings["StandardIcon"]; AutoPopDelay = (int)settings["AutoPopDelay"]; InitialDelay = (int)settings["InitialDelay"]; ReshowDelay = (int)settings["ReshowDelay"]; Font = (Font)settings["Font"]; settings = null; } /// /// Add the given window to those for whom this tooltip will show tips /// /// The window public void AddTool(IWin32Window window) { NativeMethods.TOOLINFO lParam = MakeToolInfoStruct(window); NativeMethods.SendMessageTOOLINFO(Handle, TTM_ADDTOOL, 0, lParam); } /// /// Hide any currently visible tooltip /// /// public void PopToolTip(IWin32Window window) { NativeMethods.SendMessage(Handle, TTM_POP, 0, 0); } //public void Munge() { // NativeMethods.TOOLINFO tool = new NativeMethods.TOOLINFO(); // IntPtr result = NativeMethods.SendMessageTOOLINFO(this.Handle, TTM_GETCURRENTTOOL, 0, tool); // System.Diagnostics.Trace.WriteLine("-"); // System.Diagnostics.Trace.WriteLine(result); // result = NativeMethods.SendMessageTOOLINFO(this.Handle, TTM_GETBUBBLESIZE, 0, tool); // System.Diagnostics.Trace.WriteLine(String.Format("{0} {1}", result.ToInt32() >> 16, result.ToInt32() & 0xFFFF)); // NativeMethods.ChangeSize(this, result.ToInt32() & 0xFFFF, result.ToInt32() >> 16); // //NativeMethods.RECT r = new NativeMethods.RECT(); // //r.right // //IntPtr x = NativeMethods.SendMessageRECT(this.Handle, TTM_ADJUSTRECT, true, ref r); // //System.Diagnostics.Trace.WriteLine(String.Format("{0} {1} {2} {3}", r.left, r.top, r.right, r.bottom)); //} /// /// Remove the given window from those managed by this tooltip /// /// public void RemoveToolTip(IWin32Window window) { NativeMethods.TOOLINFO lParam = MakeToolInfoStruct(window); NativeMethods.SendMessageTOOLINFO(Handle, TTM_DELTOOL, 0, lParam); } /// /// Set the maximum width of a tooltip string. /// public void SetMaxWidth() { SetMaxWidth(SystemInformation.MaxWindowTrackSize.Width); } /// /// Set the maximum width of a tooltip string. /// /// Setting this ensures that line breaks in the tooltip are honoured. public void SetMaxWidth(int maxWidth) { NativeMethods.SendMessage(Handle, TTM_SETMAXTIPWIDTH, 0, maxWidth); } #endregion #region Implementation /// /// Make a TOOLINFO structure for the given window /// /// /// A filled in TOOLINFO private NativeMethods.TOOLINFO MakeToolInfoStruct(IWin32Window window) { NativeMethods.TOOLINFO toolinfo_tooltip = new NativeMethods.TOOLINFO(); toolinfo_tooltip.hwnd = window.Handle; toolinfo_tooltip.uFlags = TTF_IDISHWND | TTF_SUBCLASS; toolinfo_tooltip.uId = window.Handle; toolinfo_tooltip.lpszText = (IntPtr)(-1); // LPSTR_TEXTCALLBACK return toolinfo_tooltip; } /// /// Handle a WmNotify message /// /// The msg /// True if the message has been handled protected virtual bool HandleNotify(ref Message msg) { //THINK: What do we have to do here? Nothing it seems :) //NativeMethods.NMHEADER nmheader = (NativeMethods.NMHEADER)msg.GetLParam(typeof(NativeMethods.NMHEADER)); //System.Diagnostics.Trace.WriteLine("HandleNotify"); //System.Diagnostics.Trace.WriteLine(nmheader.nhdr.code); //switch (nmheader.nhdr.code) { //} return false; } /// /// Handle a get display info message /// /// The msg /// True if the message has been handled public virtual bool HandleGetDispInfo(ref Message msg) { //System.Diagnostics.Trace.WriteLine("HandleGetDispInfo"); SetMaxWidth(); ToolTipShowingEventArgs args = new ToolTipShowingEventArgs(); args.ToolTipControl = this; OnShowing(args); if (String.IsNullOrEmpty(args.Text)) return false; ApplyEventFormatting(args); NativeMethods.NMTTDISPINFO dispInfo = (NativeMethods.NMTTDISPINFO)msg.GetLParam(typeof(NativeMethods.NMTTDISPINFO)); dispInfo.lpszText = args.Text; dispInfo.hinst = IntPtr.Zero; if (args.RightToLeft == RightToLeft.Yes) dispInfo.uFlags |= TTF_RTLREADING; Marshal.StructureToPtr(dispInfo, msg.LParam, false); return true; } private void ApplyEventFormatting(ToolTipShowingEventArgs args) { if (!args.IsBalloon.HasValue && !args.BackColor.HasValue && !args.ForeColor.HasValue && args.Title == null && !args.StandardIcon.HasValue && !args.AutoPopDelay.HasValue && args.Font == null) return; PushSettings(); if (args.IsBalloon.HasValue) IsBalloon = args.IsBalloon.Value; if (args.BackColor.HasValue) BackColor = args.BackColor.Value; if (args.ForeColor.HasValue) ForeColor = args.ForeColor.Value; if (args.StandardIcon.HasValue) StandardIcon = args.StandardIcon.Value; if (args.AutoPopDelay.HasValue) AutoPopDelay = args.AutoPopDelay.Value; if (args.Font != null) Font = args.Font; if (args.Title != null) Title = args.Title; } /// /// Handle a TTN_LINKCLICK message /// /// The msg /// True if the message has been handled /// This cannot call base.WndProc() since the msg may have come from another control. public virtual bool HandleLinkClick(ref Message msg) { //System.Diagnostics.Trace.WriteLine("HandleLinkClick"); return false; } /// /// Handle a TTN_POP message /// /// The msg /// True if the message has been handled /// This cannot call base.WndProc() since the msg may have come from another control. public virtual bool HandlePop(ref Message msg) { //System.Diagnostics.Trace.WriteLine("HandlePop"); PopSettings(); return true; } /// /// Handle a TTN_SHOW message /// /// The msg /// True if the message has been handled /// This cannot call base.WndProc() since the msg may have come from another control. public virtual bool HandleShow(ref Message msg) { //System.Diagnostics.Trace.WriteLine("HandleShow"); return false; } /// /// Handle a reflected notify message /// /// The msg /// True if the message has been handled protected virtual bool HandleReflectNotify(ref Message msg) { NativeMethods.NMHEADER nmheader = (NativeMethods.NMHEADER)msg.GetLParam(typeof(NativeMethods.NMHEADER)); switch (nmheader.nhdr.code) { case TTN_SHOW: //System.Diagnostics.Trace.WriteLine("reflect TTN_SHOW"); if (HandleShow(ref msg)) return true; break; case TTN_POP: //System.Diagnostics.Trace.WriteLine("reflect TTN_POP"); if (HandlePop(ref msg)) return true; break; case TTN_LINKCLICK: //System.Diagnostics.Trace.WriteLine("reflect TTN_LINKCLICK"); if (HandleLinkClick(ref msg)) return true; break; case TTN_GETDISPINFO: //System.Diagnostics.Trace.WriteLine("reflect TTN_GETDISPINFO"); if (HandleGetDispInfo(ref msg)) return true; break; } return false; } /// /// Mess with the basic message pump of the tooltip /// /// override protected void WndProc(ref Message msg) { //System.Diagnostics.Trace.WriteLine(String.Format("xx {0:x}", msg.Msg)); switch (msg.Msg) { case 0x4E: // WM_NOTIFY if (!HandleNotify(ref msg)) return; break; case 0x204E: // WM_REFLECT_NOTIFY if (!HandleReflectNotify(ref msg)) return; break; } base.WndProc(ref msg); } #endregion #region Events /// /// Tell the world that a tooltip is about to show /// public event EventHandler Showing; /// /// Tell the world that a tooltip is about to disappear /// public event EventHandler Pop; /// /// /// /// protected virtual void OnShowing(ToolTipShowingEventArgs e) { if (Showing != null) Showing(this, e); } /// /// /// /// protected virtual void OnPop(EventArgs e) { if (Pop != null) Pop(this, e); } #endregion } } ================================================ FILE: source/ObjectListView/TreeListView.cs ================================================ /* * TreeListView - A listview that can show a tree of objects in a column * * Author: Phillip Piper * Date: 23/09/2008 11:15 AM * * Change log: * v2.9 * 2015-08-02 JPP - Fixed buy with hierarchical checkboxes where setting the checkedness of a deeply * nested object would sometimes not correctly calculate the changes in the hierarchy. SF #150. * 2015-06-27 JPP - Corrected small UI glitch when focus was lost and HideSelection was false. SF #135. * v2.8.1 * 2014-11-28 JPP - Fixed issue in RefreshObject() where a model with less children than previous that could not * longer be expanded would cause an exception. * 2014-11-23 JPP - Fixed an issue where collapsing a branch could leave the internal object->index map out of date. * v2.8 * 2014-10-08 JPP - Fixed an issue where pre-expanded branches would not initially expand properly * 2014-09-29 JPP - Fixed issue where RefreshObject() on a root object could cause exceptions * - Fixed issue where CollapseAll() while filtering could cause exception * 2014-03-09 JPP - Fixed issue where removing a branches only child and then calling RefreshObject() * could throw an exception. * v2.7 * 2014-02-23 JPP - Added Reveal() method to show a deeply nested models. * 2014-02-05 JPP - Fix issue where refreshing a non-root item would collapse all expanded children of that item * 2014-02-01 JPP - ClearObjects() now actually, you know, clears objects :) * - Corrected issue where Expanded event was being raised twice. * - RebuildChildren() no longer checks if CanExpand is true before rebuilding. * 2014-01-16 JPP - Corrected an off-by-1 error in hit detection, which meant that clicking in the last 16 pixels * of an items label was being ignored. * 2013-11-20 JPP - Moved event triggers into Collapse() and Expand() so that the events are always triggered. * - CheckedObjects now includes objects that are in a branch that is currently collapsed * - CollapseAll() and ExpandAll() now trigger cancellable events * 2013-09-29 JPP - Added TreeFactory to allow the underlying Tree to be replaced by another implementation. * 2013-09-23 JPP - Fixed long standing issue where RefreshObject() would not work on root objects * which overrode Equals()/GetHashCode(). * 2013-02-23 JPP - Added HierarchicalCheckboxes. When this is true, the checkedness of a parent * is an synopsis of the checkedness of its children. When all children are checked, * the parent is checked. When all children are unchecked, the parent is unchecked. * If some children are checked and some are not, the parent is indeterminate. * v2.6 * 2012-10-25 JPP - Circumvent annoying issue in ListView control where changing * selection would leave artifacts on the control. * 2012-08-10 JPP - Don't trigger selection changed events during expands * * v2.5.1 * 2012-04-30 JPP - Fixed issue where CheckedObjects would return model objects that had been filtered out. * - Allow any column to render the tree, not just column 0 (still not sure about this one) * v2.5.0 * 2011-04-20 JPP - Added ExpandedObjects property and RebuildAll() method. * 2011-04-09 JPP - Added Expanding, Collapsing, Expanded and Collapsed events. * The ..ing events are cancellable. These are only fired in response * to user actions. * v2.4.1 * 2010-06-15 JPP - Fixed issue in Tree.RemoveObjects() which resulted in removed objects * being reported as still existing. * v2.3 * 2009-09-01 JPP - Fixed off-by-one error that was messing up hit detection * 2009-08-27 JPP - Fixed issue when dragging a node from one place to another in the tree * v2.2.1 * 2009-07-14 JPP - Clicks to the left of the expander in tree cells are now ignored. * v2.2 * 2009-05-12 JPP - Added tree traverse operations: GetParent and GetChildren. * - Added DiscardAllState() to completely reset the TreeListView. * 2009-05-10 JPP - Removed all unsafe code * 2009-05-09 JPP - Fixed issue where any command (Expand/Collapse/Refresh) on a model * object that was once visible but that is currently in a collapsed branch * would cause the control to crash. * 2009-05-07 JPP - Fixed issue where RefreshObjects() would fail when none of the given * objects were present/visible. * 2009-04-20 JPP - Fixed issue where calling Expand() on an already expanded branch confused * the display of the children (SF#2499313) * 2009-03-06 JPP - Calculate edit rectangle on column 0 more accurately * v2.1 * 2009-02-24 JPP - All commands now work when the list is empty (SF #2631054) * - TreeListViews can now be printed with ListViewPrinter * 2009-01-27 JPP - Changed to use new Renderer and HitTest scheme * 2009-01-22 JPP - Added RevealAfterExpand property. If this is true (the default), * after expanding a branch, the control scrolls to reveal as much of the * expanded branch as possible. * 2009-01-13 JPP - Changed TreeRenderer to work with visual styles are disabled * v2.0.1 * 2009-01-07 JPP - Made all public and protected methods virtual * - Changed some classes from 'internal' to 'protected' so that they * can be accessed by subclasses of TreeListView. * 2008-12-22 JPP - Added UseWaitCursorWhenExpanding property * - Made TreeRenderer public so that it can be subclassed * - Added LinePen property to TreeRenderer to allow the connection drawing * pen to be changed * - Fixed some rendering issues where the text highlight rect was miscalculated * - Fixed connection line problem when there is only a single root * v2.0 * 2008-12-10 JPP - Expand/collapse with mouse now works when there is no SmallImageList. * 2008-12-01 JPP - Search-by-typing now works. * 2008-11-26 JPP - Corrected calculation of expand/collapse icon (SF#2338819) * - Fixed ugliness with dotted lines in renderer (SF#2332889) * - Fixed problem with custom selection colors (SF#2338805) * 2008-11-19 JPP - Expand/collapse now preserve the selection -- more or less :) * - Overrode RefreshObjects() to rebuild the given objects and their children * 2008-11-05 JPP - Added ExpandAll() and CollapseAll() commands * - CanExpand is no longer cached * - Renamed InitialBranches to RootModels since it deals with model objects * 2008-09-23 JPP Initial version * * TO DO: * * Copyright (C) 2006-2014 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Windows.Forms; namespace BrightIdeasSoftware { /// /// A TreeListView combines an expandable tree structure with list view columns. /// /// /// To support tree operations, two delegates must be provided: /// /// /// /// CanExpandGetter /// /// /// This delegate must accept a model object and return a boolean indicating /// if that model should be expandable. /// /// /// /// /// ChildrenGetter /// /// /// This delegate must accept a model object and return an IEnumerable of model /// objects that will be displayed as children of the parent model. This delegate will only be called /// for a model object if the CanExpandGetter has already returned true for that model. /// /// /// /// /// ParentGetter /// /// /// This delegate must accept a model object and return the parent model. /// This delegate will only be called when HierarchicalCheckboxes is true OR when Reveal() is called. /// /// /// /// /// The top level branches of the tree are set via the Roots property. SetObjects(), AddObjects() /// and RemoveObjects() are interpreted as operations on this collection of roots. /// /// /// To add new children to an existing branch, make changes to your model objects and then /// call RefreshObject() on the parent. /// /// The tree must be a directed acyclic graph -- no cycles are allowed. Put more mundanely, /// each model object must appear only once in the tree. If the same model object appears in two /// places in the tree, the control will become confused. /// public partial class TreeListView : VirtualObjectListView { /// /// Make a default TreeListView /// public TreeListView() { OwnerDraw = true; View = View.Details; CheckedObjectsMustStillExistInList = false; // ReSharper disable DoNotCallOverridableMethodsInConstructor RegenerateTree(); TreeColumnRenderer = new TreeRenderer(); // ReSharper restore DoNotCallOverridableMethodsInConstructor // This improves hit detection even if we don't have any state image SmallImageList = new ImageList(); // this.StateImageList.ImageSize = new Size(6, 6); } //------------------------------------------------------------------------------------------ // Properties /// /// This is the delegate that will be used to decide if a model object can be expanded. /// /// /// /// This is called *often* -- on every mouse move when required. It must be fast. /// Don't do database lookups, linear searches, or pi calculations. Just return the /// value of a property. /// /// /// When this delegate is called, the TreeListView is not in a stable state. Don't make /// calls back into the control. /// /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual CanExpandGetterDelegate CanExpandGetter { get { return TreeModel.CanExpandGetter; } set { TreeModel.CanExpandGetter = value; } } /// /// Gets whether or not this listview is capable of showing groups /// [Browsable(false)] public override bool CanShowGroups { get { return false; } } /// /// This is the delegate that will be used to fetch the children of a model object /// /// /// /// This delegate will only be called if the CanExpand delegate has /// returned true for the model object. /// /// /// When this delegate is called, the TreeListView is not in a stable state. Don't do anything /// that will result in calls being made back into the control. /// /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual ChildrenGetterDelegate ChildrenGetter { get { return TreeModel.ChildrenGetter; } set { TreeModel.ChildrenGetter = value; } } /// /// This is the delegate that will be used to fetch the parent of a model object /// /// The parent of the given model, or null if the model doesn't exist or /// if the model is a root [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public ParentGetterDelegate ParentGetter { get { return parentGetter; } set { parentGetter = value; } } private ParentGetterDelegate parentGetter; /// /// Get or set the collection of model objects that are checked. /// When setting this property, any row whose model object isn't /// in the given collection will be unchecked. Setting to null is /// equivalent to unchecking all. /// /// /// /// This property returns a simple collection. Changes made to the returned /// collection do NOT affect the list. This is different to the behaviour of /// CheckedIndicies collection. /// /// /// When getting CheckedObjects, the performance of this method is O(n) where n is the number of checked objects. /// When setting CheckedObjects, the performance of this method is O(n) where n is the number of checked objects plus /// the number of objects to be checked. /// /// /// If the ListView is not currently showing CheckBoxes, this property does nothing. It does /// not remember any check box settings made. /// /// public override IList CheckedObjects { get { return base.CheckedObjects; } set { ArrayList objectsToRecalculate = new ArrayList(CheckedObjects); if (value != null) objectsToRecalculate.AddRange(value); base.CheckedObjects = value; if (HierarchicalCheckboxes) RecalculateHierarchicalCheckBoxGraph(objectsToRecalculate); } } /// /// Gets or sets the model objects that are expanded. /// /// /// This can be used to expand model objects before they are seen. /// /// Setting this does *not* force the control to rebuild /// its display. You need to call RebuildAll(true). /// /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public IEnumerable ExpandedObjects { get { return TreeModel.mapObjectToExpanded.Keys; } set { TreeModel.mapObjectToExpanded.Clear(); if (value != null) { foreach (object x in value) TreeModel.SetModelExpanded(x, true); } } } /// /// Gets or sets the filter that is applied to our whole list of objects. /// TreeListViews do not currently support whole list filters. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public override IListFilter ListFilter { get { return null; } set { Debug.Assert(value == null, "TreeListView do not support ListFilters"); } } /// /// Gets or sets whether this tree list view will display hierarchical checkboxes. /// Hierarchical checkboxes is when a parent's "checkedness" is calculated from /// the "checkedness" of its children. If all children are checked, the parent /// will be checked. If all children are unchecked, the parent will also be unchecked. /// If some children are checked and others are not, the parent will be indeterminate. /// /// /// Hierarchical checkboxes don't work with either CheckStateGetters or CheckedAspectName /// (which is basically the same thing). This is because it is too expensive to build the /// initial state of the control if these are installed, since the control would have to walk /// *every* branch recursively since a single bottom level leaf could change the checkedness /// of the top root. /// [Category("ObjectListView"), Description("Show hierarchical checkboxes be enabled?"), DefaultValue(false)] public virtual bool HierarchicalCheckboxes { get { return hierarchicalCheckboxes; } set { if (hierarchicalCheckboxes == value) return; hierarchicalCheckboxes = value; CheckBoxes = value; if (value) TriStateCheckBoxes = false; } } private bool hierarchicalCheckboxes; /// /// Gets or sets the collection of root objects of the tree /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public override IEnumerable Objects { get { return Roots; } set { Roots = value; } } /// /// Gets the collection of objects that will be considered when creating clusters /// (which are used to generate Excel-like column filters) /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public override IEnumerable ObjectsForClustering { get { for (int i = 0; i < TreeModel.GetObjectCount(); i++) yield return TreeModel.GetNthObject(i); } } /// /// After expanding a branch, should the TreeListView attempts to show as much of the /// revealed descendents as possible. /// [Category("ObjectListView"), Description("Should the parent of an expand subtree be scrolled to the top revealing the children?"), DefaultValue(true)] public bool RevealAfterExpand { get { return revealAfterExpand; } set { revealAfterExpand = value; } } private bool revealAfterExpand = true; /// /// The model objects that form the top level branches of the tree. /// /// Setting this does NOT reset the state of the control. /// In particular, it does not collapse branches. [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual IEnumerable Roots { get { return TreeModel.RootObjects; } set { TreeColumnRenderer = TreeColumnRenderer; TreeModel.RootObjects = value ?? new ArrayList(); UpdateVirtualListSize(); } } /// /// Make sure that at least one column is displaying a tree. /// If no columns is showing the tree, make column 0 do it. /// protected virtual void EnsureTreeRendererPresent(TreeRenderer renderer) { if (Columns.Count == 0) return; foreach (OLVColumn col in Columns) { if (col.Renderer is TreeRenderer) { col.Renderer = renderer; return; } } // No column held a tree renderer, so give column 0 one OLVColumn columnZero = GetColumn(0); columnZero.Renderer = renderer; columnZero.WordWrap = columnZero.WordWrap; } /// /// Gets or sets the renderer that will be used to draw the tree structure. /// Setting this to null resets the renderer to default. /// /// If a column is currently rendering the tree, the renderer /// for that column will be replaced. If no column is rendering the tree, /// column 0 will be given this renderer. [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual TreeRenderer TreeColumnRenderer { get { return treeRenderer ?? (treeRenderer = new TreeRenderer()); } set { treeRenderer = value ?? new TreeRenderer(); EnsureTreeRendererPresent(treeRenderer); } } private TreeRenderer treeRenderer; /// /// This is the delegate that will be used to create the underlying Tree structure /// that the TreeListView uses to manage the information about the tree. /// /// /// The factory must not return null. /// /// Most users of TreeListView will never have to use this delegate. /// /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public TreeFactoryDelegate TreeFactory { get { return treeFactory; } set { treeFactory = value; } } private TreeFactoryDelegate treeFactory; /// /// Should a wait cursor be shown when a branch is being expanded? /// /// When this is true, the wait cursor will be shown whilst the children of the /// branch are being fetched. If the children of the branch have already been cached, /// the cursor will not change. [Category("ObjectListView"), Description("Should a wait cursor be shown when a branch is being expanded?"), DefaultValue(true)] public virtual bool UseWaitCursorWhenExpanding { get { return useWaitCursorWhenExpanding; } set { useWaitCursorWhenExpanding = value; } } private bool useWaitCursorWhenExpanding = true; /// /// Gets the model that is used to manage the tree structure /// /// /// Don't mess with this property unless you really know what you are doing. /// If you don't already know what it's for, you don't need it. [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public Tree TreeModel { get { return treeModel; } protected set { treeModel = value; } } private Tree treeModel; //------------------------------------------------------------------------------------------ // Accessing /// /// Return true if the branch at the given model is expanded /// /// /// public virtual bool IsExpanded(Object model) { Branch br = TreeModel.GetBranch(model); return (br != null && br.IsExpanded); } //------------------------------------------------------------------------------------------ // Commands /// /// Collapse the subtree underneath the given model /// /// public virtual void Collapse(Object model) { if (GetItemCount() == 0) return; OLVListItem item = ModelToItem(model); TreeBranchCollapsingEventArgs args = new TreeBranchCollapsingEventArgs(model, item); OnCollapsing(args); if (args.Canceled) return; IList selection = SelectedObjects; int index = TreeModel.Collapse(model); if (index >= 0) { UpdateVirtualListSize(); SelectedObjects = selection; if (index < GetItemCount()) RedrawItems(index, GetItemCount() - 1, true); OnCollapsed(new TreeBranchCollapsedEventArgs(model, item)); } } /// /// Collapse all subtrees within this control /// public virtual void CollapseAll() { if (GetItemCount() == 0) return; TreeBranchCollapsingEventArgs args = new TreeBranchCollapsingEventArgs(null, null); OnCollapsing(args); if (args.Canceled) return; IList selection = SelectedObjects; int index = TreeModel.CollapseAll(); if (index >= 0) { UpdateVirtualListSize(); SelectedObjects = selection; if (index < GetItemCount()) RedrawItems(index, GetItemCount() - 1, true); OnCollapsed(new TreeBranchCollapsedEventArgs(null, null)); } } /// /// Remove all items from this list /// /// This method can safely be called from background threads. public override void ClearObjects() { if (InvokeRequired) Invoke(new MethodInvoker(ClearObjects)); else { Roots = null; DiscardAllState(); } } /// /// Collapse all roots and forget everything we know about all models /// public virtual void DiscardAllState() { CheckStateMap.Clear(); RebuildAll(false); } /// /// Expand the subtree underneath the given model object /// /// public virtual void Expand(Object model) { if (GetItemCount() == 0) return; // Give the world a chance to cancel the expansion OLVListItem item = ModelToItem(model); TreeBranchExpandingEventArgs args = new TreeBranchExpandingEventArgs(model, item); OnExpanding(args); if (args.Canceled) return; // Remember the selection so we can put it back later IList selection = SelectedObjects; // Expand the model first int index = TreeModel.Expand(model); if (index < 0) return; // Update the size of the list and restore the selection UpdateVirtualListSize(); using (SuspendSelectionEventsDuring()) SelectedObjects = selection; // Redraw the items that were changed by the expand operation RedrawItems(index, GetItemCount() - 1, true); OnExpanded(new TreeBranchExpandedEventArgs(model, item)); if (RevealAfterExpand && index > 0) { // TODO: This should be a separate method BeginUpdate(); try { int countPerPage = NativeMethods.GetCountPerPage(this); int descedentCount = TreeModel.GetVisibleDescendentCount(model); // If all of the descendents can be shown in the window, make sure that last one is visible. // If all the descendents can't fit into the window, move the model to the top of the window // (which will show as many of the descendents as possible) if (descedentCount < countPerPage) { EnsureVisible(index + descedentCount); } else { TopItemIndex = index; } } finally { EndUpdate(); } } } /// /// Expand all the branches within this tree recursively. /// /// Be careful: this method could take a long time for large trees. public virtual void ExpandAll() { if (GetItemCount() == 0) return; // Give the world a chance to cancel the expansion TreeBranchExpandingEventArgs args = new TreeBranchExpandingEventArgs(null, null); OnExpanding(args); if (args.Canceled) return; IList selection = SelectedObjects; int index = TreeModel.ExpandAll(); if (index < 0) return; UpdateVirtualListSize(); using (SuspendSelectionEventsDuring()) SelectedObjects = selection; RedrawItems(index, GetItemCount() - 1, true); OnExpanded(new TreeBranchExpandedEventArgs(null, null)); } /// /// Completely rebuild the tree structure /// /// If true, the control will try to preserve selection and expansion public virtual void RebuildAll(bool preserveState) { int previousTopItemIndex = preserveState ? TopItemIndex : -1; RebuildAll( preserveState ? SelectedObjects : null, preserveState ? ExpandedObjects : null, preserveState ? CheckedObjects : null); if (preserveState) TopItemIndex = previousTopItemIndex; } /// /// Completely rebuild the tree structure /// /// If not null, this list of objects will be selected after the tree is rebuilt /// If not null, this collection of objects will be expanded after the tree is rebuilt /// If not null, this collection of objects will be checked after the tree is rebuilt protected virtual void RebuildAll(IList selected, IEnumerable expanded, IList checkedObjects) { // Remember the bits of info we don't want to forget (anyone ever see Memento?) IEnumerable roots = Roots; CanExpandGetterDelegate canExpand = CanExpandGetter; ChildrenGetterDelegate childrenGetter = ChildrenGetter; try { BeginUpdate(); // Give ourselves a new data structure RegenerateTree(); // Put back the bits we didn't want to forget CanExpandGetter = canExpand; ChildrenGetter = childrenGetter; if (expanded != null) ExpandedObjects = expanded; Roots = roots; if (selected != null) SelectedObjects = selected; if (checkedObjects != null) CheckedObjects = checkedObjects; } finally { EndUpdate(); } } /// /// Unroll all the ancestors of the given model and make sure it is then visible. /// /// This works best when a ParentGetter is installed. /// The object to be revealed /// If true, the model will be selected and focused after being revealed /// True if the object was found and revealed. False if it was not found. public virtual void Reveal(object modelToReveal, bool selectAfterReveal) { // Collect all the ancestors of the model ArrayList ancestors = new ArrayList(); foreach (object ancestor in GetAncestors(modelToReveal)) ancestors.Add(ancestor); // Arrange them from root down to the model's immediate parent ancestors.Reverse(); try { BeginUpdate(); foreach (object ancestor in ancestors) Expand(ancestor); EnsureModelVisible(modelToReveal); if (selectAfterReveal) SelectObject(modelToReveal, true); } finally { EndUpdate(); } } /// /// Update the rows that are showing the given objects /// public override void RefreshObjects(IList modelObjects) { if (InvokeRequired) { Invoke((MethodInvoker) delegate { RefreshObjects(modelObjects); }); return; } // There is no point in refreshing anything if the list is empty if (GetItemCount() == 0) return; // Remember the selection so we can put it back later IList selection = SelectedObjects; // We actually need to refresh the parents. // Refreshes on root objects have to be handled differently ArrayList updatedRoots = new ArrayList(); Hashtable modelsAndParents = new Hashtable(); foreach (Object model in modelObjects) { if (model == null) continue; modelsAndParents[model] = true; object parent = GetParent(model); if (parent == null) { updatedRoots.Add(model); } else { modelsAndParents[parent] = true; } } // Update any changed roots if (updatedRoots.Count > 0) { ArrayList newRoots = EnumerableToArray(Roots, false); bool changed = false; foreach (Object model in updatedRoots) { int index = newRoots.IndexOf(model); if (index >= 0 && !ReferenceEquals(newRoots[index], model)) { newRoots[index] = model; changed = true; } } if (changed) Roots = newRoots; } // Refresh each object, remembering where the first update occurred int firstChange = Int32.MaxValue; foreach (Object model in modelsAndParents.Keys) { if (model != null) { int index = TreeModel.RebuildChildren(model); if (index >= 0) firstChange = Math.Min(firstChange, index); } } // If we didn't refresh any objects, don't do anything else if (firstChange >= GetItemCount()) return; ClearCachedInfo(); UpdateVirtualListSize(); SelectedObjects = selection; // Redraw everything from the first update to the end of the list RedrawItems(firstChange, GetItemCount() - 1, true); } /// /// Change the check state of the given object to be the given state. /// /// /// If the given model object isn't in the list, we still try to remember /// its state, in case it is referenced in the future. /// /// /// True if the checkedness of the model changed protected override bool SetObjectCheckedness(object modelObject, CheckState state) { // If the checkedness of the given model changes AND this tree has // hierarchical checkboxes, then we need to update the checkedness of // its children, and recalculate the checkedness of the parent (recursively) if (!base.SetObjectCheckedness(modelObject, state)) return false; if (!HierarchicalCheckboxes) return true; // Give each child the same checkedness as the model CheckState? checkedness = GetCheckState(modelObject); if (!checkedness.HasValue || checkedness.Value == CheckState.Indeterminate) return true; foreach (object child in GetChildrenWithoutExpanding(modelObject)) { SetObjectCheckedness(child, checkedness.Value); } ArrayList args = new ArrayList(); args.Add(modelObject); RecalculateHierarchicalCheckBoxGraph(args); return true; } private IEnumerable GetChildrenWithoutExpanding(Object model) { Branch br = TreeModel.GetBranch(model); if (br == null || !br.CanExpand) return new ArrayList(); return br.Children; } /// /// Toggle the expanded state of the branch at the given model object /// /// public virtual void ToggleExpansion(Object model) { if (IsExpanded(model)) Collapse(model); else Expand(model); } //------------------------------------------------------------------------------------------ // Commands - Tree traversal /// /// Return whether or not the given model can expand. /// /// /// The given model must have already been seen in the tree public virtual bool CanExpand(Object model) { Branch br = TreeModel.GetBranch(model); return (br != null && br.CanExpand); } /// /// Return the model object that is the parent of the given model object. /// /// /// /// The given model must have already been seen in the tree. public virtual Object GetParent(Object model) { Branch br = TreeModel.GetBranch(model); return br == null || br.ParentBranch == null ? null : br.ParentBranch.Model; } /// /// Return the collection of model objects that are the children of the /// given model as they exist in the tree at the moment. /// /// /// /// /// This method returns the collection of children as the tree knows them. If the given /// model has never been presented to the user (e.g. it belongs to a parent that has /// never been expanded), then this method will return an empty collection. /// /// Because of this, if you want to traverse the whole tree, this is not the method to use. /// It's better to traverse the your data model directly. /// /// /// If the given model has not already been seen in the tree or /// if it is not expandable, an empty collection will be returned. /// /// public virtual IEnumerable GetChildren(Object model) { Branch br = TreeModel.GetBranch(model); if (br == null || !br.CanExpand) return new ArrayList(); br.FetchChildren(); return br.Children; } //------------------------------------------------------------------------------------------ // Delegates /// /// Delegates of this type are use to decide if the given model object can be expanded /// /// The model under consideration /// Can the given model be expanded? public delegate bool CanExpandGetterDelegate(Object model); /// /// Delegates of this type are used to fetch the children of the given model object /// /// The parent whose children should be fetched /// An enumerable over the children public delegate IEnumerable ChildrenGetterDelegate(Object model); /// /// Delegates of this type are used to fetch the parent of the given model object. /// /// The child whose parent should be fetched /// The parent of the child or null if the child is a root public delegate Object ParentGetterDelegate(Object model); /// /// Delegates of this type are used to create a new underlying Tree structure. /// /// The view for which the Tree is being created /// A subclass of Tree public delegate Tree TreeFactoryDelegate(TreeListView view); //------------------------------------------------------------------------------------------ #region Implementation /// /// Handle a left button down event /// /// /// protected override bool ProcessLButtonDown(OlvListViewHitTestInfo hti) { // Did they click in the expander? if (hti.HitTestLocation == HitTestLocation.ExpandButton) { PossibleFinishCellEditing(); ToggleExpansion(hti.RowObject); return true; } return base.ProcessLButtonDown(hti); } /// /// Create a OLVListItem for given row index /// /// The index of the row that is needed /// An OLVListItem /// This differs from the base method by also setting up the IndentCount property. public override OLVListItem MakeListViewItem(int itemIndex) { OLVListItem olvItem = base.MakeListViewItem(itemIndex); Branch br = TreeModel.GetBranch(olvItem.RowObject); if (br != null) olvItem.IndentCount = br.Level; return olvItem; } /// /// Reinitialize the Tree structure /// protected virtual void RegenerateTree() { TreeModel = TreeFactory == null ? new Tree(this) : TreeFactory(this); Trace.Assert(TreeModel != null); VirtualListDataSource = TreeModel; } /// /// Recalculate the state of the checkboxes of all the items in the given list /// and their ancestors. /// /// This only makes sense when HierarchicalCheckboxes is true. /// protected virtual void RecalculateHierarchicalCheckBoxGraph(IList toCheck) { if (toCheck == null || toCheck.Count == 0) return; // Avoid recursive calculations if (isRecalculatingHierarchicalCheckBox) return; try { isRecalculatingHierarchicalCheckBox = true; foreach (object ancestor in CalculateDistinctAncestors(toCheck)) RecalculateSingleHierarchicalCheckBox(ancestor); } finally { isRecalculatingHierarchicalCheckBox = false; } } private bool isRecalculatingHierarchicalCheckBox; /// /// Recalculate the hierarchy state of the given item and its ancestors /// /// This only makes sense when HierarchicalCheckboxes is true. /// protected virtual void RecalculateSingleHierarchicalCheckBox(object modelObject) { if (modelObject == null) return; // Only branches have calculated check states. Leaf node checkedness is not calculated if (!CanExpandUncached(modelObject)) return; // Set the checkedness of the given model based on the state of its children. CheckState? aggregate = null; foreach (object child in GetChildrenUncached(modelObject)) { CheckState? checkedness = GetCheckState(child); if (!checkedness.HasValue) continue; if (aggregate.HasValue) { if (aggregate.Value != checkedness.Value) { aggregate = CheckState.Indeterminate; break; } } else aggregate = checkedness; } base.SetObjectCheckedness(modelObject, aggregate ?? CheckState.Indeterminate); } private bool CanExpandUncached(object model) { return CanExpandGetter != null && model != null && CanExpandGetter(model); } private IEnumerable GetChildrenUncached(object model) { return ChildrenGetter != null && model != null ? ChildrenGetter(model) : new ArrayList(); } /// /// Yield the unique ancestors of the given collection of objects. /// The order of the ancestors is guaranteed to be deeper objects first. /// Roots will always be last. /// /// /// Unique ancestors of the given objects protected virtual IEnumerable CalculateDistinctAncestors(IList toCheck) { if (toCheck.Count == 1) { foreach (object ancestor in GetAncestors(toCheck[0])) { yield return ancestor; } } else { // WARNING - Clever code // Example: Root --> GP +--> P +--> A // | +--> B // | // +--> Q +--> X // +--> Y // // Calculate ancestors of A, B, X and Y // Build a list of all ancestors of all objects we need to check ArrayList allAncestors = new ArrayList(); foreach (object child in toCheck) { foreach (object ancestor in GetAncestors(child)) { allAncestors.Add(ancestor); } } // allAncestors = { P, GP, Root, P, GP, Root, Q, GP, Root, Q, GP, Root } // Reverse them so "higher" ancestors come first allAncestors.Reverse(); // allAncestors = { Root, GP, Q, Root, GP, Q, Root, GP, P, Root, GP, P } ArrayList uniqueAncestors = new ArrayList(); Dictionary alreadySeen = new Dictionary(); foreach (object ancestor in allAncestors) { if (!alreadySeen.ContainsKey(ancestor)) { alreadySeen[ancestor] = true; uniqueAncestors.Add(ancestor); } } // uniqueAncestors = { Root, GP, Q, P } uniqueAncestors.Reverse(); foreach (object x in uniqueAncestors) yield return x; } } /// /// Return all the ancestors of the given model /// /// /// /// This uses ParentGetter if possible. /// /// If the given model is a root OR if the model doesn't exist, the collection will be empty /// /// The model whose ancestors should be calculated /// Return a collection of ancestors of the given model. protected virtual IEnumerable GetAncestors(object model) { ParentGetterDelegate parentGetterDelegate = ParentGetter ?? GetParent; object parent = parentGetterDelegate(model); while (parent != null) { yield return parent; parent = parentGetterDelegate(parent); } } #endregion //------------------------------------------------------------------------------------------ #region Event handlers /// /// The application is idle and a SelectionChanged event has been scheduled /// /// /// protected override void HandleApplicationIdle(object sender, EventArgs e) { base.HandleApplicationIdle(sender, e); // There is an annoying redraw issue on ListViews that use indentation and // that have full row select enabled. When the selection reduces to a subset // of previously selected rows, or when the selection is extended using // shift-pageup/down, then the space occupied by the indentation is not // invalidated, and hence remains highlighted. // Ideally we'd want to know exactly which rows were selected or deselected // and then invalidate just the indentation region of those rows, // but that's too much work. So just redraw the control. // Actually... the selection issues show just slightly for non-full row select // controls as well. So, always redraw the control after the selection // changes. Invalidate(); } /// /// Decide if the given key event should be handled as a normal key input to the control? /// /// /// protected override bool IsInputKey(Keys keyData) { // We want to handle Left and Right keys within the control Keys key = keyData & Keys.KeyCode; if (key == Keys.Left || key == Keys.Right) return true; return base.IsInputKey(keyData); } /// /// Handle focus being lost, including making sure that the whole control is redrawn. /// /// protected override void OnLostFocus(EventArgs e) { // When this focus is lost, the normal invalidation logic doesn't invalid the region // of the control created by the IndentLevel on each row. This makes the control // look wrong when HideSelection is false, since part of the selected row's background // correctly changes colour to the "inactive" colour, but the left part of the row // created by IndentLevel doesn't change colour. // SF #135. Invalidate(); } /// /// Handle the keyboard input to mimic a TreeView. /// /// /// Was the key press handled? protected override void OnKeyDown(KeyEventArgs e) { if (FocusedItem is not OLVListItem focused) { base.OnKeyDown(e); return; } Object modelObject = focused.RowObject; Branch br = TreeModel.GetBranch(modelObject); switch (e.KeyCode) { case Keys.Left: // If the branch is expanded, collapse it. If it's collapsed, // select the parent of the branch. if (br.IsExpanded) Collapse(modelObject); else { if (br.ParentBranch != null && br.ParentBranch.Model != null) SelectObject(br.ParentBranch.Model, true); } e.Handled = true; break; case Keys.Right: // If the branch is expanded, select the first child. // If it isn't expanded and can be, expand it. if (br.IsExpanded) { List filtered = br.FilteredChildBranches; if (filtered.Count > 0) SelectObject(filtered[0].Model, true); } else { if (br.CanExpand) Expand(modelObject); } e.Handled = true; break; } base.OnKeyDown(e); } #endregion //------------------------------------------------------------------------------------------ // Support classes /// /// A Tree object represents a tree structure data model that supports both /// tree and flat list operations as well as fast access to branches. /// /// If you create a subclass of Tree, you must install it in the TreeListView /// via the TreeFactory delegate. public class Tree : IVirtualListDataSource, IFilterableDataSource { /// /// Create a Tree /// /// public Tree(TreeListView treeView) { this.treeView = treeView; trunk = new Branch(null, this, null); trunk.IsExpanded = true; } //------------------------------------------------------------------------------------------ // Properties /// /// This is the delegate that will be used to decide if a model object can be expanded. /// public CanExpandGetterDelegate CanExpandGetter { get { return canExpandGetter; } set { canExpandGetter = value; } } private CanExpandGetterDelegate canExpandGetter; /// /// This is the delegate that will be used to fetch the children of a model object /// /// This delegate will only be called if the CanExpand delegate has /// returned true for the model object. public ChildrenGetterDelegate ChildrenGetter { get { return childrenGetter; } set { childrenGetter = value; } } private ChildrenGetterDelegate childrenGetter; /// /// Get or return the top level model objects in the tree /// public IEnumerable RootObjects { get { return trunk.Children; } set { trunk.Children = value; foreach (Branch br in trunk.ChildBranches) br.RefreshChildren(); RebuildList(); } } /// /// What tree view is this Tree the model for? /// public TreeListView TreeView { get { return treeView; } } //------------------------------------------------------------------------------------------ // Commands /// /// Collapse the subtree underneath the given model /// /// The model to be collapsed. If the model isn't in the tree, /// or if it is already collapsed, the command does nothing. /// The index of the model in flat list version of the tree public virtual int Collapse(Object model) { Branch br = GetBranch(model); if (br == null || !br.IsExpanded) return -1; // Remember that the branch is collapsed, even if it's currently not visible if (!br.Visible) { br.Collapse(); return -1; } int count = br.NumberVisibleDescendents; br.Collapse(); // Remove the visible descendents from after the branch itself int index = GetObjectIndex(model); objectList.RemoveRange(index + 1, count); RebuildObjectMap(0); return index; } /// /// Collapse all branches in this tree /// /// Nothing useful public virtual int CollapseAll() { trunk.CollapseAll(); RebuildList(); return 0; } /// /// Expand the subtree underneath the given model object /// /// The model to be expanded. /// The index of the model in flat list version of the tree /// /// If the model isn't in the tree, /// if it cannot be expanded or if it is already expanded, the command does nothing. /// public virtual int Expand(Object model) { Branch br = GetBranch(model); if (br == null || !br.CanExpand || br.IsExpanded) return -1; // Remember that the branch is expanded, even if it's currently not visible br.Expand(); if (!br.Visible) { return -1; } int index = GetObjectIndex(model); InsertChildren(br, index + 1); return index; } /// /// Expand all branches in this tree /// /// Return the index of the first branch that was expanded public virtual int ExpandAll() { trunk.ExpandAll(); Sort(lastSortColumn, lastSortOrder); return 0; } /// /// Return the Branch object that represents the given model in the tree /// /// The model whose branches is to be returned /// The branch that represents the given model, or null if the model /// isn't in the tree. public virtual Branch GetBranch(object model) { if (model == null) return null; Branch br; mapObjectToBranch.TryGetValue(model, out br); return br; } /// /// Return the number of visible descendents that are below the given model. /// /// The model whose descendent count is to be returned /// The number of visible descendents. 0 if the model doesn't exist or is collapsed public virtual int GetVisibleDescendentCount(object model) { Branch br = GetBranch(model); return br == null || !br.IsExpanded ? 0 : br.NumberVisibleDescendents; } /// /// Rebuild the children of the given model, refreshing any cached information held about the given object /// /// /// The index of the model in flat list version of the tree public virtual int RebuildChildren(Object model) { Branch br = GetBranch(model); if (br == null || !br.Visible) return -1; int count = br.NumberVisibleDescendents; // Remove the visible descendents from after the branch itself int index = GetObjectIndex(model); if (count > 0) objectList.RemoveRange(index + 1, count); // Refresh our knowledge of our children (do this even if CanExpand is false, because // the branch have already collected some children and that information could be stale) br.RefreshChildren(); // Insert the refreshed children if the branch can expand and is expanded if (br.CanExpand && br.IsExpanded) InsertChildren(br, index + 1); else RebuildObjectMap(index); return index; } //------------------------------------------------------------------------------------------ // Implementation /// /// Is the given model expanded? /// /// /// internal bool IsModelExpanded(object model) { // Special case: model == null is the container for the roots. This is always expanded if (model == null) return true; bool isExpanded; mapObjectToExpanded.TryGetValue(model, out isExpanded); return isExpanded; } /// /// Remember whether or not the given model was expanded /// /// /// internal void SetModelExpanded(object model, bool isExpanded) { if (model == null) return; if (isExpanded) mapObjectToExpanded[model] = true; else mapObjectToExpanded.Remove(model); } /// /// Insert the children of the given branch into the given position /// /// The branch whose children should be inserted /// The index where the children should be inserted protected virtual void InsertChildren(Branch br, int index) { // Expand the branch br.Expand(); br.Sort(GetBranchComparer()); // Insert the branch's visible descendents after the branch itself objectList.InsertRange(index, br.Flatten()); RebuildObjectMap(index); } /// /// Rebuild our flat internal list of objects. /// protected virtual void RebuildList() { objectList = ArrayList.Adapter(trunk.Flatten()); List filtered = trunk.FilteredChildBranches; if (filtered.Count > 0) { filtered[0].IsFirstBranch = true; filtered[0].IsOnlyBranch = (filtered.Count == 1); } RebuildObjectMap(0); } /// /// Rebuild our reverse index that maps an object to its location /// in the filteredObjectList array. /// /// protected virtual void RebuildObjectMap(int startIndex) { if (startIndex == 0) mapObjectToIndex.Clear(); for (int i = startIndex; i < objectList.Count; i++) mapObjectToIndex[objectList[i]] = i; } /// /// Create a new branch within this tree /// /// /// /// internal Branch MakeBranch(Branch parent, object model) { Branch br = new Branch(parent, this, model); // Remember that the given branch is part of this tree. mapObjectToBranch[model] = br; return br; } //------------------------------------------------------------------------------------------ #region IVirtualListDataSource Members /// /// /// /// /// public virtual object GetNthObject(int n) { return objectList[n]; } /// /// /// /// public virtual int GetObjectCount() { return trunk.NumberVisibleDescendents; } /// /// /// /// /// public virtual int GetObjectIndex(object model) { int index; if (model != null && mapObjectToIndex.TryGetValue(model, out index)) return index; return -1; } /// /// /// /// /// public virtual void PrepareCache(int first, int last) { } /// /// /// /// /// /// /// /// public virtual int SearchText(string value, int first, int last, OLVColumn column) { return AbstractVirtualListDataSource.DefaultSearchText(value, first, last, column, this); } /// /// Sort the tree on the given column and in the given order /// /// /// public virtual void Sort(OLVColumn column, SortOrder order) { lastSortColumn = column; lastSortOrder = order; // TODO: Need to raise an AboutToSortEvent here // Sorting is going to change the order of the branches so clear // the "first branch" flag foreach (Branch b in trunk.ChildBranches) b.IsFirstBranch = false; trunk.Sort(GetBranchComparer()); RebuildList(); } /// /// /// /// protected virtual BranchComparer GetBranchComparer() { if (lastSortColumn == null) return null; return new BranchComparer(new ModelObjectComparer( lastSortColumn, lastSortOrder, treeView.SecondarySortColumn ?? treeView.GetColumn(0), treeView.SecondarySortColumn == null ? lastSortOrder : treeView.SecondarySortOrder)); } /// /// Add the given collection of objects to the roots of this tree /// /// public virtual void AddObjects(ICollection modelObjects) { ArrayList newRoots = EnumerableToArray(treeView.Roots, true); foreach (Object x in modelObjects) newRoots.Add(x); SetObjects(newRoots); } /// /// /// /// /// public void InsertObjects(int index, ICollection modelObjects) { throw new NotImplementedException(); } /// /// Remove all of the given objects from the roots of the tree. /// Any objects that is not already in the roots collection is ignored. /// /// public virtual void RemoveObjects(ICollection modelObjects) { ArrayList newRoots = new ArrayList(); foreach (Object x in treeView.Roots) newRoots.Add(x); foreach (Object x in modelObjects) { newRoots.Remove(x); mapObjectToIndex.Remove(x); } SetObjects(newRoots); } /// /// Set the roots of this tree to be the given collection /// /// public virtual void SetObjects(IEnumerable collection) { // We interpret a SetObjects() call as setting the roots of the tree treeView.Roots = collection; } /// /// Update/replace the nth object with the given object /// /// /// public void UpdateObject(int index, object modelObject) { ArrayList newRoots = EnumerableToArray(treeView.Roots, false); if (index < newRoots.Count) newRoots[index] = modelObject; SetObjects(newRoots); } #endregion #region IFilterableDataSource Members /// /// /// /// /// public void ApplyFilters(IModelFilter mFilter, IListFilter lFilter) { modelFilter = mFilter; listFilter = lFilter; RebuildList(); } /// /// Is this list currently being filtered? /// internal bool IsFiltering { get { return treeView.UseFiltering && (modelFilter != null || listFilter != null); } } /// /// Should the given model be included in this control? /// /// The model to consider /// True if it will be included internal bool IncludeModel(object model) { if (!treeView.UseFiltering) return true; if (modelFilter == null) return true; return modelFilter.Filter(model); } #endregion //------------------------------------------------------------------------------------------ // Private instance variables private OLVColumn lastSortColumn; private SortOrder lastSortOrder; private readonly Dictionary mapObjectToBranch = new(); // ReSharper disable once InconsistentNaming internal Dictionary mapObjectToExpanded = new(); private readonly Dictionary mapObjectToIndex = new(); private ArrayList objectList = new(); private readonly TreeListView treeView; private readonly Branch trunk; /// /// /// // ReSharper disable once InconsistentNaming protected IModelFilter modelFilter; /// /// /// // ReSharper disable once InconsistentNaming protected IListFilter listFilter; } /// /// A Branch represents a sub-tree within a tree /// public class Branch { /// /// Indicators for branches /// [Flags] public enum BranchFlags { /// /// FirstBranch of tree /// FirstBranch = 1, /// /// LastChild of parent /// LastChild = 2, /// /// OnlyBranch of tree /// OnlyBranch = 4 } #region Life and death /// /// Create a Branch /// /// /// /// public Branch(Branch parent, Tree tree, Object model) { ParentBranch = parent; Tree = tree; Model = model; } #endregion #region Public properties //------------------------------------------------------------------------------------------ // Properties /// /// Get the ancestor branches of this branch, with the 'oldest' ancestor first. /// public virtual IList Ancestors { get { List ancestors = new List(); if (ParentBranch != null) ParentBranch.PushAncestors(ancestors); return ancestors; } } private void PushAncestors(IList list) { // This is designed to ignore the trunk (which has no parent) if (ParentBranch != null) { ParentBranch.PushAncestors(list); list.Add(this); } } /// /// Can this branch be expanded? /// public virtual bool CanExpand { get { if (Tree.CanExpandGetter == null || Model == null) return false; return Tree.CanExpandGetter(Model); } } /// /// Gets or sets our children /// public List ChildBranches { get { return childBranches; } set { childBranches = value; } } private List childBranches = new(); /// /// Get/set the model objects that are beneath this branch /// public virtual IEnumerable Children { get { ArrayList children = new ArrayList(); foreach (Branch x in ChildBranches) children.Add(x.Model); return children; } set { ChildBranches.Clear(); TreeListView treeListView = Tree.TreeView; CheckState? checkedness = null; if (treeListView != null && treeListView.HierarchicalCheckboxes) checkedness = treeListView.GetCheckState(Model); foreach (Object x in value) { AddChild(x); // If the tree view is showing hierarchical checkboxes, then // when a child object is first added, it has the same checkedness as this branch if (checkedness.HasValue && checkedness.Value == CheckState.Checked) treeListView.SetObjectCheckedness(x, checkedness.Value); } } } private void AddChild(object childModel) { Branch br = Tree.GetBranch(childModel); if (br == null) br = Tree.MakeBranch(this, childModel); else { br.ParentBranch = this; br.Model = childModel; br.ClearCachedInfo(); } ChildBranches.Add(br); } /// /// Gets a list of all the branches that survive filtering /// public List FilteredChildBranches { get { if (!IsExpanded) return new List(); if (!Tree.IsFiltering) return ChildBranches; List filtered = new List(); foreach (Branch b in ChildBranches) { if (Tree.IncludeModel(b.Model)) filtered.Add(b); else { // Also include this branch if it has any filtered branches (yes, its recursive) if (b.FilteredChildBranches.Count > 0) filtered.Add(b); } } return filtered; } } /// /// Gets or set whether this branch is expanded /// public bool IsExpanded { get { return Tree.IsModelExpanded(Model); } set { Tree.SetModelExpanded(Model, value); } } /// /// Return true if this branch is the first branch of the entire tree /// public virtual bool IsFirstBranch { get { return ((flags & BranchFlags.FirstBranch) != 0); } set { if (value) flags |= BranchFlags.FirstBranch; else flags &= ~BranchFlags.FirstBranch; } } /// /// Return true if this branch is the last child of its parent /// public virtual bool IsLastChild { get { return ((flags & BranchFlags.LastChild) != 0); } set { if (value) flags |= BranchFlags.LastChild; else flags &= ~BranchFlags.LastChild; } } /// /// Return true if this branch is the only top level branch /// public virtual bool IsOnlyBranch { get { return ((flags & BranchFlags.OnlyBranch) != 0); } set { if (value) flags |= BranchFlags.OnlyBranch; else flags &= ~BranchFlags.OnlyBranch; } } /// /// Gets the depth level of this branch /// public int Level { get { if (ParentBranch == null) return 0; return ParentBranch.Level + 1; } } /// /// Gets or sets which model is represented by this branch /// public Object Model { get { return model; } set { model = value; } } private Object model; /// /// Return the number of descendents of this branch that are currently visible /// /// public virtual int NumberVisibleDescendents { get { if (!IsExpanded) return 0; List filtered = FilteredChildBranches; int count = filtered.Count; foreach (Branch br in filtered) count += br.NumberVisibleDescendents; return count; } } /// /// Gets or sets our parent branch /// public Branch ParentBranch { get { return parentBranch; } set { parentBranch = value; } } private Branch parentBranch; /// /// Gets or sets our overall tree /// public Tree Tree { get { return tree; } set { tree = value; } } private Tree tree; /// /// Is this branch currently visible? A branch is visible /// if it has no parent (i.e. it's a root), or its parent /// is visible and expanded. /// public virtual bool Visible { get { if (ParentBranch == null) return true; return ParentBranch.IsExpanded && ParentBranch.Visible; } } #endregion #region Commands //------------------------------------------------------------------------------------------ // Commands /// /// Clear any cached information that this branch is holding /// public virtual void ClearCachedInfo() { Children = new ArrayList(); alreadyHasChildren = false; } /// /// Collapse this branch /// public virtual void Collapse() { IsExpanded = false; } /// /// Expand this branch /// public virtual void Expand() { if (CanExpand) { IsExpanded = true; FetchChildren(); } } /// /// Expand this branch recursively /// public virtual void ExpandAll() { Expand(); foreach (Branch br in ChildBranches) { if (br.CanExpand) br.ExpandAll(); } } /// /// Collapse all branches in this tree /// /// Nothing useful public virtual void CollapseAll() { Collapse(); foreach (Branch br in ChildBranches) { if (br.IsExpanded) br.CollapseAll(); } } /// /// Fetch the children of this branch. /// /// This should only be called when CanExpand is true. public virtual void FetchChildren() { if (alreadyHasChildren) return; alreadyHasChildren = true; if (Tree.ChildrenGetter == null) return; Cursor previous = Cursor.Current; try { if (Tree.TreeView.UseWaitCursorWhenExpanding) Cursor.Current = Cursors.WaitCursor; Children = Tree.ChildrenGetter(Model); } finally { Cursor.Current = previous; } } /// /// Collapse the visible descendents of this branch into list of model objects /// /// public virtual IList Flatten() { ArrayList flatList = new ArrayList(); if (IsExpanded) FlattenOnto(flatList); return flatList; } /// /// Flatten this branch's visible descendents onto the given list. /// /// /// The branch itself is not included in the list. public virtual void FlattenOnto(IList flatList) { Branch lastBranch = null; foreach (Branch br in FilteredChildBranches) { lastBranch = br; br.IsLastChild = false; flatList.Add(br.Model); if (br.IsExpanded) { br.FetchChildren(); // make sure we have the branches children br.FlattenOnto(flatList); } } if (lastBranch != null) lastBranch.IsLastChild = true; } /// /// Force a refresh of all children recursively /// public virtual void RefreshChildren() { // Forget any previous children. We always do this so that if // IsExpanded or CanExpand have changed, we aren't left with stale information. ClearCachedInfo(); if (!IsExpanded || !CanExpand) return; FetchChildren(); foreach (Branch br in ChildBranches) br.RefreshChildren(); } /// /// Sort the sub-branches and their descendents so they are ordered according /// to the given comparer. /// /// The comparer that orders the branches public virtual void Sort(BranchComparer comparer) { if (ChildBranches.Count == 0) return; if (comparer != null) ChildBranches.Sort(comparer); foreach (Branch br in ChildBranches) br.Sort(comparer); } #endregion //------------------------------------------------------------------------------------------ // Private instance variables private bool alreadyHasChildren; private BranchFlags flags; } /// /// This class sorts branches according to how their respective model objects are sorted /// public class BranchComparer : IComparer { /// /// Create a BranchComparer /// /// public BranchComparer(IComparer actualComparer) { this.actualComparer = actualComparer; } /// /// Order the two branches /// /// /// /// public int Compare(Branch x, Branch y) { return actualComparer.Compare(x.Model, y.Model); } private readonly IComparer actualComparer; } } } ================================================ FILE: source/ObjectListView/Utilities/ColumnSelectionForm.Designer.cs ================================================ namespace BrightIdeasSoftware { partial class ColumnSelectionForm { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.buttonMoveUp = new System.Windows.Forms.Button(); this.buttonMoveDown = new System.Windows.Forms.Button(); this.buttonShow = new System.Windows.Forms.Button(); this.buttonHide = new System.Windows.Forms.Button(); this.label1 = new System.Windows.Forms.Label(); this.buttonOK = new System.Windows.Forms.Button(); this.buttonCancel = new System.Windows.Forms.Button(); this.objectListView1 = new BrightIdeasSoftware.ObjectListView(); this.olvColumn1 = new BrightIdeasSoftware.OLVColumn(); ((System.ComponentModel.ISupportInitialize)(this.objectListView1)).BeginInit(); this.SuspendLayout(); // // buttonMoveUp // this.buttonMoveUp.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.buttonMoveUp.Location = new System.Drawing.Point(295, 31); this.buttonMoveUp.Name = "buttonMoveUp"; this.buttonMoveUp.Size = new System.Drawing.Size(87, 23); this.buttonMoveUp.TabIndex = 1; this.buttonMoveUp.Text = "Move &Up"; this.buttonMoveUp.UseVisualStyleBackColor = true; this.buttonMoveUp.Click += new System.EventHandler(this.buttonMoveUp_Click); // // buttonMoveDown // this.buttonMoveDown.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.buttonMoveDown.Location = new System.Drawing.Point(295, 60); this.buttonMoveDown.Name = "buttonMoveDown"; this.buttonMoveDown.Size = new System.Drawing.Size(87, 23); this.buttonMoveDown.TabIndex = 2; this.buttonMoveDown.Text = "Move &Down"; this.buttonMoveDown.UseVisualStyleBackColor = true; this.buttonMoveDown.Click += new System.EventHandler(this.buttonMoveDown_Click); // // buttonShow // this.buttonShow.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.buttonShow.Location = new System.Drawing.Point(295, 89); this.buttonShow.Name = "buttonShow"; this.buttonShow.Size = new System.Drawing.Size(87, 23); this.buttonShow.TabIndex = 3; this.buttonShow.Text = "&Show"; this.buttonShow.UseVisualStyleBackColor = true; this.buttonShow.Click += new System.EventHandler(this.buttonShow_Click); // // buttonHide // this.buttonHide.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.buttonHide.Location = new System.Drawing.Point(295, 118); this.buttonHide.Name = "buttonHide"; this.buttonHide.Size = new System.Drawing.Size(87, 23); this.buttonHide.TabIndex = 4; this.buttonHide.Text = "&Hide"; this.buttonHide.UseVisualStyleBackColor = true; this.buttonHide.Click += new System.EventHandler(this.buttonHide_Click); // // label1 // this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.label1.BackColor = System.Drawing.SystemColors.Control; this.label1.Location = new System.Drawing.Point(13, 9); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(366, 19); this.label1.TabIndex = 5; this.label1.Text = "Choose the columns you want to see in this list. "; // // buttonOK // this.buttonOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.buttonOK.Location = new System.Drawing.Point(198, 304); this.buttonOK.Name = "buttonOK"; this.buttonOK.Size = new System.Drawing.Size(87, 23); this.buttonOK.TabIndex = 6; this.buttonOK.Text = "&OK"; this.buttonOK.UseVisualStyleBackColor = true; this.buttonOK.Click += new System.EventHandler(this.buttonOK_Click); // // buttonCancel // this.buttonCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.buttonCancel.Location = new System.Drawing.Point(295, 304); this.buttonCancel.Name = "buttonCancel"; this.buttonCancel.Size = new System.Drawing.Size(87, 23); this.buttonCancel.TabIndex = 7; this.buttonCancel.Text = "&Cancel"; this.buttonCancel.UseVisualStyleBackColor = true; this.buttonCancel.Click += new System.EventHandler(this.buttonCancel_Click); // // objectListView1 // this.objectListView1.AllColumns.Add(this.olvColumn1); this.objectListView1.AlternateRowBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(192)))), ((int)(((byte)(255)))), ((int)(((byte)(192))))); this.objectListView1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.objectListView1.CellEditActivation = BrightIdeasSoftware.ObjectListView.CellEditActivateMode.SingleClick; this.objectListView1.CheckBoxes = true; this.objectListView1.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { this.olvColumn1}); this.objectListView1.FullRowSelect = true; this.objectListView1.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.None; this.objectListView1.HideSelection = false; this.objectListView1.Location = new System.Drawing.Point(12, 31); this.objectListView1.MultiSelect = false; this.objectListView1.Name = "objectListView1"; this.objectListView1.ShowGroups = false; this.objectListView1.ShowSortIndicators = false; this.objectListView1.Size = new System.Drawing.Size(273, 259); this.objectListView1.TabIndex = 0; this.objectListView1.UseCompatibleStateImageBehavior = false; this.objectListView1.View = System.Windows.Forms.View.Details; this.objectListView1.SelectionChanged += new System.EventHandler(this.objectListView1_SelectionChanged); // // olvColumn1 // this.olvColumn1.AspectName = "Text"; this.olvColumn1.IsVisible = true; this.olvColumn1.Text = "Column"; this.olvColumn1.Width = 267; // // ColumnSelectionForm // this.AcceptButton = this.buttonOK; this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.CancelButton = this.buttonCancel; this.ClientSize = new System.Drawing.Size(391, 339); this.Controls.Add(this.buttonCancel); this.Controls.Add(this.buttonOK); this.Controls.Add(this.label1); this.Controls.Add(this.buttonHide); this.Controls.Add(this.buttonShow); this.Controls.Add(this.buttonMoveDown); this.Controls.Add(this.buttonMoveUp); this.Controls.Add(this.objectListView1); this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "ColumnSelectionForm"; this.ShowIcon = false; this.ShowInTaskbar = false; this.Text = "Column Selection"; ((System.ComponentModel.ISupportInitialize)(this.objectListView1)).EndInit(); this.ResumeLayout(false); } #endregion private BrightIdeasSoftware.ObjectListView objectListView1; private System.Windows.Forms.Button buttonMoveUp; private System.Windows.Forms.Button buttonMoveDown; private System.Windows.Forms.Button buttonShow; private System.Windows.Forms.Button buttonHide; private BrightIdeasSoftware.OLVColumn olvColumn1; private System.Windows.Forms.Label label1; private System.Windows.Forms.Button buttonOK; private System.Windows.Forms.Button buttonCancel; } } ================================================ FILE: source/ObjectListView/Utilities/ColumnSelectionForm.cs ================================================ /* * ColumnSelectionForm - A utility form that allows columns to be rearranged and/or hidden * * Author: Phillip Piper * Date: 1/04/2011 11:15 AM * * Change log: * 2013-04-21 JPP - Fixed obscure bug in column re-ordered. Thanks to Edwin Chen. */ using System; using System.Collections.Generic; using System.Windows.Forms; namespace BrightIdeasSoftware { /// /// This form is an example of how an application could allows the user to select which columns /// an ObjectListView will display, as well as select which order the columns are displayed in. /// /// /// In Tile view, ColumnHeader.DisplayIndex does nothing. To reorder the columns you have /// to change the order of objects in the Columns property. /// Remember that the first column is special! /// It has to remain the first column. /// public partial class ColumnSelectionForm : Form { /// /// Make a new ColumnSelectionForm /// public ColumnSelectionForm() { InitializeComponent(); } /// /// Open this form so it will edit the columns that are available in the listview's current view /// /// The ObjectListView whose columns are to be altered public void OpenOn(ObjectListView olv) { OpenOn(olv, olv.View); } /// /// Open this form so it will edit the columns that are available in the given listview /// when the listview is showing the given type of view. /// /// The ObjectListView whose columns are to be altered /// The view that is to be altered. Must be View.Details or View.Tile public void OpenOn(ObjectListView olv, View view) { if (view != View.Details && view != View.Tile) return; InitializeForm(olv, view); if (ShowDialog() == DialogResult.OK) Apply(olv, view); } /// /// Initialize the form to show the columns of the given view /// /// /// protected void InitializeForm(ObjectListView olv, View view) { AllColumns = olv.AllColumns; RearrangableColumns = new List(AllColumns); foreach (OLVColumn col in RearrangableColumns) { if (view == View.Details) MapColumnToVisible[col] = col.IsVisible; else MapColumnToVisible[col] = col.IsTileViewColumn; } RearrangableColumns.Sort(new SortByDisplayOrder(this)); objectListView1.BooleanCheckStateGetter = delegate(Object rowObject) { return MapColumnToVisible[(OLVColumn)rowObject]; }; objectListView1.BooleanCheckStatePutter = delegate(Object rowObject, bool newValue) { // Some columns should always be shown, so ignore attempts to hide them OLVColumn column = (OLVColumn)rowObject; if (!column.CanBeHidden) return true; MapColumnToVisible[column] = newValue; EnableControls(); return newValue; }; objectListView1.SetObjects(RearrangableColumns); EnableControls(); } private List AllColumns = null; private List RearrangableColumns = new(); private Dictionary MapColumnToVisible = new(); /// /// The user has pressed OK. Do what's requied. /// /// /// protected void Apply(ObjectListView olv, View view) { olv.Freeze(); // Update the column definitions to reflect whether they have been hidden if (view == View.Details) { foreach (OLVColumn col in olv.AllColumns) col.IsVisible = MapColumnToVisible[col]; } else { foreach (OLVColumn col in olv.AllColumns) col.IsTileViewColumn = MapColumnToVisible[col]; } // Collect the columns are still visible List visibleColumns = RearrangableColumns.FindAll( delegate(OLVColumn x) { return MapColumnToVisible[x]; }); // Detail view and Tile view have to be handled in different ways. if (view == View.Details) { // Of the still visible columns, change DisplayIndex to reflect their position in the rearranged list olv.ChangeToFilteredColumns(view); foreach (OLVColumn col in visibleColumns) { col.DisplayIndex = visibleColumns.IndexOf((OLVColumn)col); col.LastDisplayIndex = col.DisplayIndex; } } else { // In Tile view, DisplayOrder does nothing. So to change the display order, we have to change the // order of the columns in the Columns property. // Remember, the primary column is special and has to remain first! OLVColumn primaryColumn = AllColumns[0]; visibleColumns.Remove(primaryColumn); olv.Columns.Clear(); olv.Columns.Add(primaryColumn); olv.Columns.AddRange(visibleColumns.ToArray()); olv.CalculateReasonableTileSize(); } olv.Unfreeze(); } #region Event handlers private void buttonMoveUp_Click(object sender, EventArgs e) { int selectedIndex = objectListView1.SelectedIndices[0]; OLVColumn col = RearrangableColumns[selectedIndex]; RearrangableColumns.RemoveAt(selectedIndex); RearrangableColumns.Insert(selectedIndex-1, col); objectListView1.BuildList(); EnableControls(); } private void buttonMoveDown_Click(object sender, EventArgs e) { int selectedIndex = objectListView1.SelectedIndices[0]; OLVColumn col = RearrangableColumns[selectedIndex]; RearrangableColumns.RemoveAt(selectedIndex); RearrangableColumns.Insert(selectedIndex + 1, col); objectListView1.BuildList(); EnableControls(); } private void buttonShow_Click(object sender, EventArgs e) { objectListView1.SelectedItem.Checked = true; } private void buttonHide_Click(object sender, EventArgs e) { objectListView1.SelectedItem.Checked = false; } private void buttonOK_Click(object sender, EventArgs e) { DialogResult = DialogResult.OK; Close(); } private void buttonCancel_Click(object sender, EventArgs e) { DialogResult = DialogResult.Cancel; Close(); } private void objectListView1_SelectionChanged(object sender, EventArgs e) { EnableControls(); } #endregion #region Control enabling /// /// Enable the controls on the dialog to match the current state /// protected void EnableControls() { if (objectListView1.SelectedIndices.Count == 0) { buttonMoveUp.Enabled = false; buttonMoveDown.Enabled = false; buttonShow.Enabled = false; buttonHide.Enabled = false; } else { // Can't move the first row up or the last row down buttonMoveUp.Enabled = (objectListView1.SelectedIndices[0] != 0); buttonMoveDown.Enabled = (objectListView1.SelectedIndices[0] < (objectListView1.GetItemCount() - 1)); OLVColumn selectedColumn = (OLVColumn)objectListView1.SelectedObject; // Some columns cannot be hidden (and hence cannot be Shown) buttonShow.Enabled = !MapColumnToVisible[selectedColumn] && selectedColumn.CanBeHidden; buttonHide.Enabled = MapColumnToVisible[selectedColumn] && selectedColumn.CanBeHidden; } } #endregion /// /// A Comparer that will sort a list of columns so that visible ones come before hidden ones, /// and that are ordered by their display order. /// private class SortByDisplayOrder : IComparer { public SortByDisplayOrder(ColumnSelectionForm form) { Form = form; } private ColumnSelectionForm Form; #region IComparer Members int IComparer.Compare(OLVColumn x, OLVColumn y) { if (Form.MapColumnToVisible[x] && !Form.MapColumnToVisible[y]) return -1; if (!Form.MapColumnToVisible[x] && Form.MapColumnToVisible[y]) return 1; if (x.DisplayIndex == y.DisplayIndex) return string.Compare(x.Text, y.Text, StringComparison.CurrentCultureIgnoreCase); else return x.DisplayIndex - y.DisplayIndex; } #endregion } } } ================================================ FILE: source/ObjectListView/Utilities/ColumnSelectionForm.resx ================================================ text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ================================================ FILE: source/ObjectListView/Utilities/Generator.cs ================================================ /* * Generator - Utility methods that generate columns or methods * * Author: Phillip Piper * Date: 15/08/2009 22:37 * * Change log: * 2015-06-17 JPP - Columns without [OLVColumn] now auto size * 2012-08-16 JPP - Generator now considers [OLVChildren] and [OLVIgnore] attributes. * 2012-06-14 JPP - Allow columns to be generated even if they are not marked with [OLVColumn] * - Converted class from static to instance to allow it to be subclassed. * Also, added IGenerator to allow it to be completely reimplemented. * v2.5.1 * 2010-11-01 JPP - DisplayIndex is now set correctly for columns that lack that attribute * v2.4.1 * 2010-08-25 JPP - Generator now also resets sort columns * v2.4 * 2010-04-14 JPP - Allow Name property to be set * - Don't double set the Text property * v2.3 * 2009-08-15 JPP - Initial version * * To do: * * Copyright (C) 2009-2014 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Globalization; using System.Reflection; using System.Text.RegularExpressions; using System.Windows.Forms; namespace BrightIdeasSoftware { /// /// An object that implements the IGenerator interface provides the ability /// to dynamically create columns /// for an ObjectListView based on the characteristics of a given collection /// of model objects. /// public interface IGenerator { /// /// Generate columns into the given ObjectListView that come from the given /// model object type. /// /// The ObjectListView to modify /// The model type whose attributes will be considered. /// Will columns be generated for properties that are not marked with [OLVColumn]. void GenerateAndReplaceColumns(ObjectListView olv, Type type, bool allProperties); /// /// Generate a list of OLVColumns based on the attributes of the given type /// If allProperties to true, all public properties will have a matching column generated. /// If allProperties is false, only properties that have a OLVColumn attribute will have a column generated. /// /// /// Will columns be generated for properties that are not marked with [OLVColumn]. /// A collection of OLVColumns matching the attributes of Type that have OLVColumnAttributes. IList GenerateColumns(Type type, bool allProperties); } /// /// The Generator class provides methods to dynamically create columns /// for an ObjectListView based on the characteristics of a given collection /// of model objects. /// /// /// For a given type, a Generator can create columns to match the public properties /// of that type. The generator can consider all public properties or only those public properties marked with /// [OLVColumn] attribute. /// public class Generator : IGenerator { #region Static convenience methods /// /// Gets or sets the actual generator used by the static convinence methods. /// /// If you subclass the standard generator or implement IGenerator yourself, /// you should install an instance of your subclass/implementation here. public static IGenerator Instance { get { return instance ?? (instance = new Generator()); } set { instance = value; } } private static IGenerator instance; /// /// Replace all columns of the given ObjectListView with columns generated /// from the first member of the given enumerable. If the enumerable is /// empty or null, the ObjectListView will be cleared. /// /// The ObjectListView to modify /// The collection whose first element will be used to generate columns. static public void GenerateColumns(ObjectListView olv, IEnumerable enumerable) { GenerateColumns(olv, enumerable, false); } /// /// Replace all columns of the given ObjectListView with columns generated /// from the first member of the given enumerable. If the enumerable is /// empty or null, the ObjectListView will be cleared. /// /// The ObjectListView to modify /// The collection whose first element will be used to generate columns. /// Will columns be generated for properties that are not marked with [OLVColumn]. static public void GenerateColumns(ObjectListView olv, IEnumerable enumerable, bool allProperties) { // Generate columns based on the type of the first model in the collection and then quit if (enumerable != null) { foreach (object model in enumerable) { Instance.GenerateAndReplaceColumns(olv, model.GetType(), allProperties); return; } } // If we reach here, the collection was empty, so we clear the list Instance.GenerateAndReplaceColumns(olv, null, allProperties); } /// /// Generate columns into the given ObjectListView that come from the public properties of the given /// model object type. /// /// The ObjectListView to modify /// The model type whose attributes will be considered. static public void GenerateColumns(ObjectListView olv, Type type) { Instance.GenerateAndReplaceColumns(olv, type, false); } /// /// Generate columns into the given ObjectListView that come from the public properties of the given /// model object type. /// /// The ObjectListView to modify /// The model type whose attributes will be considered. /// Will columns be generated for properties that are not marked with [OLVColumn]. static public void GenerateColumns(ObjectListView olv, Type type, bool allProperties) { Instance.GenerateAndReplaceColumns(olv, type, allProperties); } /// /// Generate a list of OLVColumns based on the public properties of the given type /// that have a OLVColumn attribute. /// /// /// A collection of OLVColumns matching the attributes of Type that have OLVColumnAttributes. static public IList GenerateColumns(Type type) { return Instance.GenerateColumns(type, false); } #endregion #region Public interface /// /// Generate columns into the given ObjectListView that come from the given /// model object type. /// /// The ObjectListView to modify /// The model type whose attributes will be considered. /// Will columns be generated for properties that are not marked with [OLVColumn]. public virtual void GenerateAndReplaceColumns(ObjectListView olv, Type type, bool allProperties) { IList columns = GenerateColumns(type, allProperties); if (olv is TreeListView tlv) TryGenerateChildrenDelegates(tlv, type); ReplaceColumns(olv, columns); } /// /// Generate a list of OLVColumns based on the attributes of the given type /// If allProperties to true, all public properties will have a matching column generated. /// If allProperties is false, only properties that have a OLVColumn attribute will have a column generated. /// /// /// Will columns be generated for properties that are not marked with [OLVColumn]. /// A collection of OLVColumns matching the attributes of Type that have OLVColumnAttributes. public virtual IList GenerateColumns(Type type, bool allProperties) { List columns = new List(); // Sanity if (type == null) return columns; // Iterate all public properties in the class and build columns from those that have // an OLVColumn attribute and that are not ignored. foreach (PropertyInfo pinfo in type.GetProperties()) { if (Attribute.GetCustomAttribute(pinfo, typeof(OLVIgnoreAttribute)) != null) continue; if (Attribute.GetCustomAttribute(pinfo, typeof(OLVColumnAttribute)) is not OLVColumnAttribute attr) { if (allProperties) columns.Add(MakeColumnFromPropertyInfo(pinfo)); } else { columns.Add(MakeColumnFromAttribute(pinfo, attr)); } } // How many columns have DisplayIndex specifically set? int countPositiveDisplayIndex = 0; foreach (OLVColumn col in columns) { if (col.DisplayIndex >= 0) countPositiveDisplayIndex += 1; } // Give columns that don't have a DisplayIndex an incremental index int columnIndex = countPositiveDisplayIndex; foreach (OLVColumn col in columns) if (col.DisplayIndex < 0) col.DisplayIndex = (columnIndex++); columns.Sort(delegate(OLVColumn x, OLVColumn y) { return x.DisplayIndex.CompareTo(y.DisplayIndex); }); return columns; } #endregion #region Implementation /// /// Replace all the columns in the given listview with the given list of columns. /// /// /// protected virtual void ReplaceColumns(ObjectListView olv, IList columns) { olv.Reset(); // Are there new columns to add? if (columns == null || columns.Count == 0) return; // Setup the columns olv.AllColumns.AddRange(columns); PostCreateColumns(olv); } /// /// Post process columns after creating them and adding them to the AllColumns collection. /// /// public virtual void PostCreateColumns(ObjectListView olv) { if (olv.AllColumns.Exists(delegate(OLVColumn x) { return x.CheckBoxes; })) olv.UseSubItemCheckBoxes = true; if (olv.AllColumns.Exists(delegate(OLVColumn x) { return x.Index > 0 && (x.ImageGetter != null || !String.IsNullOrEmpty(x.ImageAspectName)); })) olv.ShowImagesOnSubItems = true; olv.RebuildColumns(); olv.AutoSizeColumns(); } /// /// Create a column from the given PropertyInfo and OLVColumn attribute /// /// /// /// protected virtual OLVColumn MakeColumnFromAttribute(PropertyInfo pinfo, OLVColumnAttribute attr) { return MakeColumn(pinfo.Name, DisplayNameToColumnTitle(pinfo.Name), pinfo.CanWrite, pinfo.PropertyType, attr); } /// /// Make a column from the given PropertyInfo /// /// /// protected virtual OLVColumn MakeColumnFromPropertyInfo(PropertyInfo pinfo) { return MakeColumn(pinfo.Name, DisplayNameToColumnTitle(pinfo.Name), pinfo.CanWrite, pinfo.PropertyType, null); } /// /// Make a column from the given PropertyDescriptor /// /// /// public virtual OLVColumn MakeColumnFromPropertyDescriptor(PropertyDescriptor pd) { OLVColumnAttribute attr = pd.Attributes[typeof(OLVColumnAttribute)] as OLVColumnAttribute; return MakeColumn(pd.Name, DisplayNameToColumnTitle(pd.DisplayName), !pd.IsReadOnly, pd.PropertyType, attr); } /// /// Create a column with all the given information /// /// /// /// /// /// /// protected virtual OLVColumn MakeColumn(string aspectName, string title, bool editable, Type propertyType, OLVColumnAttribute attr) { OLVColumn column = MakeColumn(aspectName, title, attr); column.Name = (attr == null || String.IsNullOrEmpty(attr.Name)) ? aspectName : attr.Name; ConfigurePossibleBooleanColumn(column, propertyType); if (attr == null) { column.IsEditable = editable; column.Width = -1; // Auto size return column; } column.AspectToStringFormat = attr.AspectToStringFormat; if (attr.IsCheckBoxesSet) column.CheckBoxes = attr.CheckBoxes; column.DisplayIndex = attr.DisplayIndex; column.FillsFreeSpace = attr.FillsFreeSpace; if (attr.IsFreeSpaceProportionSet) column.FreeSpaceProportion = attr.FreeSpaceProportion; column.GroupWithItemCountFormat = attr.GroupWithItemCountFormat; column.GroupWithItemCountSingularFormat = attr.GroupWithItemCountSingularFormat; column.Hyperlink = attr.Hyperlink; column.ImageAspectName = attr.ImageAspectName; column.IsEditable = attr.IsEditableSet ? attr.IsEditable : editable; column.IsTileViewColumn = attr.IsTileViewColumn; column.IsVisible = attr.IsVisible; column.MaximumWidth = attr.MaximumWidth; column.MinimumWidth = attr.MinimumWidth; column.Tag = attr.Tag; if (attr.IsTextAlignSet) column.TextAlign = attr.TextAlign; column.ToolTipText = attr.ToolTipText; if (attr.IsTriStateCheckBoxesSet) column.TriStateCheckBoxes = attr.TriStateCheckBoxes; column.UseInitialLetterForGroup = attr.UseInitialLetterForGroup; column.Width = attr.Width; if (attr.GroupCutoffs != null && attr.GroupDescriptions != null) column.MakeGroupies(attr.GroupCutoffs, attr.GroupDescriptions); return column; } /// /// Create a column. /// /// /// /// /// protected virtual OLVColumn MakeColumn(string aspectName, string title, OLVColumnAttribute attr) { string columnTitle = (attr == null || String.IsNullOrEmpty(attr.Title)) ? title : attr.Title; return new OLVColumn(columnTitle, aspectName); } /// /// Convert a property name to a displayable title. /// /// /// protected virtual string DisplayNameToColumnTitle(string displayName) { string title = displayName.Replace("_", " "); // Put a space between a lower-case letter that is followed immediately by an upper case letter title = Regex.Replace(title, @"(\p{Ll})(\p{Lu})", @"$1 $2"); return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(title); } /// /// Configure the given column to show a checkbox if appropriate /// /// /// protected virtual void ConfigurePossibleBooleanColumn(OLVColumn column, Type propertyType) { if (propertyType != typeof(bool) && propertyType != typeof(bool?) && propertyType != typeof(CheckState)) return; column.CheckBoxes = true; column.TextAlign = HorizontalAlignment.Center; column.Width = 32; column.TriStateCheckBoxes = (propertyType == typeof(bool?) || propertyType == typeof(CheckState)); } /// /// If this given type has an property marked with [OLVChildren], make delegates that will /// traverse that property as the children of an instance of the model /// /// /// protected virtual void TryGenerateChildrenDelegates(TreeListView tlv, Type type) { foreach (PropertyInfo pinfo in type.GetProperties()) { if (Attribute.GetCustomAttribute(pinfo, typeof(OLVChildrenAttribute)) is OLVChildrenAttribute attr) { GenerateChildrenDelegates(tlv, pinfo); return; } } } /// /// Generate CanExpand and ChildrenGetter delegates from the given property. /// /// /// protected virtual void GenerateChildrenDelegates(TreeListView tlv, PropertyInfo pinfo) { Munger childrenGetter = new Munger(pinfo.Name); tlv.CanExpandGetter = delegate(object x) { try { IEnumerable result = childrenGetter.GetValueEx(x) as IEnumerable; return !ObjectListView.IsEnumerableEmpty(result); } catch (MungerException ex) { System.Diagnostics.Debug.WriteLine(ex); return false; } }; tlv.ChildrenGetter = delegate(object x) { try { return childrenGetter.GetValueEx(x) as IEnumerable; } catch (MungerException ex) { System.Diagnostics.Debug.WriteLine(ex); return null; } }; } #endregion /* #region Dynamic methods /// /// Generate methods so that reflection is not needed. /// /// /// public static void GenerateMethods(ObjectListView olv, Type type) { foreach (OLVColumn column in olv.Columns) { GenerateColumnMethods(column, type); } } public static void GenerateColumnMethods(OLVColumn column, Type type) { if (column.AspectGetter == null && !String.IsNullOrEmpty(column.AspectName)) column.AspectGetter = Generator.GenerateAspectGetter(type, column.AspectName); } /// /// Generates an aspect getter method dynamically. The method will execute /// the given dotted chain of selectors against a model object given at runtime. /// /// The type of model object to be passed to the generated method /// A dotted chain of selectors. Each selector can be the name of a /// field, property or parameter-less method. /// A typed delegate /// /// /// If you have an AspectName of "Owner.Address.Postcode", this will generate /// the equivilent of: this.AspectGetter = delegate (object x) { /// return x.Owner.Address.Postcode; /// } /// /// /// private static AspectGetterDelegate GenerateAspectGetter(Type type, string path) { DynamicMethod getter = new DynamicMethod(String.Empty, typeof(Object), new Type[] { type }, type, true); Generator.GenerateIL(type, path, getter.GetILGenerator()); return (AspectGetterDelegate)getter.CreateDelegate(typeof(AspectGetterDelegate)); } /// /// This method generates the actual IL for the method. /// /// /// /// private static void GenerateIL(Type modelType, string path, ILGenerator il) { // Push our model object onto the stack il.Emit(OpCodes.Ldarg_0); OpCodes.Castclass // Generate the IL to access each part of the dotted chain Type type = modelType; string[] parts = path.Split('.'); for (int i = 0; i < parts.Length; i++) { type = Generator.GeneratePart(il, type, parts[i], (i == parts.Length - 1)); if (type == null) break; } // If the object to be returned is a value type (e.g. int, bool), it // must be boxed, since the delegate returns an Object if (type != null && type.IsValueType && !modelType.IsValueType) il.Emit(OpCodes.Box, type); il.Emit(OpCodes.Ret); } private static Type GeneratePart(ILGenerator il, Type type, string pathPart, bool isLastPart) { // TODO: Generate check for null // Find the first member with the given nam that is a field, property, or parameter-less method List infos = new List(type.GetMember(pathPart)); MemberInfo info = infos.Find(delegate(MemberInfo x) { if (x.MemberType == MemberTypes.Field || x.MemberType == MemberTypes.Property) return true; if (x.MemberType == MemberTypes.Method) return ((MethodInfo)x).GetParameters().Length == 0; else return false; }); // If we couldn't find anything with that name, pop the current result and return an error if (info == null) { il.Emit(OpCodes.Pop); il.Emit(OpCodes.Ldstr, String.Format("'{0}' is not a parameter-less method, property or field of type '{1}'", pathPart, type.FullName)); return null; } // Generate the correct IL to access the member. We remember the type of object that is going to be returned // so that we can do a method lookup on it at the next iteration Type resultType = null; switch (info.MemberType) { case MemberTypes.Method: MethodInfo mi = (MethodInfo)info; if (mi.IsVirtual) il.Emit(OpCodes.Callvirt, mi); else il.Emit(OpCodes.Call, mi); resultType = mi.ReturnType; break; case MemberTypes.Property: PropertyInfo pi = (PropertyInfo)info; il.Emit(OpCodes.Call, pi.GetGetMethod()); resultType = pi.PropertyType; break; case MemberTypes.Field: FieldInfo fi = (FieldInfo)info; il.Emit(OpCodes.Ldfld, fi); resultType = fi.FieldType; break; } // If the method returned a value type, and something is going to call a method on that value, // we need to load its address onto the stack, rather than the object itself. if (resultType.IsValueType && !isLastPart) { LocalBuilder lb = il.DeclareLocal(resultType); il.Emit(OpCodes.Stloc, lb); il.Emit(OpCodes.Ldloca, lb); } return resultType; } #endregion */ } } ================================================ FILE: source/ObjectListView/Utilities/OLVExporter.cs ================================================ /* * OLVExporter - Export the contents of an ObjectListView into various text-based formats * * Author: Phillip Piper * Date: 7 August 2012, 10:35pm * * Change log: * 2012-08-07 JPP Initial code * * Copyright (C) 2012 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System; using System.Collections; using System.Collections.Generic; using System.Globalization; using System.Text; namespace BrightIdeasSoftware { /// /// An OLVExporter converts a collection of rows from an ObjectListView /// into a variety of textual formats. /// public class OLVExporter { /// /// What format will be used for exporting /// public enum ExportFormat { /// /// Tab separated values, according to http://www.iana.org/assignments/media-types/text/tab-separated-values /// TabSeparated = 1, /// /// Alias for TabSeparated /// TSV = 1, /// /// Comma separated values, according to http://www.ietf.org/rfc/rfc4180.txt /// CSV, /// /// HTML table, according to me /// HTML } #region Life and death /// /// Create an empty exporter /// public OLVExporter() {} /// /// Create an exporter that will export all the rows of the given ObjectListView /// /// public OLVExporter(ObjectListView olv) : this(olv, olv.Objects) {} /// /// Create an exporter that will export all the given rows from the given ObjectListView /// /// /// public OLVExporter(ObjectListView olv, IEnumerable objectsToExport) { if (objectsToExport == null) throw new ArgumentNullException("objectsToExport"); ListView = olv ?? throw new ArgumentNullException("olv"); ModelObjects = ObjectListView.EnumerableToArray(objectsToExport, true); } #endregion #region Properties /// /// Gets or sets whether hidden columns will also be included in the textual /// representation. If this is false (the default), only visible columns will /// be included. /// public bool IncludeHiddenColumns { get { return includeHiddenColumns; } set { includeHiddenColumns = value; } } private bool includeHiddenColumns; /// /// Gets or sets whether column headers will also be included in the text /// and HTML representation. Default is true. /// public bool IncludeColumnHeaders { get { return includeColumnHeaders; } set { includeColumnHeaders = value; } } private bool includeColumnHeaders = true; /// /// Gets the ObjectListView that is being used as the source of the data /// to be exported /// public ObjectListView ListView { get { return objectListView; } set { objectListView = value; } } private ObjectListView objectListView; /// /// Gets the model objects that are to be placed in the data object /// public IList ModelObjects { get { return modelObjects; } set { modelObjects = value; } } private IList modelObjects = new ArrayList(); #endregion #region Commands /// /// Export the nominated rows from the nominated ObjectListView. /// Returns the result in the expected format. /// /// /// /// This will perform only one conversion, even if called multiple times with different formats. public string ExportTo(ExportFormat format) { if (results == null) Convert(); return results[format]; } /// /// Convert /// public void Convert() { IList columns = IncludeHiddenColumns ? ListView.AllColumns : ListView.ColumnsInDisplayOrder; StringBuilder sbText = new StringBuilder(); StringBuilder sbCsv = new StringBuilder(); StringBuilder sbHtml = new StringBuilder(""); // Include column headers if (IncludeColumnHeaders) { List strings = new List(); foreach (OLVColumn col in columns) strings.Add(col.Text); WriteOneRow(sbText, strings, "", "\t", "", null); WriteOneRow(sbHtml, strings, "", HtmlEncode); WriteOneRow(sbCsv, strings, "", ",", "", CsvEncode); } foreach (object modelObject in ModelObjects) { List strings = new List(); foreach (OLVColumn col in columns) strings.Add(col.GetStringValue(modelObject)); WriteOneRow(sbText, strings, "", "\t", "", null); WriteOneRow(sbHtml, strings, "", HtmlEncode); WriteOneRow(sbCsv, strings, "", ",", "", CsvEncode); } sbHtml.AppendLine("
", "", "
", "", "
"); results = new Dictionary(); results[ExportFormat.TabSeparated] = sbText.ToString(); results[ExportFormat.CSV] = sbCsv.ToString(); results[ExportFormat.HTML] = sbHtml.ToString(); } private delegate string StringToString(string str); private void WriteOneRow(StringBuilder sb, IEnumerable strings, string startRow, string betweenCells, string endRow, StringToString encoder) { sb.Append(startRow); bool first = true; foreach (string s in strings) { if (!first) sb.Append(betweenCells); sb.Append(encoder == null ? s : encoder(s)); first = false; } sb.AppendLine(endRow); } private Dictionary results; #endregion #region Encoding /// /// Encode a string such that it can be used as a value in a CSV file. /// This basically means replacing any quote mark with two quote marks, /// and enclosing the whole string in quotes. /// /// /// private static string CsvEncode(string text) { if (text == null) return null; const string DOUBLEQUOTE = "\""; // one double quote const string TWODOUBEQUOTES = "\"\""; // two double quotes StringBuilder sb = new StringBuilder(DOUBLEQUOTE); sb.Append(text.Replace(DOUBLEQUOTE, TWODOUBEQUOTES)); sb.Append(DOUBLEQUOTE); return sb.ToString(); } /// /// HTML-encodes a string and returns the encoded string. /// /// The text string to encode. /// The HTML-encoded text. /// Taken from http://www.west-wind.com/weblog/posts/2009/Feb/05/Html-and-Uri-String-Encoding-without-SystemWeb private static string HtmlEncode(string text) { if (text == null) return null; StringBuilder sb = new StringBuilder(text.Length); int len = text.Length; for (int i = 0; i < len; i++) { switch (text[i]) { case '<': sb.Append("<"); break; case '>': sb.Append(">"); break; case '"': sb.Append("""); break; case '&': sb.Append("&"); break; default: if (text[i] > 159) { // decimal numeric entity sb.Append("&#"); sb.Append(((int)text[i]).ToString(CultureInfo.InvariantCulture)); sb.Append(';'); } else sb.Append(text[i]); break; } } return sb.ToString(); } #endregion } } ================================================ FILE: source/ObjectListView/Utilities/TypedObjectListView.cs ================================================ /* * TypedObjectListView - A wrapper around an ObjectListView that provides type-safe delegates. * * Author: Phillip Piper * Date: 27/09/2008 9:15 AM * * Change log: * v2.6 * 2012-10-26 JPP - Handle rare case where a null model object was passed into aspect getters. * v2.3 * 2009-03-31 JPP - Added Objects property * 2008-11-26 JPP - Added tool tip getting methods * 2008-11-05 JPP - Added CheckState handling methods * 2008-10-24 JPP - Generate dynamic methods MkII. This one handles value types * 2008-10-21 JPP - Generate dynamic methods * 2008-09-27 JPP - Separated from ObjectListView.cs * * Copyright (C) 2006-2014 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System; using System.Collections; using System.Collections.Generic; using System.Windows.Forms; using System.Reflection; using System.Reflection.Emit; namespace BrightIdeasSoftware { /// /// A TypedObjectListView is a type-safe wrapper around an ObjectListView. /// /// /// VCS does not support generics on controls. It can be faked to some degree, but it /// cannot be completely overcome. In our case in particular, there is no way to create /// the custom OLVColumn's that we need to truly be generic. So this wrapper is an /// experiment in providing some type-safe access in a way that is useful and available today. /// A TypedObjectListView is not more efficient than a normal ObjectListView. /// Underneath, the same name of casts are performed. But it is easier to use since you /// do not have to write the casts yourself. /// /// /// The class of model object that the list will manage /// /// To use a TypedObjectListView, you write code like this: /// /// TypedObjectListView<Person> tlist = new TypedObjectListView<Person>(this.listView1); /// tlist.CheckStateGetter = delegate(Person x) { return x.IsActive; }; /// tlist.GetColumn(0).AspectGetter = delegate(Person x) { return x.Name; }; /// ... /// /// To iterate over the selected objects, you can write something elegant like this: /// /// foreach (Person x in tlist.SelectedObjects) { /// x.GrantSalaryIncrease(); /// } /// /// public class TypedObjectListView where T : class { /// /// Create a typed wrapper around the given list. /// /// The listview to be wrapped public TypedObjectListView(ObjectListView olv) { this.olv = olv; } //-------------------------------------------------------------------------------------- // Properties /// /// Return the model object that is checked, if only one row is checked. /// If zero rows are checked, or more than one row, null is returned. /// public virtual T CheckedObject { get { return (T)olv.CheckedObject; } } /// /// Return the list of all the checked model objects /// public virtual IList CheckedObjects { get { IList checkedObjects = olv.CheckedObjects; List objects = new List(checkedObjects.Count); foreach (object x in checkedObjects) objects.Add((T)x); return objects; } set { olv.CheckedObjects = (IList)value; } } /// /// The ObjectListView that is being wrapped /// public virtual ObjectListView ListView { get { return olv; } set { olv = value; } } private ObjectListView olv; /// /// Get or set the list of all model objects /// public virtual IList Objects { get { List objects = new List(olv.GetItemCount()); for (int i = 0; i < olv.GetItemCount(); i++) objects.Add(GetModelObject(i)); return objects; } set { olv.SetObjects(value); } } /// /// Return the model object that is selected, if only one row is selected. /// If zero rows are selected, or more than one row, null is returned. /// public virtual T SelectedObject { get { return (T)olv.SelectedObject; } set { olv.SelectedObject = value; } } /// /// The list of model objects that are selected. /// public virtual IList SelectedObjects { get { List objects = new List(olv.SelectedIndices.Count); foreach (int index in olv.SelectedIndices) objects.Add((T)olv.GetModelObject(index)); return objects; } set { olv.SelectedObjects = (IList)value; } } //-------------------------------------------------------------------------------------- // Accessors /// /// Return a typed wrapper around the column at the given index /// /// The index of the column /// A typed column or null public virtual TypedColumn GetColumn(int i) { return new TypedColumn(olv.GetColumn(i)); } /// /// Return a typed wrapper around the column with the given name /// /// The name of the column /// A typed column or null public virtual TypedColumn GetColumn(string name) { return new TypedColumn(olv.GetColumn(name)); } /// /// Return the model object at the given index /// /// The index of the model object /// The model object or null public virtual T GetModelObject(int index) { return (T)olv.GetModelObject(index); } //-------------------------------------------------------------------------------------- // Delegates /// /// CheckStateGetter /// /// /// public delegate CheckState TypedCheckStateGetterDelegate(T rowObject); /// /// Gets or sets the check state getter /// public virtual TypedCheckStateGetterDelegate CheckStateGetter { get { return checkStateGetter; } set { checkStateGetter = value; if (value == null) olv.CheckStateGetter = null; else olv.CheckStateGetter = delegate(object x) { return checkStateGetter((T)x); }; } } private TypedCheckStateGetterDelegate checkStateGetter; /// /// BooleanCheckStateGetter /// /// /// public delegate bool TypedBooleanCheckStateGetterDelegate(T rowObject); /// /// Gets or sets the boolean check state getter /// public virtual TypedBooleanCheckStateGetterDelegate BooleanCheckStateGetter { set { if (value == null) olv.BooleanCheckStateGetter = null; else olv.BooleanCheckStateGetter = delegate(object x) { return value((T)x); }; } } /// /// CheckStatePutter /// /// /// /// public delegate CheckState TypedCheckStatePutterDelegate(T rowObject, CheckState newValue); /// /// Gets or sets the check state putter delegate /// public virtual TypedCheckStatePutterDelegate CheckStatePutter { get { return checkStatePutter; } set { checkStatePutter = value; if (value == null) olv.CheckStatePutter = null; else olv.CheckStatePutter = delegate(object x, CheckState newValue) { return checkStatePutter((T)x, newValue); }; } } private TypedCheckStatePutterDelegate checkStatePutter; /// /// BooleanCheckStatePutter /// /// /// /// public delegate bool TypedBooleanCheckStatePutterDelegate(T rowObject, bool newValue); /// /// Gets or sets the boolean check state putter /// public virtual TypedBooleanCheckStatePutterDelegate BooleanCheckStatePutter { set { if (value == null) olv.BooleanCheckStatePutter = null; else olv.BooleanCheckStatePutter = delegate(object x, bool newValue) { return value((T)x, newValue); }; } } /// /// ToolTipGetter /// /// /// /// public delegate String TypedCellToolTipGetterDelegate(OLVColumn column, T modelObject); /// /// Gets or sets the cell tooltip getter /// public virtual TypedCellToolTipGetterDelegate CellToolTipGetter { set { if (value == null) olv.CellToolTipGetter = null; else olv.CellToolTipGetter = delegate(OLVColumn col, Object x) { return value(col, (T)x); }; } } /// /// Gets or sets the header tool tip getter /// public virtual HeaderToolTipGetterDelegate HeaderToolTipGetter { get { return olv.HeaderToolTipGetter; } set { olv.HeaderToolTipGetter = value; } } //-------------------------------------------------------------------------------------- // Commands /// /// This method will generate AspectGetters for any column that has an AspectName. /// public virtual void GenerateAspectGetters() { for (int i = 0; i < ListView.Columns.Count; i++) GetColumn(i).GenerateAspectGetter(); } } /// /// A type-safe wrapper around an OLVColumn /// /// public class TypedColumn where T : class { /// /// Creates a TypedColumn /// /// public TypedColumn(OLVColumn column) { this.column = column; } private OLVColumn column; /// /// /// /// /// public delegate Object TypedAspectGetterDelegate(T rowObject); /// /// /// /// /// public delegate void TypedAspectPutterDelegate(T rowObject, Object newValue); /// /// /// /// /// public delegate Object TypedGroupKeyGetterDelegate(T rowObject); /// /// /// /// /// public delegate Object TypedImageGetterDelegate(T rowObject); /// /// /// public TypedAspectGetterDelegate AspectGetter { get { return aspectGetter; } set { aspectGetter = value; if (value == null) column.AspectGetter = null; else column.AspectGetter = delegate(object x) { return x == null ? null : aspectGetter((T)x); }; } } private TypedAspectGetterDelegate aspectGetter; /// /// /// public TypedAspectPutterDelegate AspectPutter { get { return aspectPutter; } set { aspectPutter = value; if (value == null) column.AspectPutter = null; else column.AspectPutter = delegate(object x, object newValue) { aspectPutter((T)x, newValue); }; } } private TypedAspectPutterDelegate aspectPutter; /// /// /// public TypedImageGetterDelegate ImageGetter { get { return imageGetter; } set { imageGetter = value; if (value == null) column.ImageGetter = null; else column.ImageGetter = delegate(object x) { return imageGetter((T)x); }; } } private TypedImageGetterDelegate imageGetter; /// /// /// public TypedGroupKeyGetterDelegate GroupKeyGetter { get { return groupKeyGetter; } set { groupKeyGetter = value; if (value == null) column.GroupKeyGetter = null; else column.GroupKeyGetter = delegate(object x) { return groupKeyGetter((T)x); }; } } private TypedGroupKeyGetterDelegate groupKeyGetter; #region Dynamic methods /// /// Generate an aspect getter that does the same thing as the AspectName, /// except without using reflection. /// /// /// /// If you have an AspectName of "Owner.Address.Postcode", this will generate /// the equivilent of: this.AspectGetter = delegate (object x) { /// return x.Owner.Address.Postcode; /// } /// /// /// /// If AspectName is empty, this method will do nothing, otherwise /// this will replace any existing AspectGetter. /// /// public void GenerateAspectGetter() { if (!String.IsNullOrEmpty(column.AspectName)) AspectGetter = GenerateAspectGetter(typeof(T), column.AspectName); } /// /// Generates an aspect getter method dynamically. The method will execute /// the given dotted chain of selectors against a model object given at runtime. /// /// The type of model object to be passed to the generated method /// A dotted chain of selectors. Each selector can be the name of a /// field, property or parameter-less method. /// A typed delegate private TypedAspectGetterDelegate GenerateAspectGetter(Type type, string path) { DynamicMethod getter = new DynamicMethod(String.Empty, typeof(Object), new Type[] { type }, type, true); GenerateIL(type, path, getter.GetILGenerator()); return (TypedAspectGetterDelegate)getter.CreateDelegate(typeof(TypedAspectGetterDelegate)); } /// /// This method generates the actual IL for the method. /// /// /// /// private void GenerateIL(Type type, string path, ILGenerator il) { // Push our model object onto the stack il.Emit(OpCodes.Ldarg_0); // Generate the IL to access each part of the dotted chain string[] parts = path.Split('.'); for (int i = 0; i < parts.Length; i++) { type = GeneratePart(il, type, parts[i], (i == parts.Length - 1)); if (type == null) break; } // If the object to be returned is a value type (e.g. int, bool), it // must be boxed, since the delegate returns an Object if (type != null && type.IsValueType && !typeof(T).IsValueType) il.Emit(OpCodes.Box, type); il.Emit(OpCodes.Ret); } private Type GeneratePart(ILGenerator il, Type type, string pathPart, bool isLastPart) { // TODO: Generate check for null // Find the first member with the given nam that is a field, property, or parameter-less method List infos = new List(type.GetMember(pathPart)); MemberInfo info = infos.Find(delegate(MemberInfo x) { if (x.MemberType == MemberTypes.Field || x.MemberType == MemberTypes.Property) return true; if (x.MemberType == MemberTypes.Method) return ((MethodInfo)x).GetParameters().Length == 0; else return false; }); // If we couldn't find anything with that name, pop the current result and return an error if (info == null) { il.Emit(OpCodes.Pop); if (Munger.IgnoreMissingAspects) il.Emit(OpCodes.Ldnull); else il.Emit(OpCodes.Ldstr, String.Format("'{0}' is not a parameter-less method, property or field of type '{1}'", pathPart, type.FullName)); return null; } // Generate the correct IL to access the member. We remember the type of object that is going to be returned // so that we can do a method lookup on it at the next iteration Type resultType = null; switch (info.MemberType) { case MemberTypes.Method: MethodInfo mi = (MethodInfo)info; if (mi.IsVirtual) il.Emit(OpCodes.Callvirt, mi); else il.Emit(OpCodes.Call, mi); resultType = mi.ReturnType; break; case MemberTypes.Property: PropertyInfo pi = (PropertyInfo)info; il.Emit(OpCodes.Call, pi.GetGetMethod()); resultType = pi.PropertyType; break; case MemberTypes.Field: FieldInfo fi = (FieldInfo)info; il.Emit(OpCodes.Ldfld, fi); resultType = fi.FieldType; break; } // If the method returned a value type, and something is going to call a method on that value, // we need to load its address onto the stack, rather than the object itself. if (resultType.IsValueType && !isLastPart) { LocalBuilder lb = il.DeclareLocal(resultType); il.Emit(OpCodes.Stloc, lb); il.Emit(OpCodes.Ldloca, lb); } return resultType; } #endregion } } ================================================ FILE: source/ObjectListView/VirtualObjectListView.cs ================================================ /* * VirtualObjectListView - A virtual listview delays fetching model objects until they are actually displayed. * * Author: Phillip Piper * Date: 27/09/2008 9:15 AM * * Change log: * 2015-06-14 JPP - Moved handling of CheckBoxes on virtual lists into base class (ObjectListView). * This allows the property to be set correctly, even when set via an upcast reference. * 2015-03-25 JPP - Subscribe to change notifications when objects are added * v2.8 * 2014-09-26 JPP - Correct an incorrect use of checkStateMap when setting CheckedObjects * and a CheckStateGetter is installed * v2.6 * 2012-06-13 JPP - Corrected several bugs related to groups on virtual lists. * - Added EnsureNthGroupVisible() since EnsureGroupVisible() can't work on virtual lists. * v2.5.1 * 2012-05-04 JPP - Avoid bug/feature in ListView.VirtalListSize setter that causes flickering * when the size of the list changes. * 2012-04-24 JPP - Fixed bug that occurred when adding/removing item while the view was grouped. * v2.5 * 2011-05-31 JPP - Setting CheckedObjects is more efficient on large collections * 2011-04-05 JPP - CheckedObjects now only returns objects that are currently in the list. * ClearObjects() now resets all check state info. * 2011-03-31 JPP - Filtering on grouped virtual lists no longer behaves strangely. * 2011-03-17 JPP - Virtual lists can (finally) set CheckBoxes back to false if it has been set to true. * (this is a little hacky and may not work reliably). * - GetNextItem() and GetPreviousItem() now work on grouped virtual lists. * 2011-03-08 JPP - BREAKING CHANGE: 'DataSource' was renamed to 'VirtualListDataSource'. This was necessary * to allow FastDataListView which is both a DataListView AND a VirtualListView -- * which both used a 'DataSource' property :( * v2.4 * 2010-04-01 JPP - Support filtering * v2.3 * 2009-08-28 JPP - BIG CHANGE. Virtual lists can now have groups! * - Objects property now uses "yield return" -- much more efficient for big lists * 2009-08-07 JPP - Use new scheme for formatting rows/cells * v2.2.1 * 2009-07-24 JPP - Added specialised version of RefreshSelectedObjects() which works efficiently with virtual lists * (thanks to chriss85 for finding this bug) * 2009-07-03 JPP - Standardized code format * v2.2 * 2009-04-06 JPP - ClearObjects() now works again * v2.1 * 2009-02-24 JPP - Removed redundant OnMouseDown() since checkbox * handling is now handled in the base class * 2009-01-07 JPP - Made all public and protected methods virtual * 2008-12-07 JPP - Trigger Before/AfterSearching events * 2008-11-15 JPP - Fixed some caching issues * 2008-11-05 JPP - Rewrote handling of check boxes * 2008-10-28 JPP - Handle SetSelectedObjects(null) * 2008-10-02 JPP - MAJOR CHANGE: Use IVirtualListDataSource * 2008-09-27 JPP - Separated from ObjectListView.cs * * Copyright (C) 2006-2014 Phillip Piper * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. */ using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Reflection; using System.Windows.Forms; using System.Runtime.InteropServices; using MethodInvoker = System.Windows.Forms.MethodInvoker; namespace BrightIdeasSoftware { /// /// A virtual object list view operates in virtual mode, that is, it only gets model objects for /// a row when it is needed. This gives it the ability to handle very large numbers of rows with /// minimal resources. /// /// A listview is not a great user interface for a large number of items. But if you've /// ever wanted to have a list with 10 million items, go ahead, knock yourself out. /// Virtual lists can never iterate their contents. That would defeat the whole purpose. /// Animated GIFs should not be used in virtual lists. Animated GIFs require some state /// information to be stored for each animation, but virtual lists specifically do not keep any state information. /// In any case, you really do not want to keep state information for 10 million animations! /// /// Although it isn't documented, .NET virtual lists cannot have checkboxes. This class codes around this limitation, /// but you must use the functions provided by ObjectListView: CheckedObjects, CheckObject(), UncheckObject() and their friends. /// If you use the normal check box properties (CheckedItems or CheckedIndicies), they will throw an exception, since the /// list is in virtual mode, and .NET "knows" it can't handle checkboxes in virtual mode. /// /// Due to the limits of the underlying Windows control, virtual lists do not trigger ItemCheck/ItemChecked events. /// Use a CheckStatePutter instead. /// To enable grouping, you must provide an implmentation of IVirtualGroups interface, via the GroupingStrategy property. /// Similarly, to enable filtering on the list, your VirtualListDataSource must also implement the IFilterableDataSource interface. /// public class VirtualObjectListView : ObjectListView { /// /// Create a VirtualObjectListView /// public VirtualObjectListView() : base() { VirtualMode = true; // Virtual lists have to be virtual -- no prizes for guessing that :) CacheVirtualItems += new CacheVirtualItemsEventHandler(HandleCacheVirtualItems); RetrieveVirtualItem += new RetrieveVirtualItemEventHandler(HandleRetrieveVirtualItem); SearchForVirtualItem += new SearchForVirtualItemEventHandler(HandleSearchForVirtualItem); // At the moment, we don't need to handle this event. But we'll keep this comment to remind us about it. //this.VirtualItemsSelectionRangeChanged += new ListViewVirtualItemsSelectionRangeChangedEventHandler(VirtualObjectListView_VirtualItemsSelectionRangeChanged); VirtualListDataSource = new VirtualListVersion1DataSource(this); // Virtual lists have to manage their own check state, since the normal ListView control // doesn't even allow checkboxes on virtual lists PersistentCheckBoxes = true; } #region Public Properties /// /// Gets whether or not this listview is capabale of showing groups /// [Browsable(false)] public override bool CanShowGroups { get { // Virtual lists need Vista and a grouping strategy to show groups return (IsVistaOrLater && GroupingStrategy != null); } } /// /// Get or set the collection of model objects that are checked. /// When setting this property, any row whose model object isn't /// in the given collection will be unchecked. Setting to null is /// equivilent to unchecking all. /// /// /// /// This property returns a simple collection. Changes made to the returned /// collection do NOT affect the list. This is different to the behaviour of /// CheckedIndicies collection. /// /// /// When getting CheckedObjects, the performance of this method is O(n) where n is the number of checked objects. /// When setting CheckedObjects, the performance of this method is O(n) where n is the number of checked objects plus /// the number of objects to be checked. /// /// /// If the ListView is not currently showing CheckBoxes, this property does nothing. It does /// not remember any check box settings made. /// /// /// This class optimizes the management of CheckStates so that it will work efficiently even on /// large lists of item. However, those optimizations are impossible if you install a CheckStateGetter. /// With a CheckStateGetter installed, the performance of this method is O(n) where n is the size /// of the list. This could be painfully slow. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public override IList CheckedObjects { get { // If we aren't should checkboxes, then no objects can be checked if (!CheckBoxes) return new ArrayList(); // If the data source has somehow vanished, we can't do anything if (VirtualListDataSource == null) return new ArrayList(); // If a custom check state getter is install, we can't use our check state management // We have to use the (slower) base version. if (CheckStateGetter != null) return base.CheckedObjects; // Collect items that are checked AND that still exist in the list. ArrayList objects = new ArrayList(); foreach (KeyValuePair kvp in CheckStateMap) { if (kvp.Value == CheckState.Checked && (!CheckedObjectsMustStillExistInList || VirtualListDataSource.GetObjectIndex(kvp.Key) >= 0)) objects.Add(kvp.Key); } return objects; } set { if (!CheckBoxes) return; // If a custom check state getter is install, we can't use our check state management // We have to use the (slower) base version. if (CheckStateGetter != null) { base.CheckedObjects = value; return; } Stopwatch sw = Stopwatch.StartNew(); // Set up an efficient way of testing for the presence of a particular model Hashtable table = new Hashtable(GetItemCount()); if (value != null) { foreach (object x in value) table[x] = true; } BeginUpdate(); // Uncheck anything that is no longer checked Object[] keys = new Object[CheckStateMap.Count]; CheckStateMap.Keys.CopyTo(keys, 0); foreach (Object key in keys) { if (!table.Contains(key)) SetObjectCheckedness(key, CheckState.Unchecked); } // Check all the new checked objects foreach (Object x in table.Keys) SetObjectCheckedness(x, CheckState.Checked); EndUpdate(); Debug.WriteLine(String.Format("PERF - Setting virtual CheckedObjects on {2} objects took {0}ms / {1} ticks", sw.ElapsedMilliseconds, sw.ElapsedTicks, GetItemCount())); } } /// /// Gets or sets whether or not an object will be included in the CheckedObjects /// collection, even if it is not present in the control at the moment /// /// /// This property is an implementation detail and should not be altered. /// [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] protected internal bool CheckedObjectsMustStillExistInList { get { return checkedObjectsMustStillExistInList; } set { checkedObjectsMustStillExistInList = value; } } private bool checkedObjectsMustStillExistInList = true; /// /// Gets the collection of objects that survive any filtering that may be in place. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public override IEnumerable FilteredObjects { get { for (int i = 0; i < GetItemCount(); i++) yield return GetModelObject(i); } } /// /// Gets or sets the strategy that will be used to create groups /// /// /// This must be provided for a virtual list to show groups. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public IVirtualGroups GroupingStrategy { get { return groupingStrategy; } set { groupingStrategy = value; } } private IVirtualGroups groupingStrategy; /// /// Gets whether or not the current list is filtering its contents /// /// /// This is only possible if our underlying data source supports filtering. /// public override bool IsFiltering { get { return base.IsFiltering && (VirtualListDataSource is IFilterableDataSource); } } /// /// Get/set the collection of objects that this list will show /// /// /// /// The contents of the control will be updated immediately after setting this property. /// /// Setting this property preserves selection, if possible. Use SetObjects() if /// you do not want to preserve the selection. Preserving selection is the slowest part of this /// code -- performance is O(n) where n is the number of selected rows. /// This method is not thread safe. /// The property DOES work on virtual lists, but if you try to iterate through a list /// of 10 million objects, it may take some time :) /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public override IEnumerable Objects { get { IFilterableDataSource filterable = VirtualListDataSource as IFilterableDataSource; try { // If we are filtering, we have to temporarily disable filtering so we get // the whole collection if (filterable != null && UseFiltering) filterable.ApplyFilters(null, null); return FilteredObjects; } finally { if (filterable != null && UseFiltering) filterable.ApplyFilters(ModelFilter, ListFilter); } } set { base.Objects = value; } } /// /// This delegate is used to fetch a rowObject, given it's index within the list /// /// Only use this property if you are not using a VirtualListDataSource. [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual RowGetterDelegate RowGetter { get { return ((VirtualListVersion1DataSource)virtualListDataSource).RowGetter; } set { ((VirtualListVersion1DataSource)virtualListDataSource).RowGetter = value; } } /// /// Should this list show its items in groups? /// [Category("Appearance"), Description("Should the list view show items in groups?"), DefaultValue(true)] override public bool ShowGroups { get { // Pre-Vista, virtual lists cannot show groups return IsVistaOrLater && showGroups; } set { showGroups = value; if (Created && !value) DisableVirtualGroups(); } } private bool showGroups; /// /// Get/set the data source that is behind this virtual list /// /// Setting this will cause the list to redraw. [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual IVirtualListDataSource VirtualListDataSource { get { return virtualListDataSource; } set { virtualListDataSource = value; CustomSorter = delegate(OLVColumn column, SortOrder sortOrder) { ClearCachedInfo(); virtualListDataSource.Sort(column, sortOrder); }; BuildList(false); } } private IVirtualListDataSource virtualListDataSource; /// /// Gets or sets the number of rows in this virtual list. /// /// /// There is an annoying feature/bug in the .NET ListView class. /// When you change the VirtualListSize property, it always scrolls so /// that the focused item is the top item. This is annoying since it makes /// the virtual list seem to flicker as the control scrolls to show the focused /// item and then scrolls back to where ObjectListView wants it to be. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] protected new virtual int VirtualListSize { get { return base.VirtualListSize; } set { if (value == VirtualListSize || value < 0) return; // Get around the 'private' marker on 'virtualListSize' field using reflection if (virtualListSizeFieldInfo == null) { virtualListSizeFieldInfo = typeof(ListView).GetField("virtualListSize", BindingFlags.NonPublic | BindingFlags.Instance); Debug.Assert(virtualListSizeFieldInfo != null); } // Set the base class private field so that it keeps on working virtualListSizeFieldInfo.SetValue(this, value); // Send a raw message to change the virtual list size *without* changing the scroll position if (IsHandleCreated && !DesignMode) NativeMethods.SetItemCount(this, value); } } static private FieldInfo virtualListSizeFieldInfo; #endregion #region OLV accessing /// /// Return the number of items in the list /// /// the number of items in the list public override int GetItemCount() { return VirtualListSize; } /// /// Return the model object at the given index /// /// Index of the model object to be returned /// A model object public override object GetModelObject(int index) { if (VirtualListDataSource != null && index >= 0 && index < GetItemCount()) return VirtualListDataSource.GetNthObject(index); else return null; } /// /// Find the given model object within the listview and return its index /// /// The model object to be found /// The index of the object. -1 means the object was not present public override int IndexOf(Object modelObject) { if (VirtualListDataSource == null || modelObject == null) return -1; return VirtualListDataSource.GetObjectIndex(modelObject); } /// /// Return the OLVListItem that displays the given model object /// /// The modelObject whose item is to be found /// The OLVListItem that displays the model, or null /// This method has O(n) performance. public override OLVListItem ModelToItem(object modelObject) { if (VirtualListDataSource == null || modelObject == null) return null; int index = VirtualListDataSource.GetObjectIndex(modelObject); return index >= 0 ? GetItem(index) : null; } #endregion #region Object manipulation /// /// Add the given collection of model objects to this control. /// /// A collection of model objects /// /// The added objects will appear in their correct sort position, if sorting /// is active. Otherwise, they will appear at the end of the list. /// No check is performed to see if any of the objects are already in the ListView. /// Null objects are silently ignored. /// public override void AddObjects(ICollection modelObjects) { if (VirtualListDataSource == null) return; // Give the world a chance to cancel or change the added objects ItemsAddingEventArgs args = new ItemsAddingEventArgs(modelObjects); OnItemsAdding(args); if (args.Canceled) return; try { BeginUpdate(); VirtualListDataSource.AddObjects(args.ObjectsToAdd); BuildList(); SubscribeNotifications(args.ObjectsToAdd); } finally { EndUpdate(); } } /// /// Remove all items from this list /// /// This method can safely be called from background threads. public override void ClearObjects() { if (InvokeRequired) Invoke(new MethodInvoker(ClearObjects)); else { CheckStateMap.Clear(); SetObjects(new ArrayList()); } } /// /// Scroll the listview so that the given group is at the top. /// /// The index of the group to be revealed /// /// If the group is already visible, the list will still be scrolled to move /// the group to the top, if that is possible. /// /// This only works when the list is showing groups (obviously). /// public virtual void EnsureNthGroupVisible(int groupIndex) { if (!ShowGroups) return; if (groupIndex <= 0 || groupIndex >= OLVGroups.Count) { // There is no easy way to scroll back to the beginning of the list int delta = 0 - NativeMethods.GetScrollPosition(this, false); NativeMethods.Scroll(this, 0, delta); } else { // Find the display rectangle of the last item in the previous group OLVGroup previousGroup = OLVGroups[groupIndex - 1]; int lastItemInGroup = GroupingStrategy.GetGroupMember(previousGroup, previousGroup.VirtualItemCount - 1); Rectangle r = GetItemRect(lastItemInGroup); // Scroll so that the last item of the previous group is just out of sight, // which will make the desired group header visible. int delta = r.Y + r.Height / 2; NativeMethods.Scroll(this, 0, delta); } } /// /// Inserts the given collection of model objects to this control at hte given location /// /// A collection of model objects /// /// The added objects will appear in their correct sort position, if sorting /// is active. Otherwise, they will appear at the given position of the list. /// No check is performed to see if any of the objects are already in the ListView. /// Null objects are silently ignored. /// public override void InsertObjects(int index, ICollection modelObjects) { if (VirtualListDataSource == null) return; // Give the world a chance to cancel or change the added objects ItemsAddingEventArgs args = new ItemsAddingEventArgs(index, modelObjects); OnItemsAdding(args); if (args.Canceled) return; try { BeginUpdate(); VirtualListDataSource.InsertObjects(index, args.ObjectsToAdd); BuildList(); SubscribeNotifications(args.ObjectsToAdd); } finally { EndUpdate(); } } /// /// Update the rows that are showing the given objects /// /// This method does not resort the items. public override void RefreshObjects(IList modelObjects) { if (InvokeRequired) { Invoke(new MethodInvoker(() => RefreshObjects(modelObjects))); return; } // Without a data source, we can't do this. if (VirtualListDataSource == null) return; try { BeginUpdate(); ClearCachedInfo(); foreach (object modelObject in modelObjects) { int index = VirtualListDataSource.GetObjectIndex(modelObject); if (index >= 0) { VirtualListDataSource.UpdateObject(index, modelObject); RedrawItems(index, index, true); } } } finally { EndUpdate(); } } /// /// Update the rows that are selected /// /// This method does not resort or regroup the view. public override void RefreshSelectedObjects() { foreach (int index in SelectedIndices) RedrawItems(index, index, true); } /// /// Remove all of the given objects from the control /// /// Collection of objects to be removed /// /// Nulls and model objects that are not in the ListView are silently ignored. /// Due to problems in the underlying ListView, if you remove all the objects from /// the control using this method and the list scroll vertically when you do so, /// then when you subsequenially add more objects to the control, /// the vertical scroll bar will become confused and the control will draw one or more /// blank lines at the top of the list. /// public override void RemoveObjects(ICollection modelObjects) { if (VirtualListDataSource == null) return; // Give the world a chance to cancel or change the removed objects ItemsRemovingEventArgs args = new ItemsRemovingEventArgs(modelObjects); OnItemsRemoving(args); if (args.Canceled) return; try { BeginUpdate(); VirtualListDataSource.RemoveObjects(args.ObjectsToRemove); BuildList(); UnsubscribeNotifications(args.ObjectsToRemove); } finally { EndUpdate(); } } /// /// Select the row that is displaying the given model object. All other rows are deselected. /// /// Model object to select /// Should the object be focused as well? public override void SelectObject(object modelObject, bool setFocus) { // Without a data source, we can't do this. if (VirtualListDataSource == null) return; // Check that the object is in the list (plus not all data sources can locate objects) int index = VirtualListDataSource.GetObjectIndex(modelObject); if (index < 0 || index >= VirtualListSize) return; // If the given model is already selected, don't do anything else (prevents an flicker) if (SelectedIndices.Count == 1 && SelectedIndices[0] == index) return; // Finally, select the row SelectedIndices.Clear(); SelectedIndices.Add(index); if (setFocus && SelectedItem != null) SelectedItem.Focused = true; } /// /// Select the rows that is displaying any of the given model object. All other rows are deselected. /// /// A collection of model objects /// This method has O(n) performance where n is the number of model objects passed. /// Do not use this to select all the rows in the list -- use SelectAll() for that. public override void SelectObjects(IList modelObjects) { // Without a data source, we can't do this. if (VirtualListDataSource == null) return; SelectedIndices.Clear(); if (modelObjects == null) return; foreach (object modelObject in modelObjects) { int index = VirtualListDataSource.GetObjectIndex(modelObject); if (index >= 0 && index < VirtualListSize) SelectedIndices.Add(index); } } /// /// Set the collection of objects that this control will show. /// /// /// Should the state of the list be preserved as far as is possible. public override void SetObjects(IEnumerable collection, bool preserveState) { if (InvokeRequired) { Invoke((MethodInvoker)delegate { SetObjects(collection, preserveState); }); return; } if (VirtualListDataSource == null) return; // Give the world a chance to cancel or change the assigned collection ItemsChangingEventArgs args = new ItemsChangingEventArgs(null, collection); OnItemsChanging(args); if (args.Canceled) return; BeginUpdate(); try { VirtualListDataSource.SetObjects(args.NewObjects); BuildList(); UpdateNotificationSubscriptions(args.NewObjects); } finally { EndUpdate(); } } #endregion #region Check boxes // // /// // /// Check all rows // /// // /// The performance of this method is O(n) where n is the number of rows in the control. // public override void CheckAll() // { // if (!this.CheckBoxes) // return; // // Stopwatch sw = Stopwatch.StartNew(); // // this.BeginUpdate(); // // foreach (Object x in this.Objects) // this.SetObjectCheckedness(x, CheckState.Checked); // // this.EndUpdate(); // // Debug.WriteLine(String.Format("PERF - CheckAll() on {2} objects took {0}ms / {1} ticks", sw.ElapsedMilliseconds, sw.ElapsedTicks, this.GetItemCount())); // // } // // /// // /// Uncheck all rows // /// // /// The performance of this method is O(n) where n is the number of rows in the control. // public override void UncheckAll() // { // if (!this.CheckBoxes) // return; // // Stopwatch sw = Stopwatch.StartNew(); // // this.BeginUpdate(); // // foreach (Object x in this.Objects) // this.SetObjectCheckedness(x, CheckState.Unchecked); // // this.EndUpdate(); // // Debug.WriteLine(String.Format("PERF - UncheckAll() on {2} objects took {0}ms / {1} ticks", sw.ElapsedMilliseconds, sw.ElapsedTicks, this.GetItemCount())); // } /// /// Get the checkedness of an object from the model. Returning null means the /// model does know and the value from the control will be used. /// /// /// protected override CheckState? GetCheckState(object modelObject) { if (CheckStateGetter != null) return base.GetCheckState(modelObject); CheckState state; if (modelObject != null && CheckStateMap.TryGetValue(modelObject, out state)) return state; return CheckState.Unchecked; } #endregion #region Implementation /// /// Rebuild the list with its current contents. /// /// /// Invalidate any cached information when we rebuild the list. /// public override void BuildList(bool shouldPreserveSelection) { UpdateVirtualListSize(); ClearCachedInfo(); if (ShowGroups) BuildGroups(); else Sort(); Invalidate(); } /// /// Clear any cached info this list may have been using /// public override void ClearCachedInfo() { lastRetrieveVirtualItemIndex = -1; } /// /// Do the work of creating groups for this control /// /// protected override void CreateGroups(IEnumerable groups) { // In a virtual list, we cannot touch the Groups property. // It was obviously not written for virtual list and often throws exceptions. NativeMethods.ClearGroups(this); EnableVirtualGroups(); foreach (OLVGroup group in groups) { Debug.Assert(group.Items.Count == 0, "Groups in virtual lists cannot set Items. Use VirtualItemCount instead."); Debug.Assert(group.VirtualItemCount > 0, "VirtualItemCount must be greater than 0."); group.InsertGroupNewStyle(this); } } /// /// Do the plumbing to disable groups on a virtual list /// protected void DisableVirtualGroups() { NativeMethods.ClearGroups(this); //System.Diagnostics.Debug.WriteLine(err); const int LVM_ENABLEGROUPVIEW = 0x1000 + 157; IntPtr x = NativeMethods.SendMessage(Handle, LVM_ENABLEGROUPVIEW, 0, 0); //System.Diagnostics.Debug.WriteLine(x); const int LVM_SETOWNERDATACALLBACK = 0x10BB; IntPtr x2 = NativeMethods.SendMessage(Handle, LVM_SETOWNERDATACALLBACK, 0, 0); //System.Diagnostics.Debug.WriteLine(x2); } /// /// Do the plumbing to enable groups on a virtual list /// protected void EnableVirtualGroups() { // We need to implement the IOwnerDataCallback interface if (ownerDataCallbackImpl == null) ownerDataCallbackImpl = new OwnerDataCallbackImpl(this); const int LVM_SETOWNERDATACALLBACK = 0x10BB; IntPtr ptr = Marshal.GetComInterfaceForObject(ownerDataCallbackImpl, typeof(IOwnerDataCallback)); IntPtr x = NativeMethods.SendMessage(Handle, LVM_SETOWNERDATACALLBACK, ptr, 0); //System.Diagnostics.Debug.WriteLine(x); Marshal.Release(ptr); const int LVM_ENABLEGROUPVIEW = 0x1000 + 157; x = NativeMethods.SendMessage(Handle, LVM_ENABLEGROUPVIEW, 1, 0); //System.Diagnostics.Debug.WriteLine(x); } private OwnerDataCallbackImpl ownerDataCallbackImpl; /// /// Return the position of the given itemIndex in the list as it currently shown to the user. /// If the control is not grouped, the display order is the same as the /// sorted list order. But if the list is grouped, the display order is different. /// /// /// public override int GetDisplayOrderOfItemIndex(int itemIndex) { if (!ShowGroups) return itemIndex; int groupIndex = GroupingStrategy.GetGroup(itemIndex); int displayIndex = 0; for (int i = 0; i < groupIndex - 1; i++) displayIndex += OLVGroups[i].VirtualItemCount; displayIndex += GroupingStrategy.GetIndexWithinGroup(OLVGroups[groupIndex], itemIndex); return displayIndex; } /// /// Return the last item in the order they are shown to the user. /// If the control is not grouped, the display order is the same as the /// sorted list order. But if the list is grouped, the display order is different. /// /// public override OLVListItem GetLastItemInDisplayOrder() { if (!ShowGroups) return base.GetLastItemInDisplayOrder(); if (OLVGroups.Count > 0) { OLVGroup lastGroup = OLVGroups[OLVGroups.Count - 1]; if (lastGroup.VirtualItemCount > 0) return GetItem(GroupingStrategy.GetGroupMember(lastGroup, lastGroup.VirtualItemCount - 1)); } return null; } /// /// Return the n'th item (0-based) in the order they are shown to the user. /// If the control is not grouped, the display order is the same as the /// sorted list order. But if the list is grouped, the display order is different. /// /// /// public override OLVListItem GetNthItemInDisplayOrder(int n) { if (!ShowGroups || OLVGroups == null || OLVGroups.Count == 0) return GetItem(n); foreach (OLVGroup group in OLVGroups) { if (n < group.VirtualItemCount) return GetItem(GroupingStrategy.GetGroupMember(group, n)); n -= group.VirtualItemCount; } return null; } /// /// Return the ListViewItem that appears immediately after the given item. /// If the given item is null, the first item in the list will be returned. /// Return null if the given item is the last item. /// /// The item that is before the item that is returned, or null /// A OLVListItem public override OLVListItem GetNextItem(OLVListItem itemToFind) { if (!ShowGroups) return base.GetNextItem(itemToFind); // Sanity if (OLVGroups == null || OLVGroups.Count == 0) return null; // If the given item is null, return the first member of the first group if (itemToFind == null) { return GetItem(GroupingStrategy.GetGroupMember(OLVGroups[0], 0)); } // Find where this item occurs (which group and where in that group) int groupIndex = GroupingStrategy.GetGroup(itemToFind.Index); int indexWithinGroup = GroupingStrategy.GetIndexWithinGroup(OLVGroups[groupIndex], itemToFind.Index); // If it's not the last member, just return the next member if (indexWithinGroup < OLVGroups[groupIndex].VirtualItemCount - 1) return GetItem(GroupingStrategy.GetGroupMember(OLVGroups[groupIndex], indexWithinGroup + 1)); // The item is the last member of its group. Return the first member of the next group // (unless there isn't a next group) if (groupIndex < OLVGroups.Count - 1) return GetItem(GroupingStrategy.GetGroupMember(OLVGroups[groupIndex + 1], 0)); return null; } /// /// Return the ListViewItem that appears immediately before the given item. /// If the given item is null, the last item in the list will be returned. /// Return null if the given item is the first item. /// /// The item that is before the item that is returned /// A ListViewItem public override OLVListItem GetPreviousItem(OLVListItem itemToFind) { if (!ShowGroups) return base.GetPreviousItem(itemToFind); // Sanity if (OLVGroups == null || OLVGroups.Count == 0) return null; // If the given items is null, return the last member of the last group if (itemToFind == null) { OLVGroup lastGroup = OLVGroups[OLVGroups.Count - 1]; return GetItem(GroupingStrategy.GetGroupMember(lastGroup, lastGroup.VirtualItemCount - 1)); } // Find where this item occurs (which group and where in that group) int groupIndex = GroupingStrategy.GetGroup(itemToFind.Index); int indexWithinGroup = GroupingStrategy.GetIndexWithinGroup(OLVGroups[groupIndex], itemToFind.Index); // If it's not the first member of the group, just return the previous member if (indexWithinGroup > 0) return GetItem(GroupingStrategy.GetGroupMember(OLVGroups[groupIndex], indexWithinGroup - 1)); // The item is the first member of its group. Return the last member of the previous group // (if there is one) if (groupIndex > 0) { OLVGroup previousGroup = OLVGroups[groupIndex - 1]; return GetItem(GroupingStrategy.GetGroupMember(previousGroup, previousGroup.VirtualItemCount - 1)); } return null; } /// /// Make a list of groups that should be shown according to the given parameters /// /// /// protected override IList MakeGroups(GroupingParameters parms) { if (GroupingStrategy == null) return new List(); else return GroupingStrategy.GetGroups(parms); } /// /// Create a OLVListItem for given row index /// /// The index of the row that is needed /// An OLVListItem public virtual OLVListItem MakeListViewItem(int itemIndex) { OLVListItem olvi = new OLVListItem(GetModelObject(itemIndex)); FillInValues(olvi, olvi.RowObject); PostProcessOneRow(itemIndex, GetDisplayOrderOfItemIndex(itemIndex), olvi); if (HotRowIndex == itemIndex) UpdateHotRow(olvi); return olvi; } /// /// On virtual lists, this cannot work. /// protected override void PostProcessRows() { } /// /// Record the change of checkstate for the given object in the model. /// This does not update the UI -- only the model /// /// /// /// The check state that was recorded and that should be used to update /// the control. protected override CheckState PutCheckState(object modelObject, CheckState state) { state = base.PutCheckState(modelObject, state); CheckStateMap[modelObject] = state; return state; } /// /// Refresh the given item in the list /// /// The item to refresh public override void RefreshItem(OLVListItem olvi) { ClearCachedInfo(); RedrawItems(olvi.Index, olvi.Index, true); } /// /// Change the size of the list /// /// protected virtual void SetVirtualListSize(int newSize) { if (newSize < 0 || VirtualListSize == newSize) return; int oldSize = VirtualListSize; ClearCachedInfo(); // There is a bug in .NET when a virtual ListView is cleared // (i.e. VirtuaListSize set to 0) AND it is scrolled vertically: the scroll position // is wrong when the list is next populated. To avoid this, before // clearing a virtual list, we make sure the list is scrolled to the top. // [6 weeks later] Damn this is a pain! There are cases where this can also throw exceptions! try { if (newSize == 0 && TopItemIndex > 0) TopItemIndex = 0; } catch (Exception) { // Ignore any failures } // In strange cases, this can throw the exceptions too. The best we can do is ignore them :( try { VirtualListSize = newSize; } catch (ArgumentOutOfRangeException) { // pass } catch (NullReferenceException) { // pass } // Tell the world that the size of the list has changed OnItemsChanged(new ItemsChangedEventArgs(oldSize, VirtualListSize)); } /// /// Take ownership of the 'objects' collection. This separates our collection from the source. /// /// /// /// This method /// separates the 'objects' instance variable from its source, so that any AddObject/RemoveObject /// calls will modify our collection and not the original colleciton. /// /// /// VirtualObjectListViews always own their collections, so this is a no-op. /// /// protected override void TakeOwnershipOfObjects() { } /// /// Change the state of the control to reflect changes in filtering /// protected override void UpdateFiltering() { if (VirtualListDataSource is not IFilterableDataSource filterable) return; BeginUpdate(); try { int originalSize = VirtualListSize; filterable.ApplyFilters(ModelFilter, ListFilter); BuildList(); //// If the filtering actually did something, rebuild the groups if they are being shown //if (originalSize != this.VirtualListSize && this.ShowGroups) // this.BuildGroups(); } finally { EndUpdate(); } } /// /// Change the size of the virtual list so that it matches its data source /// public virtual void UpdateVirtualListSize() { if (VirtualListDataSource != null) SetVirtualListSize(VirtualListDataSource.GetObjectCount()); } #endregion #region Event handlers /// /// Handle the CacheVirtualItems event /// /// /// protected virtual void HandleCacheVirtualItems(object sender, CacheVirtualItemsEventArgs e) { if (VirtualListDataSource != null) VirtualListDataSource.PrepareCache(e.StartIndex, e.EndIndex); } /// /// Handle a RetrieveVirtualItem /// /// /// protected virtual void HandleRetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e) { // .NET 2.0 seems to generate a lot of these events. Before drawing *each* sub-item, // this event is triggered 4-8 times for the same index. So we save lots of CPU time // by caching the last result. //System.Diagnostics.Debug.WriteLine(String.Format("HandleRetrieveVirtualItem({0})", e.ItemIndex)); if (lastRetrieveVirtualItemIndex != e.ItemIndex) { lastRetrieveVirtualItemIndex = e.ItemIndex; lastRetrieveVirtualItem = MakeListViewItem(e.ItemIndex); } e.Item = lastRetrieveVirtualItem; } /// /// Handle the SearchForVirtualList event, which is called when the user types into a virtual list /// /// /// protected virtual void HandleSearchForVirtualItem(object sender, SearchForVirtualItemEventArgs e) { // The event has e.IsPrefixSearch, but as far as I can tell, this is always false (maybe that's different under Vista) // So we ignore IsPrefixSearch and IsTextSearch and always to a case insensitve prefix match. // We can't do anything if we don't have a data source if (VirtualListDataSource == null) return; // Where should we start searching? If the last row is focused, the SearchForVirtualItemEvent starts searching // from the next row, which is actually an invalidate index -- so we make sure we never go past the last object. int start = Math.Min(e.StartIndex, VirtualListDataSource.GetObjectCount() - 1); // Give the world a chance to fiddle with or completely avoid the searching process BeforeSearchingEventArgs args = new BeforeSearchingEventArgs(e.Text, start); OnBeforeSearching(args); if (args.Canceled) return; // Do the search int i = FindMatchingRow(args.StringToFind, args.StartSearchFrom, e.Direction); // Tell the world that a search has occurred AfterSearchingEventArgs args2 = new AfterSearchingEventArgs(args.StringToFind, i); OnAfterSearching(args2); // If we found a match, tell the event if (i != -1) e.Index = i; } /// /// Find the first row in the given range of rows that prefix matches the string value of the given column. /// /// /// /// /// /// The index of the matched row, or -1 protected override int FindMatchInRange(string text, int first, int last, OLVColumn column) { return VirtualListDataSource.SearchText(text, first, last, column); } #endregion #region Variable declaractions private OLVListItem lastRetrieveVirtualItem; private int lastRetrieveVirtualItemIndex = -1; #endregion } } ================================================ FILE: source/OculusHelper/OculusApp.cs ================================================ /* Copyright (c) 2018 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ namespace OculusHelper { internal class OculusApp { public OculusApp(string canonicalName, string version, bool isCore, string installLocation, string launchFile) { CanonicalName = canonicalName; Version = version; IsCore = isCore; InstallLocation = installLocation; LaunchFile = launchFile; } public string CanonicalName { get; } public string Version { get; } public bool IsCore { get; } public string InstallLocation { get; } public string LaunchFile { get; } } } ================================================ FILE: source/OculusHelper/OculusHelper.csproj ================================================  Exe Utility for discovering and uninstalling games and apps installed through Oculus Store OculusHelper.Program ================================================ FILE: source/OculusHelper/OculusManager.cs ================================================ /* Copyright (c) 2018 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.ServiceProcess; using System.Threading; using Klocman; using Klocman.Tools; using Microsoft.Win32; using Newtonsoft.Json; namespace OculusHelper { internal static class OculusManager { private static IEnumerable _oculusLibraryLocations; private static IEnumerable OculusLibraryLocations => _oculusLibraryLocations ?? (_oculusLibraryLocations = FindOculusLibraryLocations()); private static IEnumerable FindOculusLibraryLocations() { var libPaths = new List(); // Default library is in install dir and is not listed in the Libraries key. foreach (var softwareKey in new[] {@"SOFTWARE\Oculus VR, LLC\Oculus", @"SOFTWARE\WOW6432Node\Oculus VR, LLC\Oculus"}) try { using (var key = Registry.LocalMachine.OpenSubKey(softwareKey)) { if (key != null) if (key.GetValue("Base", null, RegistryValueOptions.None) is string path) libPaths.Add(path); } } catch (SystemException ex) { Console.WriteLine(ex); } const string oculusLibPath = @"Software\Oculus VR, LLC\Oculus\Libraries"; // Each user can have different libaries set up foreach (var userName in Registry.Users.GetSubKeyNames()) try { using (var key = Registry.Users.OpenSubKey(Path.Combine(userName, oculusLibPath), false)) { if (key == null) continue; foreach (var libKeyName in key.GetSubKeyNames()) using (var libKey = key.OpenSubKey(libKeyName)) { if (libKey != null) if (libKey.GetValue("Path", null, RegistryValueOptions.None) is string path) libPaths.Add(path); } } } catch (SystemException ex) { Console.WriteLine(ex); } return libPaths.Select(x => x.Trim().ToLowerInvariant()) .Select(PathTools.ResolveVolumeIdToPath) .Where(Directory.Exists) .Distinct(); } public static IEnumerable QueryOculusApps() { var apps = new List(); foreach (var lib in OculusLibraryLocations) { var software = Path.Combine(lib, "Software"); //var support = Path.Combine(lib, "Support"); var manifests = Path.Combine(lib, "Manifests"); if (!Directory.Exists(manifests)) continue; var jsonFiles = Directory.GetFiles(manifests) .Where(x => x.EndsWith(".json", StringComparison.OrdinalIgnoreCase)); foreach (var jsonFile in jsonFiles) { if (!File.Exists(jsonFile)) continue; try { var json = JsonConvert.DeserializeXNode(File.ReadAllText(jsonFile), "root")?.Root; if (json == null) continue; var name = json.Element("canonicalName")?.Value; if (string.IsNullOrWhiteSpace(name)) continue; var installLoc = Path.Combine(software, name); if (!Directory.Exists(installLoc)) continue; var launchFile = json.Element("launchFile")?.Value; var executable = string.IsNullOrWhiteSpace(launchFile) ? null : Path.Combine(installLoc, launchFile); apps.Add(new OculusApp( name, json.Element("version")?.Value, "true".Equals(json.Element("isCore")?.Value, StringComparison.OrdinalIgnoreCase), installLoc, executable)); } catch (SystemException ex) { LogWriter.WriteExceptionToLog(ex); } } } return apps; } public static void RemoveApp(string canonicalName) { Console.WriteLine("Looking for apps with canonical name: " + canonicalName); var apps = QueryOculusApps() .Where(x => canonicalName.Equals(x.CanonicalName, StringComparison.OrdinalIgnoreCase)) .ToList(); if (apps.Count == 0) { Console.WriteLine("Invalid app name or app can't be uninstalled"); throw new Exception($"{canonicalName} is not a recognized or allowed app name"); } foreach (var app in apps) RemoveApp(app); } public static void RemoveApp(OculusApp app) { CloseOculusClient(); Console.WriteLine("Removing Oculus app: " + app.CanonicalName); Debug.Assert(app.CanonicalName.Length > 10); foreach (var libraryLocation in OculusLibraryLocations) { // Collect paths first to avoid crashing halfway var dirs = Directory.GetDirectories(libraryLocation, $"*{app.CanonicalName}*", SearchOption.AllDirectories); var files = Directory.GetFiles(libraryLocation, $"*{app.CanonicalName}*", SearchOption.AllDirectories); foreach (var path in dirs) { Console.WriteLine("Deleting " + path); Directory.Delete(path, true); } foreach (var path in files) { Console.WriteLine("Deleting " + path); File.Delete(path); } } RestartOculusService(); Console.WriteLine("Finished"); } /// /// After removing an app the oculus library service has to be restarted to update the state. /// private static void RestartOculusService() { try { // Library service can't be restarted by itself, have to do it through OVRService var serviceController = new ServiceController(@"OVRService"); if(serviceController.Status.Equals(ServiceControllerStatus.Stopped)) return; if (serviceController.Status.Equals(ServiceControllerStatus.Running) || serviceController.Status.Equals(ServiceControllerStatus.StartPending)) { Console.WriteLine("Stopping Oculus VR Services..."); serviceController.Stop(); } serviceController.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(20)); Console.WriteLine("Restarting Oculus VR Services..."); serviceController.Start(); serviceController.WaitForStatus(ServiceControllerStatus.Running, TimeSpan.FromSeconds(20)); } catch (SystemException ex) { Console.WriteLine("Restarting Oculus VR Service failed - " + ex.Message); } } private static void CloseOculusClient() { var processes = Process.GetProcessesByName("OculusClient"); if (processes.Length == 0) return; Console.WriteLine("Closing Oculus Client..."); foreach (var process in processes) { try { if (!process.HasExited) process.Kill(true); } catch (SystemException ex) { Console.WriteLine($"Failed to kill process {process.ProcessName} - {ex.Message}"); Console.WriteLine("Please close the Oculus Client manually to continue."); } } Console.WriteLine("Waiting for Oculus Client to close..."); while (processes.Any(x=>!x.HasExited)) { Thread.Sleep(250); } } } } ================================================ FILE: source/OculusHelper/Program.cs ================================================ /* Copyright (c) 2018 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.IO; using Klocman; using Microsoft.Win32.Interop; namespace OculusHelper { internal static class Program { private static int Main(string[] args) { if (args.Length == 0) return (int)ResultWin32.ERROR_BAD_ARGUMENTS; HelperTools.SetupEncoding(); if (args.Length == 1 && string.Equals(args[0], @"/query", StringComparison.OrdinalIgnoreCase)) try { var result = OculusManager.QueryOculusApps(); foreach (var app in result) Console.WriteLine(HelperTools.ObjectToConsoleOutput(app)); return (int)ResultWin32.ERROR_SUCCESS; } catch (IOException ex) { LogWriter.WriteExceptionToLog(ex); return (int)HelperTools.ExtractHrefCode(ex); } catch (Exception ex) { LogWriter.WriteExceptionToLog(ex); return (int)ResultWin32.ERROR_FUNCTION_FAILED; } if (args.Length == 2 && string.Equals(args[0], @"/uninstall", StringComparison.OrdinalIgnoreCase)) try { OculusManager.RemoveApp(args[1]); return (int)ResultWin32.ERROR_SUCCESS; } catch (IOException ex) { return (int)HelperTools.ExtractHrefCode(ex); } catch (Exception ex) { LogWriter.WriteExceptionToLog(ex); return (int)ResultWin32.ERROR_SUCCESS; } return (int)ResultWin32.ERROR_BAD_ARGUMENTS; } } } ================================================ FILE: source/PortableSettingsProvider/PortableSettingsProvider.cs ================================================ using System; using System.Collections; using System.Collections.Specialized; using System.Configuration; using System.IO; using System.Linq; using System.Windows.Forms; using System.Xml; namespace PortableSettingsProvider { /// /// License: The Code Project Open License (CPOL) 1.02 /// 18 Oct 2007 - CodeChimp - Public VB release /// Mar 26, 2016 - HakanL - Converted project to C#, cleanup /// 2010-2018 - Marcin Szeniak - Bugfixes, cleanup, improvements /// public class PortableSettingsProvider : SettingsProvider { //XML Root Node name private const string SettingsRootName = "Settings"; public static string ApplicationNameOverride { get; set; } public override string ApplicationName { get => ApplicationNameOverride ?? Path.GetFileNameWithoutExtension(Application.ExecutablePath); set { } } private XmlDocument _settingsXml; private XmlNode _settingsRootNode; private readonly string _localMachineName; public PortableSettingsProvider() { var machineName = Environment.MachineName; if (string.IsNullOrEmpty(machineName)) machineName = $"{Environment.UserDomainName}-{Environment.UserName}"; _localMachineName = XmlConvert.EncodeName(machineName); } private XmlDocument SettingsXml { get { //If we dont hold an xml document, try opening one. //If it doesnt exist then create a new one ready. if (_settingsXml == null) { _settingsXml = new XmlDocument(); try { _settingsXml.Load(Path.Combine(GetAppSettingsPath(), GetAppSettingsFilename())); if (_settingsXml.SelectSingleNode(SettingsRootName) == null) throw new Exception("Invalid config file"); } catch (Exception) { //Create new document var dec = _settingsXml.CreateXmlDeclaration("1.0", "utf-8", string.Empty); _settingsXml.AppendChild(dec); var nodeRoot = _settingsXml.CreateNode(XmlNodeType.Element, SettingsRootName, ""); _settingsXml.AppendChild(nodeRoot); } } return _settingsXml; } } private XmlNode SettingsRootNode { get { if (_settingsRootNode == null) _settingsRootNode = SettingsXml.SelectSingleNode(SettingsRootName); return _settingsRootNode; } } public override void Initialize(string name, NameValueCollection col) { base.Initialize(ApplicationName, col); } public static string AppSettingsPathOverride { get; set; } public virtual string GetAppSettingsPath() { if (Directory.Exists(AppSettingsPathOverride)) return AppSettingsPathOverride; //Used to determine where to store the settings var fi = new FileInfo(Application.ExecutablePath); return fi.DirectoryName; } public virtual string GetAppSettingsFilename() { //Used to determine the filename to store the settings return ApplicationName + ".settings"; } public override void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection propvals) { //Iterate through the settings to be stored //Only dirty settings are included in propvals, and only ones relevant to this provider foreach (SettingsPropertyValue propval in propvals) { SetValue(propval); } try { SettingsXml.Save(Path.Combine(GetAppSettingsPath(), GetAppSettingsFilename())); } catch (Exception ex) { Console.WriteLine("Failed to save settings - " + ex); } } public override SettingsPropertyValueCollection GetPropertyValues(SettingsContext context, SettingsPropertyCollection props) { //Create new collection of values var values = new SettingsPropertyValueCollection(); //Iterate through the settings to be retrieved foreach (SettingsProperty setting in props) { var value = new SettingsPropertyValue(setting); value.IsDirty = false; value.SerializedValue = GetValue(setting); values.Add(value); } return values; } private string GetValue(SettingsProperty setting) { try { if (IsRoaming(setting)) { return SettingsXml.SelectSingleNode(SettingsRootName + "/" + setting.Name)?.InnerText ?? GetDefaultValue(setting); } return SettingsXml.SelectSingleNode(SettingsRootName + "/" + _localMachineName + "/" + setting.Name)?.InnerText ?? GetDefaultValue(setting); } catch (Exception) { return GetDefaultValue(setting); } } private static string GetDefaultValue(SettingsProperty setting) { return setting.DefaultValue?.ToString() ?? string.Empty; } private void SetValue(SettingsPropertyValue propVal) { if (propVal == null) throw new ArgumentNullException(nameof(propVal)); if (propVal.SerializedValue == null) throw new ArgumentNullException(nameof(propVal.SerializedValue)); XmlElement settingNode; //Determine if the setting is roaming. //If roaming then the value is stored as an element under the root //Otherwise it is stored under a machine name node try { if (IsRoaming(propVal.Property)) { settingNode = (XmlElement)SettingsXml.SelectSingleNode( SettingsRootName + "/" + propVal.Name); } else { settingNode = (XmlElement)SettingsXml.SelectSingleNode( SettingsRootName + "/" + _localMachineName + "/" + propVal.Name); } } catch (Exception) { settingNode = null; } if (settingNode != null) { settingNode.InnerText = propVal.SerializedValue.ToString(); } else { if (IsRoaming(propVal.Property)) { CreateRoamingValue(propVal); } else { CreateLocalValue(propVal); } } } /// /// Its machine specific, store as an element of the machine name node, /// creating a new machine name node if one doesnt exist. /// private void CreateLocalValue(SettingsPropertyValue propVal) { XmlElement machineNode; try { machineNode = (XmlElement)SettingsXml.SelectSingleNode( SettingsRootName + "/" + _localMachineName); } catch (Exception) { machineNode = SettingsXml.CreateElement(_localMachineName); SettingsRootNode.AppendChild(machineNode); } if (machineNode == null) { machineNode = SettingsXml.CreateElement(_localMachineName); SettingsRootNode.AppendChild(machineNode); } var settingNode = SettingsXml.CreateElement(propVal.Name); settingNode.InnerText = propVal.SerializedValue.ToString(); machineNode.AppendChild(settingNode); } /// /// Store the value as an element of the Settings Root Node /// private void CreateRoamingValue(SettingsPropertyValue propVal) { var serializedValue = propVal.SerializedValue; if (serializedValue != null) { if (SettingsRootNode == null) throw new ArgumentNullException(nameof(SettingsRootNode)); if (SettingsXml == null) throw new ArgumentNullException(nameof(SettingsXml)); var settingNode = SettingsXml.CreateElement(propVal.Name); settingNode.InnerText = serializedValue.ToString(); SettingsRootNode.AppendChild(settingNode); } } /// /// Determine if the setting is marked as Roaming /// private bool IsRoaming(SettingsProperty prop) { try { return prop.Attributes.Cast().Select(x => x.Value) .OfType() .Any(x => x.Manageability == SettingsManageability.Roaming); } catch (Exception) { return false; } } } } ================================================ FILE: source/PortableSettingsProvider/PortableSettingsProvider.csproj ================================================  Library false ================================================ FILE: source/PortableSettingsProvider/Properties/AssemblyInfo.cs ================================================ using System.Reflection; 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("PortableSettingsProvider")] [assembly: AssemblyDescription("Library that allows saving of .NET settings to a portable file")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCompany("Marcin Szeniak, HakanL, CodeChimp")] [assembly: AssemblyProduct("PortableSettingsProvider")] [assembly: AssemblyCopyright("Copyright © 2007")] // 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("68c10a7e-883f-443a-b7a0-41e06ad56602")] // 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.2.1")] ================================================ FILE: source/PortableSettingsProvider/U3SettingsProvider.cs ================================================ using System; namespace PortableSettingsProvider { public class U3SettingsProvider : PortableSettingsProvider { private const string U3APPDATAPATH = "U3_APP_DATA_PATH"; public override string GetAppSettingsPath() { // Get the environment variable set by the U3 application for a pointer to its data try { return Environment.GetEnvironmentVariable(U3APPDATAPATH); } catch (Exception) { // Not running in a U3 environment, just return the application path return base.GetAppSettingsPath(); } } } } ================================================ FILE: source/ScriptHelper/Program.cs ================================================ /* Copyright (c) 2018 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Linq; using Klocman; using Microsoft.Win32.Interop; namespace ScriptHelper { internal static class Program { private static QueryType _queryType; private static string _appId; [STAThread] private static int Main(string[] args) { HelperTools.SetupEncoding(); try { ProcessCommandlineArguments(args); switch (_queryType) { case QueryType.Uninstall: Console.WriteLine("Uninstalling " + _appId); var tweakEntry = Tweaks.GetEntry(_appId); if (tweakEntry == null) throw new ArgumentException("Could not find a tweak with this name to uninstall"); tweakEntry.OnUninstall(true); break; case QueryType.List: foreach (var result in Tweaks.GetConsoleOutput()) { var converted = result.Select(x => new KeyValuePair(x.Key, x.Value)).ToList(); Console.WriteLine(HelperTools.KeyValueListToConsoleOutput(converted)); } break; default: Console.WriteLine("Accepted commands:\nlist\nuninstall "); break; } } catch (OperationCanceledException) { return (int)ResultWin32.ERROR_CANCELLED; } catch (FormatException ex) { LogWriter.WriteExceptionToLog(ex); return (int)ResultWin32.ERROR_BAD_ARGUMENTS; } catch (Exception ex) { LogWriter.WriteExceptionToLog(ex); return (int)ResultWin32.ERROR_UNEXP_NET_ERR; } return (int)ResultWin32.ERROR_SUCCESS; } private static void ProcessCommandlineArguments(IEnumerable args) { foreach (var arg in args) { switch (arg.ToLowerInvariant()) { case @"u": case @"uninstall": if (_queryType != QueryType.None) throw new FormatException(@"Multiple commands specified"); _queryType = QueryType.Uninstall; break; case @"l": case @"list": if (_queryType != QueryType.None) throw new FormatException(@"Multiple commands specified"); _queryType = QueryType.List; break; default: if (_appId != null) throw new FormatException(@"Too many parameters"); _appId = arg; break; } } if (_queryType == QueryType.None) throw new FormatException(@"No commands specified"); if (_queryType == QueryType.Uninstall && _appId == null) throw new FormatException(@"Missing ID parameter for what to uninstall"); } private enum QueryType { None, Uninstall, List, } } } ================================================ FILE: source/ScriptHelper/Properties/launchSettings.json ================================================ { "profiles": { "ScriptHelper": { "commandName": "Project", "commandLineArgs": "list" }, "newProfile1": { "commandName": "Project", "commandLineArgs": "uninstall Tweak-Showing3DObjectsUnderThisPC" } } } ================================================ FILE: source/ScriptHelper/ScriptHelper.csproj ================================================  Exe Provides various registry tweaks and scripts to BCU ScriptHelper.Program ================================================ FILE: source/ScriptHelper/Tweaks.cs ================================================ using System; using System.Collections.Generic; using System.IO; using System.Linq; using Klocman; using Klocman.Extensions; using Microsoft.Win32; namespace ScriptHelper { /* Some scripts are based on https://github.com/W4RH4WK/Debloat-Windows-10/ * * ## Thanks To * * - [10se1ucgo](https://github.com/10se1ucgo) * - [Plumebit](https://github.com/Plumebit) * - [aramboi](https://github.com/aramboi) * - [maci0](https://github.com/maci0) * - [narutards](https://github.com/narutards) * - [tumpio](https://github.com/tumpio) * * ## License * * "THE BEER-WARE LICENSE" (Revision 42): * * As long as you retain this notice you can do whatever you want with this * stuff. If we meet some day, and you think this stuff is worth it, you can * buy us a beer in return. * * This project is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. */ internal static class Tweaks { static Tweaks() { _tweaks = new List { new() { DisplayName = "Easy Access Keyboard Shortcuts", Publisher = "Microsoft Corporation", SystemIcon = "Shield", OnUninstall = _ => { Registry.CurrentUser.OpenSubKey(@"Control Panel\Accessibility\StickyKeys")?.SetValue("Flags", "506", RegistryValueKind.String); Registry.CurrentUser.OpenSubKey(@"Control Panel\Accessibility\Keyboard Response")?.SetValue("Flags", "122", RegistryValueKind.String); Registry.CurrentUser.OpenSubKey(@"Control Panel\Accessibility\ToggleKeys")?.SetValue("Flags", "58", RegistryValueKind.String); }, IsPresent = () => Registry.CurrentUser.OpenSubKey(@"Control Panel\Accessibility\StickyKeys")?.GetValue("Flags")?.ToString() != "506" || Registry.CurrentUser.OpenSubKey(@"Control Panel\Accessibility\Keyboard Response")?.GetValue("Flags")?.ToString() != "122" || Registry.CurrentUser.OpenSubKey(@"Control Panel\Accessibility\ToggleKeys")?.GetValue("Flags")?.ToString() != "58" }, new() { DisplayName = "Subscribed content (Auto-install suggested apps)", Publisher = "Microsoft Corporation", SystemIcon = "Shield", OnUninstall = _ => { Console.WriteLine(@"Disabling automatic downloading and installing of subscribed content"); var key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager"); if (key != null) { key.SetValue("FeatureManagementEnabled", 0, RegistryValueKind.DWord); key.SetValue("OemPreInstalledAppsEnabled", 0, RegistryValueKind.DWord); key.SetValue("PreInstalledAppsEnabled", 0, RegistryValueKind.DWord); key.SetValue("SilentInstalledAppsEnabled", 0, RegistryValueKind.DWord); key.SetValue("ContentDeliveryAllowed", 0, RegistryValueKind.DWord); key.SetValue("PreInstalledAppsEverEnabled", 0, RegistryValueKind.DWord); key.SetValue("SubscribedContentEnabled", 0, RegistryValueKind.DWord); key.SetValue("SubscribedContent-338388Enabled", 0, RegistryValueKind.DWord); key.SetValue("SubscribedContent-338389Enabled", 0, RegistryValueKind.DWord); key.SetValue("SubscribedContent-314559Enabled", 0, RegistryValueKind.DWord); key.SetValue("SubscribedContent-338387Enabled", 0, RegistryValueKind.DWord); key.SetValue("SubscribedContent-338393Enabled", 0, RegistryValueKind.DWord); key.SetValue("SystemPaneSuggestionsEnabled", 0, RegistryValueKind.DWord); } Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Policies\Microsoft\WindowsStore")?.SetValue("AutoDownload", 2, RegistryValueKind.DWord); Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Policies\Microsoft\Windows\CloudContent") ?.SetValue("DisableWindowsConsumerFeatures", 1, RegistryValueKind.DWord); }, IsPresent = () => { // If ContentDeliveryManager doesn't exist it's likely not supported by the OS // If SubscribedContentEnabled value doesn't exist assume it's turned on. It's disabled if set to 0 var key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager"); return key != null && key.GetValue("SubscribedContentEnabled", 1)?.ToString() != "0"; } }, new() { DisplayName = "Decreased Wallpaper quality (high compression)", Publisher = "Microsoft Corporation", SystemIcon = "Shield", OnUninstall = _ => { Registry.CurrentUser.OpenSubKey(@"Control Panel\Desktop")?.SetValue("JPEGImportQuality", 100, RegistryValueKind.DWord); }, IsPresent = () => { var key = Registry.CurrentUser.OpenSubKey(@"Control Panel\Desktop"); // ReSharper disable once PossibleNullReferenceException return key != null && (int)key.GetValue("JPEGImportQuality", 0) < 100; } }, new() { DisplayName = "Mouse Acceleration", Publisher = "Microsoft Corporation", SystemIcon = "Shield", OnUninstall = _ => { var key = Registry.CurrentUser.OpenSubKey(@"Control Panel\Mouse"); if (key != null) { Console.WriteLine(@"Disabling mouse acceleration"); key.SetValue("MouseSensitivity", "10", RegistryValueKind.String); key.SetValue("MouseSpeed", "0", RegistryValueKind.String); key.SetValue("MouseThreshold1", "0", RegistryValueKind.String); key.SetValue("MouseThreshold2", "0", RegistryValueKind.String); // Curves depend on display dpi and hz. They can be generated with MarkC's mouse acceleration fix // They are only active with mouse acceleration turned on, so no reason to mess with them //key.SetValue("SmoothMouseXCurve", new byte[]{0x00, 0x00, 0x00, // 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xCC, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x80, 0x99, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x66, 0x26, 0x00, 0x00, // 0x00, 0x00, 0x00, 0x00, 0x33, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00}, RegistryValueKind.Binary); //key.SetValue("SmoothMouseYCurve", new byte[]{0x00, 0x00, 0x00, // 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x00, 0x00, // 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00}, RegistryValueKind.Binary); } }, IsPresent = () => Registry.CurrentUser.OpenSubKey(@"Control Panel\Mouse")?.GetValue("MouseSpeed", "0")?.ToString() == "1" }, new() { DisplayName = "Showing Desktop under This PC", Publisher = "Microsoft Corporation", SystemIcon = "Shield", OnUninstall = _ => { Registry.LocalMachine.DeleteSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\NameSpace\{B4BFCC3A-DB2C-424C-B029-7FE99A87C641}", false); Registry.LocalMachine.DeleteSubKey(@"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\NameSpace\{B4BFCC3A-DB2C-424C-B029-7FE99A87C641}", false); }, IsPresent = () => Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\NameSpace\{B4BFCC3A-DB2C-424C-B029-7FE99A87C641}") != null }, new() { DisplayName = "Showing Documents under This PC", Publisher = "Microsoft Corporation", SystemIcon = "Shield", OnUninstall = _ => { Registry.LocalMachine.DeleteSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\NameSpace\{A8CDFF1C-4878-43be-B5FD-F8091C1C60D0}", false); Registry.LocalMachine.DeleteSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\NameSpace\{d3162b92-9365-467a-956b-92703aca08af}", false); Registry.LocalMachine.DeleteSubKey(@"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\NameSpace\{A8CDFF1C-4878-43be-B5FD-F8091C1C60D0}", false); Registry.LocalMachine.DeleteSubKey(@"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\NameSpace\{d3162b92-9365-467a-956b-92703aca08af}", false); }, IsPresent = () => Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\NameSpace\{A8CDFF1C-4878-43be-B5FD-F8091C1C60D0}") != null }, new() { DisplayName = "Showing Downloads under This PC", Publisher = "Microsoft Corporation", SystemIcon = "Shield", OnUninstall = _ => { Registry.LocalMachine.DeleteSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\NameSpace\{374DE290-123F-4565-9164-39C4925E467B}", false); Registry.LocalMachine.DeleteSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\NameSpace\{088e3905-0323-4b02-9826-5d99428e115f}", false); Registry.LocalMachine.DeleteSubKey(@"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\NameSpace\{374DE290-123F-4565-9164-39C4925E467B}", false); Registry.LocalMachine.DeleteSubKey(@"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\NameSpace\{088e3905-0323-4b02-9826-5d99428e115f}", false); }, IsPresent = () => Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\NameSpace\{374DE290-123F-4565-9164-39C4925E467B}") != null }, new() { DisplayName = "Showing Music under This PC", Publisher = "Microsoft Corporation", SystemIcon = "Shield", OnUninstall = _ => { Registry.LocalMachine.DeleteSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\NameSpace\{1CF1260C-4DD0-4ebb-811F-33C572699FDE}", false); Registry.LocalMachine.DeleteSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\NameSpace\{3dfdf296-dbec-4fb4-81d1-6a3438bcf4de}", false); Registry.LocalMachine.DeleteSubKey(@"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\NameSpace\{1CF1260C-4DD0-4ebb-811F-33C572699FDE}", false); Registry.LocalMachine.DeleteSubKey(@"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\NameSpace\{3dfdf296-dbec-4fb4-81d1-6a3438bcf4de}", false); }, IsPresent = () => Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\NameSpace\{1CF1260C-4DD0-4ebb-811F-33C572699FDE}") != null }, new() { DisplayName = "Showing Pictures under This PC", Publisher = "Microsoft Corporation", SystemIcon = "Shield", OnUninstall = _ => { Registry.LocalMachine.DeleteSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\NameSpace\{3ADD1653-EB32-4cb0-BBD7-DFA0ABB5ACCA}", false); Registry.LocalMachine.DeleteSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\NameSpace\{24ad3ad4-a569-4530-98e1-ab02f9417aa8}", false); Registry.LocalMachine.DeleteSubKey(@"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\NameSpace\{3ADD1653-EB32-4cb0-BBD7-DFA0ABB5ACCA}", false); Registry.LocalMachine.DeleteSubKey(@"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\NameSpace\{24ad3ad4-a569-4530-98e1-ab02f9417aa8}", false); }, IsPresent = () => Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\NameSpace\{3ADD1653-EB32-4cb0-BBD7-DFA0ABB5ACCA}") != null }, new() { DisplayName = "Showing Videos under This PC", Publisher = "Microsoft Corporation", SystemIcon = "Shield", OnUninstall = _ => { Registry.LocalMachine.DeleteSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\NameSpace\{A0953C92-50DC-43bf-BE83-3742FED03C9C}", false); Registry.LocalMachine.DeleteSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\NameSpace\{f86fa3ab-70d2-4fc7-9c99-fcbf05467f3a}", false); Registry.LocalMachine.DeleteSubKey(@"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\NameSpace\{A0953C92-50DC-43bf-BE83-3742FED03C9C}", false); Registry.LocalMachine.DeleteSubKey(@"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\NameSpace\{f86fa3ab-70d2-4fc7-9c99-fcbf05467f3a}", false); }, IsPresent = () => Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\NameSpace\{A0953C92-50DC-43bf-BE83-3742FED03C9C}") != null }, new() { DisplayName = "Showing 3D Objects under This PC", Publisher = "Microsoft Corporation", SystemIcon = "Shield", OnUninstall = _ => { Registry.LocalMachine.DeleteSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\NameSpace\{0DB7E03F-FC29-4DC6-9020-FF41B59E513A}", false); Registry.LocalMachine.DeleteSubKey(@"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\NameSpace\{0DB7E03F-FC29-4DC6-9020-FF41B59E513A}", false); }, IsPresent = () => Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\NameSpace\{0DB7E03F-FC29-4DC6-9020-FF41B59E513A}") != null }, /*new TweakEntry todo check if this still works and convert into a c# script { DisplayName = "Microsoft OneDrive", Publisher = "Microsoft Corporation", SystemIcon = "Shield", OnUninstall = _ => { //# This script will remove and disable OneDrive integration. // // Write-Output "Kill OneDrive process" // taskkill.exe /F /IM "OneDrive.exe" // taskkill.exe /F /IM "explorer.exe" // // Write-Output "Remove OneDrive" // if (Test-Path "$env:systemroot\System32\OneDriveSetup.exe") { // & "$env:systemroot\System32\OneDriveSetup.exe" /uninstall // } // if (Test-Path "$env:systemroot\SysWOW64\OneDriveSetup.exe") { // & "$env:systemroot\SysWOW64\OneDriveSetup.exe" /uninstall // } // // Write-Output "Removing OneDrive leftovers" // Remove-Item -Recurse -Force -ErrorAction SilentlyContinue "$env:localappdata\Microsoft\OneDrive" // Remove-Item -Recurse -Force -ErrorAction SilentlyContinue "$env:programdata\Microsoft OneDrive" // Remove-Item -Recurse -Force -ErrorAction SilentlyContinue "$env:systemdrive\OneDriveTemp" // # check if directory is empty before removing: // If ((Get-ChildItem "$env:userprofile\OneDrive" -Recurse | Measure-Object).Count -eq 0) { // Remove-Item -Recurse -Force -ErrorAction SilentlyContinue "$env:userprofile\OneDrive" // } // // Write-Output "Disable OneDrive via Group Policies" // force-mkdir "HKLM:\SOFTWARE\Wow6432Node\Policies\Microsoft\Windows\OneDrive" // Set-ItemProperty "HKLM:\SOFTWARE\Wow6432Node\Policies\Microsoft\Windows\OneDrive" "DisableFileSyncNGSC" 1 // // Write-Output "Remove Onedrive from explorer sidebar" // New-PSDrive -PSProvider "Registry" -Root "HKEY_CLASSES_ROOT" -Name "HKCR" // mkdir -Force "HKCR:\CLSID\{018D5C66-4533-4307-9B53-224DE2ED1FE6}" // Set-ItemProperty "HKCR:\CLSID\{018D5C66-4533-4307-9B53-224DE2ED1FE6}" "System.IsPinnedToNameSpaceTree" 0 // mkdir -Force "HKCR:\Wow6432Node\CLSID\{018D5C66-4533-4307-9B53-224DE2ED1FE6}" // Set-ItemProperty "HKCR:\Wow6432Node\CLSID\{018D5C66-4533-4307-9B53-224DE2ED1FE6}" "System.IsPinnedToNameSpaceTree" 0 // Remove-PSDrive "HKCR" // // # Thank you Matthew Israelsson // Write-Output "Removing run hook for new users" // reg load "hku\Default" "C:\Users\Default\NTUSER.DAT" // reg delete "HKEY_USERS\Default\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" /v "OneDriveSetup" /f // reg unload "hku\Default" // // Write-Output "Removing startmenu entry" // Remove-Item -Force -ErrorAction SilentlyContinue "$env:userprofile\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\OneDrive.lnk" // // Write-Output "Removing scheduled task" // Get-ScheduledTask -TaskPath '\' -TaskName 'OneDrive*' -ea SilentlyContinue | Unregister-ScheduledTask -Confirm:$false // // Write-Output "Restarting explorer" // Start-Process "explorer.exe" // // Write-Output "Waiting for explorer to complete loading" // Start-Sleep 10 // // Write-Output "Removing additional OneDrive leftovers" // foreach ($item in (Get-ChildItem "$env:WinDir\WinSxS\*onedrive*")) { // Takeown-Folder $item.FullName // Remove-Item -Recurse -Force $item.FullName // } }, IsPresent = () => { var key = Registry.ClassesRoot.OpenSubKey(@"CLSID\{018D5C66-4533-4307-9B53-224DE2ED1FE6}"); if (key != null && (int)key.GetValue("System.IsPinnedToNameSpaceTree", 0) > 0) return true; key = Registry.ClassesRoot.OpenSubKey(@"Wow6432Node\CLSID\{018D5C66-4533-4307-9B53-224DE2ED1FE6}"); return (key != null && (int)key.GetValue("System.IsPinnedToNameSpaceTree", 0) > 0); } }*/ }; } internal record TweakEntry { public string DisplayName { get; init; } public string RatingId => "Tweak-" + DisplayName.ToPascalCase().RemoveSpecialCharacters(); public string Publisher { get; init; } public string SystemIcon { get; init; } public Action OnUninstall { get; init; } public Func IsPresent { get; init; } } private static readonly List _tweaks; public static TweakEntry GetEntry(string ratingId) => _tweaks.FirstOrDefault(x => x.RatingId == ratingId); public static IEnumerable> GetConsoleOutput() { var fileLoc = Path.Combine(Path.GetDirectoryName(typeof(Tweaks).Assembly.Location) ?? throw new InvalidOperationException("null Location"), "ScriptHelper.exe"); foreach (var tweakEntry in _tweaks) { Dictionary dic = null; try { if (tweakEntry.IsPresent()) { dic = new Dictionary(); dic["DisplayName"] = tweakEntry.DisplayName; dic["Publisher"] = tweakEntry.Publisher; var ratingId = tweakEntry.RatingId; dic["RatingId"] = ratingId; var uninsStr = $"\"{fileLoc}\" uninstall {ratingId}"; dic["UninstallString"] = uninsStr; dic["QuietUninstallString"] = uninsStr; } } catch (Exception ex) { LogWriter.WriteExceptionToLog(ex); //Console.WriteLine(ex); continue; } if (dic != null) yield return dic; } } } } ================================================ FILE: source/SimpleTreeMap/Element.cs ================================================ using System.Drawing; namespace SimpleTreeMap { public class Element { public T Object { get; set; } public double Value { get; set; } public Color Color { get; set; } public string Text { get; set; } } } ================================================ FILE: source/SimpleTreeMap/Properties/AssemblyInfo.cs ================================================ using System.Reflection; 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("SimpleTreeMap")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("SimpleTreeMap")] [assembly: AssemblyCopyright("Copyright © 2017")] [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("52fcbdb1-48d8-448d-b8ca-07f10ab3ca25")] // 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.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")] ================================================ FILE: source/SimpleTreeMap/SimpleTreeMap.csproj ================================================  Library false ================================================ FILE: source/SimpleTreeMap/Slice.cs ================================================ using System.Collections.Generic; using System.Linq; namespace SimpleTreeMap { public class Slice { public ICollection> Elements { get; set; } public double Size { get; set; } public ICollection> SubSlices { get; set; } public string ToElementNames() { return string.Join("\n", Elements.Select(x => x.Text).ToArray()); } } } ================================================ FILE: source/SimpleTreeMap/SliceMaker.cs ================================================ using System; using System.Collections.Generic; using System.Linq; namespace SimpleTreeMap { /// /// Based on https://pascallaurin42.blogspot.com/2013/12/implementing-treemap-in-c.html /// internal static class SliceMaker { public static SliceResult GetElementsForSlice(ICollection> elements, double sliceWidth) { var elementsInSlice = new List>(); var remainingElements = new List>(); var current = 0d; var total = elements.Sum(x => x.Value); foreach (var element in elements) { if (current > sliceWidth) remainingElements.Add(element); else { elementsInSlice.Add(element); current += element.Value/total; } } return new SliceResult { Elements = elementsInSlice, ElementsSize = current, RemainingElements = remainingElements }; } public static IEnumerable> GetRectangles(Slice slice, int width, int height) { if (slice == null) yield break; var area = new SliceRectangle {Slice = slice, Width = width, Height = height}; // Handle single-item lists if(slice.SubSlices == null && slice.Elements.Count == 1) { var sliceRectangle = new SliceRectangle { X = 0, Y = 0, Height = height, Width = width, Slice = slice }; yield return sliceRectangle; yield break; } foreach (var rect in GetRectangles(area)) { // Make sure no rectangle go outside the original area if (rect.X + rect.Width > area.Width) rect.Width = area.Width - rect.X; if (rect.Y + rect.Height > area.Height) rect.Height = area.Height - rect.Y; yield return rect; } } public static IEnumerable> GetRectangles(SliceRectangle sliceRectangle) { var isHorizontalSplit = sliceRectangle.Width >= sliceRectangle.Height; var currentPos = 0; if (sliceRectangle.Slice?.SubSlices == null) yield break; foreach (var subSlice in sliceRectangle.Slice.SubSlices) { var subRect = new SliceRectangle {Slice = subSlice}; int rectSize; if (isHorizontalSplit) { rectSize = (int) Math.Round(sliceRectangle.Width*subSlice.Size); subRect.X = sliceRectangle.X + currentPos; subRect.Y = sliceRectangle.Y; subRect.Width = rectSize; subRect.Height = sliceRectangle.Height; } else { rectSize = (int) Math.Round(sliceRectangle.Height*subSlice.Size); subRect.X = sliceRectangle.X; subRect.Y = sliceRectangle.Y + currentPos; subRect.Width = sliceRectangle.Width; subRect.Height = rectSize; } currentPos += rectSize; if (subSlice.Elements.Count > 1) { foreach (var sr in GetRectangles(subRect)) yield return sr; } else if (subSlice.Elements.Count == 1) yield return subRect; } } public static Slice GetSlice(ICollection> elements, double totalSize, double sliceWidth) { if (!elements.Any()) return null; if (elements.Count == 1) return new Slice {Elements = elements, Size = totalSize}; var sliceResult = GetElementsForSlice(elements, sliceWidth); return new Slice { Elements = elements, Size = totalSize, SubSlices = new[] { GetSlice(sliceResult.Elements, sliceResult.ElementsSize, sliceWidth), GetSlice(sliceResult.RemainingElements, 1 - sliceResult.ElementsSize, sliceWidth) } }; } } } ================================================ FILE: source/SimpleTreeMap/SliceRectangle.cs ================================================ using System.Drawing; namespace SimpleTreeMap { public class SliceRectangle { public int Height { get; set; } public Slice Slice { get; set; } public int Width { get; set; } public int X { get; set; } public int Y { get; set; } public Rectangle PaintRect { get; set; } public bool Contains(Point p) { return p.X >= X && p.X <= X + Width && p.Y >= Y && p.Y <= Y + Height; } } } ================================================ FILE: source/SimpleTreeMap/SliceResult.cs ================================================ using System.Collections.Generic; namespace SimpleTreeMap { public class SliceResult { public ICollection> Elements { get; set; } public double ElementsSize { get; set; } public ICollection> RemainingElements { get; set; } } } ================================================ FILE: source/SimpleTreeMap/TreeMap.Designer.cs ================================================ namespace SimpleTreeMap { partial class TreeMap { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Component Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.components = new System.ComponentModel.Container(); this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); this.SuspendLayout(); // // toolTip1 // this.toolTip1.AutomaticDelay = 0; this.toolTip1.ShowAlways = true; this.toolTip1.UseAnimation = false; this.toolTip1.UseFading = false; // // TreeMap // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.Name = "TreeMap"; this.Size = new System.Drawing.Size(364, 136); this.ResumeLayout(false); } #endregion private System.Windows.Forms.ToolTip toolTip1; } } ================================================ FILE: source/SimpleTreeMap/TreeMap.cs ================================================ using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Linq; using System.Windows.Forms; namespace SimpleTreeMap { public partial class TreeMap : UserControl { public class SliceEventArgs : EventArgs { public ICollection Objects { get; } public SliceRectangle Rectangle { get; } public SliceEventArgs(SliceRectangle rectangle) : this(rectangle, rectangle.Slice.Elements.Select(x => x.Object).ToList()) { } public SliceEventArgs(SliceRectangle rectangle, ICollection o) { Rectangle = rectangle; Objects = o; } } public class SliceClickedEventArgs : SliceEventArgs { public bool AddToSelection { get; } public SliceClickedEventArgs(SliceRectangle rectangle, bool addToSelection) : base(rectangle) { AddToSelection = addToSelection; } public SliceClickedEventArgs(SliceRectangle rectangle, ICollection o, bool addToSelection) : base(rectangle, o) { AddToSelection = addToSelection; } } public event EventHandler SliceClicked; public event EventHandler SliceHovered; public event EventHandler SliceRightClicked; private const double MinSliceRatio = 0.35; private Slice _currentSlice; private List> _rectangles; private HashSet _selectedObjects; private SliceRectangle _currentHoveredRectangle; private static readonly SolidBrush SelectedRectBrush = new(Color.DodgerBlue); readonly Dictionary _brushCache = new(); [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [ReadOnly(true)] public Func ObjectColorGetter { get; set; } [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [ReadOnly(true)] public Func ObjectNameGetter { get; set; } [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [ReadOnly(true)] public Func ObjectValueGetter { get; set; } [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public bool ShowToolTip { get; set; } [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public bool UseLogValueScaling { get; set; } public TreeMap() { InitializeComponent(); SetStyle(ControlStyles.ResizeRedraw, true); SetStyle(ControlStyles.DoubleBuffer, true); } /// /// Calculate area to be drawn for this rectangle. /// Make sure to leave a 1px border around the map and between other rectangles. /// private void CalculatePaintRect(SliceRectangle r) { r.PaintRect = new Rectangle(r.X == 0 ? 1 : r.X, r.Y == 0 ? 1 : r.Y, r.Width - (r.X == 0 ? 2 : 1), r.Height - (r.Y == 0 ? 2 : 1)); r.PaintRect.Offset(ClientRectangle.Location); // Avoid unnecessary drawing if (r.PaintRect.Height < 2 || r.PaintRect.Width < 2) r.PaintRect = Rectangle.Empty; } private SliceRectangle GetRectangleUnderMouse() { if (_rectangles == null) return null; var mousePos = PointToClient(MousePosition); var hoveredItem = _rectangles.FirstOrDefault(x => x.Contains(mousePos)); return hoveredItem; } protected override void OnEnter(EventArgs e) { base.OnEnter(e); if (ShowToolTip) toolTip1.Hide(this); } protected override void OnLeave(EventArgs e) { base.OnLeave(e); if (ShowToolTip) toolTip1.Hide(this); } protected override void OnLostFocus(EventArgs e) { base.OnLostFocus(e); if (ShowToolTip) toolTip1.Hide(this); } protected override void OnMouseClick(MouseEventArgs e) { base.OnMouseClick(e); var r = GetRectangleUnderMouse(); if (r != null) { switch (e.Button) { case MouseButtons.Left: OnSliceClicked(new SliceClickedEventArgs(r, (ModifierKeys & Keys.Control) != 0)); break; case MouseButtons.Right: OnSliceRightClicked(new SliceClickedEventArgs(r, (ModifierKeys & Keys.Control) != 0)); break; } } } protected override void OnMouseHover(EventArgs e) { base.OnMouseHover(e); OnSliceHovered(); } protected override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); OnSliceHovered(); } protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); // todo draw whole thing based on input, input is set by populate //var font = new Font("Arial", 8); var gfx = e.Graphics; gfx.FillRectangle(new SolidBrush(Color.Black), ClientRectangle); if (_rectangles == null) { if (DesignMode) PopulateWithDemoData(); return; } foreach (var r in _rectangles) { if (r.PaintRect.IsEmpty) continue; if (_selectedObjects != null && r.Slice.Elements.Any(x => _selectedObjects.Contains(x.Object))) gfx.FillRectangle(SelectedRectBrush, r.PaintRect); else gfx.FillRectangle(_brushCache[r.Slice.Elements.First().Color], r.PaintRect); //gfx.DrawString(r.Slice.Elements.First().Object.ToString(), font, // new SolidBrush(Control.DefaultForeColor), r.X, r.Y); } } protected override void OnResize(EventArgs e) { base.OnResize(e); if (_currentSlice != null) UpdateRectangles(); } protected virtual void OnSliceClicked(SliceClickedEventArgs e) { SliceClicked?.Invoke(this, e); } protected virtual void OnSliceHovered() { if (Disposing || IsDisposed) return; var hoveredItem = GetRectangleUnderMouse(); if (ShowToolTip) { if (hoveredItem == null) toolTip1.Hide(this); else if (!toolTip1.Active || _currentHoveredRectangle != hoveredItem) toolTip1.Show(hoveredItem.Slice.ToElementNames(), this, new Point(0, Height + 2)); } if (_currentHoveredRectangle != hoveredItem && hoveredItem != null) SliceHovered?.Invoke(this, new SliceEventArgs(hoveredItem)); _currentHoveredRectangle = hoveredItem; } private void OnSliceRightClicked(SliceClickedEventArgs e) { SliceRightClicked?.Invoke(this, e); } public void Populate(IEnumerable objects) { if (Disposing || IsDisposed) return; if (ObjectValueGetter == null) throw new InvalidOperationException(nameof(ObjectValueGetter) + " can't be null"); if (ObjectNameGetter == null) throw new InvalidOperationException(nameof(ObjectNameGetter) + " can't be null"); var elements = objects.Select(x => { var element = new Element { Object = x, Text = ObjectNameGetter(x), Value = ObjectValueGetter(x) }; if (ObjectColorGetter != null) { element.Color = ObjectColorGetter.Invoke(x); if (element.Color.IsEmpty) element.Color = BackColor; } else { element.Color = BackColor; } return element; }).Where(x => x.Value > 0.0001).OrderByDescending(x => x.Value).ToList(); if (UseLogValueScaling) ScaleValuesLog(elements); _currentSlice = SliceMaker.GetSlice(elements, 1, MinSliceRatio); foreach (var c in elements.Select(x => x.Color).Distinct()) _brushCache[c] = new SolidBrush(c); UpdateRectangles(); Refresh(); } private void PopulateWithDemoData() { ObjectNameGetter = o => o.ToString(); ObjectValueGetter = o => (int)o; Populate(new[] { 10, 9, 8, 7, 6, 5, 3, 3, 3, 1 }.Cast()); } private void ScaleValuesLog(ICollection> elements) { var max = elements.Max(x => x.Value); foreach (var element in elements) { element.Value = (Math.Log10(element.Value / max + 0.3174) + 0.5) * 1.6; } } public void SetSelectedObjects(IEnumerable objects) { _selectedObjects = new HashSet(objects); Refresh(); } private void UpdateRectangles() { if (Disposing || IsDisposed) return; _rectangles = SliceMaker.GetRectangles(_currentSlice, ClientSize.Width, ClientSize.Height).ToList(); foreach (var r in _rectangles) CalculatePaintRect(r); } } } ================================================ FILE: source/SimpleTreeMap/TreeMap.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 21, 18 ================================================ FILE: source/SimpleTreeMapTests/Form1.Designer.cs ================================================ namespace SimpleTreeMapTests { partial class Form1 { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.treeMap1 = new SimpleTreeMap.TreeMap(); this.SuspendLayout(); // // treeMap1 // this.treeMap1.Dock = System.Windows.Forms.DockStyle.Fill; this.treeMap1.Location = new System.Drawing.Point(33, 33); this.treeMap1.Name = "treeMap1"; this.treeMap1.Size = new System.Drawing.Size(403, 239); this.treeMap1.TabIndex = 1; // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(469, 305); this.Controls.Add(this.treeMap1); this.Name = "Form1"; this.Padding = new System.Windows.Forms.Padding(33); this.Text = "Form1"; this.ResumeLayout(false); } #endregion private SimpleTreeMap.TreeMap treeMap1; } } ================================================ FILE: source/SimpleTreeMapTests/Form1.cs ================================================ using System.Linq; using System.Windows.Forms; namespace SimpleTreeMapTests { public partial class Form1 : Form { public Form1() { InitializeComponent(); treeMap1.ObjectNameGetter = o => o.ToString(); treeMap1.ObjectValueGetter = o => (int)o; treeMap1.Populate(new [] {10,9,8,7,6,5,3,3,3,1}.Cast()); } } } ================================================ FILE: source/SimpleTreeMapTests/Form1.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ================================================ FILE: source/SimpleTreeMapTests/Program.cs ================================================ using System; using System.Windows.Forms; namespace SimpleTreeMapTests { static class Program { /// /// The main entry point for the application. /// [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); } } } ================================================ FILE: source/SimpleTreeMapTests/Properties/AssemblyInfo.cs ================================================ using System.Reflection; 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("SimpleTreeMapTests")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("SimpleTreeMapTests")] [assembly: AssemblyCopyright("Copyright © 2017")] [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("3f3d249f-885b-4af5-b760-3900d077d66b")] // 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.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")] ================================================ FILE: source/SimpleTreeMapTests/Properties/Resources.Designer.cs ================================================ //------------------------------------------------------------------------------ // // This code was generated by a tool. // Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ namespace SimpleTreeMapTests.Properties { /// /// A strongly-typed resource class, for looking up localized strings, etc. /// // This class was auto-generated by the StronglyTypedResourceBuilder // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { private static global::System.Resources.ResourceManager resourceMan; private static global::System.Globalization.CultureInfo resourceCulture; [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] internal Resources() { } /// /// Returns the cached ResourceManager instance used by this class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Resources.ResourceManager ResourceManager { get { if ((resourceMan == null)) { global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SimpleTreeMapTests.Properties.Resources", typeof(Resources).Assembly); resourceMan = temp; } return resourceMan; } } /// /// Overrides the current thread's CurrentUICulture property for all /// resource lookups using this strongly typed resource class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Globalization.CultureInfo Culture { get { return resourceCulture; } set { resourceCulture = value; } } } } ================================================ FILE: source/SimpleTreeMapTests/Properties/Settings.Designer.cs ================================================ //------------------------------------------------------------------------------ // // This code was generated by a tool. // Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ namespace SimpleTreeMapTests.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); public static Settings Default { get { return defaultInstance; } } } } ================================================ FILE: source/SimpleTreeMapTests/Properties/Settings.settings ================================================  ================================================ FILE: source/SimpleTreeMapTests/SimpleTreeMapTestApp.csproj ================================================  WinExe false bin ================================================ FILE: source/SteamHelper/Misc.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; namespace SteamHelper { public static class Misc { /// /// Attempts to separate filename (or filename with path) from the supplied arguments. /// KeyValuePair(filename, arguments) /// public static KeyValuePair SeparateArgsFromCommand(string fullCommand) { if (fullCommand == null) throw new ArgumentNullException(nameof(fullCommand)); // Get rid of whitespaces fullCommand = fullCommand.Trim(); if (string.IsNullOrEmpty(fullCommand)) throw new ArgumentException(); var firstDot = fullCommand.IndexOf('.'); if (firstDot < 0) throw new FormatException(); // Check if the path is contained inside of quotation marks. // Assume that the quotation mark must come before the dot. Otherwise, it is likely that the arguments use quotations. var pathEnd = fullCommand.IndexOf('"', 0, firstDot); if (pathEnd >= 0) { // If yes, find the closing quotation mark and set its index as path end pathEnd = fullCommand.IndexOf('"', pathEnd + 1); if (pathEnd < 0) { // If no ending quote has been found, explode gracefully. throw new FormatException(); } pathEnd += 1; //? } // If quotation marks were missing, check for any invalid characters after last dot // in case of eg: c:\test.dir thing\filename.exe?0 used to get icons if (pathEnd < 0) { var endIndex = 0; while (true) { var dot = fullCommand.IndexOf('.', endIndex); if (dot < 0) break; var space = fullCommand.IndexOfAny(" ,:;?-=", dot); var dash = fullCommand.IndexOfAny("\\/", dot); if (space < 0) break; if (space < dash || dash < 0) { pathEnd = space; break; } endIndex = dash; } } // Begin extracting filename and arguments string filename; var args = string.Empty; if (pathEnd < 0 || pathEnd >= fullCommand.Length) { // Looks like there were no arguments, assume whole command is a filename filename = fullCommand; } else { // pathEnd shows the end of the filename (and start of the arguments) filename = fullCommand.Substring(0, pathEnd).TrimEnd(); args = fullCommand.Substring(pathEnd).TrimStart(); } filename = filename.Trim('"'); // Get rid of the quotation marks return new KeyValuePair(filename, args); } public static int IndexOfAny(this string str, IEnumerable chars, int startIndex) { foreach (var c in chars) { var i = str.IndexOf(c, startIndex); if (i >= 0) return i; } return -1; } } } ================================================ FILE: source/SteamHelper/Program.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Text; using Klocman; using Microsoft.Win32.Interop; namespace SteamHelper { internal static class Program { private static QueryType _queryType = QueryType.None; private static bool _silentSwitch, _infoSwitch; private static int _appId; /// /// Return codes: /// 0 - The operation completed successfully. /// 59 - An unexpected network error occurred. /// 1223 - The operation was canceled by the user. /// /// Commands /// u[ninstall] [/s[ilent]] AppID - Uninstall a Steam App /// i[nfo] AppID - Show information about a Steam App /// l[ist] - List all detected Steam App ID's /// l[ist] /i[nfo] - List information about all detected Steam Apps /// steam - Show Steam install location /// private static int Main(string[] args) { try { try { Console.OutputEncoding = Encoding.Unicode; } catch (IOException) { /*Old .NET v4 without support for unicode output*/ } ProcessCommandlineArguments(args); switch (_queryType) { case QueryType.GetInfo: var appInfo = SteamApplicationInfo.FromAppId(_appId); foreach (var property in typeof(SteamApplicationInfo).GetProperties(BindingFlags.Public | BindingFlags.Instance)) Console.WriteLine("{0} - {1}", property.Name, property.GetValue(appInfo, null) ?? "N/A"); break; case QueryType.Uninstall: SteamUninstaller.UninstallSteamApp(SteamApplicationInfo.FromAppId(_appId), _silentSwitch); break; case QueryType.List: if (!_infoSwitch) { foreach (var result in SteamInstallation.Instance.SteamAppsLocations .SelectMany(x => Directory.GetFiles(x, @"appmanifest_*.acf") .Select(p => Path.GetFileNameWithoutExtension(p).Substring(12))) .Select(x => int.TryParse(x, out var num) ? num : (int?)null) .Where(x => x != null) .Distinct() .OrderBy(x => x)) Console.WriteLine(result); } else { var query = from appsLocStr in SteamInstallation.Instance.SteamAppsLocations let appsLocation = new DirectoryInfo(appsLocStr) from manifest in appsLocation.GetFiles(@"appmanifest_*.acf") let info = SteamApplicationInfo.FromAppManifest(manifest, appsLocation) where info != null orderby info.AppId select info; foreach (var applicationInfo in query) Console.WriteLine(HelperTools.ObjectToConsoleOutput(applicationInfo)); } break; case QueryType.SteamDir: Console.WriteLine(SteamInstallation.Instance.InstallationDirectory); break; default: throw new ArgumentOutOfRangeException(nameof(_queryType), _queryType, null); } } catch (OperationCanceledException) { return (int)ResultWin32.ERROR_CANCELLED; } catch (FormatException ex) { LogWriter.WriteExceptionToLog(ex); return (int)ResultWin32.ERROR_BAD_ARGUMENTS; } catch (Exception ex) { LogWriter.WriteExceptionToLog(ex); return (int)ResultWin32.ERROR_UNEXP_NET_ERR; } return (int)ResultWin32.ERROR_SUCCESS; } private static void ProcessCommandlineArguments(IEnumerable args) { foreach (var arg in args) { switch (arg.ToLowerInvariant()) { case @"u": case @"uninstall": if (_queryType != QueryType.None) throw new FormatException(@"Multiple commands specified"); _queryType = QueryType.Uninstall; break; case @"i": case @"info": if (_queryType != QueryType.None) throw new FormatException(@"Multiple commands specified"); _queryType = QueryType.GetInfo; break; case @"/i": case @"/info": if (_queryType != QueryType.List) throw new FormatException(@"/info must follow the list command"); _infoSwitch = true; break; case @"/s": case @"/silent": if (_queryType != QueryType.Uninstall) throw new FormatException(@"/silent must follow the uninstall command"); _silentSwitch = true; break; case @"l": case @"list": if (_queryType != QueryType.None) throw new FormatException(@"Multiple commands specified"); _queryType = QueryType.List; break; case @"steam": if (_queryType != QueryType.None) throw new FormatException(@"Multiple commands specified"); _queryType = QueryType.SteamDir; break; default: if (_appId != default(int)) throw new FormatException(@"Multiple AppIDs specified"); if (!int.TryParse(arg, out _appId)) throw new FormatException($@"Unknown argument: {arg}"); break; } } if (_queryType == QueryType.None) throw new FormatException(@"No commands specified"); if (_queryType != QueryType.List && _queryType != QueryType.SteamDir && _appId == default(int)) throw new FormatException(@"No AppID specified"); } private enum QueryType { None, Uninstall, GetInfo, List, SteamDir } } } ================================================ FILE: source/SteamHelper/Properties/launchSettings.json ================================================ { "profiles": { "SteamHelper": { "commandName": "Project", "commandLineArgs": "list /info" } } } ================================================ FILE: source/SteamHelper/SteamApplicationInfo.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Text.RegularExpressions; namespace SteamHelper { internal class SteamApplicationInfo { private SteamApplicationInfo(int appId) { AppId = appId; } public static SteamApplicationInfo FromAppManifest(FileInfo manifestFile, DirectoryInfo containingAppsDir) { var m = Regex.Match(manifestFile.Name, @"appmanifest_(\d+)\.acf"); if (m.Success) { var idStr = m.Groups[1].Value; if (!string.IsNullOrEmpty(idStr)) { return FromParams(int.Parse(idStr, CultureInfo.InvariantCulture), manifestFile, containingAppsDir); } } return null; } public static SteamApplicationInfo FromAppId(int appId) { DirectoryInfo dir = null; FileInfo manifestFile = null; var appIdStr = appId.ToString("G"); foreach (var steamAppsLocation in SteamInstallation.Instance.SteamAppsLocations) { var result = Directory.GetFiles(steamAppsLocation, @"appmanifest_*.acf") .FirstOrDefault(x => appIdStr.Equals(Path.GetFileNameWithoutExtension(x).Substring(12), StringComparison.InvariantCulture)); if (!string.IsNullOrEmpty(result)) { manifestFile = new FileInfo(result); dir = new DirectoryInfo(steamAppsLocation); break; } } if (dir == null) throw new ArgumentException("Could not find Steam App with the ID " + appIdStr); return FromParams(appId, manifestFile, dir); } private static SteamApplicationInfo FromParams(int appId, FileInfo manifestFile, DirectoryInfo containingAppsDir) { var appIdStr = appId.ToString("G"); var output = new SteamApplicationInfo(appId); output.ManifestPath = manifestFile.FullName; //"C:\Steam\steam.exe" steam://uninstall/123 output.UninstallString = $"\"{SteamInstallation.Instance.MainExecutableFilename}\" steam://uninstall/{appIdStr}"; var manifestStrings = File.ReadAllLines(output.ManifestPath); output.Name = GetManifestValue(manifestStrings, "name"); output.SizeOnDisk = GetManifestValue(manifestStrings, "SizeOnDisk"); var installDirName = GetManifestValue(manifestStrings, "installdir"); if (!string.IsNullOrEmpty(installDirName)) { var path = Path.Combine(Path.Combine(containingAppsDir.FullName, @"common"), installDirName); if (Directory.Exists(path)) output.InstallDirectory = path; if (output.Name == null) output.Name = installDirName; } output.DownloadDirectory = containingAppsDir.GetDirectories(@"downloading").SingleOrDefault()?.GetDirectories(appIdStr).SingleOrDefault()?.FullName; var workshopDir = containingAppsDir.GetDirectories(@"workshop").SingleOrDefault(); if (workshopDir != null) { output.WorkshopManifestPath = workshopDir.GetFiles($@"appworkshop_{appIdStr}.acf").SingleOrDefault()?.FullName; output.WorkshopDirectory = workshopDir.GetDirectories(@"content").SingleOrDefault()?.GetDirectories(appIdStr).SingleOrDefault()?.FullName; } return output; } public static string GetManifestValue(string[] manifestStrings, string keyName) { var targetLine = manifestStrings .FirstOrDefault(x => x.Contains($"\"{keyName.Trim().Trim('\"')}\"", StringComparison.InvariantCultureIgnoreCase)); return string.IsNullOrEmpty(targetLine) ? null : targetLine.Split('\"').Select(x => x.Trim()).LastOrDefault(x => x.Length > 0); } public int AppId { get; } public string Name { get; private set; } public string SizeOnDisk { get; private set; } public string UninstallString { get; private set; } public string ManifestPath { get; private set; } public string InstallDirectory { get; private set; } public string DownloadDirectory { get; private set; } public string WorkshopManifestPath { get; private set; } public string WorkshopDirectory { get; private set; } public void WriteTo(TextWriter wr) { foreach (var property in typeof(SteamApplicationInfo).GetProperties(BindingFlags.Public | BindingFlags.Instance)) wr.WriteLine("{0} - {1}", property.Name, property.GetValue(this, null) ?? "N/A"); } } } ================================================ FILE: source/SteamHelper/SteamHelper.csproj ================================================  Exe Utility for discovering and uninstalling games and apps installed through Steam steam.ico SteamHelper.Program ================================================ FILE: source/SteamHelper/SteamInstallation.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.IO; using System.Linq; using Klocman.Extensions; using Microsoft.Win32; namespace SteamHelper { internal class SteamInstallation { private static SteamInstallation _instance; private IReadOnlyList _steamAppsLocations; private SteamInstallation() { InstallationDirectory = FindSteamInstallationLocation(); MainExecutableFilename = Path.Combine(InstallationDirectory, "Steam.exe"); } public static SteamInstallation Instance => _instance ??= new SteamInstallation(); public string InstallationDirectory { get; } public IReadOnlyList SteamAppsLocations => _steamAppsLocations ??= FindSteamAppsLocations(InstallationDirectory).ToList().AsReadOnly(); public string MainExecutableFilename { get; } private static IEnumerable FindSteamAppsLocations(string installationDirectory) { var libraryLocations = new List { Path.Combine(installationDirectory, @"SteamApps") }; // The libraryfolders seems to appear in multiple locations. To be safe gather info from all of them foreach (var vdfPath in new[] { @"config\libraryfolders.vdf", @"SteamApps\libraryfolders.vdf" }.Select(x => Path.Combine(installationDirectory, x))) { if (!File.Exists(vdfPath)) continue; foreach (var line in File.ReadAllLines(vdfPath)) { // Gather key/value pairs from the file. It seems to be in a proprietary format var pieces = line.Split('\"').Where(p => !string.IsNullOrWhiteSpace(p.Trim())).ToList(); if (pieces.Count != 2) continue; // Only path matters, it specifies absolute path to the library folder if (pieces[0] == "path") { var path = Path.Combine(pieces[1].Replace(@"\\", @"\"), "steamapps"); libraryLocations.Add(path); } } } return libraryLocations.Distinct(StringComparer.CurrentCultureIgnoreCase).Where(Directory.Exists); } private static string FindSteamInstallationLocation() { foreach (var keyPath in new[] { @"SOFTWARE\Valve\Steam", @"SOFTWARE\WOW6432Node\Valve\Steam" }) { using (var key = Registry.LocalMachine.OpenSubKey(keyPath)) { if (key == null) continue; var path = key.GetStringSafe(@"InstallPath"); if (path != null && Directory.Exists(path)) return path; } } try { using (var key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Classes\steam\Shell\Open\Command")) { var command = key?.GetStringSafe(null); var path = Path.GetDirectoryName(Misc.SeparateArgsFromCommand(command).Key); if (path != null && Directory.Exists(path)) return path; } throw new IOException(); } catch (Exception ex) { throw new IOException( "Failed to detect your Steam installation. Launch Steam, exit it gracefully, and try again.", ex); } } } } ================================================ FILE: source/SteamHelper/SteamUninstaller.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Diagnostics; using System.IO; using System.Linq; using System.Threading; namespace SteamHelper { internal static class SteamUninstaller { public static void UninstallSteamApp(SteamApplicationInfo appInfo, bool silent) { Console.WriteLine("Uninstalling SteamApp with ID {0}{1}", appInfo.AppId, silent ? " silently" : string.Empty); if (silent) QuietUninstall(appInfo); else LoudUninstall(appInfo); } private static void LoudUninstall(SteamApplicationInfo appInfo) { Console.WriteLine("Running " + appInfo.UninstallString); var uninstallCommand = Misc.SeparateArgsFromCommand(appInfo.UninstallString); Process.Start(new ProcessStartInfo(uninstallCommand.Key, uninstallCommand.Value) { UseShellExecute = true }); Console.WriteLine(); Console.WriteLine("To stop waiting for Steam and cancel the operation press any key."); while (File.Exists(appInfo.ManifestPath)) { Thread.Sleep(400); if (Console.KeyAvailable) throw new OperationCanceledException(); } } private static void QuietUninstall(SteamApplicationInfo appInfo) { //var steamPath = Misc.SeparateArgsFromCommand(appInfo.UninstallString).Key; //var processes = Process.GetProcesses().Where(x => x.MainModule.FileName.Equals(steamPath)).ToList(); var processes = Process.GetProcessesByName("Steam"); if (processes.Any()) { Console.WriteLine("Killing Steam processes"); foreach (var process in processes) { process.Kill(); process.Dispose(); } } if (Directory.Exists(appInfo.DownloadDirectory)) { Console.WriteLine("Deleting " + appInfo.DownloadDirectory); Directory.Delete(appInfo.DownloadDirectory, true); } if (Directory.Exists(appInfo.WorkshopDirectory)) { Console.WriteLine("Deleting " + appInfo.WorkshopDirectory); Directory.Delete(appInfo.WorkshopDirectory, true); } if (File.Exists(appInfo.WorkshopManifestPath)) { Console.WriteLine("Deleting " + appInfo.WorkshopManifestPath); File.Delete(appInfo.WorkshopManifestPath); } if (Directory.Exists(appInfo.InstallDirectory)) { Console.WriteLine("Deleting " + appInfo.InstallDirectory); Directory.Delete(appInfo.InstallDirectory, true); } if (File.Exists(appInfo.ManifestPath)) { Console.WriteLine("Deleting " + appInfo.ManifestPath); File.Delete(appInfo.ManifestPath); } } } } ================================================ FILE: source/StoreAppHelper/App.cs ================================================ namespace StoreAppHelper { public sealed class App { public App(string fullName, string displayName, string publisherDisplayName, string logo, string installedLocation, bool isProtected) { FullName = fullName; DisplayName = displayName; PublisherDisplayName = publisherDisplayName; Logo = logo; InstalledLocation = installedLocation; IsProtected = isProtected; } public string FullName { get; } public string DisplayName { get; } public string PublisherDisplayName { get; } public string Logo { get; } public string InstalledLocation { get; } public bool IsProtected { get; } } } ================================================ FILE: source/StoreAppHelper/AppManager.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Security.Principal; using System.Text; using System.Threading; using Windows.ApplicationModel; using Windows.Foundation; using Windows.Management.Deployment; using Klocman; using System.Xml; namespace StoreAppHelper { public static class AppManager { public static void UninstallApp(string fullName) { var packageManager = new PackageManager(); var deploymentOperation = packageManager.RemovePackageAsync(fullName); var opCompletedEvent = new ManualResetEvent(false); deploymentOperation.Completed += (info, status) => opCompletedEvent.Set(); Console.WriteLine($"Uninstalling \"{fullName}\""); opCompletedEvent.WaitOne(); // Check the status of the operation switch (deploymentOperation.Status) { case AsyncStatus.Error: var deploymentResult = deploymentOperation.GetResults(); Console.WriteLine(@"Error code: {0}", deploymentOperation.ErrorCode); Console.WriteLine(@"Error text: {0}", deploymentResult.ErrorText); throw new IOException(deploymentResult.ErrorText); case AsyncStatus.Canceled: Console.WriteLine(@"Uninstallation was cancelled"); throw new OperationCanceledException(); case AsyncStatus.Completed: Console.WriteLine(@"Uninstallation completed successfully"); return; default: Console.WriteLine(@"Invalid status: {0}", deploymentOperation.Status); throw new IOException(); } } public static IEnumerable QueryApps() { var packageManager = new PackageManager(); var userSecurityId = WindowsIdentity.GetCurrent().User?.Value; var packages = packageManager.FindPackagesForUserWithPackageTypes(userSecurityId, PackageTypes.Main); foreach (var package in packages) { if ( /*package.IsFramework || package.IsResourcePackage ||*/ package.Status.Disabled || package.Status.NotAvailable) continue; var result = TryCreateAppFromPackage(package); if (result != null) yield return result; } } private static App TryCreateAppFromPackage(Package package) { var manifestContents = TryGetAppManifest(package); if (manifestContents == null) return null; try { var installPath = package.InstalledLocation.Path; var externalPath = package.EffectiveLocation.Path.Equals(installPath, StringComparison.OrdinalIgnoreCase) ? null : package.EffectiveLocation.Path; var xmlDoc = new XmlDocument(); xmlDoc.LoadXml(manifestContents); // namespaces are mandatory, even if there's a default namespace var nsmgr = new XmlNamespaceManager(xmlDoc.NameTable); nsmgr.AddNamespace("ns", xmlDoc.DocumentElement!.NamespaceURI); var properties = xmlDoc.DocumentElement.SelectSingleNode("//ns:Properties", nsmgr); var displayNameRes = properties!.SelectSingleNode("ns:DisplayName/text()", nsmgr)?.Value; var displayNameExtracted = ExtractDisplayName(installPath, package.Id.Name, displayNameRes) ?? (externalPath != null ? ExtractDisplayName(externalPath, package.Id.Name, displayNameRes) : null); var logoPathRes = properties.SelectSingleNode("ns:Logo/text()", nsmgr)?.Value; var logoPathExtracted = ExtractDisplayIcon(installPath, logoPathRes) ?? (externalPath != null ? ExtractDisplayIcon(externalPath, logoPathRes) : null); var publisherDisplayNameRes = properties.SelectSingleNode("ns:PublisherDisplayName/text()", nsmgr)?.Value; var publisherDisplayNameExtracted = ExtractDisplayName(installPath, package.Id.Name, publisherDisplayNameRes) ?? (externalPath != null ? ExtractDisplayName(externalPath, package.Id.Name, publisherDisplayNameRes) : null); return new App( fullName: package.Id.FullName, displayName: FirstValidName(displayNameExtracted, displayNameRes, package.DisplayName) ?? package.InstalledLocation.DisplayName, publisherDisplayName: FirstValidName(publisherDisplayNameExtracted, package.PublisherDisplayName) ?? "", logo: logoPathExtracted, installedLocation: installPath, isProtected: package.SignatureKind == PackageSignatureKind.System); } catch (SystemException exception) { LogWriter.WriteExceptionToLog(exception); return null; } } private static string FirstValidName(params string[] names) { return names.FirstOrDefault(s => !string.IsNullOrEmpty(s) && !s.StartsWith("ms-resource:")); } private static string TryGetAppManifest(Package package) { try { var file = Path.Combine(package.InstalledLocation.Path, "AppxManifest.xml"); if (!File.Exists(file)) return null; var manifestContents = File.ReadAllText(file); return string.IsNullOrWhiteSpace(manifestContents) ? null : manifestContents; } catch (SystemException exception) { LogWriter.WriteExceptionToLog(exception); return null; } } private static string ExtractDisplayIcon(string appDir, string iconDir) { var logo = Path.Combine(appDir, iconDir); if (File.Exists(logo)) return logo; logo = Path.Combine(appDir, Path.ChangeExtension(logo, "scale-100.png")); if (File.Exists(logo)) return logo; var localized = Path.Combine(Path.Combine(appDir, "en-us"), iconDir); localized = Path.Combine(appDir, Path.ChangeExtension(localized, "scale-100.png")); return File.Exists(localized) ? localized : null; } /// /// Grabs display name from resources if necessary. /// /// package.InstalledLocation.Path /// Package.Id.Name /// Application.VisualElements.DisplayName private static string ExtractDisplayName(string appDir, string packageName, string displayName) { if (!Uri.TryCreate(displayName, UriKind.Absolute, out var uri)) return displayName; var priPath = Path.Combine(appDir, "resources.pri"); var resource = $"ms-resource://{packageName}/resources/{uri.Segments.Last()}"; var name = NativeMethods.ExtractStringFromPriFile(priPath, resource)?.Trim(); if (!string.IsNullOrEmpty(name)) return name; var res = string.Concat(uri.Segments.Skip(1)); resource = $"ms-resource://{packageName}/{res}"; name = NativeMethods.ExtractStringFromPriFile(priPath, resource)?.Trim(); if (!string.IsNullOrEmpty(name)) return name; name = NativeMethods.ExtractStringFromPriFile(priPath, displayName)?.Trim(); if (!string.IsNullOrEmpty(name)) return name; return null; } private static class NativeMethods { [DllImport("shlwapi.dll", BestFitMapping = false, CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = false, ThrowOnUnmappableChar = true)] private static extern int SHLoadIndirectString(string pszSource, StringBuilder pszOutBuf, int cchOutBuf, IntPtr ppvReserved); internal static string ExtractStringFromPriFile(string pathToPri, string resourceKey) { var sWin8ManifestString = $"@{{{pathToPri}? {resourceKey}}}"; var outBuff = new StringBuilder(1024); SHLoadIndirectString(sWin8ManifestString, outBuff, outBuff.Capacity, IntPtr.Zero); return outBuff.ToString(); } } } } ================================================ FILE: source/StoreAppHelper/Program.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.IO; using Klocman; using Microsoft.Win32.Interop; namespace StoreAppHelper { internal static class Program { [STAThread] private static int Main(string[] args) { if (args.Length == 0) return (int)ResultWin32.ERROR_BAD_ARGUMENTS; HelperTools.SetupEncoding(); if (args.Length == 1 && string.Equals(args[0], @"/query", StringComparison.OrdinalIgnoreCase)) { try { var result = AppManager.QueryApps(); foreach (var app in result) Console.WriteLine(HelperTools.ObjectToConsoleOutput(app)); return (int)ResultWin32.ERROR_SUCCESS; } catch (IOException ex) { LogWriter.WriteExceptionToLog(ex); return (int)HelperTools.ExtractHrefCode(ex); } catch (Exception ex) { LogWriter.WriteExceptionToLog(ex); return (int)ResultWin32.ERROR_FUNCTION_FAILED; } } if (args.Length == 2 && string.Equals(args[0], @"/uninstall", StringComparison.OrdinalIgnoreCase)) { try { AppManager.UninstallApp(args[1]); return (int)ResultWin32.ERROR_SUCCESS; } catch (IOException ex) { return (int)HelperTools.ExtractHrefCode(ex); } catch (Exception ex) { LogWriter.WriteExceptionToLog(ex); return (int)ResultWin32.ERROR_FUNCTION_FAILED; } } return (int)ResultWin32.ERROR_BAD_ARGUMENTS; } } } ================================================ FILE: source/StoreAppHelper/StoreAppHelper.csproj ================================================  Exe Utility for discovering and uninstalling Windows Store apps (including pre-installed apps) icon.ico StoreAppHelper.Program ================================================ FILE: source/UninstallTools/ApplicationEntrySerializer.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System.Collections.Generic; using System.Linq; using Klocman.Tools; namespace UninstallTools { public sealed class ApplicationEntrySerializer { public static void SerializeApplicationEntries(string filename, IEnumerable items) { SerializationTools.SerializeToXml(filename, new ApplicationEntrySerializer(items)); } public ApplicationEntrySerializer(IEnumerable items) { Items = items.ToList(); } // Needed for serialization public ApplicationEntrySerializer() { } public List Items { get; set; } } } ================================================ FILE: source/UninstallTools/ApplicationUninstallerEntry.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Drawing; using System.IO; using System.Linq; using System.Security.Cryptography.X509Certificates; using System.Text; using System.Xml.Serialization; using Klocman.Extensions; using Klocman.IO; using Klocman.Localising; using Klocman.Tools; using Microsoft.Win32; using UninstallTools.Factory; using UninstallTools.Factory.InfoAdders; using UninstallTools.Lists; using UninstallTools.Properties; using UninstallTools.Startup; namespace UninstallTools { public class ApplicationUninstallerEntry { /// /// List of properties that migh have changed by updating the key property /// IMPORTANT: Keep up to date! /// internal static readonly ILookup PropertyRelationships = new Dictionary> { { nameof(UninstallString), new List { nameof(UninstallerLocation), nameof(UninstallerFullFilename) } }, { nameof(UninstallerFullFilename), new List {nameof(UninstallerLocation)} }, { nameof(RawDisplayName), new List {nameof(DisplayName)} }, { nameof(RegistryKeyName), new List {nameof(RatingId)} }, }.SelectMany(x => x.Value.Select(y => new { x.Key, Value = y })).ToLookup(x => x.Key, x => x.Value); internal static readonly IEnumerable CompanyNameEndTrimmers = new[] { "corp", "corporation", "limited", "inc", "incorporated" }; private X509Certificate2 _certificate; private bool _certificateGotten; private bool? _certificateValid; private string _ratingId; private string _installLocation; private string _installSource; private string _modifyPath; private string _displayIcon; private string _uninstallString; private string _uninstallerFullFilename; /// /// Junk specified during creation of the entry that would not be detected afterwards. It's added to the results during junk scan. /// [XmlIgnore] internal readonly List AdditionalJunk = new(); [ComparisonTarget] [LocalisedName(typeof(Localisation), nameof(Localisation.DisplayName))] public string DisplayName { get { return (string.IsNullOrEmpty(RawDisplayName) ? RegistryKeyName : RawDisplayName) ?? string.Empty; } set { RawDisplayName = value; } } [XmlIgnore] [LocalisedName(typeof(Localisation), nameof(Localisation.DisplayNameTrimmed))] public string DisplayNameTrimmed => StringTools.StripStringFromVersionNumber(DisplayName); [XmlIgnore] [LocalisedName(typeof(Localisation), nameof(Localisation.PublisherTrimmed))] public string PublisherTrimmed => string.IsNullOrEmpty(Publisher) ? string.Empty : Publisher.Replace("(R)", string.Empty) .ExtendedTrimEndAny(CompanyNameEndTrimmers, StringComparison.CurrentCultureIgnoreCase); [XmlIgnore] [LocalisedName(typeof(Localisation), nameof(Localisation.QuietUninstallPossible))] public bool QuietUninstallPossible => !string.IsNullOrEmpty(QuietUninstallString) || (UninstallerKind == UninstallerType.Msiexec && BundleProviderKey != Guid.Empty); [XmlIgnore] [LocalisedName(typeof(Localisation), nameof(Localisation.UninstallPossible))] public bool UninstallPossible => !string.IsNullOrEmpty(UninstallString); [ComparisonTarget] [LocalisedName(typeof(Localisation), nameof(Localisation.AboutUrl))] public string AboutUrl { get; set; } /// /// Product code used by msiexec. If it wasn't found, returns Guid.Empty. /// [ComparisonTarget] [LocalisedName(typeof(Localisation), nameof(Localisation.BundleProviderKey))] public Guid BundleProviderKey { get; set; } [LocalisedName(typeof(Localisation), nameof(Localisation.Comment))] public string Comment { get; set; } [LocalisedName(typeof(Localisation), nameof(Localisation.DisplayIcon))] public string DisplayIcon { get { return _displayIcon; } set { _displayIcon = CleanupPath(value, true); } } [ComparisonTarget] [LocalisedName(typeof(Localisation), nameof(Localisation.DisplayVersion))] public string DisplayVersion { get; set; } [LocalisedName(typeof(Localisation), nameof(Localisation.EstimatedSize))] public FileSize EstimatedSize { get; set; } [LocalisedName(typeof(Localisation), nameof(Localisation.InstallDate))] public DateTime InstallDate { get; set; } [ComparisonTarget] [LocalisedName(typeof(Localisation), nameof(Localisation.InstallLocation))] public string InstallLocation { get { return _installLocation; } set { _installLocation = CleanupPath(value); } } [ComparisonTarget] [LocalisedName(typeof(Localisation), nameof(Localisation.InstallSource))] public string InstallSource { get { return _installSource; } set { _installSource = CleanupPath(value); } } [ComparisonTarget] [LocalisedName(typeof(Localisation), nameof(Localisation.Is64Bit))] public MachineType Is64Bit { get; set; } /// /// Protection from uninstalling. /// [ComparisonTarget] [LocalisedName(typeof(Localisation), nameof(Localisation.IsProtected))] public bool IsProtected { get; set; } /// /// The application's uniunstaller is mentioned in the registry (if it's not normal uninstallers will not see it) /// [LocalisedName(typeof(Localisation), nameof(Localisation.IsRegistered))] public bool IsRegistered { get; set; } /// /// The application is present on the drive, but not in any of the application listings /// [ComparisonTarget] [LocalisedName(typeof(Localisation), nameof(Localisation.IsOrphaned))] public bool IsOrphaned { get; set; } /// /// True if this is an update for another product /// [ComparisonTarget] [LocalisedName(typeof(Localisation), nameof(Localisation.IsUpdate))] public bool IsUpdate { get; set; } /// /// True if the application can be uninstalled. False if the uninstaller is missing or is otherwise invalid. /// [ComparisonTarget] [LocalisedName(typeof(Localisation), nameof(Localisation.IsValid))] public bool IsValid { get; set; } /// /// True if the application is listed as a web browser. /// [ComparisonTarget] [LocalisedName(typeof(Localisation), nameof(Localisation.IsWebBrowser))] public bool IsWebBrowser { get; set; } [ComparisonTarget] [LocalisedName(typeof(Localisation), nameof(Localisation.ModifyPath))] public string ModifyPath { get { return _modifyPath; } set { _modifyPath = CleanupPath(value); } } [LocalisedName(typeof(Localisation), nameof(Localisation.ParentKeyName))] public string ParentKeyName { get; set; } [ComparisonTarget] [LocalisedName(typeof(Localisation), nameof(Localisation.Publisher))] public string Publisher { get; set; } [ComparisonTarget] [LocalisedName(typeof(Localisation), nameof(Localisation.QuietUninstallString))] public string QuietUninstallString { get; set; } /// /// Get a unique cache ID of this item. /// Returns null if there isn't enough information to get a reasonably unique key. /// public string GetCacheId() { if (!string.IsNullOrEmpty(CacheIdOverride)) return CacheIdOverride; var rid = RatingId; if (!string.IsNullOrEmpty(rid)) return rid; if (!string.IsNullOrEmpty(DisplayName) && !string.IsNullOrEmpty(InstallLocation)) return DisplayName + InstallLocation;// + DisplayVersion + InstallDate + EstimatedSize; return null; } public string CacheIdOverride; public string RatingId { get { if (!string.IsNullOrEmpty(_ratingId)) return _ratingId; if (!string.IsNullOrEmpty(RegistryKeyName)) return RegistryKeyName; //if (BundleProviderKey != Guid.Empty) // return BundleProviderKey.ToString(); return null; } set { _ratingId = value; } } [ComparisonTarget] [LocalisedName(typeof(Localisation), nameof(Localisation.RegistryKeyName))] public string RegistryKeyName { get; set; } /// /// Full registry path of this entry /// [LocalisedName(typeof(Localisation), nameof(Localisation.RegistryPath))] public string RegistryPath { get; set; } [XmlIgnore] [LocalisedName(typeof(Localisation), nameof(Localisation.StartupEntries))] public IEnumerable StartupEntries { get; set; } [ComparisonTarget] [LocalisedName(typeof(Localisation), nameof(Localisation.HasStartupEntries))] public bool HasStartups => StartupEntries != null && StartupEntries.Any(); [ComparisonTarget] [LocalisedName(typeof(Localisation), nameof(Localisation.SystemComponent))] public bool SystemComponent { get; set; } [ComparisonTarget] [LocalisedName(typeof(Localisation), nameof(Localisation.UninstallerFullFilename))] public string UninstallerFullFilename { get { return _uninstallerFullFilename; } set { _uninstallerFullFilename = value; UninstallerLocation = ApplicationEntryTools.ExtractDirectoryName(UninstallerFullFilename) ?? UninstallerLocation ?? string.Empty; } } [ComparisonTarget] [LocalisedName(typeof(Localisation), nameof(Localisation.UninstallerKind))] public UninstallerType UninstallerKind { get; set; } //[LocalisedName(typeof(Localisation), nameof(Localisation.IsInstalled))] //public bool IsInstalled { get; internal set; } [LocalisedName(typeof(Localisation), nameof(Localisation.UninstallerLocation))] public string UninstallerLocation { get; set; } [ComparisonTarget] [LocalisedName(typeof(Localisation), nameof(Localisation.UninstallString))] public string UninstallString { get { return _uninstallString; } set { _uninstallString = value; UninstallerFullFilename = ApplicationEntryTools.ExtractFullFilename(value) ?? UninstallerFullFilename ?? string.Empty; } } internal string RawDisplayName { get; set; } internal Icon IconBitmap { get; set; } /// /// Check if the install location is not empty and is not a system directory /// public bool IsInstallLocationValid() { if (string.IsNullOrEmpty(InstallLocation?.Trim())) return false; return !UninstallToolsGlobalConfig.GetAllProgramFiles().Any(x => PathTools.PathsEqual(x, InstallLocation)); } /*/// /// Get the certificate associated to the uninstaller or application. /// /// If true only return the stored value, otherwise generate it if needed. public X509Certificate2 GetCertificate(bool onlyStored) { return onlyStored ? _certificate : GetCertificate(); }*/ /// /// Get the certificate associated to the uninstaller or application. /// public X509Certificate2 GetCertificate() { if (!_certificateGotten) { _certificateGotten = true; _certificate = CertificateGetter.TryGetCertificate(this); if (_certificate != null) _certificateValid = _certificate.Verify(); } return _certificate; } public void SetCertificate(X509Certificate2 c) { _certificateGotten = true; _certificate = c; if (_certificate != null) _certificateValid = _certificate.Verify(); } public void SetCertificate(X509Certificate2 c, bool v) { _certificateGotten = true; _certificate = c; _certificateValid = v; } public Icon GetIcon() { return IconBitmap; } /// /// Ordered collection of filenames that could be the main executable of the application. /// The most likely files are first, the least likely are last. /// internal string[] SortedExecutables { get; set; } public IEnumerable GetSortedExecutables() { if (SortedExecutables == null) return Enumerable.Empty(); var output = SortedExecutables.AsEnumerable(); if (!string.IsNullOrEmpty(UninstallerFullFilename)) output = output.OrderBy(x => x.Equals(UninstallerFullFilename, StringComparison.InvariantCultureIgnoreCase)); return output; } public Uri GetAboutUri() { var temp = AboutUrl; if (!temp.IsNotEmpty()) return null; temp = temp.ToLowerInvariant().Replace("www.", temp.StartsWith("www.", StringComparison.InvariantCulture) ? @"http://www." : string.Empty); try { return new Uri(temp, UriKind.Absolute); } catch { return null; } } /// /// Check if certificate is valid. It returns null if the certificate is missing or GetCertificate has not /// been ran yet and onlyStored is set to true. /// public bool? IsCertificateValid(bool onlyStored) { if (!onlyStored && !_certificateGotten) GetCertificate(); return _certificateValid; } /// /// Opens a new read-only instance of registry key used by this uninstaller. Remember to close it! /// public RegistryKey OpenRegKey() { return RegistryPath != null ? RegistryTools.OpenRegistryKey(RegistryPath) : null; } /// /// Opens a new instance of registry key used by this uninstaller. Remember to close it! /// /// /// The user does not have the permissions required to access the registry key in the /// specified mode. /// public RegistryKey OpenRegKey(bool writable) { return RegistryTools.OpenRegistryKey(RegistryPath, writable); } /// /// Check if entry has not been uninstalled already (check registry key) /// /// public bool RegKeyStillExists() { if (string.IsNullOrEmpty(RegistryPath)) return false; try { using (var key = OpenRegKey()) return key != null; } catch { return false; } } public string ToLongString() { var sb = new StringBuilder(); sb.Append(DisplayName); sb.AppendFormat(" | {0}", Publisher); sb.AppendFormat(" | {0}", DisplayVersion); sb.AppendFormat(" | {0}", GetInstallDateString()); sb.AppendFormat(" | {0}", EstimatedSize); sb.AppendFormat(" | {0}", RegistryPath); sb.AppendFormat(" | {0}", UninstallerKind); sb.AppendFormat(" | {0}", UninstallString); sb.AppendFormat(" | {0}", QuietUninstallString); sb.AppendFormat(" | {0}", Comment); return sb.ToString(); } private string GetInstallDateString() { try { return DateTime.MinValue.Equals(InstallDate) ? string.Empty : InstallDate.ToShortDateString(); } catch (SystemException) { return string.Empty; } } public override string ToString() { var sb = new StringBuilder(); sb.Append(DisplayName); sb.AppendFormat(" | {0}", Publisher); sb.AppendFormat(" | {0}", DisplayVersion); sb.AppendFormat(" | {0}", UninstallString); sb.AppendFormat(" | {0}", Comment); return sb.ToString(); } private static readonly char[] InvalidPathChars = Path.GetInvalidPathChars(); private static string CleanupPath(string path, bool isFilename = false) { if (string.IsNullOrEmpty(path)) return null; if (!isFilename) { // Try the fast method first for directories var trimmed = path.Trim('"', ' ', '\'', '\\', '/'); if (!trimmed.ContainsAny(InvalidPathChars)) return trimmed; } try { path = ProcessTools.SeparateArgsFromCommand(path).FileName; if (!isFilename && path.Contains('.') && !Directory.Exists(path)) return Path.GetDirectoryName(path); } catch { // If sanitization failed just leave it be, it will be handled afterwards } return path.TrimEnd('\\'); } } } ================================================ FILE: source/UninstallTools/Controls/FilterEditor.Designer.cs ================================================ using System; namespace UninstallTools.Controls { partial class FilterEditor { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Component Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FilterEditor)); this.labelText = new System.Windows.Forms.Label(); this.textBoxFilterText = new System.Windows.Forms.TextBox(); this.label2 = new System.Windows.Forms.Label(); this.comboBoxCompareMethod = new System.Windows.Forms.ComboBox(); this.comboBox1 = new System.Windows.Forms.ComboBox(); this.label1 = new System.Windows.Forms.Label(); this.panel1 = new System.Windows.Forms.Panel(); this.checkBoxInvert = new System.Windows.Forms.CheckBox(); this.searchBox1 = new Klocman.Controls.SearchBox(); this.panel1.SuspendLayout(); this.SuspendLayout(); // // labelText // this.labelText.AccessibleRole = System.Windows.Forms.AccessibleRole.StaticText; resources.ApplyResources(this.labelText, "labelText"); this.labelText.Name = "labelText"; // // textBoxFilterText // resources.ApplyResources(this.textBoxFilterText, "textBoxFilterText"); this.textBoxFilterText.Name = "textBoxFilterText"; this.textBoxFilterText.TextChanged += new System.EventHandler(this.textBoxFilterText_TextChanged); // // label2 // this.label2.AccessibleRole = System.Windows.Forms.AccessibleRole.StaticText; resources.ApplyResources(this.label2, "label2"); this.label2.Name = "label2"; // // comboBoxCompareMethod // resources.ApplyResources(this.comboBoxCompareMethod, "comboBoxCompareMethod"); this.comboBoxCompareMethod.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.comboBoxCompareMethod.Name = "comboBoxCompareMethod"; this.comboBoxCompareMethod.Sorted = true; this.comboBoxCompareMethod.SelectedIndexChanged += new System.EventHandler(this.comboBoxCompareMethod_SelectedIndexChanged); // // comboBox1 // resources.ApplyResources(this.comboBox1, "comboBox1"); this.comboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.comboBox1.Name = "comboBox1"; this.comboBox1.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged); // // label1 // this.label1.AccessibleRole = System.Windows.Forms.AccessibleRole.StaticText; resources.ApplyResources(this.label1, "label1"); this.label1.Name = "label1"; // // panel1 // resources.ApplyResources(this.panel1, "panel1"); this.panel1.Controls.Add(this.checkBoxInvert); this.panel1.Name = "panel1"; // // checkBoxInvert // resources.ApplyResources(this.checkBoxInvert, "checkBoxInvert"); this.checkBoxInvert.Name = "checkBoxInvert"; this.checkBoxInvert.UseVisualStyleBackColor = true; this.checkBoxInvert.CheckedChanged += new System.EventHandler(this.checkBoxInvert_CheckedChanged); // // searchBox1 // resources.ApplyResources(this.searchBox1, "searchBox1"); this.searchBox1.BackColor = System.Drawing.SystemColors.Window; this.searchBox1.Cursor = System.Windows.Forms.Cursors.Default; this.searchBox1.InactiveSearchColor = System.Drawing.SystemColors.GrayText; this.searchBox1.Name = "searchBox1"; this.searchBox1.NormalSearchColor = System.Drawing.SystemColors.WindowText; this.searchBox1.SearchBoxBorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; this.searchBox1.SearchTextChanged += new System.EventHandler(this.searchBox1_SearchTextChanged); // // FilterEditor // resources.ApplyResources(this, "$this"); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.Controls.Add(this.panel1); this.Controls.Add(this.comboBox1); this.Controls.Add(this.label1); this.Controls.Add(this.comboBoxCompareMethod); this.Controls.Add(this.label2); this.Controls.Add(this.textBoxFilterText); this.Controls.Add(this.labelText); this.Controls.Add(this.searchBox1); this.Name = "FilterEditor"; this.panel1.ResumeLayout(false); this.panel1.PerformLayout(); this.ResumeLayout(false); this.PerformLayout(); } #endregion private System.Windows.Forms.Label labelText; private System.Windows.Forms.TextBox textBoxFilterText; private System.Windows.Forms.Label label2; private System.Windows.Forms.ComboBox comboBoxCompareMethod; private Klocman.Controls.SearchBox searchBox1; private System.Windows.Forms.ComboBox comboBox1; private System.Windows.Forms.Label label1; private System.Windows.Forms.Panel panel1; private System.Windows.Forms.CheckBox checkBoxInvert; } } ================================================ FILE: source/UninstallTools/Controls/FilterEditor.ar.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 نص الفلتر طريقة المقارنة الخصائص المستهدفة عكس النتائج ================================================ FILE: source/UninstallTools/Controls/FilterEditor.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Windows.Forms; using Klocman.Controls; using Klocman.Localising; using UninstallTools.Lists; namespace UninstallTools.Controls { public partial class FilterEditor : UserControl { public event EventHandler FocusSearchTarget { add { searchBox1.FocusSearchTarget += value; } remove { searchBox1.FocusSearchTarget -= value; } } private static readonly LocalisedEnumWrapper[] FilteringOptions; private static readonly Dictionary PropertyTargets; private FilterCondition _targetFilterCondition; static FilterEditor() { FilteringOptions = Enum.GetValues(typeof(ComparisonMethod)) .Cast().Select(x => new LocalisedEnumWrapper(x)).ToArray(); PropertyTargets = new Dictionary(); foreach (var comparisonTarget in ComparisonTargetInfo.ComparisonTargets.OrderBy(x => x.DisplayName)) { PropertyTargets.Add(comparisonTarget.DisplayName, comparisonTarget); } } public FilterEditor() { InitializeComponent(); comboBoxCompareMethod.Items.AddRange(FilteringOptions.Cast().ToArray()); comboBoxCompareMethod.SelectedIndex = 0; comboBox1.Items.Add(ComparisonTargetInfo.AllTargetComparison.DisplayName); comboBox1.Items.AddRange(PropertyTargets.Keys.Cast().ToArray()); comboBox1.SelectedIndex = 0; var autoCompleteStringCollection = new AutoCompleteStringCollection(); textBoxFilterText.AutoCompleteCustomSource = autoCompleteStringCollection; textBoxFilterText.AutoCompleteMode = AutoCompleteMode.SuggestAppend; textBoxFilterText.AutoCompleteSource = AutoCompleteSource.CustomSource; searchBox1.AutoCompleteCustomSource = autoCompleteStringCollection; } private ComparisonTargetInfo SelectedTargetInfo { get { var selection = comboBox1.SelectedItem?.ToString(); if (string.IsNullOrEmpty(selection)) return ComparisonTargetInfo.AllTargetComparison; ComparisonTargetInfo c; return PropertyTargets.TryGetValue(selection, out c) ? c : ComparisonTargetInfo.AllTargetComparison; } } [Browsable(false)] [ReadOnly(true)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public FilterCondition TargetFilterCondition { get { return _targetFilterCondition; } set { _targetFilterCondition = value; RefreshEditor(); //event } } public void RefreshEditor() { if (_targetFilterCondition == null) { Enabled = false; textBoxFilterText.Text = string.Empty; checkBoxInvert.Checked = false; comboBox1.SelectedIndex = 0; comboBoxCompareMethod.SelectedIndex = 0; return; } Enabled = true; var option = FilteringOptions.FirstOrDefault(x => _targetFilterCondition.ComparisonMethod.Equals(x.TargetEnum)); comboBoxCompareMethod.SelectedItem = option ?? FilteringOptions[0]; comboBox1.SelectedIndex = string.IsNullOrEmpty(_targetFilterCondition.TargetPropertyId) ? 0 : Math.Max(0, comboBox1.Items.IndexOf(PropertyTargets.First(x=>x.Value.Id.Equals(_targetFilterCondition.TargetPropertyId)).Key)); if (textBoxFilterText.Text != _targetFilterCondition.FilterText) textBoxFilterText.Text = _targetFilterCondition.FilterText; if (searchBox1.SearchString != _targetFilterCondition.FilterText) { searchBox1.SearchTextChanged -= searchBox1_SearchTextChanged; searchBox1.Search(_targetFilterCondition.FilterText); searchBox1.SearchTextChanged += searchBox1_SearchTextChanged; } if (checkBoxInvert.Checked != _targetFilterCondition.InvertResults) checkBoxInvert.Checked = _targetFilterCondition.InvertResults; } [DefaultValue(false)] public bool ShowAsSearch { get { return searchBox1.Visible; } set { searchBox1.Visible = value; searchBox1.Enabled = value; labelText.Visible = !value; textBoxFilterText.Visible = !value; textBoxFilterText.Enabled = !value; } } /// /// Fires after any part of the edited comparison method is changed. /// public event EventHandler ComparisonMethodChanged; private void OnComparisonMethodChanged(object sender, EventArgs e) { if (!IsDisposed && !Disposing && Enabled) ComparisonMethodChanged?.Invoke(sender, e); } public void FocusSearchbox() { if (searchBox1.Visible) searchBox1.FocusSearchBox(); else textBoxFilterText.Focus(); } public void Search(string searchStr, ComparisonMethod method, string targetPropertyName = null, bool negate = false) { _targetFilterCondition.ComparisonMethod = method; _targetFilterCondition.InvertResults = negate; _targetFilterCondition.FilterText = searchStr; _targetFilterCondition.TargetPropertyId = targetPropertyName; searchBox1.SearchTextChanged -= searchBox1_SearchTextChanged; searchBox1.Search(searchStr); searchBox1.SearchTextChanged += searchBox1_SearchTextChanged; RefreshEditor(); OnComparisonMethodChanged(this, EventArgs.Empty); } private void comboBoxCompareMethod_SelectedIndexChanged(object sender, EventArgs e) { if (comboBoxCompareMethod.SelectedItem is not LocalisedEnumWrapper localisedEnumWrapper || _targetFilterCondition == null || _targetFilterCondition.ComparisonMethod == (ComparisonMethod)localisedEnumWrapper.TargetEnum) return; _targetFilterCondition.ComparisonMethod = (ComparisonMethod)localisedEnumWrapper.TargetEnum; OnComparisonMethodChanged(sender, e); } private void searchBox1_SearchTextChanged(object sender, SearchBox.SearchEventArgs searchEventArgs) { if (_targetFilterCondition == null || _targetFilterCondition.FilterText == searchEventArgs.SearchText) return; _targetFilterCondition.FilterText = searchEventArgs.SearchText; OnComparisonMethodChanged(sender, searchEventArgs); } private void textBoxFilterText_TextChanged(object sender, EventArgs e) { if (_targetFilterCondition == null || _targetFilterCondition.FilterText == textBoxFilterText.Text) return; _targetFilterCondition.FilterText = textBoxFilterText.Text; OnComparisonMethodChanged(sender, e); } private void checkBoxInvert_CheckedChanged(object sender, EventArgs e) { if (_targetFilterCondition == null || _targetFilterCondition.InvertResults == checkBoxInvert.Checked) return; _targetFilterCondition.InvertResults = checkBoxInvert.Checked; OnComparisonMethodChanged(sender, e); } private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) { if (_targetFilterCondition == null) return; textBoxFilterText.AutoCompleteCustomSource.Clear(); var targetInfo = SelectedTargetInfo; if (targetInfo == null) return; if (targetInfo.PossibleStrings != null) { textBoxFilterText.AutoCompleteCustomSource.AddRange(SelectedTargetInfo.PossibleStrings); //textBoxFilterText.Text = SelectedTargetInfo.PossibleStrings.First(); } if (_targetFilterCondition.TargetPropertyId .Equals(targetInfo.Id, StringComparison.InvariantCultureIgnoreCase)) return; _targetFilterCondition.TargetPropertyId = targetInfo.Id; OnComparisonMethodChanged(sender, e); } } } ================================================ FILE: source/UninstallTools/Controls/FilterEditor.cs.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Filtr textu Srovnávací metoda Vlastnost cíle Otočení výsledků True ================================================ FILE: source/UninstallTools/Controls/FilterEditor.de.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Filtertext Vergleichsmethode Zieleigenschaft Umgekehrte Ergebnisse True ================================================ FILE: source/UninstallTools/Controls/FilterEditor.es.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Filtrar texto Método de comparación Invertir resultados Propiedad de destino ================================================ FILE: source/UninstallTools/Controls/FilterEditor.fr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Filtrer le texte Méthode de comparaison Propriété de la cible Inverser les résultats True ================================================ FILE: source/UninstallTools/Controls/FilterEditor.hu.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Szűrő szövege Összehasonlító módszer Céltulajdonság Eredmények megfordítása ================================================ FILE: source/UninstallTools/Controls/FilterEditor.it.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Filtro del testo Medoto di comparazione Proprietà della destinazione Inverti i risultati ================================================ FILE: source/UninstallTools/Controls/FilterEditor.ja.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 テキストをフィルタリング 比較方法 対象プロパティ 結果を反転させる ================================================ FILE: source/UninstallTools/Controls/FilterEditor.nl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Filter tekst Vergelijkingsmethode Doel eigenschap Resultaten omkeren ================================================ FILE: source/UninstallTools/Controls/FilterEditor.pl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Tekst filtru Metoda porównania Porównane pole Odwróć wynik True ================================================ FILE: source/UninstallTools/Controls/FilterEditor.pt-BR.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Filtrar o texto. Método de comparação Propriedade do destino Inverter os resultados ================================================ FILE: source/UninstallTools/Controls/FilterEditor.pt.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Filtrar o texto. Método de comparação Propriedade do destino Inverter os resultados True ================================================ FILE: source/UninstallTools/Controls/FilterEditor.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 True Top NoControl 0, 27 4, 0, 4, 0 0, 0, 0, 3 71, 23 1 Filter text labelText System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 6 Top 0, 50 4, 5, 4, 5 133, 27 2 textBoxFilterText System.Windows.Forms.TextBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 5 True Top NoControl 0, 77 4, 0, 4, 0 0, 6, 0, 3 145, 29 3 Comparison method label2 System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 4 Top 0, 106 4, 5, 4, 5 133, 28 4 comboBoxCompareMethod System.Windows.Forms.ComboBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 3 Top 0, 163 4, 5, 4, 5 133, 28 6 comboBox1 System.Windows.Forms.ComboBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 1 True Top NoControl 0, 134 4, 0, 4, 0 0, 6, 0, 3 111, 29 5 Target property label1 System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 2 True True Top NoControl 0, 6 4, 5, 4, 5 1, 0, 0, 0 130, 24 8 Invert results checkBoxInvert System.Windows.Forms.CheckBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel1 0 Top 0, 191 4, 5, 4, 5 0, 6, 3, 0 133, 30 8 panel1 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 0 True GrowAndShrink Top False 0, 0 4, 5, 4, 5 67, 0 133, 27 0 False searchBox1 Klocman.Controls.SearchBox, KlocTools, Culture=neutral, PublicKeyToken=null $this 7 True 8, 20 True GrowAndShrink 0, 0, 0, 0 133, 0 133, 221 FilterEditor System.Windows.Forms.UserControl, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 ================================================ FILE: source/UninstallTools/Controls/FilterEditor.ru.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Текст фильтра Метод сравнения Целевое свойство Обратить результаты True ================================================ FILE: source/UninstallTools/Controls/FilterEditor.sl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Filtriraj besedilo Metoda primerjave Lastnost cilja Obrni rezultate True ================================================ FILE: source/UninstallTools/Controls/FilterEditor.sv.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Filter text Jämförelsemetod Målegenskaper Omvänd resultat ================================================ FILE: source/UninstallTools/Controls/FilterEditor.tr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Metni filtrele Karşılaştırma yöntemi Hedef özelliği Sonuçları ters çevir ================================================ FILE: source/UninstallTools/Controls/FilterEditor.vi.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Văn bản lọc Phương thức so sánh Thuộc tính mục tiêu Đảo ngược kết quả ================================================ FILE: source/UninstallTools/Controls/FilterEditor.zh-Hans.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 筛选器文本 比较方法 目标属性 反转结果 ================================================ FILE: source/UninstallTools/Controls/FilterEditor.zh-Hant.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 篩選器文字 比較方式 目標屬性 反向結果 ================================================ FILE: source/UninstallTools/Controls/UninstallListEditor.Designer.cs ================================================ namespace UninstallTools.Controls { partial class UninstallListEditor { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Component Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(UninstallListEditor)); this.splitContainer1 = new System.Windows.Forms.SplitContainer(); this.groupBoxFilterList = new System.Windows.Forms.GroupBox(); this.listView1 = new System.Windows.Forms.ListView(); this.columnHeaderName = new System.Windows.Forms.ColumnHeader(); this.columnHeaderType = new System.Windows.Forms.ColumnHeader(); this.columnHeaderConditions = new System.Windows.Forms.ColumnHeader(); this.toolStrip1 = new System.Windows.Forms.ToolStrip(); this.toolStripButtonAddFilter = new System.Windows.Forms.ToolStripButton(); this.toolStripButtonRemoveFilter = new System.Windows.Forms.ToolStripButton(); this.toolStripButtonAddFiltersFromList = new System.Windows.Forms.ToolStripButton(); this.panel2 = new System.Windows.Forms.Panel(); this.groupBoxFilterSettings = new System.Windows.Forms.GroupBox(); this.textBoxFilterName = new System.Windows.Forms.TextBox(); this.labelFilterType = new System.Windows.Forms.Label(); this.comboBoxFilterType = new System.Windows.Forms.ComboBox(); this.labelFilterName = new System.Windows.Forms.Label(); this.splitContainer2 = new System.Windows.Forms.SplitContainer(); this.groupBoxConditions = new System.Windows.Forms.GroupBox(); this.panel1 = new System.Windows.Forms.Panel(); this.listBoxConditions = new System.Windows.Forms.ListBox(); this.toolStrip2 = new System.Windows.Forms.ToolStrip(); this.toolStripButtonAddCondition = new System.Windows.Forms.ToolStripButton(); this.toolStripButtonRemoveCondition = new System.Windows.Forms.ToolStripButton(); this.groupBoxConditionEditor = new System.Windows.Forms.GroupBox(); this.filterEditor = new UninstallTools.Controls.FilterEditor(); this.openFileDialog = new System.Windows.Forms.OpenFileDialog(); ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); this.splitContainer1.Panel1.SuspendLayout(); this.splitContainer1.Panel2.SuspendLayout(); this.splitContainer1.SuspendLayout(); this.groupBoxFilterList.SuspendLayout(); this.toolStrip1.SuspendLayout(); this.groupBoxFilterSettings.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.splitContainer2)).BeginInit(); this.splitContainer2.Panel1.SuspendLayout(); this.splitContainer2.Panel2.SuspendLayout(); this.splitContainer2.SuspendLayout(); this.groupBoxConditions.SuspendLayout(); this.panel1.SuspendLayout(); this.toolStrip2.SuspendLayout(); this.groupBoxConditionEditor.SuspendLayout(); this.SuspendLayout(); // // splitContainer1 // resources.ApplyResources(this.splitContainer1, "splitContainer1"); this.splitContainer1.Name = "splitContainer1"; // // splitContainer1.Panel1 // this.splitContainer1.Panel1.Controls.Add(this.groupBoxFilterList); this.splitContainer1.Panel1.Controls.Add(this.panel2); this.splitContainer1.Panel1.Controls.Add(this.groupBoxFilterSettings); resources.ApplyResources(this.splitContainer1.Panel1, "splitContainer1.Panel1"); // // splitContainer1.Panel2 // this.splitContainer1.Panel2.Controls.Add(this.splitContainer2); // // groupBoxFilterList // this.groupBoxFilterList.Controls.Add(this.listView1); this.groupBoxFilterList.Controls.Add(this.toolStrip1); resources.ApplyResources(this.groupBoxFilterList, "groupBoxFilterList"); this.groupBoxFilterList.Name = "groupBoxFilterList"; this.groupBoxFilterList.TabStop = false; // // listView1 // this.listView1.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { this.columnHeaderName, this.columnHeaderType, this.columnHeaderConditions}); resources.ApplyResources(this.listView1, "listView1"); this.listView1.FullRowSelect = true; this.listView1.GridLines = true; this.listView1.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable; this.listView1.HideSelection = false; this.listView1.MultiSelect = false; this.listView1.Name = "listView1"; this.listView1.ShowGroups = false; this.listView1.ShowItemToolTips = true; this.listView1.Sorting = System.Windows.Forms.SortOrder.Ascending; this.listView1.UseCompatibleStateImageBehavior = false; this.listView1.View = System.Windows.Forms.View.Details; this.listView1.SelectedIndexChanged += new System.EventHandler(this.OnSelectedFilterChanged); // // columnHeaderName // resources.ApplyResources(this.columnHeaderName, "columnHeaderName"); // // columnHeaderType // resources.ApplyResources(this.columnHeaderType, "columnHeaderType"); // // columnHeaderConditions // resources.ApplyResources(this.columnHeaderConditions, "columnHeaderConditions"); // // toolStrip1 // this.toolStrip1.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden; this.toolStrip1.ImageScalingSize = new System.Drawing.Size(20, 20); this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.toolStripButtonAddFilter, this.toolStripButtonRemoveFilter, this.toolStripButtonAddFiltersFromList}); resources.ApplyResources(this.toolStrip1, "toolStrip1"); this.toolStrip1.Name = "toolStrip1"; // // toolStripButtonAddFilter // this.toolStripButtonAddFilter.Image = global::UninstallTools.Properties.Resources.add; resources.ApplyResources(this.toolStripButtonAddFilter, "toolStripButtonAddFilter"); this.toolStripButtonAddFilter.Name = "toolStripButtonAddFilter"; this.toolStripButtonAddFilter.Click += new System.EventHandler(this.buttonAdd_Click); // // toolStripButtonRemoveFilter // this.toolStripButtonRemoveFilter.Image = global::UninstallTools.Properties.Resources.minus; resources.ApplyResources(this.toolStripButtonRemoveFilter, "toolStripButtonRemoveFilter"); this.toolStripButtonRemoveFilter.Name = "toolStripButtonRemoveFilter"; this.toolStripButtonRemoveFilter.Click += new System.EventHandler(this.buttonRemove_Click); // // toolStripButtonAddFiltersFromList // this.toolStripButtonAddFiltersFromList.Image = global::UninstallTools.Properties.Resources.folder_open; resources.ApplyResources(this.toolStripButtonAddFiltersFromList, "toolStripButtonAddFiltersFromList"); this.toolStripButtonAddFiltersFromList.Name = "toolStripButtonAddFiltersFromList"; this.toolStripButtonAddFiltersFromList.Click += new System.EventHandler(this.buttonImport_Click); // // panel2 // resources.ApplyResources(this.panel2, "panel2"); this.panel2.Name = "panel2"; // // groupBoxFilterSettings // this.groupBoxFilterSettings.Controls.Add(this.textBoxFilterName); this.groupBoxFilterSettings.Controls.Add(this.labelFilterType); this.groupBoxFilterSettings.Controls.Add(this.comboBoxFilterType); this.groupBoxFilterSettings.Controls.Add(this.labelFilterName); resources.ApplyResources(this.groupBoxFilterSettings, "groupBoxFilterSettings"); this.groupBoxFilterSettings.Name = "groupBoxFilterSettings"; this.groupBoxFilterSettings.TabStop = false; // // textBoxFilterName // resources.ApplyResources(this.textBoxFilterName, "textBoxFilterName"); this.textBoxFilterName.Name = "textBoxFilterName"; this.textBoxFilterName.TextChanged += new System.EventHandler(this.textBoxFilterName_TextChanged); // // labelFilterType // resources.ApplyResources(this.labelFilterType, "labelFilterType"); this.labelFilterType.Name = "labelFilterType"; // // comboBoxFilterType // resources.ApplyResources(this.comboBoxFilterType, "comboBoxFilterType"); this.comboBoxFilterType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.comboBoxFilterType.FormattingEnabled = true; this.comboBoxFilterType.Items.AddRange(new object[] { resources.GetString("comboBoxFilterType.Items"), resources.GetString("comboBoxFilterType.Items1")}); this.comboBoxFilterType.Name = "comboBoxFilterType"; this.comboBoxFilterType.SelectedIndexChanged += new System.EventHandler(this.comboBoxFilterType_SelectedIndexChanged); // // labelFilterName // resources.ApplyResources(this.labelFilterName, "labelFilterName"); this.labelFilterName.Name = "labelFilterName"; // // splitContainer2 // resources.ApplyResources(this.splitContainer2, "splitContainer2"); this.splitContainer2.Name = "splitContainer2"; // // splitContainer2.Panel1 // this.splitContainer2.Panel1.Controls.Add(this.groupBoxConditions); // // splitContainer2.Panel2 // this.splitContainer2.Panel2.Controls.Add(this.groupBoxConditionEditor); // // groupBoxConditions // this.groupBoxConditions.Controls.Add(this.panel1); resources.ApplyResources(this.groupBoxConditions, "groupBoxConditions"); this.groupBoxConditions.Name = "groupBoxConditions"; this.groupBoxConditions.TabStop = false; // // panel1 // resources.ApplyResources(this.panel1, "panel1"); this.panel1.Controls.Add(this.listBoxConditions); this.panel1.Controls.Add(this.toolStrip2); this.panel1.Name = "panel1"; // // listBoxConditions // resources.ApplyResources(this.listBoxConditions, "listBoxConditions"); this.listBoxConditions.FormattingEnabled = true; this.listBoxConditions.Name = "listBoxConditions"; this.listBoxConditions.SelectedIndexChanged += new System.EventHandler(this.listBox1_SelectedIndexChanged); // // toolStrip2 // this.toolStrip2.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden; this.toolStrip2.ImageScalingSize = new System.Drawing.Size(20, 20); this.toolStrip2.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.toolStripButtonAddCondition, this.toolStripButtonRemoveCondition}); resources.ApplyResources(this.toolStrip2, "toolStrip2"); this.toolStrip2.Name = "toolStrip2"; // // toolStripButtonAddCondition // this.toolStripButtonAddCondition.Image = global::UninstallTools.Properties.Resources.add; resources.ApplyResources(this.toolStripButtonAddCondition, "toolStripButtonAddCondition"); this.toolStripButtonAddCondition.Name = "toolStripButtonAddCondition"; this.toolStripButtonAddCondition.Click += new System.EventHandler(this.toolStripButtonAddCondition_Click); // // toolStripButtonRemoveCondition // this.toolStripButtonRemoveCondition.Image = global::UninstallTools.Properties.Resources.minus; resources.ApplyResources(this.toolStripButtonRemoveCondition, "toolStripButtonRemoveCondition"); this.toolStripButtonRemoveCondition.Name = "toolStripButtonRemoveCondition"; this.toolStripButtonRemoveCondition.Click += new System.EventHandler(this.toolStripButtonRemoveCondition_Click); // // groupBoxConditionEditor // this.groupBoxConditionEditor.Controls.Add(this.filterEditor); resources.ApplyResources(this.groupBoxConditionEditor, "groupBoxConditionEditor"); this.groupBoxConditionEditor.Name = "groupBoxConditionEditor"; this.groupBoxConditionEditor.TabStop = false; // // filterEditor // resources.ApplyResources(this.filterEditor, "filterEditor"); this.filterEditor.Name = "filterEditor"; // // openFileDialog // resources.ApplyResources(this.openFileDialog, "openFileDialog"); this.openFileDialog.Multiselect = true; this.openFileDialog.FileOk += new System.ComponentModel.CancelEventHandler(this.openFileDialog_FileOk); // // UninstallListEditor // resources.ApplyResources(this, "$this"); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.Controls.Add(this.splitContainer1); this.Name = "UninstallListEditor"; this.splitContainer1.Panel1.ResumeLayout(false); this.splitContainer1.Panel2.ResumeLayout(false); ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit(); this.splitContainer1.ResumeLayout(false); this.groupBoxFilterList.ResumeLayout(false); this.groupBoxFilterList.PerformLayout(); this.toolStrip1.ResumeLayout(false); this.toolStrip1.PerformLayout(); this.groupBoxFilterSettings.ResumeLayout(false); this.groupBoxFilterSettings.PerformLayout(); this.splitContainer2.Panel1.ResumeLayout(false); this.splitContainer2.Panel2.ResumeLayout(false); ((System.ComponentModel.ISupportInitialize)(this.splitContainer2)).EndInit(); this.splitContainer2.ResumeLayout(false); this.groupBoxConditions.ResumeLayout(false); this.panel1.ResumeLayout(false); this.panel1.PerformLayout(); this.toolStrip2.ResumeLayout(false); this.toolStrip2.PerformLayout(); this.groupBoxConditionEditor.ResumeLayout(false); this.groupBoxConditionEditor.PerformLayout(); this.ResumeLayout(false); } #endregion private System.Windows.Forms.GroupBox groupBoxFilterList; private System.Windows.Forms.ListView listView1; private System.Windows.Forms.ColumnHeader columnHeaderName; private System.Windows.Forms.ColumnHeader columnHeaderType; private System.Windows.Forms.GroupBox groupBoxConditions; private System.Windows.Forms.OpenFileDialog openFileDialog; private System.Windows.Forms.ColumnHeader columnHeaderConditions; private System.Windows.Forms.ToolStrip toolStrip1; private System.Windows.Forms.ToolStripButton toolStripButtonAddFilter; private System.Windows.Forms.ToolStripButton toolStripButtonRemoveFilter; private System.Windows.Forms.ToolStripButton toolStripButtonAddFiltersFromList; private System.Windows.Forms.Panel panel1; private System.Windows.Forms.SplitContainer splitContainer1; private System.Windows.Forms.SplitContainer splitContainer2; private System.Windows.Forms.ToolStrip toolStrip2; private System.Windows.Forms.ToolStripButton toolStripButtonAddCondition; private System.Windows.Forms.ListBox listBoxConditions; private System.Windows.Forms.ToolStripButton toolStripButtonRemoveCondition; private System.Windows.Forms.GroupBox groupBoxConditionEditor; private FilterEditor filterEditor; private System.Windows.Forms.Panel panel2; private System.Windows.Forms.GroupBox groupBoxFilterSettings; private System.Windows.Forms.TextBox textBoxFilterName; private System.Windows.Forms.Label labelFilterType; private System.Windows.Forms.ComboBox comboBoxFilterType; private System.Windows.Forms.Label labelFilterName; } } ================================================ FILE: source/UninstallTools/Controls/UninstallListEditor.ar.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 اسم الفلتر نوع ظروف اضافه ازاله اضافه من القائمه... قائمه الفلاتر نوع: تضمين استبعاد اسم: اعدادات الفلتر اضافه ازاله شروط الفلتر محرر الشرط قوائم الغاء تثبيت(*.bcul)|*.bcul|All files|*.* تحميل قائمه الغاء التثبيت... ================================================ FILE: source/UninstallTools/Controls/UninstallListEditor.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.ComponentModel; using System.Linq; using System.Windows.Forms; using Klocman.Forms.Tools; using UninstallTools.Lists; using UninstallTools.Properties; namespace UninstallTools.Controls { public partial class UninstallListEditor : UserControl { private UninstallList _currentList; public UninstallListEditor() { InitializeComponent(); comboBoxFilterType.SelectedIndex = 0; filterEditor.ComparisonMethodChanged += OnFiltersChanged; filterEditor.LostFocus += EditorFocusLost; groupBoxFilterSettings.Enabled = false; splitContainer1.Panel2.Enabled = false; filterEditor.TargetFilterCondition = null; } [ReadOnly(true)] [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public UninstallList CurrentList { get { return _currentList; } set { _currentList = value; Enabled = _currentList != null; PopulateList(); OnCurrentListChanged(this, EventArgs.Empty); } } private Filter CurrentlySelected { get { if (listView1.SelectedItems.Count <= 0) return null; return listView1.SelectedItems[0].Tag as Filter; } } public event EventHandler CurrentListChanged; private void OnCurrentListChanged(object sender, EventArgs e) { OnFiltersChanged(sender, e); CurrentListChanged?.Invoke(sender, e); } private void buttonAdd_Click(object sender, EventArgs e) { Filter newItem; try { newItem = new Filter(Localisation.UninstallListEditor_NewFilter, Localisation.UninstallListEditor_NewFilter); } catch (Exception ex) { PremadeDialogs.GenericError(ex); return; } CurrentList.Add(newItem); PopulateList(); OnFiltersChanged(sender, e); } private void buttonImport_Click(object sender, EventArgs e) { openFileDialog.ShowDialog(); } private void buttonRemove_Click(object sender, EventArgs e) { var item = CurrentlySelected; if (item == null) return; CurrentList.Remove(item); PopulateList(); OnFiltersChanged(sender, e); } private void EditorFocusLost(object sender, EventArgs e) { RefreshSelectedFilter(); } private void OnSelectedFilterChanged(object sender, EventArgs e) { var selection = CurrentlySelected; if (selection != null) { textBoxFilterName.Text = selection.Name; comboBoxFilterType.SelectedIndex = selection.Exclude ? 1 : 0; splitContainer1.Panel2.Enabled = true; groupBoxFilterSettings.Enabled = true; } else { groupBoxFilterSettings.Enabled = false; splitContainer1.Panel2.Enabled = false; } PopulateConditions(); } private void PopulateConditions() { listBoxConditions.SelectedItem = null; listBoxConditions.Items.Clear(); var selection = CurrentlySelected; if (selection?.ComparisonEntries != null) { groupBoxConditions.Enabled = true; listBoxConditions.Items.AddRange(selection.ComparisonEntries.AsEnumerable().Reverse().Cast().ToArray()); } else { groupBoxConditions.Enabled = false; } } private void openFileDialog_FileOk(object sender, CancelEventArgs e) { try { CurrentList.AddItems(UninstallList.ReadFromFile(openFileDialog.FileName).Filters); PopulateList(); } catch (Exception ex) { PremadeDialogs.GenericError(ex); e.Cancel = true; } } public void PopulateList() { groupBoxConditions.Enabled = false; listView1.Items.Clear(); textBoxFilterName.Text = string.Empty; comboBoxFilterType.SelectedIndex = 0; if (CurrentList == null) return; listView1.Items.AddRange(CurrentList.Filters.Select(x => new ListViewItem( new[] { x.Name, Filter.ExcludeToString(x.Exclude), x.ComparisonEntries.Count.ToString() }) { Tag = x }).ToArray()); } private void OnFiltersChanged(object sender, EventArgs e) { listBoxConditions.Update(); FiltersChanged?.Invoke(sender, e); } /// /// Fires whenever the filters can potentially give a different result /// public event EventHandler FiltersChanged; private void RefreshSelectedFilter() { if (listView1.SelectedItems.Count <= 0) return; var item = listView1.SelectedItems[0]; var tag = CurrentlySelected; item.SubItems[0].Text = tag.Name; item.SubItems[1].Text = Filter.ExcludeToString(tag.Exclude); item.SubItems[2].Text = tag.ComparisonEntries.Count.ToString(); item.EnsureVisible(); } private void listBox1_SelectedIndexChanged(object sender, EventArgs e) { if (listBoxConditions.SelectedItem is not FilterCondition item) { filterEditor.TargetFilterCondition = null; } else if (!ReferenceEquals(filterEditor.TargetFilterCondition, item)) { filterEditor.TargetFilterCondition = item; } } private void toolStripButtonAddCondition_Click(object sender, EventArgs e) { filterEditor.TargetFilterCondition = null; CurrentlySelected.ComparisonEntries.Add(new FilterCondition()); PopulateConditions(); OnFiltersChanged(sender, e); } private void toolStripButtonRemoveCondition_Click(object sender, EventArgs e) { if (listBoxConditions.SelectedItem is not FilterCondition item) return; filterEditor.TargetFilterCondition = null; CurrentlySelected.ComparisonEntries.Remove(item); PopulateConditions(); OnFiltersChanged(sender, e); } private void textBoxFilterName_TextChanged(object sender, EventArgs e) { if (CurrentlySelected == null) return; CurrentlySelected.Name = textBoxFilterName.Text ?? string.Empty; RefreshSelectedFilter(); } private void comboBoxFilterType_SelectedIndexChanged(object sender, EventArgs e) { if (CurrentlySelected == null) return; CurrentlySelected.Exclude = comboBoxFilterType.SelectedIndex != 0; RefreshSelectedFilter(); OnFiltersChanged(sender, e); } } } ================================================ FILE: source/UninstallTools/Controls/UninstallListEditor.cs.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Název filtru Typ Podmínky Přidat Odstranit Přidat ze seznamu ... Filtr seznamu Typ: Zahrnout Vyloučit Název: Nastavení filtru Přidat Odstranit Podmínky filtru Editor podmínek Seznam odinstalace (*.bcul)|*.bcul|All files|*.* Načíst seznam odinstalace... ================================================ FILE: source/UninstallTools/Controls/UninstallListEditor.de.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Hinzufügen Entfernen Hinzufügen von Liste... Filterliste Hinzufügen Entfernen Uninstall-Listen (*.bcul)|*.bcul|All files|*.* Uninstall-Liste laden... Filter Name Vorbild Bedingungen Vorbild Einschließen Ausschließen Name: Filter Einstellungen Filterbedingungen Bedingungseditor ================================================ FILE: source/UninstallTools/Controls/UninstallListEditor.es.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Añadir desde la lista... Excluir Cargar lista de desinstalación... Editor de condición Eliminar Añadir Lista del filtro Agregar Incluir Nombre del filtro Eliminar Tipo Nombre: Ajustes del filtro Condiciones Listas de desinstalación (*.bcul)|*.bcul|Todos los archivos|*.* Tipo: Condiciones del filtro ================================================ FILE: source/UninstallTools/Controls/UninstallListEditor.fr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Ajouter Supprimer Ajouter depuis la liste... Filtrer la liste Ajouter Supprimer Listes de désinstallation (*.bcul)|*.bcul|Tous les fichiers|*.* Charger la liste de désinstallation... Exclure Éditeur de condition Inclure Nom de filtre Conditions de filtre Type Nom: Réglages de filtre Conditions Type: ================================================ FILE: source/UninstallTools/Controls/UninstallListEditor.hu.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Hozzáadás listából... Kihagyva Eltávolítási lista betöltése... Feltételszerkesztő Törlés Hozzáad Szűrőlista Hozzáad Tartalmazza Szűrőnév Eltávolítási lista (*.bcul)|*.bcul|Minden fájl|*.* Törlés Szűrőfeltételek Típus Név: Szűrőbeállítások Feltételek Típus: ================================================ FILE: source/UninstallTools/Controls/UninstallListEditor.it.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Aggiungi dalla lista... Escludi Carica la lista di disinstallazione... Editore di condizioni Rimuovi Aggiungi Filtro della lista Aggiungi Includi Nome del filtro Liste di disinstallazione (*.bcul)|*.bcul|Tutti i file|*.* Rimuovi Condizioni del filtro Tipo Nome: Configurazione del filtro Condizioni Tipo: ================================================ FILE: source/UninstallTools/Controls/UninstallListEditor.ja.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 フィルター名 タイプ 条件 追加 削除 リストから追加... フィルターリスト タイプ: 含む 除外する 名前: フィルター設定 追加 削除 フィルター条件 条件エディタ アンインストールリスト (*.bcul)|*.bcul|All files|*.* アンインストールリストを読み込む... ================================================ FILE: source/UninstallTools/Controls/UninstallListEditor.nl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Filternaam Type Condities Toevoegen Verwijderen Toevoegen uit lijst Filterlijst Type: Inclusief Exclusief Naam: Filter instellingen Toevoegen Verwijderen Filter condities Conditie editor De-installatie lijsten (*.bcul)|*.bcul|Alle bestanden|*.* De-installatie lijst laden... ================================================ FILE: source/UninstallTools/Controls/UninstallListEditor.pl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Nazwa filtra Typ Kondycje Dodaj Usuń Dodaj z listy... Lista filtrów Typ: Uwzględnij Wyklucz Nazwa: Ustawienia filtra Dodaj Usuń Kondycje filtra Edytor kondycji Listy dezinstalatorów (*.bcul)|*.bcul|Wszystkie pliki|*.* Otwórz listę dezinstalatorów... ================================================ FILE: source/UninstallTools/Controls/UninstallListEditor.pt-BR.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Nome do filtro Tipo Condições Adicionar Remover Adicionar da lista... Filtrar a lista Tipo: Incluir Excluir Nome: Configurações do filtro Adicionar Remover Condições de filtro Editor de condição Listas de Desinstalações (*.bcul)|*.bcul|Todos os arquivos|*.* Carregar Lista de Desinstalação... ================================================ FILE: source/UninstallTools/Controls/UninstallListEditor.pt.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Adicionar da lista... Excluir Carregar a Lista de Desinstalação... Editor de condição Remover Adicionar Filtrar a lista Adicionar Incluir Nome do filtro Listas de Desinstalações (*.bcul)|*.bcul|Todos os ficheiros|*.* Remover Condições de filtro Tipo Nome: Configurações do filtro Condições Tipo: 17, 17 cs True 81 255, 17 150, 17 ================================================ FILE: source/UninstallTools/Controls/UninstallListEditor.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Fill 0, 0 4, 5, 4, 5 Horizontal Filter name 130 Type 100 Conditions 100 Fill 8, 56 4, 5, 4, 5 417, 296 0 listView1 System.Windows.Forms.ListView, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBoxFilterList 0 150, 17 Magenta 61, 24 Add Magenta 87, 24 Remove Magenta 129, 24 Add from list... 8, 29 417, 27 2 toolStrip1 System.Windows.Forms.ToolStrip, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBoxFilterList 1 Fill 5, 6 4, 5, 4, 5 8, 9, 8, 9 433, 361 3 Filter list groupBoxFilterList System.Windows.Forms.GroupBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 splitContainer1.Panel1 0 Bottom 5, 367 4, 5, 4, 5 433, 6 5 panel2 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 splitContainer1.Panel1 1 Fill 65, 26 4, 5, 4, 5 185, 27 1 textBoxFilterName System.Windows.Forms.TextBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBoxFilterSettings 0 True Right NoControl 250, 26 4, 0, 4, 0 4, 5, 4, 5 51, 30 3 Type: labelFilterType System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBoxFilterSettings 1 Right Include Exclude 301, 26 4, 5, 4, 5 127, 28 2 comboBoxFilterType System.Windows.Forms.ComboBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBoxFilterSettings 2 True Left NoControl 5, 26 4, 0, 4, 0 4, 5, 4, 5 60, 30 0 Name: labelFilterName System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBoxFilterSettings 3 Bottom 5, 373 4, 5, 4, 5 5, 6, 5, 6 433, 66 4 Filter settings groupBoxFilterSettings System.Windows.Forms.GroupBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 splitContainer1.Panel1 2 5, 6, 5, 6 splitContainer1.Panel1 System.Windows.Forms.SplitterPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 splitContainer1 0 Fill 0, 0 4, 5, 4, 5 True Fill False 20 0, 27 4, 5, 4, 5 True 185, 259 14 listBoxConditions System.Windows.Forms.ListBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel1 0 255, 17 Magenta 61, 24 Add Magenta 87, 24 Remove 0, 0 185, 27 13 toolStrip2 System.Windows.Forms.ToolStrip, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel1 1 Fill 5, 26 4, 5, 4, 5 185, 286 12 panel1 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 groupBoxConditions 0 Fill False 0, 0 4, 5, 4, 5 5, 6, 5, 6 195, 318 4 Filter conditions groupBoxConditions System.Windows.Forms.GroupBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 splitContainer2.Panel1 0 splitContainer2.Panel1 System.Windows.Forms.SplitterPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 splitContainer2 0 True GrowAndShrink Top 4, 25 0, 0, 0, 0 5, 6, 5, 6 236, 206 17 filterEditor UninstallTools.Controls.FilterEditor, UninstallTools, Culture=neutral, PublicKeyToken=null groupBoxConditionEditor 0 Fill 0, 0 4, 5, 4, 5 4, 5, 4, 5 244, 318 17 Condition editor groupBoxConditionEditor System.Windows.Forms.GroupBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 splitContainer2.Panel2 0 splitContainer2.Panel2 System.Windows.Forms.SplitterPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 splitContainer2 1 443, 318 195 6 splitContainer2 System.Windows.Forms.SplitContainer, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 splitContainer1.Panel2 0 splitContainer1.Panel2 System.Windows.Forms.SplitterPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 splitContainer1 1 443, 769 445 6 11 splitContainer1 System.Windows.Forms.SplitContainer, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 0 17, 17 Uninstall lists (*.bcul)|*.bcul|All files|*.* Load Uninstall List... True 81 8, 20 4, 5, 4, 5 443, 769 columnHeaderName System.Windows.Forms.ColumnHeader, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 columnHeaderType System.Windows.Forms.ColumnHeader, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 columnHeaderConditions System.Windows.Forms.ColumnHeader, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripButtonAddFilter System.Windows.Forms.ToolStripButton, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripButtonRemoveFilter System.Windows.Forms.ToolStripButton, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripButtonAddFiltersFromList System.Windows.Forms.ToolStripButton, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripButtonAddCondition System.Windows.Forms.ToolStripButton, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripButtonRemoveCondition System.Windows.Forms.ToolStripButton, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 openFileDialog System.Windows.Forms.OpenFileDialog, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 UninstallListEditor System.Windows.Forms.UserControl, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 ================================================ FILE: source/UninstallTools/Controls/UninstallListEditor.ru.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Добавить из списка... Исключить Загрузить список деинсталляции... Редактор условий Удалить Добавить Список фильтров Добавить Включить Имя фильтра Список деинсталляции (*.bcul)|*.bcul|Все файлы|*.* Удалить Условия фильтрации Тип Имя: Установки фильтра Условия Тип: 17, 17 cs True 81 255, 17 150, 17 ================================================ FILE: source/UninstallTools/Controls/UninstallListEditor.sl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Filtriraj seznam Seznami odstranjevanja (*.bcul)|*.bcul|Vse datoteke|*.* Naloži seznam odstranjevanja... Dodaj Odstrani Dodaj s seznama... Dodaj Odstrani Izključi Urejevalnik pogoja Vključi Pogoji filtra Vrsta Ime: Nastavitve filtra Pogoji Vrsta: Ime filtra 17, 17 True ================================================ FILE: source/UninstallTools/Controls/UninstallListEditor.sv.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Filternamn Typ Villkor Lägg till Ta bort Lägg till från lista... Filtrera lista Typ: Inkludera Exkludera Namn: Filter-inställningar Lägg till Ta bort Filter villkor Villkors-redigerare Avinstallationslistor (*.bcul)|*.bcul|Alla filer|*.* Ladda avinstallationslista... ================================================ FILE: source/UninstallTools/Controls/UninstallListEditor.tr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Filtreleme adı Tip Koşullar Ekle Kaldır Listeden ekle... Listeyi filtrele Tip: Dahil et Hariç tut Adı: Filtreleme ayarları Ekle Kaldır Filtreleme koşulları Koşul düzenleyici Listeleri kaldır (*.bcul)|*.bcul|Tüm dosyalar|*. * Kaldırma listesini yükle ================================================ FILE: source/UninstallTools/Controls/UninstallListEditor.vi.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Tên bộ lọc Kiểu Điều kiện Thêm Loại bỏ Thêm từ danh sách... Danh sách bộ lọc Kiểu: Bao gôm Ngoại trừ Tên: Cài đặt bộ lọc Thêm Loại bỏ Điều kiện bộ lọc Trình chỉnh sửa điều kiện Danh sách bộ lọc gỡ cài đặt (*.bcul)|*.bcul|Tất cả tệp|*.* Làm mới danh sách bộ lọc gỡ cài đặt ================================================ FILE: source/UninstallTools/Controls/UninstallListEditor.zh-Hans.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 筛选器名 类型 条件 添加 删除 从列表添加... 筛选器列表 类型: 包括 排除 名称: 筛选器设置 添加 删除 筛选器条件 筛选器编辑器 卸载列表(*.bcul)|*.bcul|所有文件|*.* 加载卸载列表... ================================================ FILE: source/UninstallTools/Controls/UninstallListEditor.zh-Hant.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 選項名稱 類型 條件 新增 删除 從清單新增 篩選清單 類型: 包含 不包含 名稱: 選項設定 新增 删除 選項條件 選項編輯器 移除列表(*.bcul)|*.bcul|所有檔案|*.* 載入移除清單... ================================================ FILE: source/UninstallTools/Controls/UninstallerIconGetter.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Linq; using System.Windows.Forms; using Klocman.Extensions; namespace UninstallTools.Controls { public class UninstallerIconGetter : Component { private static readonly string ApplicationIconKey = "applicationIcon"; private static readonly string InvalidIconKey = "invalidIcon"; private static readonly string MsiexecIconKey = "msiexecIcon"; private static readonly string UpdateIconKey = "updateIcon"; // The name "OperatingSystem" is important private static readonly string WindowsIconKey = "OperatingSystem"; public UninstallerIconGetter() { Disposed += DisposeHandler; } public ImageList IconList { get; private set; } public object ColumnImageGetter(object rowObj) { if (rowObj is not ApplicationUninstallerEntry entry || IconList == null) return null; if (IconListContainsKey(entry.DisplayName)) return entry.DisplayName; if (entry.ParentKeyName.IsNotEmpty()) { if (entry.ParentKeyName.Equals(WindowsIconKey)) return WindowsIconKey; if (IconListContainsKey(entry.ParentKeyName)) return entry.ParentKeyName; } if (entry.IsUpdate || entry.UninstallerKind == UninstallerType.WindowsFeature) return UpdateIconKey; if (entry.UninstallerKind == UninstallerType.Msiexec || entry.UninstallerKind == UninstallerType.SdbInst) return MsiexecIconKey; if (entry.IsValid) return ApplicationIconKey; return InvalidIconKey; } /// The current platform is not supported. public void UpdateIconList(IEnumerable objList) { IconList = new ImageList(); var windowsPath = Environment.GetFolderPath(Environment.SpecialFolder.System); IconList.Images.Add(ApplicationIconKey, SystemIcons.Application); IconList.Images.Add(InvalidIconKey, SystemIcons.Exclamation); IconList.Images.Add(WindowsIconKey, SystemIcons.Shield); //SystemIcons.WinLogo); winlogo not working on xp? IconList.Images.Add(UpdateIconKey, SystemIcons.Shield); var msiIcon = UninstallToolsGlobalConfig.TryExtractAssociatedIcon(windowsPath + @"\msiexec.exe"); IconList.Images.Add(MsiexecIconKey, msiIcon ?? SystemIcons.Application); foreach (var obj in objList) { if (IconListContainsKey(obj.DisplayName)) continue; try { var image = obj.GetIcon(); if (image != null) { IconList.Images.Add(obj.DisplayName, image); } } catch { // Revert to default icon } } } private void DisposeHandler(object x, EventArgs y) { if (IconList != null) { IconList.Dispose(); IconList = null; } } private bool IconListContainsKey(string key) { if (string.IsNullOrEmpty(key)) return false; if (IconList == null) throw new InvalidOperationException("IconListContainsKey called when IconList is null"); return IconList.Images.Keys.Cast().Any(x => x.Equals(key)); } } } ================================================ FILE: source/UninstallTools/Dialogs/StartupManagerWindow.Designer.cs ================================================ using BrightIdeasSoftware; namespace UninstallTools.Dialogs { partial class StartupManagerWindow { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { components = new System.ComponentModel.Container(); System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(StartupManagerWindow)); panel2 = new System.Windows.Forms.Panel(); panel5 = new System.Windows.Forms.Panel(); comboBoxFilter = new System.Windows.Forms.ComboBox(); panel4 = new System.Windows.Forms.Panel(); panel3 = new System.Windows.Forms.Panel(); buttonRefresh = new System.Windows.Forms.Button(); panel1 = new System.Windows.Forms.Panel(); buttonCancel = new System.Windows.Forms.Button(); buttonExport = new System.Windows.Forms.Button(); groupBox1 = new System.Windows.Forms.GroupBox(); listView1 = new ObjectListView(); columnHeader1 = new OLVColumn(); columnHeader5 = new OLVColumn(); columnHeader2 = new OLVColumn(); columnHeader3 = new OLVColumn(); columnHeader4 = new OLVColumn(); contextMenuStrip = new System.Windows.Forms.ContextMenuStrip(components); openFileLocationToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); openLinkLocationToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); runCommandToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); copyToClipboardToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); createBackupToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); moveToRegistryToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); runForAllUsersToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator(); enableToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); deleteToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); exportDialog = new System.Windows.Forms.SaveFileDialog(); folderBrowserDialog = new System.Windows.Forms.FolderBrowserDialog(); panel2.SuspendLayout(); panel5.SuspendLayout(); groupBox1.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)listView1).BeginInit(); contextMenuStrip.SuspendLayout(); SuspendLayout(); // // panel2 // panel2.Controls.Add(panel5); panel2.Controls.Add(panel4); panel2.Controls.Add(panel3); panel2.Controls.Add(buttonRefresh); panel2.Controls.Add(panel1); panel2.Controls.Add(buttonCancel); panel2.Controls.Add(buttonExport); resources.ApplyResources(panel2, "panel2"); panel2.Name = "panel2"; // // panel5 // panel5.Controls.Add(comboBoxFilter); resources.ApplyResources(panel5, "panel5"); panel5.Name = "panel5"; // // comboBoxFilter // resources.ApplyResources(comboBoxFilter, "comboBoxFilter"); comboBoxFilter.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; comboBoxFilter.FormattingEnabled = true; comboBoxFilter.Items.AddRange(new object[] { resources.GetString("comboBoxFilter.Items"), resources.GetString("comboBoxFilter.Items1"), resources.GetString("comboBoxFilter.Items2"), resources.GetString("comboBoxFilter.Items3"), resources.GetString("comboBoxFilter.Items4") }); comboBoxFilter.Name = "comboBoxFilter"; comboBoxFilter.SelectedIndexChanged += comboBoxFilter_SelectedIndexChanged; // // panel4 // resources.ApplyResources(panel4, "panel4"); panel4.Name = "panel4"; // // panel3 // resources.ApplyResources(panel3, "panel3"); panel3.Name = "panel3"; // // buttonRefresh // resources.ApplyResources(buttonRefresh, "buttonRefresh"); buttonRefresh.Name = "buttonRefresh"; buttonRefresh.UseVisualStyleBackColor = true; buttonRefresh.Click += buttonRefresh_Click; // // panel1 // resources.ApplyResources(panel1, "panel1"); panel1.Name = "panel1"; // // buttonCancel // resources.ApplyResources(buttonCancel, "buttonCancel"); buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; buttonCancel.Name = "buttonCancel"; buttonCancel.UseVisualStyleBackColor = true; buttonCancel.Click += buttonCancel_Click; // // buttonExport // resources.ApplyResources(buttonExport, "buttonExport"); buttonExport.Name = "buttonExport"; buttonExport.UseVisualStyleBackColor = true; buttonExport.Click += buttonExport_Click; // // groupBox1 // groupBox1.Controls.Add(listView1); resources.ApplyResources(groupBox1, "groupBox1"); groupBox1.Name = "groupBox1"; groupBox1.TabStop = false; // // listView1 // listView1.AutoArrange = false; listView1.CellEditUseWholeCell = false; listView1.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { columnHeader1, columnHeader5, columnHeader2, columnHeader3, columnHeader4 }); listView1.ContextMenuStrip = contextMenuStrip; resources.ApplyResources(listView1, "listView1"); listView1.FullRowSelect = true; listView1.GridLines = true; listView1.Name = "listView1"; listView1.ShowGroups = false; listView1.ShowItemToolTips = true; listView1.Sorting = System.Windows.Forms.SortOrder.Ascending; listView1.UseCompatibleStateImageBehavior = false; listView1.View = System.Windows.Forms.View.Details; listView1.SelectedIndexChanged += SelectionChanged; listView1.MouseClick += listView1_MouseClick; listView1.MouseDoubleClick += listView1_MouseDoubleClick; // // columnHeader1 // columnHeader1.AspectName = "ProgramName"; resources.ApplyResources(columnHeader1, "columnHeader1"); // // columnHeader5 // columnHeader5.AspectName = "Disabled"; resources.ApplyResources(columnHeader5, "columnHeader5"); // // columnHeader2 // columnHeader2.AspectName = "Company"; resources.ApplyResources(columnHeader2, "columnHeader2"); // // columnHeader3 // columnHeader3.AspectName = "ParentShortName"; resources.ApplyResources(columnHeader3, "columnHeader3"); // // columnHeader4 // columnHeader4.AspectName = "Command"; resources.ApplyResources(columnHeader4, "columnHeader4"); // // contextMenuStrip // contextMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { openFileLocationToolStripMenuItem, openLinkLocationToolStripMenuItem, runCommandToolStripMenuItem, toolStripSeparator2, copyToClipboardToolStripMenuItem, createBackupToolStripMenuItem, toolStripSeparator1, moveToRegistryToolStripMenuItem, runForAllUsersToolStripMenuItem, toolStripSeparator3, enableToolStripMenuItem, deleteToolStripMenuItem }); contextMenuStrip.Name = "contextMenuStrip1"; resources.ApplyResources(contextMenuStrip, "contextMenuStrip"); contextMenuStrip.Opening += contextMenuStrip1_Opening; // // openFileLocationToolStripMenuItem // resources.ApplyResources(openFileLocationToolStripMenuItem, "openFileLocationToolStripMenuItem"); openFileLocationToolStripMenuItem.Image = Properties.Resources.folder_open; openFileLocationToolStripMenuItem.Name = "openFileLocationToolStripMenuItem"; openFileLocationToolStripMenuItem.Click += openFileLocationToolStripMenuItem_Click; // // openLinkLocationToolStripMenuItem // openLinkLocationToolStripMenuItem.Image = Properties.Resources.link; openLinkLocationToolStripMenuItem.Name = "openLinkLocationToolStripMenuItem"; resources.ApplyResources(openLinkLocationToolStripMenuItem, "openLinkLocationToolStripMenuItem"); openLinkLocationToolStripMenuItem.Click += openLinkLocationToolStripMenuItem_Click; // // runCommandToolStripMenuItem // runCommandToolStripMenuItem.Image = Properties.Resources.app; runCommandToolStripMenuItem.Name = "runCommandToolStripMenuItem"; resources.ApplyResources(runCommandToolStripMenuItem, "runCommandToolStripMenuItem"); runCommandToolStripMenuItem.Click += runCommandToolStripMenuItem_Click; // // toolStripSeparator2 // toolStripSeparator2.Name = "toolStripSeparator2"; resources.ApplyResources(toolStripSeparator2, "toolStripSeparator2"); // // copyToClipboardToolStripMenuItem // copyToClipboardToolStripMenuItem.Image = Properties.Resources.page_copy; copyToClipboardToolStripMenuItem.Name = "copyToClipboardToolStripMenuItem"; resources.ApplyResources(copyToClipboardToolStripMenuItem, "copyToClipboardToolStripMenuItem"); copyToClipboardToolStripMenuItem.Click += copyToClipboardToolStripMenuItem_Click; // // createBackupToolStripMenuItem // createBackupToolStripMenuItem.Image = Properties.Resources.page_duplicate; createBackupToolStripMenuItem.Name = "createBackupToolStripMenuItem"; resources.ApplyResources(createBackupToolStripMenuItem, "createBackupToolStripMenuItem"); createBackupToolStripMenuItem.Click += createBackupToolStripMenuItem_Click; // // toolStripSeparator1 // toolStripSeparator1.Name = "toolStripSeparator1"; resources.ApplyResources(toolStripSeparator1, "toolStripSeparator1"); // // moveToRegistryToolStripMenuItem // moveToRegistryToolStripMenuItem.Image = Properties.Resources.arrow_right; moveToRegistryToolStripMenuItem.Name = "moveToRegistryToolStripMenuItem"; resources.ApplyResources(moveToRegistryToolStripMenuItem, "moveToRegistryToolStripMenuItem"); moveToRegistryToolStripMenuItem.Click += moveToRegistryToolStripMenuItem_Click; // // runForAllUsersToolStripMenuItem // runForAllUsersToolStripMenuItem.Checked = true; runForAllUsersToolStripMenuItem.CheckState = System.Windows.Forms.CheckState.Checked; runForAllUsersToolStripMenuItem.Name = "runForAllUsersToolStripMenuItem"; resources.ApplyResources(runForAllUsersToolStripMenuItem, "runForAllUsersToolStripMenuItem"); runForAllUsersToolStripMenuItem.Click += runForAllUsersToolStripMenuItem_Click; // // toolStripSeparator3 // toolStripSeparator3.Name = "toolStripSeparator3"; resources.ApplyResources(toolStripSeparator3, "toolStripSeparator3"); // // enableToolStripMenuItem // enableToolStripMenuItem.Checked = true; enableToolStripMenuItem.CheckState = System.Windows.Forms.CheckState.Checked; enableToolStripMenuItem.Name = "enableToolStripMenuItem"; resources.ApplyResources(enableToolStripMenuItem, "enableToolStripMenuItem"); enableToolStripMenuItem.Click += enableToolStripMenuItem_Click; // // deleteToolStripMenuItem // deleteToolStripMenuItem.Image = Properties.Resources.delete; deleteToolStripMenuItem.Name = "deleteToolStripMenuItem"; resources.ApplyResources(deleteToolStripMenuItem, "deleteToolStripMenuItem"); deleteToolStripMenuItem.Click += deleteToolStripMenuItem_Click; // // exportDialog // exportDialog.DefaultExt = "txt"; resources.ApplyResources(exportDialog, "exportDialog"); exportDialog.FileOk += saveFileDialog1_FileOk; // // folderBrowserDialog // resources.ApplyResources(folderBrowserDialog, "folderBrowserDialog"); // // StartupManagerWindow // AcceptButton = buttonCancel; resources.ApplyResources(this, "$this"); AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; CancelButton = buttonCancel; Controls.Add(groupBox1); Controls.Add(panel2); Name = "StartupManagerWindow"; SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; Shown += StartupManagerWindow_Shown; panel2.ResumeLayout(false); panel2.PerformLayout(); panel5.ResumeLayout(false); groupBox1.ResumeLayout(false); ((System.ComponentModel.ISupportInitialize)listView1).EndInit(); contextMenuStrip.ResumeLayout(false); ResumeLayout(false); } #endregion private System.Windows.Forms.Panel panel2; private System.Windows.Forms.Button buttonExport; private System.Windows.Forms.Button buttonCancel; private System.Windows.Forms.GroupBox groupBox1; private ObjectListView listView1; private OLVColumn columnHeader1; private OLVColumn columnHeader2; private OLVColumn columnHeader3; private OLVColumn columnHeader4; private System.Windows.Forms.ContextMenuStrip contextMenuStrip; private System.Windows.Forms.ToolStripMenuItem deleteToolStripMenuItem; private System.Windows.Forms.ToolStripSeparator toolStripSeparator2; private System.Windows.Forms.ToolStripMenuItem copyToClipboardToolStripMenuItem; private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; private System.Windows.Forms.ToolStripMenuItem openLinkLocationToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem openFileLocationToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem runCommandToolStripMenuItem; private System.Windows.Forms.Button buttonRefresh; private System.Windows.Forms.SaveFileDialog exportDialog; private OLVColumn columnHeader5; private System.Windows.Forms.ToolStripMenuItem enableToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem createBackupToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem moveToRegistryToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem runForAllUsersToolStripMenuItem; private System.Windows.Forms.ToolStripSeparator toolStripSeparator3; private System.Windows.Forms.FolderBrowserDialog folderBrowserDialog; private System.Windows.Forms.ComboBox comboBoxFilter; private System.Windows.Forms.Panel panel4; private System.Windows.Forms.Panel panel3; private System.Windows.Forms.Panel panel1; private System.Windows.Forms.Panel panel5; } } ================================================ FILE: source/UninstallTools/Dialogs/StartupManagerWindow.ar.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 اظهار كل شيء اظهار ادخالات بدء التشغيل اظهار المهام اظهار ملحقات المستعرض اظهار الخدمات تحديث اغلاق تصدير... اسم البرنامج تمكين ناشر موقع امر &فتح الموقع القابل للتنفيذ فتح موقع الارتباط &تشغيل الامر &نسخ الى الحافظة انشاء &نسخ احتياطي... الانتقال الى التسجيل تشغيل لكافة المستخدمين &ممكن &حذف قائمه بالاوامر التي يمكن تنفيذها تلقائيا دون تدخل المستخدم Text files|*.txt تصدير ادخالات بدء التشغيل... حدد دليل فارغ للنسخ الاحتياطي. مدير بدء التشغيل ================================================ FILE: source/UninstallTools/Dialogs/StartupManagerWindow.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.IO; using System.Linq; using System.Windows.Forms; using Klocman.Extensions; using Klocman.Forms; using Klocman.Forms.Tools; using Klocman.Tools; using UninstallTools.Properties; using UninstallTools.Startup; using UninstallTools.Startup.Browser; using UninstallTools.Startup.Normal; using UninstallTools.Startup.Service; using UninstallTools.Startup.Task; namespace UninstallTools.Dialogs { public partial class StartupManagerWindow : Form { private StartupManagerWindow() { InitializeComponent(); comboBoxFilter.SelectedIndex = 0; columnHeader5.AspectToStringConverter = x => (!(bool)x).ToYesNo(); listView1.FormatRow += (sender, args) => { if (args.Model is StartupEntryBase seb) args.Item.ForeColor = seb.Disabled ? SystemColors.GrayText : SystemColors.ControlText; }; } private List AllItems { get; set; } private IEnumerable Selection => listView1.SelectedObjects.Cast(); /// /// Show startup manager dialog. Returns latest startup entry list. /// /// Parent form public static IEnumerable ShowManagerDialog(Form owner) { using (var window = new StartupManagerWindow()) { if (owner != null) { window.StartPosition = FormStartPosition.CenterParent; window.Icon = owner.Icon; } window.ShowDialog(owner); return window.AllItems; } } public static StartupManagerWindow ShowManagerWindow() { var window = new StartupManagerWindow(); try { window.Icon = ProcessTools.GetIconFromEntryExe(); } catch (Exception e) { Trace.WriteLine(e); } return window; } private void buttonExport_Click(object sender, EventArgs e) { exportDialog.ShowDialog(); } private void buttonRefresh_Click(object sender, EventArgs e) { ReloadItems(sender, e); } private void contextMenuStrip1_Opening(object sender, CancelEventArgs e) { e.Cancel = true; moveToRegistryToolStripMenuItem.Enabled = false; CheckState? enableCheckState = null; CheckState? allUserCheckState = null; foreach (var item in Selection) { e.Cancel = false; if (!enableCheckState.HasValue) enableCheckState = item.Disabled ? CheckState.Unchecked : CheckState.Checked; else if (enableCheckState.Value != (item.Disabled ? CheckState.Unchecked : CheckState.Checked)) enableCheckState = CheckState.Indeterminate; if (item is StartupEntry normalStartupEntry) { if (!allUserCheckState.HasValue) allUserCheckState = normalStartupEntry.AllUsers ? CheckState.Checked : CheckState.Unchecked; else if (allUserCheckState.Value != (normalStartupEntry.AllUsers ? CheckState.Checked : CheckState.Unchecked)) allUserCheckState = CheckState.Indeterminate; if (!normalStartupEntry.IsRegKey) moveToRegistryToolStripMenuItem.Enabled = true; } } enableToolStripMenuItem.Enabled = enableCheckState.HasValue; enableToolStripMenuItem.CheckState = enableCheckState ?? CheckState.Unchecked; runForAllUsersToolStripMenuItem.Enabled = allUserCheckState.HasValue; runForAllUsersToolStripMenuItem.CheckState = allUserCheckState ?? CheckState.Unchecked; } private void copyToClipboardToolStripMenuItem_Click(object sender, EventArgs e) { var parts = Selection.Select(x => x.ToLongString()).ToArray(); if (parts.Any()) { try { Clipboard.SetText(string.Join(Environment.NewLine, parts)); } catch (Exception ex) { ShowSecurityOrGenericError(ex, "copying to clipboard"); } } } private void ShowSecurityOrGenericError(Exception ex, string context, string extraInfo = null) { if (ex is System.Security.SecurityException || ex is UnauthorizedAccessException) { PremadeDialogs.GenericError( $"Access denied while {context}." + (string.IsNullOrWhiteSpace(extraInfo) ? "" : $" {extraInfo}") + $"\nError: {ex.Message}\n\n" + "You may not have sufficient permissions to perform this operation. Here are some possible causes:\n" + "1.\tService/File Permissions: The user (even admin) may lack permissions on the specific item. Security descriptors can restrict who can modify or delete a service/file.\n" + "2.\tWMI Namespace Permissions: The user may lack permissions on the root\\CIMV2 namespace.\n" + "3.\tService/File in Use: Some system services cannot be deleted or modified, even by administrators.\n" + "4.\tAnti-malware/AV: Security software may block service modifications."); } else { PremadeDialogs.GenericError(ex); } } private void DeleteSelected() { if (CustomMessageBox.ShowDialog(this, new CmbBasicSettings( Localisation.StartupManager_Message_Delete_Title, Localisation.StartupManager_Message_Delete_Header, Localisation.StartupManager_Message_Delete_Details, SystemIcons.Question, Buttons.ButtonRemove, Buttons.ButtonCancel)) == CustomMessageBox.PressedButton.Middle) { try { foreach (var item in Selection) { try { item.Delete(); } catch (Exception ex) { ShowSecurityOrGenericError(ex, "deleting service", $"Service name: {item.ProgramName}"); } } } catch (Exception ex) { ShowSecurityOrGenericError(ex, "deleting service"); } } } private void deleteToolStripMenuItem_Click(object sender, EventArgs e) { DeleteSelected(); ReloadItems(sender, e); } private void listView1_MouseClick(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Right) { if (listView1.SelectedItems.Count > 0 && listView1.FocusedItem.Bounds.Contains(e.Location)) { contextMenuStrip.Show(Cursor.Position); } } } private void listView1_MouseDoubleClick(object sender, MouseEventArgs e) { if (listView1.SelectedItems.Count > 0 && listView1.FocusedItem.Bounds.Contains(e.Location)) { openFileLocationToolStripMenuItem_Click(sender, e); } } private void openFileLocationToolStripMenuItem_Click(object sender, EventArgs e) { foreach (var item in Selection) { try { if (item.CommandFilePath == null) throw new IOException(Localisation.Error_InvalidPath + "\n" + item.Command); WindowsTools.OpenExplorerFocusedOnObject(item.CommandFilePath); } catch (Exception ex) { ShowSecurityOrGenericError(ex, "opening file location", $"Path: {item.CommandFilePath}"); } } } private void openLinkLocationToolStripMenuItem_Click(object sender, EventArgs e) { try { StartupManager.OpenStartupEntryLocations(Selection); } catch (Exception ex) { ShowSecurityOrGenericError(ex, "opening link location"); } } private void ReloadItems(object sender, EventArgs e) { Cursor = Cursors.WaitCursor; if (listView1.Items.Count < 1) { listView1.EmptyListMsg = Localisation.StartupManager_Loading; listView1.Update(); } SelectionChanged(sender, e); listView1.BeginUpdate(); AllItems = StartupManager.GetAllStartupItems().ToList(); // Get icons if (listView1.SmallImageList == null) listView1.SmallImageList = new ImageList(); listView1.SmallImageList.Images.Clear(); listView1.SmallImageList.Images.Add(SystemIcons.Warning); foreach (var entry in AllItems) { if (entry.CommandFilePath != null && !listView1.SmallImageList.Images.ContainsKey(entry.ProgramName)) { var icon = UninstallToolsGlobalConfig.TryExtractAssociatedIcon(entry.CommandFilePath); if (icon != null) listView1.SmallImageList.Images.Add(entry.ProgramName, icon); } } UpdateList(false); listView1.EndUpdate(); Cursor = Cursors.Default; listView1.EmptyListMsg = null; } private void UpdateList(bool pauseLvUpdates = true) { if (pauseLvUpdates) { Cursor = Cursors.WaitCursor; listView1.BeginUpdate(); } listView1.ClearObjects(); listView1.Sort(columnHeader1, SortOrder.Ascending); var query = from item in AllItems where comboBoxFilter.SelectedIndex == 0 || comboBoxFilter.SelectedIndex == 1 && item is StartupEntry || comboBoxFilter.SelectedIndex == 2 && item is TaskEntry || comboBoxFilter.SelectedIndex == 3 && item is BrowserHelperEntry || comboBoxFilter.SelectedIndex == 4 && item is ServiceEntry orderby item.ProgramName ascending select item; // Populate list items listView1.SetObjects(query); if (pauseLvUpdates) { listView1.EndUpdate(); Cursor = Cursors.Default; } } private void runCommandToolStripMenuItem_Click(object sender, EventArgs e) { foreach (var command in Selection) { if (!PremadeDialogs.StartProcessSafely(command.Command)) break; } } private void saveFileDialog1_FileOk(object sender, CancelEventArgs e) { var parts = Selection.Select(x => x.ToLongString()).ToArray(); if (parts.Any()) { try { File.WriteAllText(exportDialog.FileName, string.Join(Environment.NewLine, parts)); } catch (Exception ex) { ShowSecurityOrGenericError(ex, "saving file", $"File: {exportDialog.FileName}"); e.Cancel = true; } } } private void SelectionChanged(object sender, EventArgs e) { var sel = listView1.SelectedItems.Count > 0; buttonExport.Enabled = sel; } private void StartupManagerWindow_Shown(object sender, EventArgs e) { Refresh(); ReloadItems(sender, e); } private void enableToolStripMenuItem_Click(object sender, EventArgs e) { enableToolStripMenuItem.CheckState = enableToolStripMenuItem.CheckState == CheckState.Unchecked ? CheckState.Checked : CheckState.Unchecked; foreach (var item in Selection) { try { item.Disabled = enableToolStripMenuItem.CheckState == CheckState.Unchecked; } catch (Exception ex) { ShowSecurityOrGenericError(ex, "enabling/disabling entry", $"Entry: {item.ProgramName}"); } } UpdateList(); } private void runForAllUsersToolStripMenuItem_Click(object sender, EventArgs e) { runForAllUsersToolStripMenuItem.CheckState = runForAllUsersToolStripMenuItem.CheckState == CheckState.Unchecked ? CheckState.Checked : CheckState.Unchecked; foreach (var item in Selection.OfType()) { try { item.AllUsers = runForAllUsersToolStripMenuItem.CheckState == CheckState.Checked; } catch (Exception ex) { ShowSecurityOrGenericError(ex, "setting run for all users", $"Entry: {item.ProgramName}"); } } UpdateList(); } private void moveToRegistryToolStripMenuItem_Click(object sender, EventArgs e) { foreach (var item in Selection.OfType()) { try { StartupEntryManager.MoveToRegistry(item); } catch (Exception ex) { ShowSecurityOrGenericError(ex, "moving to registry", $"Entry: {item.ProgramName}"); } } UpdateList(); } private void createBackupToolStripMenuItem_Click(object sender, EventArgs e) { folderBrowserDialog.ShowDialog(this); if (!Directory.Exists(folderBrowserDialog.SelectedPath)) return; foreach (var item in Selection) { try { item.CreateBackup(folderBrowserDialog.SelectedPath); } catch (Exception ex) { ShowSecurityOrGenericError(ex, "creating backup", $"Entry: {item.ProgramName}"); } } try { Process.Start(new ProcessStartInfo(folderBrowserDialog.SelectedPath) { UseShellExecute = true }); } catch (Exception ex) { ShowSecurityOrGenericError(ex, "opening backup folder", $"Path: {folderBrowserDialog.SelectedPath}"); } UpdateList(); } private void comboBoxFilter_SelectedIndexChanged(object sender, EventArgs e) { if (AllItems != null) UpdateList(); } private void buttonCancel_Click(object sender, EventArgs e) { DialogResult = DialogResult.OK; Close(); } } } ================================================ FILE: source/UninstallTools/Dialogs/StartupManagerWindow.cs.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Zobrazit vše Zobrazit položky po spustění Zobrazit úlohy Zobrazit rozšíření prohlížeče Obnovit Zavřit Název programu Povolen Vydavatel Umístění Příkaz &Otevřete umístění aplikace Otevřená umístění odkazu &Spustit příkaz &Zkopírovat do schránky Vytvořit & zálohu ... Přesnuout do registrů Pro všechny uživatele &Vybrán &Odstranit Příkazy spuštěné při startu systému nebo přihlášení Textové soubory|*.txt Export položek po spuštění... Vyberte prázdný adresář pro zálohování. Manager po spuštění Export... Zobrazit služby ================================================ FILE: source/UninstallTools/Dialogs/StartupManagerWindow.de.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Alles anzeigen Autostart-Einträge anzeigen Aufgaben anzeigen Browser-Erweiterungen anzeigen Aktualisieren Schließen Programmname Aktiviert Herausgeber Speicherort Befehl EXE-Speicherort ö&ffnen Link-Speicherort öffnen &Befehl ausführen In Zwischenablage &kopieren &Backup erstellen... In die Registry verschieben Für alle Benutzer ausführen &Aktiviert &Löschen Befehle, die während des Systemstarts oder der Anmeldung ausgeführt werden Textdateien|*.txt Autostart-Einträge exportieren... Wählen Sie ein leeres Verzeichnis für die Sicherung. Autostart Manager Export... Dienstleistungen anzeigen ================================================ FILE: source/UninstallTools/Dialogs/StartupManagerWindow.es.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Mostrar todo Mostrar entradas de inicio Mostrar tareas Mostrar extensiones del navegador Refrescar Cerrar Exportar... Nombre del programa Habilitado Editor Ubicación Comando &Abrir ubicación del ejecutable Abrir ubicación del enlace &Ejecutar comando &Copiar al portapapeles Crear &copia de seguridad... Mover al registro... Ejecutar para todos los usuarios &Habilitado &Eliminar Lista de comandos que se pueden ejecutar automáticamente sin intervención del usuario Archivos de texto|*.txt Exportar entradas de inicio... Seleccione un directorio vacío para la copia de seguridad. Administrador de inicio Mostrar servicios ================================================ FILE: source/UninstallTools/Dialogs/StartupManagerWindow.fr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Afficher tout Afficher les entrées de démarrage Afficher les tâches Afficher les extensions de navigateur Rafraîchir 更新 Fermer Exporter... Liste de commandes pouvant s'exécuter automatiquement sans intervention uyilisateur Nom du programme Activé Éditeur Emplacement Commande &Ouvrir l'emplacement de l'exécutable Ouvrir l'emplacement du lien Lance&r la commande &Copier dans le presse-papiers Créer une &sauvegarde... Déplacer vers le registre Lancer pour tous utilisateurs &Activé &Supprimer Fichiers texte|*.txt Exporter les entrées de démarrage... Sélectionner un dossier vide pour la sauvegarde. Gestionnaire de Démarrage Afficher les services ================================================ FILE: source/UninstallTools/Dialogs/StartupManagerWindow.hu.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Minden tartalom mutatása Indítópult bejegyzések mutatása Feladatok mutatása Böngésző kiterjesztések mutatása Show szolgáltatások Frissítés Bezárás Exportálás... Program neve Engedélyezve Kiadó Hely Parancs F&uttatható helyének megnyitása Hivatkozás helyének megnyitása &Parancs futtatása Másolás a &Vágólapra Me&ntés létrehozása... Áthelyezés a registry-be Futtatás az összes felhasználó részére &Engedélyezve &Törlés Felhasználói beavatkozás nélkül automatikusan végrehajtható parancsok listája Szövegfájlok|*.txt Indítópult bejegyzések exportálása... Válasszon ki egy üres könyvtárat a mentéshez. Indítópult kezelő ================================================ FILE: source/UninstallTools/Dialogs/StartupManagerWindow.it.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Mostra tutto Mostra le voci di avvio Mostra le attività Mostra le estensioni del browser Mostra i servizi Aggiorna Chiudi Esporta... Nome del programma Abilita Editore Posizione Comando &Apri posizione dell'eseguibile Apri posizione del link &Esegui comando &Copia nella clipboard Crea &backup Sposta nel registro Esegui per tutti gli utenti &Abilita &Cancella Lista di comandi che possono essere eseguiti automaticamente senza l'intervento dell'utente File di testo|*.txt Esporta voci dell'avvio Seleziona una cartella vuota per il backup. Gestore dell'avvio ================================================ FILE: source/UninstallTools/Dialogs/StartupManagerWindow.ja.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 すべてを表示 スタートアップエントリーを表示 タスクの表示 ブラウザ拡張機能を表示 サービスを表示 閉じる エクスポート... プログラム名 有効 発行者 位置 コマンド &実行可能ファイルの場所を開く リンクの場所を開く &コマンドを実行 &クリップボードにコピー &バックアップを作成... レジストリに移動 すべてのユーザーのために実行 &有効 &削除 ユーザーの介入なしに自動的に実行できるコマンドのリスト テキストファイル|*.txt スタートアップエントリをエクスポート... バックアップ用の空のディレクトリを選択してください。 スタートアップマネージャー 更新 更新 ================================================ FILE: source/UninstallTools/Dialogs/StartupManagerWindow.nl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Alles weergeven Autostart registraties weergeven Taken weergeven Browser extensies wergeven Services weergeven Verversen Sluiten Exporteren Programma naam Ingeschakeld Uitgever Opslag locatie Opdracht EXE-opslag locatie openen Link opslag locatie openen &Opdracht uitvoeren &Kopieer naar klembord &Back-up van register maken... Verplaatsen naar het register Voor alle gebruikers uitvoeren &Ingeschakeld &Verwijderen Opdrachten die automatisch kunnen worden uitgevoerd, zonder gebruikersinterventie Tekst bestanden|*.txt Opstart registraties exporteren... Selecteer een lege map voor de back-up Opstartmanager starten ================================================ FILE: source/UninstallTools/Dialogs/StartupManagerWindow.pl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Pokaż wszystko Pokaż wpisy startowe Pokaż zadania Pokaż rozszerzenia przeglądarek Odśwież Zamknij Eksportuj... Nazwa programu Włączony Wydawca Lokalizacja Komenda &Otwórz lokalizację aplikacji Otwórz lokalizację łącza &Uruchom komendę &Kopiuj do schowka Utwórz kopię zapasową... Przenieś do rejestru &Wszyscy użytkownicy &Włączony &Usuń Aplikacje uruchamiane podczas startu systemu lub logowania Pliki tekstowe|*.txt Eksportuj wpisy startowe... Wybierz pusty folder na pliki kopii zapasowej. Menedżer Autostartu Pokaż usługi ================================================ FILE: source/UninstallTools/Dialogs/StartupManagerWindow.pt-BR.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Mostrar tudo Mostrar entradas de inicialização Mostrar tarefas Mostrar extensões de navegador Mostrar serviços Atualizar 更新 Fechar Exportar... Nome do programa Ativado Editor Local Comando &Abrir local do executável Abrir a local do link &Executar o comando &Copiar para a área de transferência Criar &cópia de segurança... Mover para o registro Executar para todos os usuários &Ativado E&xcluir Lista de comandos que podem ser executados automaticamente sem a intervenção do usuário Arquivos texto|*.txt Exportar as entradas de inicialização... Selecione um diretório vazio para o backup. Gerenciador de Inicialização ================================================ FILE: source/UninstallTools/Dialogs/StartupManagerWindow.pt.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Mostrar tudo Mostrar as entradas de inicialização Mostrar as tarefas Mostrar as extensões do navegador Refrescar Fechar Exportar... Nome do programa Activado Editor Localização Comando &Abrir a localização do executável Abrir a localização do link &Executar o comando &Copiar para a área de transferência Criar &cópia de segurança... Mover para o registo Executar para todos os utilizadores &Activado &Suprimido Lista de comandos que podem ser executados sem a intervgenção do utilizador Ficheiros texto|*.txt Exportar as entradas de inicialização... Seleccionar uma pasta vazia para a cópia de segurança Gestor de inicialização Mostrar serviços 12, 17 157, 17 279, 17 True ================================================ FILE: source/UninstallTools/Dialogs/StartupManagerWindow.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Fill Show everything Show startup entries Show tasks Show browser extensions Show services 0, 1 4, 3, 4, 3 576, 23 4 comboBoxFilter System.Windows.Forms.ComboBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel5 0 Fill 178, 6 4, 3, 4, 3 0, 1, 0, 0 576, 27 8 panel5 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel2 0 Right 754, 6 4, 3, 4, 3 7, 27 7, 27 7, 27 7 panel4 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel2 1 Left 171, 6 4, 3, 4, 3 7, 27 7, 27 7, 27 6 panel3 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel2 2 True GrowAndShrink Left NoControl 91, 6 4, 3, 4, 3 2590, 27 0, 27 12, 0, 12, 0 80, 27 1 Refresh buttonRefresh System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel2 3 Left 84, 6 4, 3, 4, 3 7, 27 7, 27 7, 27 5 panel1 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel2 4 True GrowAndShrink Right NoControl 761, 6 4, 3, 4, 3 2590, 27 0, 27 12, 0, 12, 0 70, 27 3 Close buttonCancel System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel2 5 True GrowAndShrink Left NoControl 0, 6 4, 3, 4, 3 2590, 27 0, 27 12, 0, 12, 0 84, 27 0 Export... buttonExport System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 panel2 6 Bottom 7, 539 4, 3, 4, 3 0, 6, 0, 0 831, 33 1 panel2 System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 2 Program name 176 Enabled 58 Publisher 102 Location 112 Command 213 12, 17 Tahoma, 8.25pt, style=Bold 217, 22 &Open executable location 217, 22 Open link location 217, 22 &Run command 214, 6 217, 22 &Copy to clipboard 217, 22 Create &backup... 214, 6 217, 22 Move to registry 217, 22 Run for all users 214, 6 217, 22 &Enabled 217, 22 &Delete 218, 220 contextMenuStrip System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 Fill 7, 23 4, 3, 4, 3 817, 502 0 listView1 BrightIdeasSoftware.ObjectListView, ObjectListView, Culture=neutral, PublicKeyToken=null groupBox1 0 Fill 7, 7 4, 3, 4, 3 7, 7, 7, 7 831, 532 0 List of commands that can be executed automatically without user intervention groupBox1 System.Windows.Forms.GroupBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 $this 1 157, 17 Text files|*.txt Export startup entries... 279, 17 Select an empty directory for the backup. True 7, 15 845, 579 4, 3, 4, 3 429, 190 7, 7, 7, 7 Startup Manager columnHeader1 BrightIdeasSoftware.OLVColumn, ObjectListView, Culture=neutral, PublicKeyToken=null columnHeader5 BrightIdeasSoftware.OLVColumn, ObjectListView, Culture=neutral, PublicKeyToken=null columnHeader2 BrightIdeasSoftware.OLVColumn, ObjectListView, Culture=neutral, PublicKeyToken=null columnHeader3 BrightIdeasSoftware.OLVColumn, ObjectListView, Culture=neutral, PublicKeyToken=null columnHeader4 BrightIdeasSoftware.OLVColumn, ObjectListView, Culture=neutral, PublicKeyToken=null openFileLocationToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 openLinkLocationToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 runCommandToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripSeparator2 System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 copyToClipboardToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 createBackupToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripSeparator1 System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 moveToRegistryToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 runForAllUsersToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 toolStripSeparator3 System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 enableToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 deleteToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 exportDialog System.Windows.Forms.SaveFileDialog, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 folderBrowserDialog System.Windows.Forms.FolderBrowserDialog, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 StartupManagerWindow System.Windows.Forms.Form, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089 ================================================ FILE: source/UninstallTools/Dialogs/StartupManagerWindow.ru.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Показать все Показать записи автозагрузки Показать задачи Показать расширения браузера Обновить Закрыть Экспорт... Имя программы Включено Издатель Расположение Команда &Открыть расположение Открыть папку ссылки &Выполнить команду &Копировать в буфер Создать &бэкап... Перейти в реестр Запуск для всех пользователей &Включено &Удалить Список автозагружаемых программ при запуске ОС или входе в систему Текстровые файлы|*.txt Экспорт записей автозагрузки... Выберите пустой каталог для резервного копирования. Менеджер автозагрузки Показать службы 12, 17 157, 17 279, 17 True ================================================ FILE: source/UninstallTools/Dialogs/StartupManagerWindow.sl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Prikaži vse Prikaži zagonske vnose Prikaži opravila Prikaži razširitve brskalnika Osveži Zapri Izvozi... Ime programa Omogočen Založnik Mesto Ukaz &Odpri mesto izvršljive Odpri mesto povezave Zaženi &ukaz &Kopiraj v odložišče Naredi &varnostno kopijo... Premakni v register Zaženi za vse uporabnike &Omogočen &Izbriši Seznam ukazov, ki jih je mogoče samodejno izvesti brez uporabnikovega posega Besedilne datoteke|*.txt Izvozi zagonske vnose... Izberite prazen imenik za varnostno kopijo. Upravitelj zagona Prikaži storitve 12, 17 157, 17 279, 17 True ================================================ FILE: source/UninstallTools/Dialogs/StartupManagerWindow.sv.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Visa allt Visa startposter Visa uppgifter Visa webbläsartillägg Visa tjänster Uppdatera Stäng Exportera... Programnamn Aktiverad Utgivare Plats Kommando &Öppna den körbara filens plats Öppna länkplatsen &Kör kommando &Kopiera till urklipp Skapa &säkerhetskopia... Flytta till register Kör för alla användare &Aktiverad &Radera Lista över kommandon som kan utföras automatiskt utan användarens inblandning Text filer|*.txt Exportera startposter… Välj en tom mapp för säkerhetskopian. Uppstartshanterare ================================================ FILE: source/UninstallTools/Dialogs/StartupManagerWindow.tr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Her şeyi göster Başlangıç girişlerini göster Görevleri göster Tarayıcı eklentilerini göster Servisleri göster Yenile Kapat Dışarıya aktar... Program adı Etkin Yayıncı Yer Komut &Çalıştırılabilir konumu aç Bağlantı konumunu aç &Çalıştır komutu &Panoya kopyala Oluştur ve &yedekle ... Kayıt defterine taşı Tüm kullanıcılar için çalıştır &Etkin &Sil Kullanıcı müdahalesi olmadan otomatik olarak çalıştırılabilen komutların listesi Metin dosyaları|* .txt Başlangıç girişlerini dışa aktar ... Yedekleme için boş bir dizin seçin. Başlangıç Yöneticisi ================================================ FILE: source/UninstallTools/Dialogs/StartupManagerWindow.vi.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Hiển thị tất cả Hiển thị các mục khởi động cùng hệ thống Hiển thị các tác vụ Hiển thị các các tiện ích mở rộng của trình duyệt Hiển thị các dịch vụ Làm mới Đóng Xuất... Tên chường trình Đã kích hoạt Nhà phát hành Vị trí Câu lệnh &Mở vị trí tệp thực thi Mở liên kết &Thực thi câu lệnh &Sao chép vào bảng nhớ tạm Tạo &bản sao lưu Di chuyển đến registry Chạy cho tất cả người dùng &Kích hoạt &Xoá Danh sách các câu lệnh có thể được thực thi tự động mà không cần sự can thiệp của người dùng Tệp văn bản|*.txt Xuất các mục khởi động cùng hệ thống... Chọn một thư mục trống để sao lưu. Trình quản lý Khởi động cùng hệ thống ================================================ FILE: source/UninstallTools/Dialogs/StartupManagerWindow.zh-Hans.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 显示所有 显示开机启动项 显示任务 显示浏览器扩展 显示服务 刷新 关闭 导出... 程序名称 启用 发布者 未知 命令 打开可执行程序位置 打开链接位置 运行命令 复制到剪贴板 创建备份 移动到注册表 为所有用户运行 启用 删除 无需用户干预即可自动执行的命令列表 文本文件|*.txt 导出开机启动项... 选择空文件夹用于备份。 开机启动项管理器 ================================================ FILE: source/UninstallTools/Dialogs/StartupManagerWindow.zh-Hant.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 顯示所有 顯示開機啟動項目 顯示任務 顯示瀏覽器元件 顯示服務 重整 關閉 匯出... 程式名稱 啟用 發布人員 位置 指令 開啟可執行程式位置 開啟連結位置 執行指令 複製到剪貼簿 建立備份 移動到登錄項目 為所有使用者執行 啟用 刪除 無需使用者干預即可自動執行的指令清單 文字文件|*.txt 匯出開機啟動項目... 選擇空目錄用於備份。 開機啟動項目管理員 ================================================ FILE: source/UninstallTools/Factory/ApplicationEntryTools.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Diagnostics; using System.IO; using Klocman.Extensions; using Klocman.Tools; namespace UninstallTools.Factory { public static class ApplicationEntryTools { /// /// Try to figure out if base uninstaller entry and other entry are pointing to the same application. /// Minimum score changes how similar the applications have to be (best use small values, higher is harder) /// Suggested min score is 1 /// public static bool AreEntriesRelated(ApplicationUninstallerEntry baseEntry, ApplicationUninstallerEntry otherEntry, int minimumScore) { var score = AreEntriesRelated(baseEntry, otherEntry); return score > minimumScore; } /// /// Check how related are the two entries. /// Values above 0 mean there is good confidence /// public static int AreEntriesRelated(ApplicationUninstallerEntry baseEntry, ApplicationUninstallerEntry otherEntry) { if (PathTools.PathsEqual(baseEntry.InstallLocation, otherEntry.InstallLocation)) return 100; if (!string.IsNullOrEmpty(baseEntry.UninstallString)) { if (PathTools.PathsEqual(baseEntry.UninstallString, otherEntry.UninstallString)) return 100; if (otherEntry.IsOrphaned && !string.IsNullOrEmpty(otherEntry.InstallLocation) && baseEntry.UninstallString.Contains(otherEntry.InstallLocation, StringComparison.InvariantCultureIgnoreCase)) return 100; } if (otherEntry.IsOrphaned && !string.IsNullOrEmpty(baseEntry.UninstallerLocation) && !string.IsNullOrEmpty(otherEntry.InstallLocation) && baseEntry.UninstallerLocation.StartsWith(otherEntry.InstallLocation, StringComparison.InvariantCultureIgnoreCase)) return 100; var score = 0; if(!string.IsNullOrEmpty(baseEntry.RatingId) && !string.IsNullOrEmpty(otherEntry.RatingId)) AddScore(ref score, -5, 0, 10, baseEntry.RatingId == otherEntry.RatingId); if (!string.IsNullOrEmpty(baseEntry.InstallLocation) && !string.IsNullOrEmpty(otherEntry.InstallLocation)) AddScore(ref score, -8, 0, -3, baseEntry.InstallLocation.Contains(otherEntry.InstallLocation, StringComparison.InvariantCultureIgnoreCase)); AddScore(ref score, -5, 0, 3, baseEntry.Is64Bit != MachineType.Unknown && otherEntry.Is64Bit != MachineType.Unknown ? baseEntry.Is64Bit == otherEntry.Is64Bit : null); AddScore(ref score, -3, -1, 5, CompareDates(baseEntry.InstallDate, otherEntry.InstallDate)); AddScore(ref score, -2, 0, 5, CompareStrings(baseEntry.DisplayVersion, otherEntry.DisplayVersion, true)); AddScore(ref score, -5, 0, 5, CompareStrings(baseEntry.Publisher, otherEntry.Publisher)); // Check if base entry was installed from inside other entry's install directory if (string.IsNullOrEmpty(baseEntry.InstallLocation) && !string.IsNullOrEmpty(baseEntry.InstallSource) && !string.IsNullOrEmpty(otherEntry.InstallLocation) && otherEntry.InstallLocation.Length >= 5) { AddScore(ref score, 0, 0, 5, baseEntry.InstallSource.Contains( otherEntry.InstallLocation, StringComparison.InvariantCultureIgnoreCase)); } var nameSimilarity = CompareStrings(baseEntry.DisplayName, otherEntry.DisplayName); AddScore(ref score, -5, -2, 8, nameSimilarity); if (!nameSimilarity.HasValue || nameSimilarity == false) { var trimmedSimilarity = CompareStrings(baseEntry.DisplayNameTrimmed, otherEntry.DisplayNameTrimmed); // Don't risk it if names can't be compared at all //if (!trimmedSimilarity.HasValue && !nameSimilarity.HasValue) return false; AddScore(ref score, -5, -2, 8, trimmedSimilarity); } try { AddScore(ref score, -2, -2, 5, CompareStrings(baseEntry.DisplayNameTrimmed.Length < 5 ? baseEntry.DisplayName : baseEntry.DisplayNameTrimmed, Path.GetFileName(otherEntry.InstallLocation))); } catch (Exception ex) { Debug.Fail(ex.Message); } //Debug.Assert(score <= 0); return score; } /// /// Check if dates are very close together, or if they differ by a few hours. /// Result is null if the length of the difference can't be compared confidently. /// private static bool? CompareDates(DateTime a, DateTime b) { if (a.IsDefault() || b.IsDefault()) return null; var totalHours = Math.Abs((a - b).TotalHours); if (totalHours > 40) return null; if (totalHours <= 1) return true; // One of the dates is lacking time part, so can't be compared if (a.TimeOfDay.TotalSeconds < 1 || b.TimeOfDay.TotalSeconds < 1) return null; return totalHours <= 1; } private static bool? CompareStrings(string a, string b, bool relaxMatchRequirement = false) { var lengthRequirement = !relaxMatchRequirement ? 5 : 4; if (a == null || (a.Length < lengthRequirement) || b == null || b.Length < lengthRequirement) return null; if (relaxMatchRequirement) { if (a.StartsWith(b, StringComparison.Ordinal) || b.StartsWith(a, StringComparison.Ordinal)) return true; } var changesRequired = Sift4.SimplestDistance(a, b, 3); return changesRequired == 0 || changesRequired < a.Length / 6; } private static void AddScore(ref int score, int failScore, int unsureScore, int successScore, bool? testResult) { if (!testResult.HasValue) score += unsureScore; else score = testResult.Value ? score + successScore : score + failScore; } /// /// Check if path points to the windows installer program or to a .msi package /// /// /// public static bool PathPointsToMsiExec(string path) { if (string.IsNullOrEmpty(path)) return false; return path.ContainsAny(new[] { "msiexec ", "msiexec.exe" }, StringComparison.OrdinalIgnoreCase) || path.EndsWith(".msi", StringComparison.OrdinalIgnoreCase); } public static string CleanupDisplayVersion(string version) { return version?.Replace(", ", ".").Replace(". ", ".").Replace(",", ".").Replace(". ", ".").Trim(); } public static string ExtractDirectoryName(string uninstallerLocation) { if (!string.IsNullOrEmpty(uninstallerLocation)) { try { return Path.GetDirectoryName(uninstallerLocation); } catch (ArgumentException) { } catch (PathTooLongException) { } } return null; } public static string ExtractFullFilename(string uninstallString) { if (!string.IsNullOrEmpty(uninstallString)) { try { var fileName = ProcessTools.SeparateArgsFromCommand(uninstallString).FileName; Debug.Assert(!string.IsNullOrEmpty(fileName?.Trim()), $@"SeparateArgsFromCommand failed for {fileName}"); return fileName; } catch (ArgumentException) { } catch (FormatException) { } } return null; } } } ================================================ FILE: source/UninstallTools/Factory/ApplicationUninstallerFactory.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading.Tasks; using Klocman.Extensions; using Klocman.Forms.Tools; using Klocman.IO; using Klocman.Tools; using UninstallTools.Factory.InfoAdders; using UninstallTools.Properties; using UninstallTools.Startup; namespace UninstallTools.Factory { public static class ApplicationUninstallerFactory { private static readonly InfoAdderManager InfoAdder = new(); public static IList GetUninstallerEntries(ListGenerationProgress.ListGenerationCallback callback) { const int totalStepCount = 8; var currentStep = 1; var concurrentFactory = new ConcurrentApplicationFactory(GetMiscUninstallerEntries); try { // Find msi products --------------------------------------------------------------------------------------- var msiProgress = new ListGenerationProgress(currentStep++, totalStepCount, Localisation.Progress_MSI); callback(msiProgress); var msiGuidCount = 0; var msiProducts = MsiTools.MsiEnumProducts().DoForEach(x => { msiProgress.Inner = new ListGenerationProgress(0, -1, string.Format(Localisation.Progress_MSI_sub, ++msiGuidCount)); callback(msiProgress); }).ToList(); // Run some factories in a separate thread ----------------------------------------------------------------- concurrentFactory.Start(); // Start populating lookups now before they are needed since they can take a few seconds Task.Run(MsiTools.InitLookups); // Find stuff mentioned in registry ------------------------------------------------------------------------ IList registryResults; if (UninstallToolsGlobalConfig.ScanRegistry) { var regProgress = new ListGenerationProgress(currentStep++, totalStepCount, Localisation.Progress_Registry); callback(regProgress); var sw = Stopwatch.StartNew(); var registryFactory = new RegistryFactory(msiProducts); registryResults = registryFactory.GetUninstallerEntries(report => { regProgress.Inner = report; callback(regProgress); }); Trace.WriteLine($"[Performance] Factory {nameof(RegistryFactory)} took {sw.ElapsedMilliseconds}ms to finish"); // Fill in install llocations for DirectoryFactory to improve speed and quality of results if (UninstallToolsGlobalConfig.UninstallerFactoryCache != null) ApplyCache(registryResults, UninstallToolsGlobalConfig.UninstallerFactoryCache, InfoAdder); var installLocAddProgress = new ListGenerationProgress(currentStep++, totalStepCount, Localisation.Progress_GatherUninstallerInfo); callback(installLocAddProgress); FactoryThreadedHelpers.GenerateMissingInformation(registryResults, InfoAdder, null, true, report => { installLocAddProgress.Inner = report; callback(installLocAddProgress); }); } else { registryResults = new List(); } // Look for entries on drives, based on info in registry. ---------------------------------------------------- // Will introduce duplicates to already detected stuff. Need to check for duplicates with other entries later. IList driveResults; if (UninstallToolsGlobalConfig.ScanDrives) { var driveProgress = new ListGenerationProgress(currentStep++, totalStepCount, Localisation.Progress_DriveScan); callback(driveProgress); var sw = Stopwatch.StartNew(); var driveFactory = new DirectoryFactory(registryResults); driveResults = driveFactory.GetUninstallerEntries(report => { driveProgress.Inner = report; callback(driveProgress); }); Trace.WriteLine($"[Performance] Factory {nameof(DirectoryFactory)} took {sw.ElapsedMilliseconds}ms to finish"); } else { driveResults = new List(); } // Join up with the thread ---------------------------------------------------------------------------------- var miscProgress = new ListGenerationProgress(currentStep++, totalStepCount, Localisation.Progress_AppStores); callback(miscProgress); var otherResults = concurrentFactory.GetResults(callback, miscProgress); // Handle duplicate entries ---------------------------------------------------------------------------------- var mergeProgress = new ListGenerationProgress(currentStep++, totalStepCount, Localisation.Progress_Merging); callback(mergeProgress); var mergedResults = registryResults.ToList(); MergeResults(mergedResults, otherResults, report => { mergeProgress.Inner = report; report.TotalCount *= 2; report.Message = Localisation.Progress_Merging_Stores; callback(mergeProgress); }); // Make sure to merge driveResults last MergeResults(mergedResults, driveResults, report => { mergeProgress.Inner = report; report.CurrentCount += report.TotalCount; report.TotalCount *= 2; report.Message = Localisation.Progress_Merging_Drives; callback(mergeProgress); }); // Fill in any missing information ------------------------------------------------------------------------- if (UninstallToolsGlobalConfig.UninstallerFactoryCache != null) ApplyCache(mergedResults, UninstallToolsGlobalConfig.UninstallerFactoryCache, InfoAdder); var infoAddProgress = new ListGenerationProgress(currentStep++, totalStepCount, Localisation.Progress_GeneratingInfo); callback(infoAddProgress); FactoryThreadedHelpers.GenerateMissingInformation(mergedResults, InfoAdder, msiProducts, false, report => { infoAddProgress.Inner = report; callback(infoAddProgress); }); // Cache missing information to speed up future scans if (UninstallToolsGlobalConfig.UninstallerFactoryCache != null) { foreach (var entry in mergedResults) UninstallToolsGlobalConfig.UninstallerFactoryCache.TryCacheItem(entry); try { UninstallToolsGlobalConfig.UninstallerFactoryCache.Save(); } catch (SystemException e) { Trace.WriteLine(@"Failed to save cache: " + e); } } // Detect startups and attach them to uninstaller entries ---------------------------------------------------- var startupsProgress = new ListGenerationProgress(currentStep, totalStepCount, Localisation.Progress_Startup); callback(startupsProgress); var i = 0; var startupEntries = new List(); foreach (var factory in StartupManager.Factories) { startupsProgress.Inner = new ListGenerationProgress(i++, StartupManager.Factories.Count, factory.Key); callback(startupsProgress); try { startupEntries.AddRange(factory.Value()); } catch (Exception ex) { PremadeDialogs.GenericError(ex); } } startupsProgress.Inner = new ListGenerationProgress(1, 1, Localisation.Progress_Merging); callback(startupsProgress); try { AttachStartupEntries(mergedResults, startupEntries); } catch (Exception ex) { PremadeDialogs.GenericError(ex); } return mergedResults; } finally { concurrentFactory.Dispose(); } } /// /// Merge new results into the base list /// internal static void MergeResults(ICollection baseEntries, ICollection newResults, ListGenerationProgress.ListGenerationCallback progressCallback) { var newToAdd = new List(); var progress = 0; foreach (var entry in newResults) { progressCallback?.Invoke(new ListGenerationProgress(progress++, newResults.Count, null)); var matchedEntry = baseEntries.Select(x => new { x, score = ApplicationEntryTools.AreEntriesRelated(x, entry) }) .Where(x => x.score >= 1) .OrderByDescending(x => x.score) .Select(x => x.x) .FirstOrDefault(); if (matchedEntry != null) { // Prevent setting incorrect UninstallerType if (matchedEntry.UninstallPossible) entry.UninstallerKind = UninstallerType.Unknown; InfoAdder.CopyMissingInformation(matchedEntry, entry); continue; } // If the entry failed to match to anything, add it to the base results as new newToAdd.Add(entry); } foreach (var newEntry in newToAdd) baseEntries.Add(newEntry); } private static void ApplyCache(ICollection baseEntries, ApplicationUninstallerFactoryCache cache, InfoAdderManager infoAdder) { var hits = 0; foreach (var entry in baseEntries) { var matchedEntry = cache.TryGetCachedItem(entry); if (matchedEntry != null) { infoAdder.CopyMissingInformation(entry, matchedEntry); hits++; } else { Debug.WriteLine("Cache miss: " + entry.DisplayName); } } Trace.WriteLine($@"Cache hits: {hits}/{baseEntries.Count}"); } private static List GetMiscUninstallerEntries(ListGenerationProgress.ListGenerationCallback progressCallback) { var otherResults = new List(); var miscFactories = ReflectionTools.GetTypesImplementingBase() .Attempt(Activator.CreateInstance) .Cast() .Where(x => x.IsEnabled()) .ToList(); var progress = 0; foreach (var kvp in miscFactories) { progressCallback(new ListGenerationProgress(progress++, miscFactories.Count, kvp.DisplayName)); try { var sw = Stopwatch.StartNew(); MergeResults(otherResults, kvp.GetUninstallerEntries(null), null); Trace.WriteLine($"[Performance] Factory {kvp.GetType().Name} took {sw.ElapsedMilliseconds}ms to finish"); } catch (Exception ex) { PremadeDialogs.GenericError(ex); } } return otherResults; } /// /// Attach startup entries to uninstaller entries that are automatically detected as related. /// public static void AttachStartupEntries(IEnumerable uninstallers, IEnumerable startupEntries) { // Using DoForEach to avoid multiple enumerations StartupManager.AssignStartupEntries(uninstallers .DoForEach(x => { if (x != null) x.StartupEntries = null; }), startupEntries); } } } ================================================ FILE: source/UninstallTools/Factory/ApplicationUninstallerFactoryCache.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Drawing; using System.IO; using System.Linq; using Klocman.Extensions; using Klocman.Tools; namespace UninstallTools.Factory { public class ApplicationUninstallerFactoryCache { private ApplicationUninstallerFactoryCache(string filename, Dictionary cacheData) { Filename = filename; Cache = cacheData; } public ApplicationUninstallerFactoryCache(string filename) : this(filename, new Dictionary()) { } public ApplicationUninstallerEntry TryGetCachedItem(ApplicationUninstallerEntry notCachedEntry) { var id = notCachedEntry?.GetCacheId(); if (!string.IsNullOrEmpty(id) && Cache.TryGetValue(id, out var matchedEntry)) return matchedEntry; return null; } public void TryCacheItem(ApplicationUninstallerEntry item) { var id = item?.GetCacheId(); if (!string.IsNullOrEmpty(id)) Cache[id] = item; } private Dictionary Cache { get; } public string Filename { get; set; } public bool SerializeIcons { get; set; } private static byte[] SerializeIcon(Icon ic) { using (var stream = new MemoryStream()) { ic.Save(stream); return stream.ToArray(); } } private static Icon DeserializeIcon(byte[] bytes) { using (var stream = new MemoryStream(bytes, false)) return new Icon(stream); } public void Read() { try { var result = SerializationTools.DeserializeFromXml>(Filename); Cache.Clear(); // Ignore entries if more than 1 have the same cache id foreach (var group in result .GroupBy(x => x.Entry.GetCacheId()) .Where(g => g.Key != null && g.CountEquals(1))) { var cacheEntry = group.Single(); if (SerializeIcons && cacheEntry.Icon != null) cacheEntry.Entry.IconBitmap = DeserializeIcon(cacheEntry.Icon); Cache.Add(group.Key, cacheEntry.Entry); } } catch (Exception e) { Console.WriteLine($@"Failed to load cache from {Filename} - {e}"); Cache.Clear(); File.Delete(Filename); } } public void Save() { SerializationTools.SerializeToXml(Filename, Cache.Select(x => new CacheEntry( x.Value, SerializeIcons && x.Value.IconBitmap != null ? SerializeIcon(x.Value.IconBitmap) : null)) .ToList()); } public class CacheEntry { public CacheEntry() { } public CacheEntry(ApplicationUninstallerEntry entry, byte[] icon) { Entry = entry; Icon = icon; } public ApplicationUninstallerEntry Entry { get; set; } public byte[] Icon { get; set; } } public void Delete() { Cache.Clear(); try { File.Delete(Filename); } catch { System.Threading.Thread.Sleep(50); File.Delete(Filename); } } } } ================================================ FILE: source/UninstallTools/Factory/ChocolateyFactory.cs ================================================ using Klocman.Tools; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Text; using UninstallTools.Properties; namespace UninstallTools.Factory { public sealed class ChocolateyFactory : IIndependantUninstallerFactory { private static bool GetChocoInfo(out string chocoLocation) { chocoLocation = null; try { var chocoPath = PathTools.GetFullPathOfExecutable("choco.exe"); if (string.IsNullOrEmpty(chocoPath)) return false; var result = StartProcessAndReadOutput(chocoPath, string.Empty); if (result.StartsWith("Chocolatey", StringComparison.Ordinal)) { chocoLocation = chocoPath; return true; } } catch (SystemException ex) { Trace.WriteLine("Failed to get Choco info: " + ex); } return false; } private static readonly string[] NewlineSeparators = StringTools.NewLineChars.ToArray(); public IList GetUninstallerEntries(ListGenerationProgress.ListGenerationCallback progressCallback) { var results = new List(); // Check on every reload in case Chocolatey was uninstalled since last reload if (!GetChocoInfo(out var chocoFullFilename)) return results; var versionResult = StartProcessAndReadOutput(chocoFullFilename, "--version"); if (string.IsNullOrEmpty(versionResult)) return results; var versionString = versionResult.Trim(); string result; if (Version.TryParse(versionString, out var version)) { if (version >= new Version(2, 0, 0)) { result = StartProcessAndReadOutput(chocoFullFilename, @"list -nocolor --detail"); } else { result = StartProcessAndReadOutput(chocoFullFilename, @"list -lo -nocolor --detail"); } } else { Trace.WriteLine("Failed to parse Chocolatey version: " + versionString); return results; } if (string.IsNullOrEmpty(result)) return results; var re = new System.Text.RegularExpressions.Regex(@"\n\w.+\r\n Title:"); var match = re.Match(result); if (!match.Success) return results; var begin = match.Index + 1; while (true) { match = match.NextMatch(); if (!match.Success) break; var end = match.Index + 1; var info = result.Substring(begin, end - begin); int i = info.IndexOf(' '), j = info.IndexOf("\r\n", StringComparison.Ordinal); var appName = new { name = info.Substring(0, i), version = info.Substring(i + 1, j - i - 1) }; var kvps = ExtractPackageInformation(info); if (kvps.Count == 0) continue; var entry = new ApplicationUninstallerEntry(); AddInfo(entry, kvps, "Title", (e, s) => e.RawDisplayName = s); entry.DisplayVersion = ApplicationEntryTools.CleanupDisplayVersion(appName.version); entry.RatingId = "Choco " + appName.name; entry.UninstallerKind = UninstallerType.Chocolatey; AddInfo(entry, kvps, "Summary", (e, s) => e.Comment = s); if (string.IsNullOrEmpty(entry.Comment)) { AddInfo(entry, kvps, "Description", (e, s) => e.Comment = s); if (string.IsNullOrEmpty(entry.Comment)) AddInfo(entry, kvps, "Tags", (e, s) => e.Comment = s); } AddInfo(entry, kvps, "Documentation", (e, s) => e.AboutUrl = s); if (string.IsNullOrEmpty(entry.AboutUrl)) { AddInfo(entry, kvps, "Software Site", (e, s) => e.AboutUrl = s); if (string.IsNullOrEmpty(entry.AboutUrl)) AddInfo(entry, kvps, "Chocolatey Package Source", (e, s) => e.AboutUrl = s); } var psc = new ProcessStartCommand(chocoFullFilename, $"uninstall {appName.name} -y -r"); entry.UninstallString = psc.ToString(); if (entry.RawDisplayName == "Chocolatey") entry.InstallLocation = GetChocoInstallLocation(chocoFullFilename); // Prevent chocolatey from trying to run the original uninstaller (it's deleted by now), only remove the package psc.Arguments += " -n --skipautouninstaller"; var junk = new Junk.Containers.RunProcessJunk(entry, null, psc, Localisation.ChocolateyFactory_UninstallInChocolateyJunkName); junk.Confidence.Add(Junk.Confidence.ConfidenceRecords.ExplicitConnection); junk.Confidence.Add(4); entry.AdditionalJunk.Add(junk); results.Add(entry); begin = end; } return results; } private static string GetChocoInstallLocation(string chocoFullFilename) { // The path is C:\ProgramData\chocolatey\bin\choco.exe OR C:\ProgramData\chocolatey\choco.exe var chocoLocation = Path.GetDirectoryName(chocoFullFilename); if (chocoLocation != null && chocoLocation.EndsWith(@"\bin", StringComparison.OrdinalIgnoreCase)) return chocoLocation.Substring(0, chocoLocation.Length - 4); return chocoLocation; } private static void AddInfo(ApplicationUninstallerEntry target, Dictionary source, string key, Action setter) { if (source.TryGetValue(key, out var val)) { try { setter(target, val); } catch (SystemException ex) { Trace.WriteLine(@"Exception while extracting info from choco: " + ex.Message); } } } private static Dictionary ExtractPackageInformation(string result) { // Parse the console output into lines, then into key-value pairs var lines = result.Split(NewlineSeparators, StringSplitOptions.RemoveEmptyEntries) .Where(x => x.Length > 2 && x[0] == ' ' && x[1] != ' ' && x.Contains(": ")) .Select(x => x.TrimStart()) .SelectMany(x => x.Split(new[] { " | " }, StringSplitOptions.None)); var kvps = new Dictionary(); foreach (var line in lines) { var i = line.IndexOf(": ", StringComparison.Ordinal); if (i <= 0) continue; var key = line.Substring(0, i); var val = line.Substring(i + 2); if (string.IsNullOrEmpty(key) || string.IsNullOrEmpty(val)) continue; kvps.Add(key, val); } return kvps; } public bool IsEnabled() => UninstallToolsGlobalConfig.ScanChocolatey; public string DisplayName => Localisation.Progress_AppStores_Chocolatey; private static string StartProcessAndReadOutput(string filename, string args) { using (var process = Process.Start(new ProcessStartInfo(filename, args) { UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = false, CreateNoWindow = true, StandardOutputEncoding = Encoding.Default })) { var sw = Stopwatch.StartNew(); var output = process?.StandardOutput.ReadToEnd(); Trace.WriteLine($"[Performance] Running command {filename} {args} took {sw.ElapsedMilliseconds}ms"); return output; } } } } ================================================ FILE: source/UninstallTools/Factory/ConcurrentApplicationFactory.cs ================================================ /* Copyright (c) 2018 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Threading; namespace UninstallTools.Factory { internal sealed class ConcurrentApplicationFactory : IDisposable { private ListGenerationProgress.ListGenerationCallback _callback; private bool _cancelled; private ListGenerationProgress _parentProgress; private readonly Thread _thread; private ListGenerationProgress _threadLastReport; private List _threadResults; public ConcurrentApplicationFactory( Func> factoryMethod) { _thread = new Thread(() => { try { _threadResults = factoryMethod(ProgressCallback); } catch (OperationCanceledException) { _cancelled = true; } }); _thread.IsBackground = false; _thread.Name = "ConcurrentGetUninstallerEntries"; _thread.Priority = ThreadPriority.Normal; } public void Dispose() { _cancelled = true; } private void ProgressCallback(ListGenerationProgress report) { if (_cancelled) throw new OperationCanceledException(); lock (_thread) { if (_parentProgress == null) { _threadLastReport = report; } else { _parentProgress.Inner = report; _callback.Invoke(_parentProgress); } } } public void Start() { _thread.Start(); } public List GetResults(ListGenerationProgress.ListGenerationCallback callback, ListGenerationProgress parentProgress) { if (parentProgress == null) throw new ArgumentNullException(nameof(parentProgress)); if (callback == null) throw new ArgumentNullException(nameof(callback)); Debug.Assert(_thread != null); if (_thread.IsAlive) { lock (_thread) { _parentProgress = parentProgress; if (_threadLastReport != null) { _parentProgress.Inner = _threadLastReport; callback.Invoke(_parentProgress); } _callback = callback; } _thread.Join(); } if (_cancelled) throw new OperationCanceledException(); return _threadResults ?? new List(); } } } ================================================ FILE: source/UninstallTools/Factory/DirectoryFactory.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using Klocman.Extensions; using Klocman.Tools; using UninstallTools.Factory.InfoAdders; using UninstallTools.Properties; namespace UninstallTools.Factory { public class DirectoryFactory : IUninstallerFactory { private readonly IEnumerable _existingUninstallerEntries; public DirectoryFactory(IEnumerable existing) { _existingUninstallerEntries = existing; } public IList GetUninstallerEntries(ListGenerationProgress.ListGenerationCallback progressCallback) { progressCallback(new ListGenerationProgress(0, -1, Localisation.Progress_DriveScan_Gathering)); var existingUninstallers = _existingUninstallerEntries.ToList(); var pfDirs = UninstallToolsGlobalConfig.GetProgramFilesDirectories(true); var dirsToSkip = GetDirectoriesToSkip(existingUninstallers, pfDirs).ToList(); var itemsToScan = GetDirectoriesToScan(existingUninstallers, pfDirs, dirsToSkip).ToList(); return FactoryThreadedHelpers.DriveApplicationScan(progressCallback, dirsToSkip, itemsToScan); } /// /// Get directories to scan for applications /// private static IEnumerable GetDirectoriesToScan(IEnumerable existingUninstallers, IEnumerable pfDirs, IEnumerable dirsToSkip) { var pfDirectories = pfDirs.ToList(); if (UninstallToolsGlobalConfig.AutoDetectCustomProgramFiles) { var extraPfDirectories = FindExtraPfDirectories(existingUninstallers) .Where(extraDir => !extraDir.FullName.Contains(@"\Common Files", StringComparison.InvariantCultureIgnoreCase)) .Where(extraDir => pfDirectories.All(pfDir => !PathTools.PathsEqual(pfDir.FullName, extraDir.FullName))); pfDirectories.AddRange(extraPfDirectories); string[] goodNames = { "Apps", "App", "Applications", "Programs", "Games", "Game", "Portable", "PortableApplications", "PortablePrograms", "PortableGames", "PortableApps", "LiberKey" }; IEnumerable FindDirsOnDrive(DriveInfo d) { return d.RootDirectory.GetDirectories().Where(x => goodNames.Contains(x.Name, StringComparison.InvariantCultureIgnoreCase)); } var drives = DriveInfo.GetDrives(); foreach (var driveInfo in drives) { if (!driveInfo.IsReady) continue; switch (driveInfo.DriveType) { case DriveType.Fixed: try { pfDirectories.AddRange(FindDirsOnDrive(driveInfo)); } catch (SystemException ex) { Trace.WriteLine(ex); } break; case DriveType.Removable: if (UninstallToolsGlobalConfig.AutoDetectScanRemovable) goto case DriveType.Fixed; break; case DriveType.Network: // Slow and unreliable, might also be buggy break; case DriveType.Unknown: case DriveType.NoRootDirectory: case DriveType.CDRom: case DriveType.Ram: // No point in scanning break; } } } var directoriesToSkip = dirsToSkip.ToList(); // Get sub directories which could contain user programs var directoriesToCheck = pfDirectories.SelectMany(x => { try { return x.GetDirectories(); } catch (SystemException ex) { Trace.WriteLine($"Could not access a program files directory: {x?.Name} | Reason:{ex.Message}"); } return Enumerable.Empty(); }); // Get directories that can be relatively safely checked return directoriesToCheck.Where(check => !directoriesToSkip.Any(skip => check.FullName.StartsWith(skip, StringComparison.InvariantCultureIgnoreCase))) .Distinct((pair, otherPair) => PathTools.PathsEqual(pair.FullName, otherPair.FullName)); } /// /// Get directories which are already used and should be skipped /// private static IEnumerable GetDirectoriesToSkip(IEnumerable existingUninstallers, IEnumerable pfDirectories) { var dirs = new List(); foreach (var x in existingUninstallers) { dirs.Add(x.InstallLocation); dirs.Add(x.UninstallerLocation); if (string.IsNullOrEmpty(x.DisplayIcon)) continue; try { var iconFilename = x.DisplayIcon.Contains('.') ? ProcessTools.SeparateArgsFromCommand(x.DisplayIcon).FileName : x.DisplayIcon; dirs.Add(PathTools.GetDirectory(iconFilename)); } catch { // Ignore invalid DisplayIcon paths } } return dirs.Where(x => !string.IsNullOrEmpty(x)).Distinct() .Where(x => !pfDirectories.Any(pfd => pfd.FullName.Contains(x, StringComparison.InvariantCultureIgnoreCase))); } private static IEnumerable FindExtraPfDirectories(IEnumerable existingUninstallers) { var extraSearchLocations = existingUninstallers .Select(x => x.InstallLocation) .Where(x => !string.IsNullOrEmpty(x)) .Select(s => { try { return Path.GetDirectoryName(s); } catch (ArgumentException) { return null; } }).Where(x => x != null) .GroupBy(x => x.ToLowerInvariant()) // Select only groups with 2 or more hits .Where(g => g.Take(2).Count() == 2) .Select(g => g.Key); return extraSearchLocations.Select(x => { try { var directoryInfo = new DirectoryInfo(PathTools.PathToNormalCase(x).TrimEnd('\\')); return directoryInfo.Exists ? directoryInfo : null; } catch { return null; } }).Where(x => x != null); } private static void CreateFromDirectoryHelper(ICollection results, DirectoryInfo directory, int level, ICollection dirsToSkip) { // Level 0 is for the pf folder itself. First subfolder is level 1. if (level > 2 || dirsToSkip.Any(x => directory.FullName.Contains(x, StringComparison.InvariantCultureIgnoreCase))) return; // Get contents of this installDir AppExecutablesSearcher.ScanDirectoryResult result; try { result = AppExecutablesSearcher.ScanDirectory(directory); } catch (IOException) { return; } catch (UnauthorizedAccessException) { return; } // Check if it is potentially dangerous to process this installDir. if (result.ExecutableFiles.Count > 40) return; var anyFiles = result.ExecutableFiles.Any(); if (UninstallToolsGlobalConfig.IsKnownFolder(directory) || !anyFiles && !result.BinSubdirs.Any()) { foreach (var dir in result.OtherSubdirs) CreateFromDirectoryHelper(results, dir, level + 1, dirsToSkip); } else if (anyFiles) { var entry = new ApplicationUninstallerEntry(); // Parse directories into useful information if (level > 0 && directory.Name.StartsWithAny(AppExecutablesSearcher.BinaryDirectoryNames, StringComparison.OrdinalIgnoreCase)) { entry.InstallLocation = directory.Parent?.FullName; entry.RawDisplayName = directory.Parent?.Name; } else { entry.InstallLocation = directory.FullName; entry.RawDisplayName = directory.Name; if (level > 0) entry.Publisher = directory.Parent?.Name; } var sorted = AppExecutablesSearcher.SortListExecutables(result.ExecutableFiles, entry.DisplayNameTrimmed).ToArray(); entry.SortedExecutables = sorted.Select(x => x.FullName).ToArray(); entry.InstallDate = directory.CreationTime; //entry.IconBitmap = TryExtractAssociatedIcon(compareBestMatchFile.FullName); // Extract info from file metadata and overwrite old values var compareBestMatchFile = sorted.First(); ExecutableAttributeExtractor.FillInformationFromFileAttribs(entry, compareBestMatchFile.FullName, false); results.Add(entry); } } /// /// Try to get the main executable from the filtered folders. If no executables are present check subfolders. /// public static IEnumerable TryCreateFromDirectory( DirectoryInfo directory, ICollection dirsToSkip) { if (directory == null) throw new ArgumentNullException(nameof(directory)); var results = new List(); CreateFromDirectoryHelper(results, directory, 0, dirsToSkip); foreach (var tempEntry in results) { if (tempEntry.Is64Bit == MachineType.Unknown) tempEntry.Is64Bit = UninstallToolsGlobalConfig.IsPathInsideProgramFiles(directory.FullName); tempEntry.IsRegistered = false; tempEntry.IsOrphaned = true; } return results; } public static IEnumerable TryCreateFromDirectory( DirectoryInfo directoryToScan, IEnumerable existingUninstallers) { var pfDirs = UninstallToolsGlobalConfig.GetProgramFilesDirectories(true); var dirsToSkip = GetDirectoriesToSkip(existingUninstallers, pfDirs).ToList(); if (UninstallToolsGlobalConfig.IsSystemDirectory(directoryToScan) || directoryToScan.Name.StartsWith("Windows", StringComparison.InvariantCultureIgnoreCase)) return Enumerable.Empty(); return TryCreateFromDirectory(directoryToScan, dirsToSkip); } } } ================================================ FILE: source/UninstallTools/Factory/FactoryThreadedHelpers.cs ================================================ /* Copyright (c) 2018 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Management; using Klocman.Extensions; using UninstallTools.Factory.InfoAdders; namespace UninstallTools.Factory { internal static class FactoryThreadedHelpers { public static int MaxThreadsPerDrive = 2; public static IList DriveApplicationScan( ListGenerationProgress.ListGenerationCallback progressCallback, List dirsToSkip, List itemsToScan) { var dividedItems = SplitByPhysicalDrives(itemsToScan, d => d); void GetUninstallerEntriesThread(DirectoryInfo data, List state) { if (UninstallToolsGlobalConfig.IsSystemDirectory(data) || data.Name.StartsWith("Windows", StringComparison.InvariantCultureIgnoreCase)) return; var detectedEntries = DirectoryFactory.TryCreateFromDirectory(data, dirsToSkip).ToList(); ApplicationUninstallerFactory.MergeResults(state, detectedEntries, null); } var workSpreader = new ThreadedWorkSpreader> (MaxThreadsPerDrive, GetUninstallerEntriesThread, list => new List(list.Count), data => data.FullName); workSpreader.Start(dividedItems, progressCallback); var results = new List(); foreach (var workerResults in workSpreader.Join()) ApplicationUninstallerFactory.MergeResults(results, workerResults, null); return results; } public static void GenerateMissingInformation(IList entries, InfoAdderManager infoAdder, IList msiProducts, bool skipRunLast, ListGenerationProgress.ListGenerationCallback progressCallback) { void WorkLogic(ApplicationUninstallerEntry entry, object state) { infoAdder.AddMissingInformation(entry, skipRunLast); if (msiProducts != null) entry.IsValid = FactoryTools.CheckIsValid(entry, msiProducts); } var workSpreader = new ThreadedWorkSpreader(MaxThreadsPerDrive, WorkLogic, list => null, entry => entry.DisplayName ?? entry.RatingId ?? string.Empty); var cDrive = new DirectoryInfo(Environment.SystemDirectory).Root; var dividedItems = SplitByPhysicalDrives(entries, entry => { var loc = entry.InstallLocation ?? entry.UninstallerLocation; if (!string.IsNullOrEmpty(loc)) { try { return new DirectoryInfo(loc); } catch (SystemException ex) { Trace.WriteLine(ex); } } return cDrive; }); workSpreader.Start(dividedItems, progressCallback); workSpreader.Join(); } private static IList> SplitByPhysicalDrives(IList itemsToScan, Func locationGetter) { var output = new List>(); try { using (var searcherDtp = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_DiskDriveToDiskPartition")) using (var searcherLtp = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_LogicalDiskToPartition")) { var dtp = searcherDtp.Get().Cast().Select(queryObj => new { Drive = queryObj["Antecedent"] as string, Partition = queryObj["Dependent"] as string }); var ltp = searcherLtp.Get().Cast().Select(queryObj => new { Partition = queryObj["Antecedent"] as string, LogicalDrive = queryObj["Dependent"] as string }); var correlatedDriveList = ltp.Join(dtp, arg => arg.Partition, arg => arg.Partition, (x, y) => new { LogicalName = x.LogicalDrive.Split(new[] { '"' }, StringSplitOptions.RemoveEmptyEntries).LastOrDefault()?.Append(@"\"), y.Drive }).Where(x => !string.IsNullOrEmpty(x.LogicalName)).GroupBy(x => x.Drive); var inputList = itemsToScan.Select(x => new { locationGetter(x).Root.Name, x }).ToList(); foreach (var logicalDriveGroup in correlatedDriveList) { var filteredByPhysicalDrive = inputList.Where(x => logicalDriveGroup.Any(y => y.LogicalName.Equals(x.Name, StringComparison.OrdinalIgnoreCase))).ToList(); inputList.RemoveAll(filteredByPhysicalDrive); output.Add(filteredByPhysicalDrive.Select(x => x.x).ToList()); } // Bundle leftovers as a single drive output.Add(inputList.Select(x => x.x).ToList()); } } catch (SystemException ex) { Trace.WriteLine(@"Failed to get logical disk to physical drive relationships - " + ex); output.Clear(); output.Add(itemsToScan); } return output; } } } ================================================ FILE: source/UninstallTools/Factory/FactoryTools.cs ================================================ /* Copyright (c) 2018 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Linq; using System.Text; using Klocman.Extensions; using Klocman.Forms.Tools; namespace UninstallTools.Factory { internal static class FactoryTools { /// /// Warning: only use with helpers that output unicode and use 0 as success return code. /// internal static string StartHelperAndReadOutput(string filename, string args) { if (!File.Exists(filename)) return null; using (var process = Process.Start(new ProcessStartInfo(filename, args) { UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = false, CreateNoWindow = true, StandardOutputEncoding = Encoding.Unicode })) { try { var sw = Stopwatch.StartNew(); var output = process?.StandardOutput.ReadToEnd(); Trace.WriteLine($"[Performance] Running command {filename} {args} took {sw.ElapsedMilliseconds}ms"); return process?.ExitCode == 0 ? output : null; } catch (Win32Exception ex) { PremadeDialogs.GenericError(ex); return null; } } } internal static IEnumerable> ExtractAppDataSetsFromHelperOutput(string helperOutput) { ICollection allParts = helperOutput.SplitNewlines(StringSplitOptions.None); while (allParts.Count > 0) { var singleAppParts = allParts.TakeWhile(x => !String.IsNullOrEmpty(x)).ToList(); allParts = allParts.Skip(singleAppParts.Count + 1).ToList(); if (!singleAppParts.Any()) continue; yield return singleAppParts.Where(x => x.Contains(':')).ToDictionary( x => x.Substring(0, x.IndexOf(":", StringComparison.Ordinal)).Trim(), x => x.Substring(x.IndexOf(":", StringComparison.Ordinal) + 1).Trim()); } } internal static bool CheckIsValid(ApplicationUninstallerEntry target, IEnumerable msiProducts) { if (string.IsNullOrEmpty(target.UninstallerFullFilename)) return false; bool isPathRooted; try { isPathRooted = Path.IsPathRooted(target.UninstallerFullFilename); } catch (ArgumentException) { isPathRooted = false; } if (isPathRooted && File.Exists(target.UninstallerFullFilename)) return true; if (target.UninstallerKind == UninstallerType.Msiexec) return msiProducts.Contains(target.BundleProviderKey); return !isPathRooted; } } } ================================================ FILE: source/UninstallTools/Factory/IUninstallerFactory.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System.Collections.Generic; namespace UninstallTools.Factory { public interface IIndependantUninstallerFactory : IUninstallerFactory { bool IsEnabled(); string DisplayName { get; } } public interface IUninstallerFactory { IList GetUninstallerEntries(ListGenerationProgress.ListGenerationCallback progressCallback); } } ================================================ FILE: source/UninstallTools/Factory/InfoAdders/AppExecutablesSearcher.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.IO; using System.Linq; using Klocman.Extensions; using Klocman.Tools; namespace UninstallTools.Factory.InfoAdders { public class AppExecutablesSearcher : IMissingInfoAdder { internal static readonly string[] BinaryDirectoryNames; static AppExecutablesSearcher() { var postfixes = new List {"arm64", "aarch64", "32", "64", "x32", "x64", "x86", "x86-64", "ia32", "ia64", "ia-32", "ia-64" }; var connectors = new[] { "-", "_", " ", "." }; postfixes.AddRange(connectors.SelectMany(c => postfixes.Select(p => c + p)).ToList()); var prefixes = new[] { "bin", "binaries", "program", "client", "app", "application", "win", "win7", "win8", "win81", "win10" }; var names = new List(); names.AddRange(prefixes); names.AddRange(postfixes); names.AddRange(prefixes.SelectMany(pr => postfixes.Select(po => pr + po))); BinaryDirectoryNames = names.ToArray(); } public string[] CanProduceValueNames { get; } = { nameof(ApplicationUninstallerEntry.SortedExecutables) }; public InfoAdderPriority Priority { get; } = InfoAdderPriority.RunFirst; public string[] RequiredValueNames { get; } = { nameof(ApplicationUninstallerEntry.InstallLocation) }; public bool RequiresAllValues { get; } = true; public bool AlwaysRun { get; } = false; public void AddMissingInformation(ApplicationUninstallerEntry target) { /*var trimmedDispName = target.DisplayNameTrimmed; if (string.IsNullOrEmpty(trimmedDispName) || trimmedDispName.Length < 5) { trimmedDispName = target.DisplayName; if (string.IsNullOrEmpty(trimmedDispName)) // Impossible to search for the executable without knowing the app name return; }*/ if (!Directory.Exists(target.InstallLocation)) return; var trimmedDispName = target.DisplayNameTrimmed; try { var results = ScanDirectory(new DirectoryInfo(target.InstallLocation)); target.SortedExecutables = SortListExecutables(results.ExecutableFiles, trimmedDispName) .Select(x => x.FullName).ToArray(); } catch (IOException) { } catch (UnauthorizedAccessException) { } } internal static ScanDirectoryResult ScanDirectory(DirectoryInfo directory) { var results = new List(directory.GetFiles("*.exe", SearchOption.TopDirectoryOnly)); var binSubdirs = new List(); var otherSubdirs = new List(); var maybeSubdirs = new List(); foreach (var subdir in directory.GetDirectories()) { try { var subName = subdir.Name; if (subName.StartsWithAny(BinaryDirectoryNames, StringComparison.OrdinalIgnoreCase)) { binSubdirs.Add(subdir); results.AddRange(subdir.GetFiles("*.exe", SearchOption.TopDirectoryOnly)); } else { // This skips ISO language codes, much faster than a more specific compare if (subName.Length == 5 && subName[2].Equals('-')) continue; // Directories with very short names likely contain program files if (subName.Length > 3) otherSubdirs.Add(subdir); else maybeSubdirs.Add(subdir); } } catch (IOException) { } catch (UnauthorizedAccessException) { } } if (results.Count == 0 && binSubdirs.Count == 0) otherSubdirs.AddRange(maybeSubdirs); // 7-Zip console application. Sometimes causes bad display data if it's picked as the most likely executable. No effect on real 7-Zip entries. results.RemoveAll(x => string.Equals(x.Name, "7z.exe", StringComparison.OrdinalIgnoreCase)); return new ScanDirectoryResult(results, binSubdirs, otherSubdirs); } internal static IEnumerable SortListExecutables(IEnumerable targets, string targetString) { var reportInName = targetString.Contains("report", StringComparison.OrdinalIgnoreCase); var crashInName = targetString.Contains("crash", StringComparison.OrdinalIgnoreCase); int GetPenaltyPoints(FileInfo fileInfo) { var fileName = fileInfo.Name; if (fileName.Equals("uninstaller.exe", StringComparison.OrdinalIgnoreCase) || fileName.Equals("uninstall.exe", StringComparison.OrdinalIgnoreCase) || fileName.Contains("unins00", StringComparison.OrdinalIgnoreCase)) return 20; if(!reportInName && fileName.Contains("report", StringComparison.OrdinalIgnoreCase)) return 10; if(!crashInName && fileName.Contains("crash", StringComparison.OrdinalIgnoreCase)) return 10; if (fileName.Contains("uninsta", StringComparison.OrdinalIgnoreCase)) return 4; if (fileName.Contains("unins", StringComparison.OrdinalIgnoreCase)) return 2; return 0; } return targets.Select(x => new { x, p = GetPenaltyPoints(x) }) .OrderBy(x => Sift4.SimplestDistance(x.x.Name, targetString, 3) + x.p) .Select(x => x.x); } internal sealed class ScanDirectoryResult { public ScanDirectoryResult(ICollection executableFiles, ICollection binSubdirs, ICollection otherSubdirs) { OtherSubdirs = otherSubdirs; ExecutableFiles = executableFiles; BinSubdirs = binSubdirs; } public ICollection BinSubdirs { get; } public ICollection ExecutableFiles { get; } public ICollection OtherSubdirs { get; } } } } ================================================ FILE: source/UninstallTools/Factory/InfoAdders/BasicIconGetter.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System.IO; using Klocman.Tools; namespace UninstallTools.Factory.InfoAdders { public class BasicIconGetter :IMissingInfoAdder { public void AddMissingInformation(ApplicationUninstallerEntry entry) { if (entry.IconBitmap != null) return; // Check for any specified icons if (!string.IsNullOrEmpty(entry.DisplayIcon) && !ApplicationEntryTools.PathPointsToMsiExec(entry.DisplayIcon)) { string resultFilename = null; if (File.Exists(entry.DisplayIcon)) resultFilename = entry.DisplayIcon; if (resultFilename == null) { try { var fName = ProcessTools.SeparateArgsFromCommand(entry.DisplayIcon).FileName; if (fName != null && File.Exists(fName)) { resultFilename = fName; } } catch { // Ignore error and try another method } } var icon = UninstallToolsGlobalConfig.TryExtractAssociatedIcon(resultFilename); if (icon != null) { entry.DisplayIcon = resultFilename; entry.IconBitmap = icon; } } } public string[] RequiredValueNames { get; } = { nameof(ApplicationUninstallerEntry.DisplayIcon) }; public bool RequiresAllValues { get; } = true; public bool AlwaysRun { get; } = false; public string[] CanProduceValueNames { get; } = { nameof(ApplicationUninstallerEntry.DisplayIcon), nameof(ApplicationUninstallerEntry.IconBitmap) }; public InfoAdderPriority Priority { get; } = InfoAdderPriority.RunFirst; } } ================================================ FILE: source/UninstallTools/Factory/InfoAdders/CertificateGetter.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System.Linq; using System.Security.Cryptography.X509Certificates; using Klocman.IO; namespace UninstallTools.Factory.InfoAdders { public static class CertificateGetter { internal static X509Certificate2 TryGetCertificate(ApplicationUninstallerEntry entry) { // Don't even try if the entry is invalid, it will be marked as bad anyways if (!entry.IsValid) return null; try { X509Certificate2 result = null; if (entry.SortedExecutables != null) result = TryExtractCertificateHelper(entry.SortedExecutables); // Check executables before this because signatures in MSI store are modified and won't verify if (result == null && entry.UninstallerKind == UninstallerType.Msiexec) result = MsiTools.GetCertificate(entry.BundleProviderKey); // If no certs were found finally check the uninstaller if (result == null && !string.IsNullOrEmpty(entry.UninstallerFullFilename)) result = TryExtractCertificateHelper(entry.UninstallerFullFilename); return result; } catch { // Default to no certificate return null; } } /// /// Check first few files from the install directory for certificates /// private static X509Certificate2 TryExtractCertificateHelper(params string[] fileNames) { foreach (var candidate in fileNames.Take(2)) { try { return new X509Certificate2(candidate); } catch { // No cert was found, try next } } return null; } } } ================================================ FILE: source/UninstallTools/Factory/InfoAdders/ExecutableAttributeExtractor.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Diagnostics; using System.Linq; using Klocman.Tools; namespace UninstallTools.Factory.InfoAdders { public class ExecutableAttributeExtractor : IMissingInfoAdder { public void AddMissingInformation(ApplicationUninstallerEntry target) { if (target.SortedExecutables == null || !target.SortedExecutables.Any()) return; FillInformationFromFileAttribs(target, target.SortedExecutables[0], true); } public string[] RequiredValueNames { get; } = { nameof(ApplicationUninstallerEntry.SortedExecutables) }; public bool RequiresAllValues { get; } = true; public bool AlwaysRun { get; } = false; public string[] CanProduceValueNames { get; } = { nameof(ApplicationUninstallerEntry.RawDisplayName), nameof(ApplicationUninstallerEntry.DisplayVersion), nameof(ApplicationUninstallerEntry.Publisher) //nameof(ApplicationUninstallerEntry.Comment) }; public InfoAdderPriority Priority { get; } = InfoAdderPriority.RunLast; /// /// Add information from FileVersionInfo of specified file to the targetEntry /// /// Entry to update /// Binary file to get the information from /// Only update unpopulated fields of the targetEntry internal static void FillInformationFromFileAttribs(ApplicationUninstallerEntry targetEntry, string infoSourceFilename, bool onlyUnpopulated) { FileVersionInfo verInfo; try { verInfo = FileVersionInfo.GetVersionInfo(infoSourceFilename); } catch { return; } Func unpopulatedCheck; if (onlyUnpopulated) unpopulatedCheck = target => string.IsNullOrEmpty(target?.Trim()); else unpopulatedCheck = target => true; var companyName = verInfo.CompanyName?.Trim(); if (unpopulatedCheck(targetEntry.Publisher) && !string.IsNullOrEmpty(companyName)) targetEntry.Publisher = companyName; if (unpopulatedCheck(targetEntry.RawDisplayName)) { var fileDescription = StringTools.StripStringFromVersionNumber(verInfo.FileDescription?.Trim()); var productName = verInfo.ProductName?.Trim(); if (!string.IsNullOrEmpty(fileDescription)) { if (!string.IsNullOrEmpty(productName) && productName.Length > fileDescription.Length) targetEntry.RawDisplayName = productName; else targetEntry.RawDisplayName = fileDescription; } else if (!string.IsNullOrEmpty(productName)) targetEntry.RawDisplayName = productName; } var comment = verInfo.Comments?.Trim(); if (unpopulatedCheck(targetEntry.Comment) && !string.IsNullOrEmpty(comment)) targetEntry.Comment = comment; if (unpopulatedCheck(targetEntry.DisplayVersion)) { var productVersion = verInfo.ProductVersion?.Trim(); if (string.IsNullOrEmpty(productVersion)) productVersion = verInfo.FileVersion?.Trim(); if (!string.IsNullOrEmpty(productVersion)) targetEntry.DisplayVersion = ApplicationEntryTools.CleanupDisplayVersion(productVersion); } } } } ================================================ FILE: source/UninstallTools/Factory/InfoAdders/FastSizeGenerator.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Diagnostics; using System.IO; using System.Text; using System.Threading.Tasks; using Klocman.Extensions; using Klocman.IO; using Scripting; using File = System.IO.File; namespace UninstallTools.Factory.InfoAdders { public class FastSizeGenerator : IMissingInfoAdder { private static readonly FileSystemObjectClass _fileSystemObject; private static bool _everythingAvailable; static FastSizeGenerator() { try { _fileSystemObject = new FileSystemObjectClass(); } catch (Exception ex) { Trace.WriteLine(@"FastSizeGenerator: Scripting.FileSystemObjectClass is not available - " + ex.Message); } try { if (EvGetSize(UninstallToolsGlobalConfig.AssemblyLocation).GetKbSize() == 0) throw new SystemException("Test failed to get valid BCU directory size"); _everythingAvailable = true; } catch (SystemException ex) { _everythingAvailable = false; Trace.WriteLine(@"FastSizeGenerator: Everything search engine is not available - " + ex.Message); } } public void AddMissingInformation(ApplicationUninstallerEntry target) { if (!Directory.Exists(target.InstallLocation) || UninstallToolsGlobalConfig.IsSystemDirectory(target.InstallLocation)) return; if (_everythingAvailable) { try { target.EstimatedSize = EvGetSize(target.InstallLocation); return; } catch (Exception ex) { Trace.WriteLine(ex); _everythingAvailable = false; } } if (_fileSystemObject != null) { try { var folder = _fileSystemObject.GetFolder(target.InstallLocation); var size = new FileSize(Convert.ToInt64(folder.Size) / 1024); target.EstimatedSize = size; } catch (Exception ex) { Trace.WriteLine(ex); } } } private static FileSize EvGetSize(string path) { path = Path.GetFullPath(path); var output = StartHelperAndReadOutput($"-size -a-d -size-leading-zero -no-digit-grouping -size-format 1 path:\"{path}\"").Result; var allResults = output.SplitNewlines(StringSplitOptions.RemoveEmptyEntries); long sum = 0; foreach (var result in allResults) { var split = result.Split(new[] { ' ' }, 2, StringSplitOptions.None); sum += long.Parse(split[0]); } return FileSize.FromBytes(sum); } private static async Task StartHelperAndReadOutput(string args) { var esPath = Path.Combine(UninstallToolsGlobalConfig.AssemblyLocation, "es.exe"); if (!File.Exists(esPath)) throw new FileNotFoundException(); using (var process = Process.Start(new ProcessStartInfo(esPath, args) { UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = false, CreateNoWindow = true, StandardOutputEncoding = Encoding.UTF8 })) { if (process == null) throw new InvalidOperationException("Could not start a new process"); var timeoutTask = Task.Delay(TimeSpan.FromSeconds(40)); var readOutputTask = process.StandardOutput.ReadToEndAsync(); await Task.WhenAny(readOutputTask, timeoutTask); if (!readOutputTask.IsCompleted) { try { process.Kill(); } catch { // Ignore exceptions from killing the process } throw new TimeoutException("es.exe appears to have hung"); } if (process.ExitCode == 0) return await readOutputTask; throw new IOException("es.exe failed to connect to Everything", process.ExitCode); } } public string[] RequiredValueNames { get; } = { nameof(ApplicationUninstallerEntry.InstallLocation) }; public bool RequiresAllValues { get; } = true; public bool AlwaysRun { get; } = false; public string[] CanProduceValueNames { get; } = { nameof(ApplicationUninstallerEntry.EstimatedSize) }; public InfoAdderPriority Priority { get; } = InfoAdderPriority.RunLast; } } ================================================ FILE: source/UninstallTools/Factory/InfoAdders/FileIconGetter.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System.Linq; namespace UninstallTools.Factory.InfoAdders { public class FileIconGetter : IMissingInfoAdder { public string[] RequiredValueNames { get; } = { nameof(ApplicationUninstallerEntry.UninstallerFullFilename), nameof(ApplicationUninstallerEntry.SortedExecutables) }; public bool RequiresAllValues { get; } = false; public bool AlwaysRun { get; } = false; public string[] CanProduceValueNames { get; } = { nameof(ApplicationUninstallerEntry.DisplayIcon), nameof(ApplicationUninstallerEntry.IconBitmap) }; public InfoAdderPriority Priority { get; } = InfoAdderPriority.RunLast; /// /// Run after DisplayIcon, DisplayName, UninstallerKind, InstallLocation, UninstallString have been initialized. /// public void AddMissingInformation(ApplicationUninstallerEntry entry) { if (entry.IconBitmap != null) return; // SdbInst uninstallers do not have any executables to check if (entry.UninstallerKind == UninstallerType.SdbInst) return; // Try getting an icon from the app's executables if (entry.SortedExecutables != null) { foreach (var executablePath in entry.SortedExecutables.Take(2)) { var exeIcon = UninstallToolsGlobalConfig.TryExtractAssociatedIcon(executablePath); if (exeIcon != null) { entry.DisplayIcon = executablePath; entry.IconBitmap = exeIcon; return; } } } var uninsIcon = UninstallToolsGlobalConfig.TryExtractAssociatedIcon(entry.UninstallerFullFilename); if (uninsIcon != null) { entry.DisplayIcon = entry.UninstallerFullFilename; entry.IconBitmap = uninsIcon; } } } } ================================================ FILE: source/UninstallTools/Factory/InfoAdders/GenerateSteamHelperStrings.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Linq; namespace UninstallTools.Factory.InfoAdders { public class GenerateSteamHelperStrings : IMissingInfoAdder { public void AddMissingInformation(ApplicationUninstallerEntry target) { if (target.UninstallerKind != UninstallerType.Steam) return; var appId = target.RatingId.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries).Last(); if (!int.TryParse(appId, out _)) return; if(!target.UninstallPossible || UninstallToolsGlobalConfig.QuietAutomatization) target.UninstallString = $"\"{SteamFactory.SteamHelperPath}\" uninstall {appId}"; if (UninstallToolsGlobalConfig.QuietAutomatization) target.QuietUninstallString = $"\"{SteamFactory.SteamHelperPath}\" uninstall /silent {appId}"; } public string[] RequiredValueNames { get; } = { nameof(ApplicationUninstallerEntry.UninstallerKind), nameof(ApplicationUninstallerEntry.RatingId) }; public bool RequiresAllValues { get; } = true; public bool AlwaysRun { get; } = true; public string[] CanProduceValueNames { get; } = { nameof(ApplicationUninstallerEntry.UninstallString), nameof(ApplicationUninstallerEntry.QuietUninstallString) }; public InfoAdderPriority Priority { get; } = InfoAdderPriority.RunLast; } } ================================================ FILE: source/UninstallTools/Factory/InfoAdders/IMissingInfoAdder.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ namespace UninstallTools.Factory.InfoAdders { public interface IMissingInfoAdder { /// /// Try to add missing information to the target entry. /// void AddMissingInformation(ApplicationUninstallerEntry target); /// /// Names of values this InfoAdder requires to work. /// string[] RequiredValueNames { get; } /// /// True if all Required Values need to be defined. /// False if only one needs to be defined. /// bool RequiresAllValues { get; } /// /// Always run this adder if the requirements are met. /// If false, only run this adder if it can produce any missing values. /// bool AlwaysRun { get; } /// /// Names of values this InfoAdder can fill in. /// string[] CanProduceValueNames { get; } /// /// Higher priority InfoAdders are executed first. /// InfoAdderPriority Priority { get; } } } ================================================ FILE: source/UninstallTools/Factory/InfoAdders/InfoAdderManager.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using Klocman.Extensions; using Klocman.Tools; namespace UninstallTools.Factory.InfoAdders { public class InfoAdderManager { private static readonly IMissingInfoAdder[] InfoAdders; private static readonly Dictionary> TargetProperties; private static readonly ICollection> UninstallerProperties; private static readonly ICollection> NonUninstallerProperties; static InfoAdderManager() { InfoAdders = GetInfoAdders().ToArray(); var defaultValues = new ApplicationUninstallerEntry(); TargetProperties = typeof(ApplicationUninstallerEntry) .GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) .Where(x => x.CanRead && x.CanWrite) .Where(x => IsTypeValid(x.PropertyType)) .ToDictionary(x => x.Name, x => { var compiled = x.CompileAccessors(); compiled.Tag = compiled.CompiledGet(defaultValues); return compiled; }); // Split properties related to uninstaller and its type so they can be moved all at same time // TODO Better sorting logic? If names change or props are added without uninstall in name they'll slip through foreach (var group in TargetProperties.Where(x => x.Key != nameof(ApplicationUninstallerEntry.UninstallerKind)) .GroupBy(x => x.Key.Contains("uninstall", StringComparison.OrdinalIgnoreCase))) { if (group.Key) UninstallerProperties = group.Select(x => x.Value).ToList(); else NonUninstallerProperties = group.Select(x => x.Value).ToList(); } } private static readonly Type BoolType = typeof(bool); /// /// Check if we can correctly detect if the type has no value. /// private static bool IsTypeValid(Type type) { // TODO is this filtering neccessary? return type != BoolType || Nullable.GetUnderlyingType(type) != null; } private static IEnumerable GetInfoAdders() { var type = typeof(IMissingInfoAdder); var types = Assembly.GetExecutingAssembly().GetTypes() //AppDomain.CurrentDomain.GetAssemblies().SelectMany(s => s.GetTypes()) .Where(p => type.IsAssignableFrom(p) && p.IsClass && !p.IsAbstract); var instances = types.Attempt(Activator.CreateInstance); return instances.Cast().OrderByDescending(x => x.Priority); } /// /// Fill in information using all detected IMissingInfoAdder classes /// public void AddMissingInformation(ApplicationUninstallerEntry target, bool skipRunLast = false) { var adders = InfoAdders.Where(x => !skipRunLast || x.Priority > InfoAdderPriority.RunLast).ToList(); var valueIsDefaultCache = new Dictionary(); // Checks if the value is default, buffering the result bool IsValueDefault(string key) { if (valueIsDefaultCache.TryGetValue(key, out var valIsDefault)) return valIsDefault; if (TargetProperties.TryGetValue(key, out var property)) { valIsDefault = Equals(property.CompiledGet(target), property.Tag); valueIsDefaultCache.Add(key, valIsDefault); return valIsDefault; } // If we can't check if the value is default, assume that it is to be safe return true; } for (var index = 0; index < adders.Count; index++) { var infoAdder = adders[index]; var requirements = infoAdder.RequiredValueNames; //TODO prioritize ones with all values existing from same priority tier? if (requirements.Any()) { if (infoAdder.RequiresAllValues) { if (infoAdder.RequiredValueNames.Any(IsValueDefault)) continue; } else { if (infoAdder.RequiredValueNames.All(IsValueDefault)) continue; } } // Only run the adder if it can actually fill in any missing values if (!infoAdder.AlwaysRun && !infoAdder.CanProduceValueNames.Any(IsValueDefault)) continue; infoAdder.AddMissingInformation(target); adders.Remove(infoAdder); // Remove items that might have changed from cache so they get recalculated foreach (var valueName in infoAdder.CanProduceValueNames) { valueIsDefaultCache.Remove(valueName); foreach (var relatedValueName in ApplicationUninstallerEntry.PropertyRelationships[valueName]) valueIsDefaultCache.Remove(relatedValueName); } // Retry all adders from the start if any of them succeeded index = -1; } } public void TryAddFieldInformation(ApplicationUninstallerEntry target, string targetValueName) { // TODO /* create copy list of adders similar logic to above try running whatever can add targetValueName if can't run any, check if any other adders can fill in the required values and try again */ throw new NotImplementedException(); } /// /// Copy missing property values /// /// Copy values to this object /// Copy from this object public void CopyMissingInformation(ApplicationUninstallerEntry baseEntry, ApplicationUninstallerEntry entryToMerge) { // If one of these is not null it will be merged by loop below. If both are not null they need special logic. if (baseEntry.StartupEntries != null && entryToMerge.StartupEntries != null) { baseEntry.StartupEntries = baseEntry.StartupEntries.Concat(entryToMerge.StartupEntries); } void CopyPropertyIfBetter(CompiledPropertyInfo property, bool alwaysCopy) { // If entryToMerge has a default (not set) value for this property, skip it so we don't lose data var newValue = property.CompiledGet(entryToMerge); if (Equals(newValue, property.Tag)) return; if (alwaysCopy) { property.CompiledSet(baseEntry, newValue); } else { // Copy new value to base entry if base doesn't have the value set, // or if the values are strings and merged value is longer var oldValue = property.CompiledGet(baseEntry); if (Equals(oldValue, property.Tag) || newValue is string sNew && oldValue is string sOld && sNew.Length > sOld.Length) { property.CompiledSet(baseEntry, newValue); } } } foreach (var property in NonUninstallerProperties) CopyPropertyIfBetter(property, false); // Make sure that all uninstaller-related properties are only copied when necessary, and that UninstallerKind // always changes together with the uninstall strings or we will get bugs elsewhere if there is a mismatch if (baseEntry.UninstallerKind == UninstallerType.Unknown && entryToMerge.UninstallerKind != UninstallerType.Unknown || baseEntry.UninstallerKind == UninstallerType.SimpleDelete && entryToMerge.UninstallPossible || !baseEntry.UninstallPossible || entryToMerge.UninstallerKind == UninstallerType.PowerShell) { baseEntry.UninstallerKind = entryToMerge.UninstallerKind; foreach (var property in UninstallerProperties) CopyPropertyIfBetter(property, true); } baseEntry.AdditionalJunk.AddRange(entryToMerge.AdditionalJunk); } } } ================================================ FILE: source/UninstallTools/Factory/InfoAdders/InfoAdderPriority.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ namespace UninstallTools.Factory.InfoAdders { public enum InfoAdderPriority { RunDeadLast = -2, RunLast = -1, Normal = 0, RunFirst = 1 } } ================================================ FILE: source/UninstallTools/Factory/InfoAdders/InnoSetupQuietUninstallStringGenerator.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ namespace UninstallTools.Factory.InfoAdders { public class InnoSetupQuietUninstallStringGenerator : IMissingInfoAdder { public void AddMissingInformation(ApplicationUninstallerEntry target) { if (target.UninstallerKind != UninstallerType.InnoSetup || string.IsNullOrEmpty(target.UninstallerFullFilename)) return; if (!UninstallToolsGlobalConfig.QuietAutomatization) return; /* Use UninstallerFullFilename to get rid of quotes and arguments (InnoSetup doesn't need any arguments) * * Unlike '/SILENT', when '/VERYSILENT' is specified, the uninstallation progress window is not displayed. * -> But if a restart is necessary and the '/NORESTART' command isn't used, the uninstaller will reboot without asking. * * /SUPPRESSMSGBOXES Instructs the uninstaller to suppress message boxes. Doesn't affect boxes from spawned processes. */ target.QuietUninstallString = $"\"{target.UninstallerFullFilename}\" /VERYSILENT /SUPPRESSMSGBOXES /NORESTART"; } public string[] RequiredValueNames { get; } = { nameof(ApplicationUninstallerEntry.UninstallerFullFilename), nameof(ApplicationUninstallerEntry.UninstallerKind) }; public bool RequiresAllValues { get; } = true; public bool AlwaysRun { get; } = true; public string[] CanProduceValueNames { get; } = { nameof(ApplicationUninstallerEntry.QuietUninstallString) }; public InfoAdderPriority Priority { get; } = InfoAdderPriority.Normal; } } ================================================ FILE: source/UninstallTools/Factory/InfoAdders/InstallDateAdder.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.IO; namespace UninstallTools.Factory.InfoAdders { public class InstallDateAdder : IMissingInfoAdder { public void AddMissingInformation(ApplicationUninstallerEntry target) { try { if (File.Exists(target.UninstallerFullFilename)) target.InstallDate = File.GetCreationTime(target.UninstallerFullFilename); else if (Directory.Exists(target.InstallLocation)) target.InstallDate = Directory.GetCreationTime(target.InstallLocation); } catch { target.InstallDate = DateTime.MinValue; } } public string[] RequiredValueNames { get; } = { nameof(ApplicationUninstallerEntry.InstallLocation), nameof(ApplicationUninstallerEntry.UninstallerFullFilename) }; public bool RequiresAllValues { get; } = false; public bool AlwaysRun { get; } = false; public string[] CanProduceValueNames { get; } = { nameof(ApplicationUninstallerEntry.InstallDate) }; public InfoAdderPriority Priority { get; } = InfoAdderPriority.RunLast; } } ================================================ FILE: source/UninstallTools/Factory/InfoAdders/InstallLocationGenerator.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ namespace UninstallTools.Factory.InfoAdders { public class InstallLocationGenerator : IMissingInfoAdder { public void AddMissingInformation(ApplicationUninstallerEntry target) { if (target.UninstallerKind == UninstallerType.Nsis || target.UninstallerKind == UninstallerType.InnoSetup) { if(!string.IsNullOrEmpty(target.UninstallerLocation)) target.InstallLocation = target.UninstallerLocation; } } public string[] RequiredValueNames { get; } = { nameof(ApplicationUninstallerEntry.UninstallerKind), nameof(ApplicationUninstallerEntry.UninstallerLocation) }; public bool RequiresAllValues { get; } = true; public bool AlwaysRun { get; } = false; public string[] CanProduceValueNames { get; } = { nameof(ApplicationUninstallerEntry.InstallLocation) }; public InfoAdderPriority Priority { get; } = InfoAdderPriority.RunFirst; } } ================================================ FILE: source/UninstallTools/Factory/InfoAdders/Is64BitGetter.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using Klocman.Tools; namespace UninstallTools.Factory.InfoAdders { public class Is64BitGetter : IMissingInfoAdder { public void AddMissingInformation(ApplicationUninstallerEntry target) { if (target.SortedExecutables == null || target.SortedExecutables.Length == 0 || target.Is64Bit != MachineType.Unknown) return; try { target.Is64Bit = FilesystemTools.CheckExecutableMachineType(target.SortedExecutables[0]); } catch { target.Is64Bit = MachineType.Unknown; } } public string[] RequiredValueNames { get; } = { nameof(ApplicationUninstallerEntry.SortedExecutables) }; public bool RequiresAllValues { get; } = true; public bool AlwaysRun { get; } = false; public string[] CanProduceValueNames { get; } = { nameof(ApplicationUninstallerEntry.Is64Bit) }; public InfoAdderPriority Priority { get; } = InfoAdderPriority.Normal; } } ================================================ FILE: source/UninstallTools/Factory/InfoAdders/KnownNameIconGetter.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.IO; using System.Linq; using System.Security; namespace UninstallTools.Factory.InfoAdders { public class KnownNameIconGetter : IMissingInfoAdder { private static readonly string[] IconNames = { "DisplayIcon.ico", "Icon.ico", "app.ico", "appicon.ico", "application.ico", "logo.ico" }; public string[] RequiredValueNames { get; } = { nameof(ApplicationUninstallerEntry.UninstallerLocation), nameof(ApplicationUninstallerEntry.InstallLocation) }; public bool RequiresAllValues { get; } = false; public bool AlwaysRun { get; } = false; public string[] CanProduceValueNames { get; } = { nameof(ApplicationUninstallerEntry.DisplayIcon), nameof(ApplicationUninstallerEntry.IconBitmap) }; public InfoAdderPriority Priority { get; } = InfoAdderPriority.Normal; public void AddMissingInformation(ApplicationUninstallerEntry entry) { if (entry.IconBitmap != null) return; // SdbInst uninstallers do not have any executables to check if (entry.UninstallerKind == UninstallerType.SdbInst) return; try { // Look for icons with known names in InstallLocation and UninstallerLocation var query = from targetDir in new[] {entry.InstallLocation, entry.UninstallerLocation} where !string.IsNullOrEmpty(targetDir) && Directory.Exists(targetDir) from iconName in IconNames let combinedIconPath = Path.Combine(targetDir, iconName) where File.Exists(combinedIconPath) select combinedIconPath; foreach (var iconPath in query) { var icon = UninstallToolsGlobalConfig.TryExtractAssociatedIcon(iconPath); if (icon != null) { entry.IconBitmap = icon; entry.DisplayIcon = iconPath; return; } } } catch (SecurityException) { } catch (UnauthorizedAccessException) { } } } } ================================================ FILE: source/UninstallTools/Factory/InfoAdders/MsiInfoAdder.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.IO; using System.Linq; using Klocman.Extensions; using Klocman.IO; using Klocman.Native; namespace UninstallTools.Factory.InfoAdders { public class MsiInfoAdder : IMissingInfoAdder { public void AddMissingInformation(ApplicationUninstallerEntry target) { //Debug.Assert(target.UninstallerKind != UninstallerType.Msiexec); if (target.UninstallerKind != UninstallerType.Msiexec) return; ApplyMsiInfo(target, target.BundleProviderKey); } public string[] RequiredValueNames { get; } = { nameof(ApplicationUninstallerEntry.UninstallerKind), nameof(ApplicationUninstallerEntry.BundleProviderKey) }; public bool RequiresAllValues { get; } = true; public bool AlwaysRun { get; } = false; public string[] CanProduceValueNames { get; } = { nameof(ApplicationUninstallerEntry.RawDisplayName), nameof(ApplicationUninstallerEntry.DisplayVersion), nameof(ApplicationUninstallerEntry.Publisher), nameof(ApplicationUninstallerEntry.InstallLocation), nameof(ApplicationUninstallerEntry.InstallSource), nameof(ApplicationUninstallerEntry.UninstallerFullFilename), nameof(ApplicationUninstallerEntry.DisplayIcon), nameof(ApplicationUninstallerEntry.AboutUrl), nameof(ApplicationUninstallerEntry.InstallDate), //nameof(ApplicationUninstallerEntry.SortedExecutables) // TODO: This works but is much too slow to run for every entry }; public InfoAdderPriority Priority { get; } = InfoAdderPriority.RunFirst; /// /// A valid guid is REQUIRED. It doesn't have to be set on the entry, but should be. /// private static void ApplyMsiInfo(ApplicationUninstallerEntry entry, Guid guid) { // Make sure this is a real msiexec product ID if (!MsiTools.IsInstalled(guid)) return; FillInMissingInfoMsiHelper(() => entry.RawDisplayName, x => entry.RawDisplayName = x, guid, MsiWrapper.INSTALLPROPERTY.INSTALLEDPRODUCTNAME, MsiWrapper.INSTALLPROPERTY.PRODUCTNAME); FillInMissingInfoMsiHelper(() => entry.DisplayVersion, x => entry.DisplayVersion = ApplicationEntryTools.CleanupDisplayVersion(x), guid, MsiWrapper.INSTALLPROPERTY.VERSIONSTRING, MsiWrapper.INSTALLPROPERTY.VERSION); FillInMissingInfoMsiHelper(() => entry.Publisher, x => entry.Publisher = x, guid, MsiWrapper.INSTALLPROPERTY.PUBLISHER); FillInMissingInfoMsiHelper(() => entry.InstallLocation, x => entry.InstallLocation = x, guid, MsiWrapper.INSTALLPROPERTY.INSTALLLOCATION); FillInMissingInfoMsiHelper(() => entry.InstallSource, x => entry.InstallSource = x, guid, MsiWrapper.INSTALLPROPERTY.INSTALLSOURCE); FillInMissingInfoMsiHelper(() => entry.UninstallerFullFilename, x => entry.UninstallerFullFilename = x, guid, MsiWrapper.INSTALLPROPERTY.LOCALPACKAGE); FillInMissingInfoMsiHelper(() => entry.DisplayIcon, x => entry.DisplayIcon = x, guid, MsiWrapper.INSTALLPROPERTY.PRODUCTICON); FillInMissingInfoMsiHelper(() => entry.AboutUrl, x => entry.AboutUrl = x, guid, MsiWrapper.INSTALLPROPERTY.HELPLINK, MsiWrapper.INSTALLPROPERTY.URLUPDATEINFO, MsiWrapper.INSTALLPROPERTY.URLINFOABOUT); if (entry.InstallDate.IsDefault()) { var temp = MsiTools.MsiGetProductInfo(guid, MsiWrapper.INSTALLPROPERTY.INSTALLDATE); if (temp.IsNotEmpty()) { try { entry.InstallDate = new DateTime(int.Parse(temp.Substring(0, 4)), int.Parse(temp.Substring(4, 2)), int.Parse(temp.Substring(6, 2))); } catch { // Date had invalid format, default to nothing } } } if (string.IsNullOrWhiteSpace(entry.InstallLocation) || entry.SortedExecutables == null) { var paths = MsiTools.GetInstalledComponentPaths(guid); if (paths == null) return; // Checking .exe paths seems to be pretty reliable var executables = paths.Filenames.Where(x => x.EndsWith(".exe", StringComparison.OrdinalIgnoreCase)).ToArray(); if (executables.Length > 0) { var addedInstallLocation = false; if (string.IsNullOrWhiteSpace(entry.InstallLocation)) { var bestGuess = executables.GroupBy(Path.GetDirectoryName, StringComparer.OrdinalIgnoreCase) .Where(x => !UninstallToolsGlobalConfig.IsSystemDirectory(x.Key)) // Deal with apps installing executables to the Windows directory .OrderByDescending(x => UninstallToolsGlobalConfig.IsPathInsideProgramFiles(x.Key)) // Always prefer PF .ThenBy(x => x.Key.Length) // Shortest path is most likely to be the application root .FirstOrDefault(); if (!string.IsNullOrEmpty(bestGuess?.Key)) { entry.InstallLocation = bestGuess.Key; addedInstallLocation = true; } } // Update executable list based on new information. Keep existing executables if they exist, as they may be more accurate than the MSI component paths var executablesToSort = executables.Select(x => new FileInfo(x)); if (entry.SortedExecutables != null) executablesToSort = executablesToSort.Concat(entry.SortedExecutables.Select(x => new FileInfo(x))); if (addedInstallLocation) executablesToSort = executablesToSort.Concat(AppExecutablesSearcher.ScanDirectory(new DirectoryInfo(entry.InstallLocation)).ExecutableFiles); entry.SortedExecutables = AppExecutablesSearcher.SortListExecutables(executablesToSort.DistinctBy(x => x.FullName, StringComparer.OrdinalIgnoreCase), entry.DisplayName) .Select(x => x.FullName).ToArray(); } // If the exe search failed, pick the folder with the most files in it instead (needed with e.g. Net Framework reference assemblies) if (string.IsNullOrWhiteSpace(entry.InstallLocation)) { var bestGuess = paths.Filenames .Where(Path.HasExtension) .GroupBy(Path.GetDirectoryName, StringComparer.OrdinalIgnoreCase) .Where(x => !UninstallToolsGlobalConfig.IsSystemDirectory(x.Key)) // Deal with apps installing executables to the Windows directory .OrderByDescending(x => UninstallToolsGlobalConfig.IsPathInsideProgramFiles(x.Key)) // Always prefer PF .ThenByDescending(x => x.Count()) // Directory with the highest amount of files is the safest bet .ThenBy(x => x.Key.Length) .FirstOrDefault(); if (!string.IsNullOrEmpty(bestGuess?.Key)) entry.InstallLocation = bestGuess.Key; } } } private static void FillInMissingInfoMsiHelper(Func get, Action set, Guid guid, params MsiWrapper.INSTALLPROPERTY[] properties) { if (string.IsNullOrEmpty(get())) { foreach (var item in properties) { var temp = MsiTools.MsiGetProductInfo(guid, item); //IMPORTANT: Do not assign empty strings, they will mess up automatic property creation later on. if (temp.IsNotEmpty()) set(temp); } } } } } ================================================ FILE: source/UninstallTools/Factory/InfoAdders/MsiUninstallStringGenerator.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using UninstallTools.Uninstaller; namespace UninstallTools.Factory.InfoAdders { public class MsiUninstallStringGenerator : IMissingInfoAdder { public void AddMissingInformation(ApplicationUninstallerEntry target) { if (target.UninstallerKind != UninstallerType.Msiexec) return; if (string.IsNullOrEmpty(target.UninstallString)) target.UninstallString = UninstallManager.GetMsiString(target.BundleProviderKey, MsiUninstallModes.Uninstall); if (string.IsNullOrEmpty(target.QuietUninstallString)) target.QuietUninstallString = UninstallManager.GetMsiString(target.BundleProviderKey, MsiUninstallModes.QuietUninstall); } public string[] RequiredValueNames { get; } = { nameof(ApplicationUninstallerEntry.UninstallerKind), nameof(ApplicationUninstallerEntry.BundleProviderKey) }; public bool RequiresAllValues { get; } = true; public bool AlwaysRun { get; } = false; public string[] CanProduceValueNames { get; } = { nameof(ApplicationUninstallerEntry.QuietUninstallString), nameof(ApplicationUninstallerEntry.UninstallString) }; public InfoAdderPriority Priority { get; } = InfoAdderPriority.Normal; } } ================================================ FILE: source/UninstallTools/Factory/InfoAdders/NsisQuietUninstallStringGenerator.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using Klocman.Extensions; namespace UninstallTools.Factory.InfoAdders { public class NsisQuietUninstallStringGenerator : IMissingInfoAdder { public void AddMissingInformation(ApplicationUninstallerEntry target) { if (target.QuietUninstallPossible || target.UninstallerKind != UninstallerType.Nsis || string.IsNullOrEmpty(target.UninstallString)) return; if (!UninstallToolsGlobalConfig.QuietAutomatization || !UninstallToolsGlobalConfig.UninstallerAutomatizerExists) return; var nsisCommandStart = $"\"{UninstallToolsGlobalConfig.UninstallerAutomatizerPath}\" {nameof(UninstallerType.Nsis)} "; nsisCommandStart = nsisCommandStart.AppendIf(UninstallToolsGlobalConfig.QuietAutomatizationKillStuck, "/K "); target.QuietUninstallString = nsisCommandStart.Append(target.UninstallString); } public string[] RequiredValueNames { get; } = { nameof(ApplicationUninstallerEntry.UninstallString), nameof(ApplicationUninstallerEntry.UninstallerKind) }; public bool RequiresAllValues { get; } = true; public bool AlwaysRun { get; } = false; public string[] CanProduceValueNames { get; } = { nameof(ApplicationUninstallerEntry.QuietUninstallString) }; public InfoAdderPriority Priority { get; } = InfoAdderPriority.Normal; } } ================================================ FILE: source/UninstallTools/Factory/InfoAdders/PredefinedAppQuietUninstallStringGenerator.cs ================================================ /* Copyright (c) 2019 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; namespace UninstallTools.Factory.InfoAdders { /// /// Hardcoded quiet string generators for specific applications /// public class PredefinedAppQuietUninstallStringGenerator : IMissingInfoAdder { public void AddMissingInformation(ApplicationUninstallerEntry target) { if (target.QuietUninstallPossible || !target.UninstallPossible) return; var uninstallString = target.UninstallString; // MS Edge developer builds if (uninstallString.Contains("--msedge-beta", StringComparison.Ordinal) && uninstallString.Contains("--uninstall", StringComparison.Ordinal)) target.QuietUninstallString = uninstallString.Replace("--uninstall", "--force-uninstall"); } public string[] RequiredValueNames { get; } = { nameof(ApplicationUninstallerEntry.UninstallString) }; public bool RequiresAllValues { get; } = true; public bool AlwaysRun { get; } = false; public string[] CanProduceValueNames { get; } = { nameof(ApplicationUninstallerEntry.QuietUninstallString) }; public InfoAdderPriority Priority { get; } = InfoAdderPriority.Normal; } } ================================================ FILE: source/UninstallTools/Factory/InfoAdders/QuietUninstallStringCopier.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ namespace UninstallTools.Factory.InfoAdders { public class QuietUninstallStringCopier : IMissingInfoAdder { public void AddMissingInformation(ApplicationUninstallerEntry target) { target.UninstallString = target.QuietUninstallString; } public string[] RequiredValueNames { get; } = { nameof(ApplicationUninstallerEntry.QuietUninstallString) }; public bool RequiresAllValues { get; } = true; public bool AlwaysRun { get; } = false; public string[] CanProduceValueNames { get; } = { nameof(ApplicationUninstallerEntry.UninstallString) }; public InfoAdderPriority Priority { get; } = InfoAdderPriority.RunFirst; } } ================================================ FILE: source/UninstallTools/Factory/InfoAdders/SimpleDeleteUninstallStringGenerator.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Diagnostics; using System.IO; namespace UninstallTools.Factory.InfoAdders { public class SimpleDeleteUninstallStringGenerator : IMissingInfoAdder { static SimpleDeleteUninstallStringGenerator() { try { UniversalUninstallerFilename = new FileInfo( Path.Combine(UninstallToolsGlobalConfig.AssemblyLocation, "UniversalUninstaller.exe")); UniversalUninstallerIsAvailable = UniversalUninstallerFilename.Exists; } catch (Exception e) { Trace.WriteLine(e); UniversalUninstallerFilename = null; UniversalUninstallerIsAvailable = false; } } public static FileInfo UniversalUninstallerFilename { get; } public static bool UniversalUninstallerIsAvailable { get; } public void AddMissingInformation(ApplicationUninstallerEntry target) { if (target.UninstallerKind != UninstallerType.SimpleDelete) return; if (target.UninstallString == null) { target.UninstallString = UniversalUninstallerIsAvailable ? GetNewUninstallString(target.InstallLocation, false) : GetOldSimpleDeleteString(target.InstallLocation, false); } if (target.QuietUninstallString == null) { target.QuietUninstallString = UniversalUninstallerIsAvailable ? GetNewUninstallString(target.InstallLocation, true) : GetOldSimpleDeleteString(target.InstallLocation, true); } } public string[] RequiredValueNames { get; } = { nameof(ApplicationUninstallerEntry.UninstallerKind), nameof(ApplicationUninstallerEntry.InstallLocation) }; public bool RequiresAllValues { get; } = true; public bool AlwaysRun { get; } = false; public string[] CanProduceValueNames { get; } = { nameof(ApplicationUninstallerEntry.UninstallString), nameof(ApplicationUninstallerEntry.QuietUninstallString) }; public InfoAdderPriority Priority { get; } = InfoAdderPriority.RunDeadLast; private static string GetNewUninstallString(string installLocation, bool quiet) { return quiet ? $"\"{UniversalUninstallerFilename.FullName}\" /Q \"{installLocation}\\\"" : $"\"{UniversalUninstallerFilename.FullName}\" \"{installLocation}\\\""; } private static string GetOldSimpleDeleteString(string installLocation, bool quiet) { return quiet ? $"cmd.exe /C del /F /S /Q \"{installLocation}\\\"" : $"cmd.exe /C del /S \"{installLocation}\\\" && pause"; } } } ================================================ FILE: source/UninstallTools/Factory/InfoAdders/UninstallerSearcher.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.IO; using System.Linq; namespace UninstallTools.Factory.InfoAdders { public class UninstallerSearcher : IMissingInfoAdder { private static readonly string[] UninstallerFilters = { "unins0", "uninstall", "uninst", "uninstaller" }; public void AddMissingInformation(ApplicationUninstallerEntry target) { if (!string.IsNullOrEmpty(target.UninstallString) || target.SortedExecutables == null) return; // Attempt to find an uninstaller application foreach (var file in target.SortedExecutables.Concat(FindExtraExecutables(target.InstallLocation))) { string name; try { name = Path.GetFileNameWithoutExtension(file); if (string.IsNullOrEmpty(name)) continue; } catch (ArgumentException) { continue; } if (UninstallerFilters.Any(filter => name.StartsWith(filter, StringComparison.InvariantCultureIgnoreCase) || name.EndsWith(filter, StringComparison.InvariantCultureIgnoreCase))) { target.UninstallString = file; return; } } } private static IEnumerable FindExtraExecutables(string directoryPath) { if (Directory.Exists(directoryPath)) { try { return Directory.GetFiles(directoryPath, "*.bat", SearchOption.TopDirectoryOnly); } catch (IOException) { } catch (UnauthorizedAccessException) { } } return Enumerable.Empty(); } public string[] RequiredValueNames { get; } = { nameof(ApplicationUninstallerEntry.SortedExecutables) }; public bool RequiresAllValues { get; } = true; public bool AlwaysRun { get; } = false; public string[] CanProduceValueNames { get; } = { nameof(ApplicationUninstallerEntry.UninstallString) }; public InfoAdderPriority Priority { get; } = InfoAdderPriority.RunLast; } } ================================================ FILE: source/UninstallTools/Factory/InfoAdders/UninstallerTypeAdder.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.IO; using System.Security; using System.Text; using System.Text.RegularExpressions; using Klocman.Extensions; using Klocman.Tools; namespace UninstallTools.Factory.InfoAdders { public class UninstallerTypeAdder : IMissingInfoAdder { private static readonly Regex InnoSetupFilenameRegex = new(@"unins\d\d\d", RegexOptions.Compiled | RegexOptions.IgnoreCase); public void AddMissingInformation(ApplicationUninstallerEntry target) { if (target.UninstallerKind != UninstallerType.Unknown) return; var uninstallString = !string.IsNullOrEmpty(target.UninstallString) ? target.UninstallString : target.QuietUninstallString; if (!string.IsNullOrEmpty(uninstallString)) { target.UninstallerKind = GetUninstallerType(uninstallString); } else if (!string.IsNullOrEmpty(target.InstallLocation)) { // We don't have a valid uninstaller, so tell simple delete adder to do its job and make our own target.UninstallerKind = UninstallerType.SimpleDelete; } } public string[] RequiredValueNames { get; } = { nameof(ApplicationUninstallerEntry.UninstallString), nameof(ApplicationUninstallerEntry.QuietUninstallString), nameof(ApplicationUninstallerEntry.InstallLocation) }; public bool RequiresAllValues { get; } = false; public bool AlwaysRun { get; } = false; public string[] CanProduceValueNames { get; } = { nameof(ApplicationUninstallerEntry.UninstallerKind) }; // Let other adders run first in case they add uninstall strings public InfoAdderPriority Priority { get; } = InfoAdderPriority.RunLast; public static UninstallerType GetUninstallerType(string uninstallString) { // Detect MSI / Windows installer based on the uninstall string // e.g. "C:\ProgramData\Package Cache\{33d1fd90-4274-48a1-9bc1-97e33d9c2d6f}\vcredist_x86.exe" /uninstall if (ApplicationEntryTools.PathPointsToMsiExec(uninstallString) || uninstallString.ContainsAll( new[] { @"\Package Cache\{", @"}\", ".exe" }, StringComparison.OrdinalIgnoreCase)) return UninstallerType.Msiexec; // Detect Sdbinst if (uninstallString.Contains("sdbinst", StringComparison.OrdinalIgnoreCase) && uninstallString.Contains(".sdb", StringComparison.OrdinalIgnoreCase)) return UninstallerType.SdbInst; if (uninstallString.Contains(@"InstallShield Installation Information\{", StringComparison.OrdinalIgnoreCase)) return UninstallerType.InstallShield; if (uninstallString.Contains("powershell.exe", StringComparison.OrdinalIgnoreCase) || uninstallString.Contains(".ps1", StringComparison.OrdinalIgnoreCase)) return UninstallerType.PowerShell; if (ProcessStartCommand.TryParse(uninstallString, out var ps) && Path.IsPathRooted(ps.FileName) && File.Exists(ps.FileName)) { try { var fileName = Path.GetFileNameWithoutExtension(ps.FileName); // Detect Inno Setup if (fileName != null && InnoSetupFilenameRegex.IsMatch(fileName)) { // Check if Inno Setup Uninstall Log exists if (File.Exists(ps.FileName.Substring(0, ps.FileName.Length - 3) + "dat")) return UninstallerType.InnoSetup; } // Detect NSIS Nullsoft.NSIS. Slow, but there's no other way than to scan the file using (var reader = new StreamReader(ps.FileName!, Encoding.ASCII)) { string line; while ((line = reader.ReadLine()) != null) { if (line.Contains("Nullsoft", StringComparison.Ordinal)) return UninstallerType.Nsis; } } /* Unused/unnecessary if (result.Contains("InstallShield")) return UninstallerType.InstallShield; if (result.Contains("Inno.Setup") || result.Contains("Inno Setup")) return UninstallerType.InnoSetup; if(result.Contains(@"Adobe Systems Incorporated Setup")) return UninstallerType.AdobeSetup; */ } catch (IOException) { } catch (UnauthorizedAccessException) { } catch (SecurityException) { } } return UninstallerType.Unknown; } } } ================================================ FILE: source/UninstallTools/Factory/InfoAdders/VersionCleaner.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ namespace UninstallTools.Factory.InfoAdders { public class VersionCleaner : IMissingInfoAdder { public void AddMissingInformation(ApplicationUninstallerEntry target) { if (string.IsNullOrEmpty(target.DisplayVersion)) return; target.DisplayVersion = ApplicationEntryTools.CleanupDisplayVersion(target.DisplayVersion); } public string[] RequiredValueNames { get; } = { nameof(ApplicationUninstallerEntry.DisplayVersion) }; public bool RequiresAllValues { get; } = true; public bool AlwaysRun { get; } = true; public string[] CanProduceValueNames { get; } = {}; public InfoAdderPriority Priority { get; } = InfoAdderPriority.RunDeadLast; } } ================================================ FILE: source/UninstallTools/Factory/InfoAdders/WebBrowserMarker.cs ================================================ /* Copyright (c) 2018 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System.Linq; using Klocman.Tools; namespace UninstallTools.Factory.InfoAdders { public class WebBrowserMarker : IMissingInfoAdder { private static readonly string[] BrowserExecutables = WindowsTools.GetInstalledWebBrowsers(); public void AddMissingInformation(ApplicationUninstallerEntry target) { if (target == null || target.SortedExecutables.Length == 0) return; target.IsWebBrowser = target.SortedExecutables.Any( x => BrowserExecutables.Any( y => PathTools.PathsEqual(x, y))); } public string[] RequiredValueNames { get; } = { nameof(ApplicationUninstallerEntry.SortedExecutables) }; public string[] CanProduceValueNames { get; } = { nameof(ApplicationUninstallerEntry.IsWebBrowser) }; public bool RequiresAllValues { get; } = true; public bool AlwaysRun { get; } = false; public InfoAdderPriority Priority { get; } = InfoAdderPriority.RunLast; } } ================================================ FILE: source/UninstallTools/Factory/Json/DynamicStringArrayConverter.cs ================================================ using System; using System.Collections.Generic; using System.Text.Json; using System.Text.Json.Serialization; namespace UninstallTools.Factory.Json { /// /// Handle JSON string array entry that has one dimension less or more. /// internal class DynamicStringArrayConverter : JsonConverter { public override string[] Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { // 0-dimension if (reader.TokenType == JsonTokenType.String) return new[] { reader.GetString() }; if (reader.TokenType == JsonTokenType.StartArray) { var results = new List(); ReadStrings(ref reader, results); return results.ToArray(); } throw new JsonException($"Expected string or array token but got {reader.TokenType}"); } private static void ReadStrings(ref Utf8JsonReader reader, List results) { while (reader.Read() && reader.TokenType != JsonTokenType.EndArray) { switch (reader.TokenType) { // normal case JsonTokenType.String: results.Add(reader.GetString()); break; // nested case JsonTokenType.StartArray: var first = ReadFirstString(ref reader); if (first != null) results.Add(first); break; case JsonTokenType.StartObject: reader.Skip(); break; } } } private static string ReadFirstString(ref Utf8JsonReader reader) { string result = null; while (reader.Read() && reader.TokenType != JsonTokenType.EndArray) { if (result != null) { if (reader.TokenType == JsonTokenType.StartArray || reader.TokenType == JsonTokenType.StartObject) reader.Skip(); continue; } switch (reader.TokenType) { case JsonTokenType.String: result = reader.GetString(); break; case JsonTokenType.StartArray: result = ReadFirstString(ref reader); break; case JsonTokenType.StartObject: reader.Skip(); break; } } return result; } public override void Write(Utf8JsonWriter writer, string[] value, JsonSerializerOptions options) { throw new NotImplementedException(); } } } ================================================ FILE: source/UninstallTools/Factory/Json/PowerShellDateTimeOffsetConverter.cs ================================================ using System; using System.Text.Json; using System.Text.Json.Serialization; namespace UninstallTools.Factory.Json { internal class PowerShellDateTimeOffsetConverter : JsonConverter { public override DateTimeOffset Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TokenType == JsonTokenType.String) { var value = reader.GetString(); // Windows PowerShell: /Date(1640995200000)/ if (value.StartsWith("/", StringComparison.Ordinal)) { var timestamp = long.Parse(value.Substring(6, value.Length - 8)); return DateTimeOffset.FromUnixTimeMilliseconds(timestamp); } // PowerShell Core: 2022-01-01T00:00:00.0000000+00:00 else { return DateTimeOffset.Parse(value); } } // Windows PowerShell: nested { value: /Date(1640995200000)/ } else if (reader.TokenType == JsonTokenType.StartObject) { var clone = reader; reader.Skip(); while (clone.Read() && clone.TokenType != JsonTokenType.EndObject) { if (clone.TokenType == JsonTokenType.PropertyName && clone.GetString() == "value") { _ = clone.Read(); var value = clone.GetString(); var timestamp = long.Parse(value.Substring(6, value.Length - 8)); return DateTimeOffset.FromUnixTimeMilliseconds(timestamp); } } } throw new JsonException(); } public override void Write(Utf8JsonWriter writer, DateTimeOffset value, JsonSerializerOptions options) { throw new NotImplementedException(); } } } ================================================ FILE: source/UninstallTools/Factory/OculusFactory.cs ================================================ /* Copyright (c) 2018 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.IO; using Klocman.Extensions; using Klocman.Tools; using UninstallTools.Factory.InfoAdders; using UninstallTools.Properties; namespace UninstallTools.Factory { public class OculusFactory : IIndependantUninstallerFactory { private static string HelperPath { get; } = Path.Combine(UninstallToolsGlobalConfig.AssemblyLocation, @"OculusHelper.exe"); private static bool IsHelperAvailable() => File.Exists(HelperPath); public IList GetUninstallerEntries(ListGenerationProgress.ListGenerationCallback progressCallback) { var results = new List(); if (!IsHelperAvailable()) return results; var output = FactoryTools.StartHelperAndReadOutput(HelperPath, "/query"); if (string.IsNullOrEmpty(output)) return results; foreach (var data in FactoryTools.ExtractAppDataSetsFromHelperOutput(output)) { if (!data.ContainsKey("CanonicalName")) continue; var name = data["CanonicalName"]; if (string.IsNullOrEmpty(name)) continue; var uninstallStr = $"\"{HelperPath}\" /uninstall {name}"; var entry = new ApplicationUninstallerEntry { RatingId = name, //RegistryKeyName = name, UninstallString = uninstallStr, QuietUninstallString = uninstallStr, IsValid = true, UninstallerKind = UninstallerType.Oculus, InstallLocation = data["InstallLocation"], DisplayVersion = ApplicationEntryTools.CleanupDisplayVersion(data["Version"]), IsProtected = "true".Equals(data["IsCore"], StringComparison.OrdinalIgnoreCase), }; var executable = data["LaunchFile"]; if (File.Exists(executable)) { ExecutableAttributeExtractor.FillInformationFromFileAttribs(entry, executable, true); entry.DisplayIcon = executable; } if (Directory.Exists(entry.InstallLocation)) entry.InstallDate = Directory.GetCreationTime(entry.InstallLocation); if (string.IsNullOrEmpty(entry.RawDisplayName)) entry.RawDisplayName = name.Replace('-', ' ').ToTitleCase(); results.Add(entry); } return results; } public bool IsEnabled() => UninstallToolsGlobalConfig.ScanOculus; public string DisplayName => Localisation.Progress_AppStores_Oculus; } } ================================================ FILE: source/UninstallTools/Factory/PredefinedFactory.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System.Collections.Generic; using System.IO; using Klocman.IO; using UninstallTools.Properties; namespace UninstallTools.Factory { /// /// Get uninstallers that were manually pre-defined. /// public class PredefinedFactory : IIndependantUninstallerFactory { public IList GetUninstallerEntries( ListGenerationProgress.ListGenerationCallback progressCallback) { var items = new List(); return items; } public bool IsEnabled() => UninstallToolsGlobalConfig.ScanPreDefined; public string DisplayName => Localisation.Progress_AppStores_Templates; } } ================================================ FILE: source/UninstallTools/Factory/RegistryFactory.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Security; using Klocman.Extensions; using Klocman.IO; using Klocman.Tools; using Microsoft.Win32; using UninstallTools.Factory.InfoAdders; using UninstallTools.Properties; namespace UninstallTools.Factory { public class RegistryFactory : IUninstallerFactory { public static readonly string RegistryNameBundleProviderKey = "BundleProviderKey"; public static readonly string RegistryNameComment = "Comment"; public static readonly string RegistryNameDisplayIcon = "DisplayIcon"; public static readonly string RegistryNameDisplayName = "DisplayName"; public static readonly string RegistryNameDisplayVersion = "DisplayVersion"; public static readonly string RegistryNameEstimatedSize = "EstimatedSize"; public static readonly string RegistryNameInstallDate = "InstallDate"; public static readonly string RegistryNameInstallLocation = "InstallLocation"; public static readonly string RegistryNameInstallSource = "InstallSource"; public static readonly string RegistryNameModifyPath = "ModifyPath"; public static readonly string RegistryNameParentKeyName = "ParentKeyName"; public static readonly string RegistryNamePublisher = "Publisher"; public static readonly string RegistryNameQuietUninstallString = "QuietUninstallString"; public static readonly IEnumerable RegistryNamesOfUrlSources = new[] {"URLInfoAbout", "URLUpdateInfo", "HelpLink"}; public static readonly string RegistryNameSystemComponent = "SystemComponent"; public static readonly string RegistryNameUninstallString = "UninstallString"; public static readonly string RegistryNameWindowsInstaller = "WindowsInstaller"; private static readonly string RegUninstallersKeyDirect = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"; private static readonly string RegUninstallersKeyWow = @"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"; private readonly IEnumerable _windowsInstallerValidGuids; public RegistryFactory(IEnumerable windowsInstallerValidGuids) { _windowsInstallerValidGuids = windowsInstallerValidGuids; } public IList GetUninstallerEntries(ListGenerationProgress.ListGenerationCallback progressCallback) { var uninstallerRegistryKeys = new List>(); progressCallback(new ListGenerationProgress(0, -1, Localisation.Progress_Registry_Gathering)); foreach (var kvp in GetParentRegistryKeys()) { uninstallerRegistryKeys.AddRange( kvp.Key.GetSubKeyNames() .Select(subkeyName => OpenSubKeySafe(kvp.Key, subkeyName)) .Where(subkey => subkey != null) .Select(subkey => new KeyValuePair(subkey, kvp.Value))); kvp.Key.Close(); } void WorkLogic(KeyValuePair data, List state) { try { var entry = TryCreateFromRegistry(data.Key, data.Value); if (entry != null) state.Add(entry); } catch (Exception ex) { //Uninstaller is invalid or there is no uninstaller in the first place. Skip it to avoid problems. Trace.WriteLine($@"Failed to extract reg entry {data.Key.Name} - {ex}"); } finally { data.Key.Close(); } } var workSpreader = new ThreadedWorkSpreader, List>( FactoryThreadedHelpers.MaxThreadsPerDrive, WorkLogic, list => new List(list.Count), pair => { try { return string.Format(Localisation.Progress_Registry_Processing, Path.GetFileName(pair.Key.Name)); } catch { return string.Empty; } }); // We are mostly reading from registry, so treat everything as on a single drive var dataBuckets = new List>> { uninstallerRegistryKeys }; workSpreader.Start(dataBuckets, progressCallback); return workSpreader.Join().SelectMany(x => x).ToList(); } private static string GetAboutUrl(RegistryKey uninstallerKey) { return RegistryNamesOfUrlSources.Select(uninstallerKey.GetStringSafe) .FirstOrDefault(tempSource => !string.IsNullOrEmpty(tempSource) && tempSource.Contains('.')); } private static ApplicationUninstallerEntry GetBasicInformation(RegistryKey uninstallerKey) { return new ApplicationUninstallerEntry { RegistryPath = uninstallerKey.Name, RegistryKeyName = uninstallerKey.GetKeyName(), Comment = uninstallerKey.GetStringSafe(RegistryNameComment), RawDisplayName = uninstallerKey.GetStringSafe(RegistryNameDisplayName), DisplayVersion = ApplicationEntryTools.CleanupDisplayVersion(uninstallerKey.GetStringSafe(RegistryNameDisplayVersion)), ParentKeyName = uninstallerKey.GetStringSafe(RegistryNameParentKeyName), Publisher = uninstallerKey.GetStringSafe(RegistryNamePublisher), UninstallString = GetUninstallString(uninstallerKey), QuietUninstallString = GetQuietUninstallString(uninstallerKey), ModifyPath = uninstallerKey.GetStringSafe(RegistryNameModifyPath), InstallLocation = uninstallerKey.GetStringSafe(RegistryNameInstallLocation), InstallSource = uninstallerKey.GetStringSafe(RegistryNameInstallSource), SystemComponent = Convert.ToInt32(uninstallerKey.GetValue(RegistryNameSystemComponent, 0)) != 0, DisplayIcon = uninstallerKey.GetStringSafe(RegistryNameDisplayIcon) }; } private static FileSize GetEstimatedSize(RegistryKey uninstallerKey) { try { // Use Convert.ToInt64 because some applications put a string in here instead of a number var tempSize = Convert.ToInt64(uninstallerKey.GetValue(RegistryNameEstimatedSize, 0)); return FileSize.FromKilobytes(tempSize); } catch (SystemException e) when (e is FormatException or InvalidCastException) { return FileSize.Empty; } } private static Guid GetGuid(RegistryKey uninstallerKey) { // Look for a GUID registry entry var tempGuidString = uninstallerKey.GetStringSafe(RegistryNameBundleProviderKey); if (GuidTools.GuidTryParse(tempGuidString, out var resultGuid)) return resultGuid; if (GuidTools.TryExtractGuid(uninstallerKey.GetKeyName(), out resultGuid)) return resultGuid; string uninstallString = GetUninstallString(uninstallerKey); // Look for a valid GUID in the path return GuidTools.TryExtractGuid(uninstallString, out resultGuid) ? resultGuid : Guid.Empty; } private static string GetUninstallString(RegistryKey uninstallerKey) { return GetKeyFuzzy(uninstallerKey, RegistryNameUninstallString) ?? GetQuietUninstallString(uninstallerKey); } private static string GetQuietUninstallString(RegistryKey uninstallerKey) { return GetKeyFuzzy(uninstallerKey, RegistryNameQuietUninstallString); } private static string GetKeyFuzzy(RegistryKey uninstallerKey, string keyName) { var uninstallString = uninstallerKey.GetStringSafe(keyName); if (uninstallString == null) { // Handle hidden uninstall strings like UninstallString_hidden uninstallString = uninstallerKey.GetValueNames() .Where(x => x.StartsWith(keyName, StringComparison.OrdinalIgnoreCase)) .Select(uninstallerKey.GetStringSafe) .FirstOrDefault(x => !string.IsNullOrEmpty(x)); } return uninstallString; } private static DateTime GetInstallDate(RegistryKey uninstallerKey) { var dateString = uninstallerKey.GetStringSafe(RegistryNameInstallDate); if (dateString != null && dateString.Length == 8) { try { // Likely to be in YYYYMMDD format return new DateTime(int.Parse(dateString.Substring(0, 4)), int.Parse(dateString.Substring(4, 2)), int.Parse(dateString.Substring(6, 2))); } catch (ArgumentOutOfRangeException) { try { // YYYYDDMM format instead of standard YYYYMMDD? return new DateTime(int.Parse(dateString.Substring(0, 4)), int.Parse(dateString.Substring(6, 2)), int.Parse(dateString.Substring(4, 2))); } catch (SystemException) { } } catch (FormatException) { } catch (ArgumentException) { } } return DateTime.MinValue; } private static bool GetIsUpdate(RegistryKey uninstallerKey) { var parentKeyName = uninstallerKey.GetStringSafe("ParentKeyName"); if (!string.IsNullOrEmpty(parentKeyName)) return true; var releaseType = uninstallerKey.GetStringSafe("ReleaseType"); if (!string.IsNullOrEmpty(releaseType) && releaseType.ContainsAny(new[] { "Update", "Hotfix" }, StringComparison.OrdinalIgnoreCase)) return true; var defaultValue = uninstallerKey.GetStringSafe(null); if (string.IsNullOrEmpty(defaultValue)) return false; //Regex WindowsUpdateRegEx = new Regex(@"KB[0-9]{6}$"); //Doesnt work for all cases return defaultValue.Length > 6 && defaultValue.StartsWith("KB", StringComparison.Ordinal) && char.IsNumber(defaultValue[2]) && char.IsNumber(defaultValue.Last()); } private static bool GetProtectedFlag(RegistryKey uninstallerKey) { return Convert.ToInt32(uninstallerKey.GetValue("NoRemove", 0)) != 0; } private static RegistryKey OpenSubKeySafe(RegistryKey baseKey, string name, bool writable = false) { try { return baseKey.OpenSubKey(name, writable); } catch (SecurityException) { return null; } } private static IEnumerable> GetParentRegistryKeys() { var keysToCheck = new List>(); var hklm = Registry.LocalMachine; var hkcu = Registry.CurrentUser; if (ProcessTools.Is64BitProcess) { keysToCheck.Add(new KeyValuePair(OpenSubKeySafe(hklm, RegUninstallersKeyDirect), true)); keysToCheck.Add(new KeyValuePair(OpenSubKeySafe(hkcu, RegUninstallersKeyDirect), true)); keysToCheck.Add(new KeyValuePair(OpenSubKeySafe(hklm, RegUninstallersKeyWow), false)); keysToCheck.Add(new KeyValuePair(OpenSubKeySafe(hkcu, RegUninstallersKeyWow), false)); } else { keysToCheck.Add(new KeyValuePair(OpenSubKeySafe(hklm, RegUninstallersKeyDirect), false)); keysToCheck.Add(new KeyValuePair(OpenSubKeySafe(hkcu, RegUninstallersKeyDirect), false)); } return keysToCheck.Where(x => x.Key != null); } private static UninstallerType GetUninstallerType(RegistryKey uninstallerKey) { // Detect MSI installer based on registry entry (the proper way) if (Convert.ToInt32(uninstallerKey.GetValue(RegistryNameWindowsInstaller, 0)) != 0) { return UninstallerType.Msiexec; } // Detect InnoSetup if (uninstallerKey.GetValueNames().Any(x => x.Contains("Inno Setup:"))) { return UninstallerType.InnoSetup; } // Detect Steam if (uninstallerKey.GetKeyName().StartsWith("Steam App ", StringComparison.Ordinal)) { return UninstallerType.Steam; } var uninstallString = GetUninstallString(uninstallerKey); return string.IsNullOrEmpty(uninstallString) ? UninstallerType.Unknown : UninstallerTypeAdder.GetUninstallerType(uninstallString); } /// /// Tries to create a new uninstaller entry. If the registry key doesn't contain valid uninstaller /// information, null is returned. It will throw ArgumentNullException if passed uninstallerKey is null. /// If there are any problems while reading the registry an exception will be thrown as well. /// /// Registry key which contains the uninstaller information. /// Is the registry key pointing to a 64 bit subkey? private ApplicationUninstallerEntry TryCreateFromRegistry(RegistryKey uninstallerKey, bool is64Bit) { if (uninstallerKey == null) throw new ArgumentNullException(nameof(uninstallerKey)); var tempEntry = GetBasicInformation(uninstallerKey); tempEntry.IsRegistered = true; // Check for invalid registry key if (tempEntry.RawDisplayName == null) { if (tempEntry.Publisher == null && !tempEntry.UninstallPossible && !tempEntry.QuietUninstallPossible) { //throw new ArgumentException("Supplied key doesn't contain any useful information"); return null; } tempEntry.RawDisplayName = string.Empty; } // Get rest of the information from registry tempEntry.IsProtected = GetProtectedFlag(uninstallerKey); tempEntry.InstallDate = GetInstallDate(uninstallerKey); tempEntry.EstimatedSize = GetEstimatedSize(uninstallerKey); tempEntry.AboutUrl = GetAboutUrl(uninstallerKey); tempEntry.Is64Bit = is64Bit ? MachineType.X64 : MachineType.X86; tempEntry.IsUpdate = GetIsUpdate(uninstallerKey); tempEntry.BundleProviderKey = GetGuid(uninstallerKey); // Figure out what we are dealing with tempEntry.UninstallerKind = GetUninstallerType(uninstallerKey); // Corner case with some microsoft application installations. // They will sometimes create a naked registry key (product code as reg name) with only the display name value. if (tempEntry.UninstallerKind != UninstallerType.Msiexec && tempEntry.BundleProviderKey != Guid.Empty && !tempEntry.UninstallPossible && !tempEntry.QuietUninstallPossible) { if (_windowsInstallerValidGuids.Contains(tempEntry.BundleProviderKey)) tempEntry.UninstallerKind = UninstallerType.Msiexec; } return tempEntry; } } } ================================================ FILE: source/UninstallTools/Factory/ScoopFactory.cs ================================================ using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.IO; using System.Linq; using System.Text; using System.Text.Json; using System.Text.Json.Serialization; using Klocman.Native; using Klocman.Tools; using UninstallTools.Factory.InfoAdders; using UninstallTools.Factory.Json; using UninstallTools.Junk.Confidence; using UninstallTools.Junk.Containers; using UninstallTools.Properties; namespace UninstallTools.Factory { public sealed partial class ScoopFactory : IIndependantUninstallerFactory { private static string _scoopUserPath; private static string _scoopGlobalPath; private static string _scriptPath; private static string _powershellPath; private static readonly JsonContext _jsonContext; static ScoopFactory() { JsonSerializerOptions jsonOptions = new(JsonSerializerDefaults.Web); // ignore property name case jsonOptions.Converters.Add(new PowerShellDateTimeOffsetConverter()); _jsonContext = new JsonContext(jsonOptions); } private static bool GetScoopInfo() { try { _scoopUserPath = Environment.GetEnvironmentVariable("SCOOP"); if (string.IsNullOrEmpty(_scoopUserPath)) _scoopUserPath = Path.Combine(WindowsTools.GetEnvironmentPath(CSIDL.CSIDL_PROFILE), "scoop"); _scoopGlobalPath = Environment.GetEnvironmentVariable("SCOOP_GLOBAL"); if (string.IsNullOrEmpty(_scoopGlobalPath)) _scoopGlobalPath = Path.Combine(WindowsTools.GetEnvironmentPath(CSIDL.CSIDL_COMMON_APPDATA), "scoop"); _scriptPath = Path.Combine(_scoopUserPath, "shims\\scoop.ps1"); if (File.Exists(_scriptPath)) { _powershellPath = PathTools.GetFullPathOfExecutable("powershell.exe"); if (!File.Exists(_powershellPath)) throw new InvalidOperationException(@"Detected Scoop program installer, but failed to detect PowerShell"); return true; } } catch (SystemException ex) { Trace.WriteLine("Failed to get Scoop info: " + ex); } return false; } private sealed class ExportInfo { //public ExportBucketEntry[] Buckets { get; set; } public ExportAppEntry[] Apps { get; set; } } //private sealed class ExportBucketEntry //{ // public string Name { get; set; } // public string Source { get; set; } // public DateTimeOffset Updated { get; set; } // public ulong Manifests { get; set; } //} private sealed class ExportAppEntry { public string Name { get; set; } public string Version { get; set; } public string Source { get; set; } public DateTimeOffset Updated { get; set; } public string Info { get; set; } [JsonIgnore] public bool IsPublic => Info?.Contains("Global install", StringComparison.InvariantCultureIgnoreCase) == true; } public IList GetUninstallerEntries(ListGenerationProgress.ListGenerationCallback progressCallback) { var results = new List(); if (!GetScoopInfo()) return results; // Make uninstaller for scoop itself var scoopEntry = new ApplicationUninstallerEntry { RawDisplayName = "Scoop", Comment = "Automated program installer", AboutUrl = "https://github.com/ScoopInstaller/Scoop", InstallLocation = _scoopUserPath, IsOrphaned = false, RatingId = "Scoop" }; // Make sure the global directory gets removed as well var junk = new FileSystemJunk(new DirectoryInfo(_scoopGlobalPath), scoopEntry, null); junk.Confidence.Add(ConfidenceRecords.ExplicitConnection); junk.Confidence.Add(4); scoopEntry.AdditionalJunk.Add(junk); scoopEntry.UninstallString = MakeScoopCommand("uninstall scoop").ToString(); scoopEntry.UninstallerKind = UninstallerType.PowerShell; results.Add(scoopEntry); // Make uninstallers for apps installed by scoop var result = RunScoopCommand("export"); if (string.IsNullOrEmpty(result)) return results; var exeSearcher = new AppExecutablesSearcher(); // JSON export format since July 2022 try { var export = JsonSerializer.Deserialize(result, _jsonContext.ExportInfo); foreach (var app in export.Apps) { var entry = CreateUninstallerEntry( app.Name, app.Version, app.IsPublic, exeSearcher); entry.InstallDate = app.Updated.LocalDateTime; results.Add(entry); } } // Fallback to plain text export format catch (JsonException e) { var appEntries = result.Split(StringTools.NewLineChars.ToArray(), StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()); foreach (var str in appEntries) { // Format should be "$app (v:$ver) $global_display $bucket $arch" // app has no spaces, $global_display is *global*, bucket is inside [] brackets like [main] // version should always be there but the check errored out for some users, everything after version is optional string name; string version = null; bool isGlobal = false; var spaceIndex = str.IndexOf(" ", StringComparison.Ordinal); if (spaceIndex > 0) { name = str.Substring(0, spaceIndex); var startIndex = str.IndexOf("(v:", StringComparison.Ordinal); if (startIndex > 0) { var verEndIndex = str.IndexOf(')', startIndex); version = str.Substring(Math.Min(startIndex + 3, str.Length - 1), Math.Max(verEndIndex - startIndex - 3, 0)); if (version.Length == 0) version = null; } isGlobal = str.Substring(spaceIndex).Contains("*global*"); } else { name = str; } // Make sure that this isn't just a corrupted json export if (string.Equals(name, "\"apps\":", StringComparison.Ordinal) || string.Equals(name, "\"buckets\":", StringComparison.Ordinal)) throw new InvalidDataException("Scoop export is in unkown or invalid format! Try updating Scoop and try again.\n\nContents:\n" + result, e); var entry = CreateUninstallerEntry(name, version, isGlobal, exeSearcher); results.Add(entry); } } return results; } private sealed class AppInstall { public string Bucket { get; set; } public string Architecture { get; set; } } private sealed class AppManifest { public string Homepage { get; set; } [JsonPropertyName("env_add_path"), JsonConverter(typeof(DynamicStringArrayConverter))] public string[] EnvAddPath { get; set; } [JsonConverter(typeof(DynamicStringArrayConverter))] public string[] Bin { get; set; } public string[][] Shortcuts { get; set; } public IDictionary Architecture { get; set; } } private sealed class AppManifestArchitecture { public string[] EnvAddPath { get; set; } [JsonConverter(typeof(DynamicStringArrayConverter))] public string[] Bin { get; set; } public string[][] Shortcuts { get; set; } } public static ApplicationUninstallerEntry CreateUninstallerEntry( string name, string version, bool isGlobal, AppExecutablesSearcher searcher) { var entry = new ApplicationUninstallerEntry { RawDisplayName = name, DisplayVersion = ApplicationEntryTools.CleanupDisplayVersion(version), RatingId = "Scoop " + name }; var installDir = Path.Combine(isGlobal ? _scoopGlobalPath : _scoopUserPath, "apps\\" + name); if (Directory.Exists(installDir)) { List executables = new(); var currentDir = Path.Combine(installDir, "current"); try { var install = JsonSerializer.Deserialize( File.ReadAllText(Path.Combine(currentDir, "install.json")), _jsonContext.AppInstall); var manifest = JsonSerializer.Deserialize( File.ReadAllText(Path.Combine(currentDir, "manifest.json")), _jsonContext.AppManifest); entry.AboutUrl = manifest.Homepage; var shortcuts = manifest.Architecture?[install.Architecture]?.Shortcuts ?? manifest.Shortcuts; if (shortcuts != null) { var files = shortcuts.Select(x => Path.Combine(currentDir, x[0])) .Where(File.Exists) .Select(Path.GetFullPath) .Distinct(StringComparer.OrdinalIgnoreCase) .ToList(); executables.AddRange(files.Where(x => x.EndsWith(".exe", StringComparison.OrdinalIgnoreCase)).Concat(files.Where(x => x.EndsWith(".cmd", StringComparison.OrdinalIgnoreCase)))); var potentialIcons = files.Where(x => x.EndsWith(".ico", StringComparison.OrdinalIgnoreCase)).Concat(files.Where(x => x.EndsWith(".exe", StringComparison.OrdinalIgnoreCase))).ToList(); foreach (var potentialIcon in potentialIcons) { try { var icon = potentialIcon.EndsWith(".ico", StringComparison.OrdinalIgnoreCase) ? new Icon(potentialIcon) : Icon.ExtractAssociatedIcon(potentialIcon); if (icon == null || icon.Size == Size.Empty) continue; entry.IconBitmap = icon; break; } catch (Exception ex) { Console.WriteLine($@"Failed to get icon for [{name}] from [{potentialIcon}] - {ex}"); } } } var bin = manifest.Architecture?[install.Architecture]?.Bin ?? manifest.Bin; if (bin != null) { var filteredBins = bin.Select(x => Path.Combine(installDir, "current", x)) .Where(File.Exists) .Select(Path.GetFullPath) .Except(executables, StringComparer.OrdinalIgnoreCase) .Where(x => x.EndsWith(".exe", StringComparison.OrdinalIgnoreCase) || x.EndsWith(".cmd", StringComparison.OrdinalIgnoreCase)) .ToList(); executables.AddRange(filteredBins); } var env = manifest.Architecture?[install.Architecture]?.EnvAddPath ?? manifest.EnvAddPath; if (env is { Length: > 0 }) { currentDir = Path.Combine(currentDir, env[0]); } } catch (IOException) { } catch (UnauthorizedAccessException) { } catch (JsonException) { } if (executables.Any()) { // No need to sort, safe to assume the manifest has the most important executables in first positions entry.SortedExecutables = executables.ToArray(); } else { // Avoid looking for executables in old versions entry.InstallLocation = currentDir; searcher.AddMissingInformation(entry); } entry.InstallLocation = installDir; } entry.UninstallerKind = UninstallerType.PowerShell; entry.UninstallString = MakeScoopCommand("uninstall " + name + (isGlobal ? " --global" : "")).ToString(); return entry; } public bool IsEnabled() => UninstallToolsGlobalConfig.ScanScoop; public string DisplayName => Localisation.Progress_AppStores_Scoop; private static string RunScoopCommand(string scoopArgs) { var startInfo = MakeScoopCommand(scoopArgs).ToProcessStartInfo(); startInfo.UseShellExecute = false; startInfo.RedirectStandardOutput = true; startInfo.RedirectStandardError = false; startInfo.CreateNoWindow = true; startInfo.StandardOutputEncoding = Encoding.Default; using (var process = Process.Start(startInfo)) { var sw = Stopwatch.StartNew(); var output = process?.StandardOutput.ReadToEnd(); Trace.WriteLine($"[Performance] Running command {startInfo.FileName} {startInfo.Arguments} took {sw.ElapsedMilliseconds}ms"); return output; } } private static ProcessStartCommand MakeScoopCommand(string scoopArgs) { return new ProcessStartCommand(_powershellPath, $"-NoProfile -ex unrestricted \"{_scriptPath}\" {scoopArgs}"); } [JsonSerializable(typeof(ExportInfo))] [JsonSerializable(typeof(AppInstall))] [JsonSerializable(typeof(AppManifest))] private sealed partial class JsonContext : JsonSerializerContext { } } } ================================================ FILE: source/UninstallTools/Factory/ScriptFactory.cs ================================================ /* Copyright (c) 2018 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.IO; using System.Linq; using System.Reflection; using Klocman.Tools; using UninstallTools.Properties; namespace UninstallTools.Factory { public class ScriptFactory : IIndependantUninstallerFactory { private static readonly PropertyInfo[] EntryProps; //private static readonly PropertyInfo[] SystemIconProps; private static string HelperPath { get; } = Path.Combine(UninstallToolsGlobalConfig.AssemblyLocation, @"ScriptHelper.exe"); private static bool IsHelperAvailable() => File.Exists(HelperPath); static ScriptFactory() { EntryProps = typeof(ApplicationUninstallerEntry) .GetProperties(BindingFlags.Instance | BindingFlags.Public) .Where(p => p.CanWrite && p.PropertyType == typeof(string)) .ToArray(); // SystemIconProps = typeof(SystemIcons) // .GetProperties(BindingFlags.Static | BindingFlags.Public) // .Where(p => p.CanRead) // .ToArray(); } public IList GetUninstallerEntries( ListGenerationProgress.ListGenerationCallback progressCallback) { var results = new List(); if (!IsHelperAvailable()) return results; var result = FactoryTools.StartHelperAndReadOutput(HelperPath, "list"); if (string.IsNullOrEmpty(result)) return results; var dataSets = FactoryTools.ExtractAppDataSetsFromHelperOutput(result); foreach (var dataSet in dataSets) { var entry = new ApplicationUninstallerEntry(); // Automatically fill in any supplied static properties foreach (var entryProp in EntryProps) { if (!dataSet.TryGetValue(entryProp.Name, out var item) || string.IsNullOrEmpty(item)) continue; try { entryProp.SetValue(entry, item, null); } catch (SystemException ex) { Trace.WriteLine(ex); } } if (!entry.UninstallPossible && !entry.QuietUninstallPossible) continue; if (string.IsNullOrEmpty(entry.Publisher)) entry.Publisher = "Script"; //if (dataSet.TryGetValue("SystemIcon", out var icon) && !string.IsNullOrEmpty(icon)) //{ // var iconObj = SystemIconProps // .FirstOrDefault(p => p.Name.Equals(icon, StringComparison.OrdinalIgnoreCase)) // ?.GetValue(null, null) as Icon; // entry.IconBitmap = iconObj; //} entry.IconBitmap = SystemIcons.Shield; results.Add(entry); } return results; } public bool IsEnabled() => UninstallToolsGlobalConfig.ScanPreDefined; public string DisplayName => Localisation.Progress_AppStores_Templates; } } ================================================ FILE: source/UninstallTools/Factory/SteamFactory.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Security; using Klocman.IO; using UninstallTools.Junk; using UninstallTools.Junk.Confidence; using UninstallTools.Junk.Containers; using UninstallTools.Properties; namespace UninstallTools.Factory { public class SteamFactory : IIndependantUninstallerFactory, IJunkCreator { private static bool GetSteamInfo(out string steamLocation) { steamLocation = null; if (File.Exists(SteamHelperPath)) { var output = FactoryTools.StartHelperAndReadOutput(SteamHelperPath, "steam"); if (!string.IsNullOrEmpty(output) && !output.Contains("error", StringComparison.InvariantCultureIgnoreCase) && Directory.Exists(output = output.Trim().TrimEnd('\\', '/'))) { steamLocation = output; return true; } } return false; } internal static string SteamHelperPath { get; } = Path.Combine(UninstallToolsGlobalConfig.AssemblyLocation, @"SteamHelper.exe"); #region IIndependantUninstallerFactory public IList GetUninstallerEntries( ListGenerationProgress.ListGenerationCallback progressCallback) { var results = new List(); if (!GetSteamInfo(out var steamLocation)) return results; var output = FactoryTools.StartHelperAndReadOutput(SteamHelperPath, "l /i"); if (string.IsNullOrEmpty(output)) return results; foreach (var data in FactoryTools.ExtractAppDataSetsFromHelperOutput(output)) { if (!int.TryParse(data["AppId"], out var appId)) continue; var entry = new ApplicationUninstallerEntry { DisplayName = data["Name"], UninstallString = data["UninstallString"], InstallLocation = data["InstallDirectory"], UninstallerKind = UninstallerType.Steam, IsValid = true, IsOrphaned = true, RatingId = "Steam App " + appId.ToString("G") }; if (long.TryParse(data["SizeOnDisk"], out var bytes)) entry.EstimatedSize = FileSize.FromBytes(bytes); results.Add(entry); } results.Add(new ApplicationUninstallerEntry { AboutUrl = @"http://steampowered.com/", InstallLocation = steamLocation, DisplayIcon = Path.Combine(steamLocation, "Steam.exe"), DisplayName = "Steam", UninstallerKind = UninstallerType.Nsis, UninstallString = Path.Combine(steamLocation, "uninstall.exe"), IsOrphaned = false, RatingId = "Steam", IsValid = File.Exists(Path.Combine(steamLocation, "uninstall.exe")), InstallDate = Directory.GetCreationTime(steamLocation), Publisher = "Valve Corporation", // Prevent very long size scan in case of many games, the install itself is about 600-800MB EstimatedSize = FileSize.FromKilobytes(1024 * 700) }); return results; } public bool IsEnabled() => UninstallToolsGlobalConfig.ScanSteam; public string DisplayName => Localisation.Progress_AppStores_Steam; #endregion #region IJunkCreator private static readonly string[] TempFolderNames = { "downloading", "shadercache", "temp" }; public void Setup(ICollection allUninstallers) { } public IEnumerable FindJunk(ApplicationUninstallerEntry target) { if (target.UninstallerKind != UninstallerType.Steam || string.IsNullOrEmpty(target.InstallLocation)) return Enumerable.Empty(); var results = new List(); try { // Look for this appID in steam library's temporary folders (game is inside "common" folder, temp folders are next to that) var d = new DirectoryInfo(target.InstallLocation); if (d.Exists && d.Parent?.Name == "common" && d.Parent.Parent != null) { var libraryDir = d.Parent.Parent.FullName; Debug.Assert(target.RatingId.StartsWith("Steam App ")); var appIdStr = target.RatingId.Substring("Steam App ".Length); foreach (var cacheFolderName in TempFolderNames) { var subpath = Path.Combine(libraryDir, cacheFolderName, appIdStr); if (Directory.Exists(subpath)) { var junk = new FileSystemJunk(new DirectoryInfo(subpath), target, this); junk.Confidence.Add(ConfidenceRecords.ExplicitConnection); junk.Confidence.Add(4); results.Add(junk); } } } else { Debug.Fail(target.InstallLocation + " does not point inside of a steam library's common folder"); } } catch (SystemException e) { Console.WriteLine(e); } return results; } public string CategoryName { get; } = Localisation.UninstallerType_Steam; #endregion } } ================================================ FILE: source/UninstallTools/Factory/StoreAppFactory.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Drawing; using System.Globalization; using System.IO; using System.Linq; using Klocman.Native; using Klocman.Tools; using UninstallTools.Properties; namespace UninstallTools.Factory { public class StoreAppFactory : IIndependantUninstallerFactory { private static string HelperPath { get; } = Path.Combine(UninstallToolsGlobalConfig.AssemblyLocation, @"StoreAppHelper.exe"); private static bool IsHelperAvailable() => File.Exists(HelperPath); public static string GetPowerShellRemoveCommand(string fullName) { return $"Remove-AppxPackage -package {fullName} -confirm:$false"; } /// /// Convert supplied store app entries to power shell uninstall commands. Non-store app entries are ignored. /// public static string[] ToPowerShellRemoveCommands(IEnumerable appEntries) { return appEntries.Where(x => x.UninstallerKind == UninstallerType.StoreApp) .Select(x => GetPowerShellRemoveCommand(x.Comment)) .ToArray(); } public IList GetUninstallerEntries( ListGenerationProgress.ListGenerationCallback progressCallback) { var results = new List(); if (!IsHelperAvailable()) return results; var output = FactoryTools.StartHelperAndReadOutput(HelperPath, "/query"); if (string.IsNullOrEmpty(output)) return results; var windowsPath = WindowsTools.GetEnvironmentPath(CSIDL.CSIDL_WINDOWS); foreach (var data in FactoryTools.ExtractAppDataSetsFromHelperOutput(output)) { if (!data.ContainsKey("InstalledLocation") || !Directory.Exists(data["InstalledLocation"])) continue; var fullName = data["FullName"]; var separatorIndex = fullName.IndexOf("_", StringComparison.Ordinal); var uninstallStr = $"\"{HelperPath}\" /uninstall \"{fullName}\""; var isProtected = data.ContainsKey("IsProtected") && Convert.ToBoolean(data["IsProtected"], CultureInfo.InvariantCulture); var result = new ApplicationUninstallerEntry { Comment = fullName, CacheIdOverride = fullName, RatingId = separatorIndex >= 0 ? fullName.Substring(0, separatorIndex) : fullName, UninstallString = uninstallStr, QuietUninstallString = uninstallStr, RawDisplayName = string.IsNullOrEmpty(data["DisplayName"]) ? fullName : data["DisplayName"], Publisher = data["PublisherDisplayName"], IsValid = true, UninstallerKind = UninstallerType.StoreApp, InstallLocation = data["InstalledLocation"], InstallDate = Directory.GetCreationTime(data["InstalledLocation"]), IsProtected = isProtected, SystemComponent = isProtected }; if (File.Exists(data["Logo"])) { try { result.DisplayIcon = data["Logo"]; result.IconBitmap = DrawingTools.IconFromImage(new Bitmap(data["Logo"])); } catch { result.DisplayIcon = null; result.IconBitmap = null; } } if (result.InstallLocation.StartsWith(windowsPath, StringComparison.InvariantCultureIgnoreCase)) { result.SystemComponent = true; //result.IsProtected = true; } results.Add(result); } return results; } public bool IsEnabled() => UninstallToolsGlobalConfig.ScanStoreApps; public string DisplayName => Localisation.Progress_AppStores_WinStore; } } ================================================ FILE: source/UninstallTools/Factory/WindowsFeatureFactory.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading; using Klocman.IO; using Klocman.Tools; using UninstallTools.Properties; namespace UninstallTools.Factory { public class WindowsFeatureFactory : IIndependantUninstallerFactory { public IList GetUninstallerEntries( ListGenerationProgress.ListGenerationCallback progressCallback) { var results = new List(); if (Environment.OSVersion.Version < WindowsTools.Windows7) return results; Exception error = null; var t = new Thread(() => { try { results.AddRange(WmiQueries.GetWindowsFeatures() .Where(x => x.Enabled) .Select(WindowsFeatureToUninstallerEntry)); } catch (Exception ex) { error = ex; } }); t.Start(); t.Join(TimeSpan.FromSeconds(40)); if (error != null) throw new IOException("Error while collecting Windows Features. If Windows Update is running wait until it finishes and try again. If the error persists try restarting your computer. In case nothing helps, read the KB957310 article.", error); if (t.IsAlive) { //t.Abort(); throw new TimeoutException("WMI query has hung while collecting Windows Features, try restarting your computer. If the error persists read the KB957310 article."); } return results; } private static ApplicationUninstallerEntry WindowsFeatureToUninstallerEntry(WindowsFeatureInfo info) { var displayName = !string.IsNullOrEmpty(info.DisplayName) ? info.DisplayName : info.FeatureName; return new ApplicationUninstallerEntry { RawDisplayName = displayName, Comment = info.Description, UninstallString = DismTools.GetDismUninstallString(info.FeatureName, false), QuietUninstallString = DismTools.GetDismUninstallString(info.FeatureName, true), UninstallerKind = UninstallerType.WindowsFeature, Publisher = "Microsoft Corporation", IsValid = true, Is64Bit = ProcessTools.Is64BitProcess ? MachineType.X64 : MachineType.X86, RatingId = "WindowsFeature_" + info.FeatureName }; } public bool IsEnabled() => UninstallToolsGlobalConfig.ScanWinFeatures; public string DisplayName => Localisation.Progress_AppStores_WinFeatures; } } ================================================ FILE: source/UninstallTools/Factory/WindowsUpdateFactory.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using Klocman.IO; using Klocman.Tools; using UninstallTools.Properties; namespace UninstallTools.Factory { public class WindowsUpdateFactory : IIndependantUninstallerFactory { private static string HelperPath { get; } = Path.Combine(UninstallToolsGlobalConfig.AssemblyLocation, @"WinUpdateHelper.exe"); private static bool IsHelperAvailable() => File.Exists(HelperPath); public IList GetUninstallerEntries(ListGenerationProgress.ListGenerationCallback progressCallback) { var results = new List(); if (!IsHelperAvailable()) return results; var output = FactoryTools.StartHelperAndReadOutput(HelperPath, "list"); if (string.IsNullOrEmpty(output) || output.Trim().StartsWith("Error", StringComparison.OrdinalIgnoreCase)) return results; foreach (var group in FactoryTools.ExtractAppDataSetsFromHelperOutput(output)) { var entry = new ApplicationUninstallerEntry { UninstallerKind = UninstallerType.WindowsUpdate, IsUpdate = true, Publisher = "Microsoft Corporation" }; foreach (var valuePair in group) { switch (valuePair.Key) { case "UpdateID": entry.RatingId = valuePair.Value; if (GuidTools.TryExtractGuid(valuePair.Value, out var result)) entry.BundleProviderKey = result; break; case "RevisionNumber": entry.DisplayVersion = ApplicationEntryTools.CleanupDisplayVersion(valuePair.Value); break; case "Title": entry.RawDisplayName = valuePair.Value; break; case "IsUninstallable": if (bool.TryParse(valuePair.Value, out var isUnins)) entry.IsProtected = !isUnins; break; case "SupportUrl": entry.AboutUrl = valuePair.Value; break; case "MinDownloadSize": if (long.TryParse(valuePair.Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var size)) entry.EstimatedSize = FileSize.FromBytes(size); break; case "MaxDownloadSize": break; case "LastDeploymentChangeTime": if (DateTime.TryParse(valuePair.Value, CultureInfo.InvariantCulture, DateTimeStyles.None, out var date) && !DateTime.MinValue.Equals(date)) entry.InstallDate = date; break; default: Debug.Fail("Unknown label"); break; } } entry.UninstallString = $"\"{HelperPath}\" uninstall {entry.RatingId}"; entry.QuietUninstallString = entry.UninstallString; results.Add(entry); } return results; } public bool IsEnabled() => UninstallToolsGlobalConfig.ScanWinUpdates; public string DisplayName => Localisation.Progress_AppStores_WinUpdates; } } ================================================ FILE: source/UninstallTools/Junk/Confidence/ConfidenceCollection.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System.Collections; using System.Collections.Generic; using System.Linq; namespace UninstallTools.Junk.Confidence { public sealed class ConfidenceCollection : IEnumerable { private readonly List _items = new(); internal ConfidenceCollection() { } public bool IsEmpty => _items.Count == 0; public IEnumerable ConfidenceParts => _items; public ConfidenceLevel GetConfidence() { if (_items.Count < 1) return ConfidenceLevel.Unknown; var result = GetRawConfidence(); if (result < 0) return ConfidenceLevel.Bad; if (result < 2) return ConfidenceLevel.Questionable; if (result < 5) return ConfidenceLevel.Good; return ConfidenceLevel.VeryGood; } // Returns a number representing the confidence. 0 is a mid-point. public int GetRawConfidence() { var result = 0; _items.ForEach(x => result += x.Change); return result; } public string GetWorstOffender() { var lowest = _items.Min(x => x.Change); var item = _items.FirstOrDefault(x => x.Change.Equals(lowest)); if (item != null) return item.Reason ?? string.Empty; return string.Empty; } internal void Add(int value) { _items.Add(new ConfidenceRecord(value)); } internal void Add(ConfidenceRecord value) { _items.Add(value); } internal void AddRange(IEnumerable values) { _items.AddRange(values.Where(x => !_items.Contains(x))); } public IEnumerator GetEnumerator() { return _items.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable) _items).GetEnumerator(); } } } ================================================ FILE: source/UninstallTools/Junk/Confidence/ConfidenceGenerators.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Linq; using Klocman.Tools; using UninstallTools.Junk.Containers; namespace UninstallTools.Junk.Confidence { public static class ConfidenceGenerators { public static IEnumerable GenerateConfidence(string itemName, ApplicationUninstallerEntry applicationUninstallerEntry) { return GenerateConfidence(itemName, null, 0, applicationUninstallerEntry); } internal static IEnumerable GenerateConfidence(string itemName, string itemParentPath, int level, ApplicationUninstallerEntry applicationUninstallerEntry) { var matchResult = MatchStringToProductName(applicationUninstallerEntry, itemName); return GenerateConfidence(itemName, matchResult, itemParentPath, level, applicationUninstallerEntry); } internal static IEnumerable GenerateConfidence(string itemName, int similarityToEntry, string itemParentPath, int level, ApplicationUninstallerEntry applicationUninstallerEntry) { if (similarityToEntry < 0) yield break; yield return similarityToEntry < 2 ? ConfidenceRecords.ProductNamePerfectMatch : ConfidenceRecords.ProductNameDodgyMatch; // Base rating according to path depth. 0 is best yield return new ConfidenceRecord(2 - Math.Abs(level) * 2); if (ItemNameEqualsCompanyName(applicationUninstallerEntry, itemName)) yield return ConfidenceRecords.ItemNameEqualsCompanyName; if (level > 0) { if (applicationUninstallerEntry.PublisherTrimmed.ToLowerInvariant() .Contains(PathTools.GetName(itemParentPath).Replace('_', ' ').ToLowerInvariant())) yield return ConfidenceRecords.CompanyNameMatch; } if (UninstallToolsGlobalConfig.IsKnownFolder(itemParentPath)) yield return ConfidenceRecords.DirectlyInsideKnownFolder; } /// /// -1 if match failed, 0 if string matched perfectly, higher if match was worse /// internal static int MatchStringToProductName(ApplicationUninstallerEntry applicationUninstallerEntry, string str) { var productName = applicationUninstallerEntry.DisplayNameTrimmed.ToLowerInvariant(); str = str.Replace('_', ' ').ToLowerInvariant().Trim(); var lowestLength = Math.Min(productName.Length, str.Length); // Don't match short strings if (lowestLength <= 4) return -1; var result = Sift4.SimplestDistance(productName, str, 1); // Strings match perfectly if (result <= 1) return result; // If the product name contains company name, try trimming it and testing again var publisher = applicationUninstallerEntry.PublisherTrimmed.ToLower(); if (publisher.Length > 4 && productName.Contains(publisher)) { var trimmedProductName = productName.Replace(publisher, "").Trim(); if (trimmedProductName.Length <= 4) return -1; var trimmedResult = Sift4.SimplestDistance(trimmedProductName, str, 1); if (trimmedResult <= 1) return trimmedResult; } var dirToName = str.Contains(productName); var nameToDir = productName.Contains(str); if (dirToName || nameToDir) return 2; // Hard cut-off if the difference is more than a third of the checked name if (result < lowestLength / 3) return result; return -1; } // Check if name is the same as publisher, could be "Adobe AIR" getting matched to a folder "Adobe" internal static bool ItemNameEqualsCompanyName(ApplicationUninstallerEntry applicationUninstallerEntry, string itemName) { var publisher = applicationUninstallerEntry.PublisherTrimmed.ToLowerInvariant(); itemName = itemName.ToLowerInvariant(); return !publisher.Equals(applicationUninstallerEntry.DisplayNameTrimmed.ToLowerInvariant()) && publisher.Contains(itemName); } /// /// Check if there are any similar names that match DisplayNameTrimmed, and if there are then add negative confidence to names other than the best match. /// This is to avoid e.g. `AppX Extended` matching junk entries from `AppX` /// internal static void TestForSimilarNames(ApplicationUninstallerEntry thisUninstaller, IEnumerable otherUninstallers, ICollection> createdJunk) { if (createdJunk.Count == 0) return; var thisDisplayName = thisUninstaller.DisplayNameTrimmed; // Check if any of the other apps match any of the entries, as long as the app names don't contain this app's name var otherFiltered = otherUninstallers.Where(x => x != thisUninstaller && !x.DisplayNameTrimmed.Contains(thisDisplayName)).ToList(); var matchingWithOther = createdJunk.Where(x => otherFiltered.Any(y => y.DisplayNameTrimmed.Contains(x.Value))); if (createdJunk.Count >= 2) { // Check for folders with similar names like `AppX Extended` and `AppX` and give confidence penalty to every one other than the best match matchingWithOther = matchingWithOther .Concat(createdJunk .Where(x => x.Value.Contains(thisDisplayName) || thisDisplayName.Contains(x.Value)) .OrderBy(x => Sift4.SimplestDistance(x.Value, thisDisplayName, 100)) .Skip(1)) .Distinct(); } foreach (var sketchyJunk in matchingWithOther) sketchyJunk.Key.Confidence.Add(ConfidenceRecords.UsedBySimilarNamedApp); } } } ================================================ FILE: source/UninstallTools/Junk/Confidence/ConfidenceLevel.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using Klocman.Localising; using UninstallTools.Properties; namespace UninstallTools.Junk.Confidence { public enum ConfidenceLevel { [LocalisedName(typeof (Localisation), "Confidence_Unknown")] Unknown = 0, [LocalisedName(typeof (Localisation), "Confidence_Bad")] Bad = 5, [LocalisedName(typeof (Localisation), "Confidence_Questionable")] Questionable = 7, [LocalisedName(typeof (Localisation), "Confidence_Good")] Good = 9, [LocalisedName(typeof (Localisation), "Confidence_VeryGood")] VeryGood = 12 } } ================================================ FILE: source/UninstallTools/Junk/Confidence/ConfidenceRecord.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ namespace UninstallTools.Junk.Confidence { public sealed class ConfidenceRecord { public ConfidenceRecord(int change, string reason) { Change = change; Reason = reason; } public ConfidenceRecord(int change) { Change = change; } public int Change { get; } public string Reason { get; } public override bool Equals(object obj) { if (obj is not ConfidenceRecord casted) return false; if (ReferenceEquals(this, obj)) return true; return (casted.Change == Change) && (casted.Reason == Reason); } public override int GetHashCode() { return Change.GetHashCode() ^ Reason.GetHashCode(); } } } ================================================ FILE: source/UninstallTools/Junk/Confidence/ConfidenceRecords.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using UninstallTools.Properties; namespace UninstallTools.Junk.Confidence { /// /// Universal confidence pieces /// public static class ConfidenceRecords { public static readonly ConfidenceRecord CompanyNameDidNotMatch = new(-2, Localisation.ConfidencePart_CompanyNameDidNotMatch); public static readonly ConfidenceRecord CompanyNameMatch = new(4, Localisation.ConfidencePart_CompanyNameMatch); public static readonly ConfidenceRecord AllSubdirsMatched = new(4, Localisation.ConfidencePart_AllSubdirsMatched); public static readonly ConfidenceRecord DirectoryStillUsed = new(-7, Localisation.ConfidencePart_DirectoryStillUsed); public static readonly ConfidenceRecord ExplicitConnection = new(4, Localisation.ConfidencePart_ExplicitConnection); public static readonly ConfidenceRecord ItemNameEqualsCompanyName = new(-2, Localisation.ConfidencePart_ItemNameEqualsCompanyName); public static readonly ConfidenceRecord ProductNameDodgyMatch = new(-2, Localisation.ConfidencePart_ProductNameDodgyMatch); public static readonly ConfidenceRecord ProductNamePerfectMatch = new(2, Localisation.ConfidencePart_ProductNamePerfectMatch); public static readonly ConfidenceRecord QuestionableDirectoryName = new(-3, Localisation.ConfidencePart_QuestionableDirectoryName); public static readonly ConfidenceRecord IsUninstallerRegistryKey = new(20, Localisation.ConfidencePart_IsUninstallerRegistryKey); public static readonly ConfidenceRecord IsStoreApp = new(-10, Localisation.ConfidencePart_IsStoreApp); public static readonly ConfidenceRecord IsEmptyFolder = new(4, Localisation.Confidence_PF_EmptyFolder); public static readonly ConfidenceRecord ExecutablesArePresent = new(-4, Localisation.Confidence_PF_ExecsPresent); public static readonly ConfidenceRecord FilesArePresent = new(0, Localisation.Confidence_PF_FilesPresent); public static readonly ConfidenceRecord ManyFilesArePresent = new(-2, Localisation.Confidence_PF_ManyFilesPresent); public static readonly ConfidenceRecord ProgramNameIsStillUsed = new(-4, Localisation.Confidence_PF_NameIsUsed); public static readonly ConfidenceRecord FolderHasNoSubdirectories = new(2, Localisation.Confidence_PF_NoSubdirs); public static readonly ConfidenceRecord PublisherIsStillUsed = new(-4, Localisation.Confidence_PF_PublisherIsUsed); public static readonly ConfidenceRecord UsedBySimilarNamedApp = new(-2, Localisation.Confidence_UsedBySimilarNamedApp); public static readonly ConfidenceRecord DirectlyInsideKnownFolder = new(-1, Localisation.Confidence_DirectlyInsideKnownFolder); } } ================================================ FILE: source/UninstallTools/Junk/Containers/FileSystemJunk.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.IO; using Klocman.Tools; using Microsoft.VisualBasic.FileIO; namespace UninstallTools.Junk.Containers { public class FileSystemJunk : JunkResultBase { public FileSystemJunk(FileSystemInfo path, ApplicationUninstallerEntry application, IJunkCreator source) : base(application, source) { Path = path; } public FileSystemInfo Path { get; } public override void Backup(string backupDirectory) { // Items are deleted to the recycle bin } public override void Delete() { if (Path is DirectoryInfo) FileSystem.DeleteDirectory(Path.FullName, UIOption.OnlyErrorDialogs, RecycleOption.SendToRecycleBin, UICancelOption.DoNothing); else if (Path is FileInfo) FileSystem.DeleteFile(Path.FullName, UIOption.OnlyErrorDialogs, RecycleOption.SendToRecycleBin, UICancelOption.DoNothing); else throw new NotImplementedException("Unknown FileSystemInfo implementation"); } public override string GetDisplayName() { return Path.FullName; } public override void Open() { if (Path.Exists) WindowsTools.OpenExplorerFocusedOnObject(Path.FullName); else throw new FileNotFoundException(null, Path.FullName); } } } ================================================ FILE: source/UninstallTools/Junk/Containers/IJunkResult.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using UninstallTools.Junk.Confidence; namespace UninstallTools.Junk.Containers { public interface IJunkResult { /// /// Confidence that this entry is safe to remove /// ConfidenceCollection Confidence { get; } /// /// Create this item's backup inside of the supplied directory /// void Backup(string backupDirectory); /// /// Delete this entry permanently /// void Delete(); /// /// Origin of this junk /// IJunkCreator Source { get; } /// /// Uninstaller this entry belongs to /// ApplicationUninstallerEntry Application { get; } string GetDisplayName(); /// /// Preview item in an external application /// void Open(); /// /// Get extended information with overall confidence information. /// string ToLongString(); } } ================================================ FILE: source/UninstallTools/Junk/Containers/JunkResultBase.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System.IO; using Klocman.Tools; using UninstallTools.Junk.Confidence; using UninstallTools.Properties; namespace UninstallTools.Junk.Containers { public abstract class JunkResultBase : IJunkResult { protected JunkResultBase(ApplicationUninstallerEntry application, IJunkCreator source) : this(application, source, new ConfidenceCollection()) { } protected JunkResultBase(ApplicationUninstallerEntry application, IJunkCreator source, ConfidenceCollection confidence) { Application = application; Source = source; Confidence = confidence; } public ConfidenceCollection Confidence { get; } public IJunkCreator Source { get; } public ApplicationUninstallerEntry Application { get; } public abstract void Backup(string backupDirectory); public abstract void Delete(); public abstract void Open(); public abstract string GetDisplayName(); public virtual string ToLongString() { return $@"{Application} - {Localisation.JunkRemover_Confidence}: {Confidence.GetConfidence()} - { GetDisplayName()}"; } /// /// Prepare a backup directory in the specified parent folder, and return it. /// protected string CreateBackupDirectory(string parent) { var p = Path.Combine(parent, PathTools.SanitizeFileName(Application.DisplayName)); Directory.CreateDirectory(p); return p; } public override string ToString() { return GetType().Name + " - " + GetDisplayName(); } } } ================================================ FILE: source/UninstallTools/Junk/Containers/RegistryKeyJunk.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.IO; using Klocman.Tools; using Microsoft.Win32; namespace UninstallTools.Junk.Containers { public class RegistryKeyJunk : JunkResultBase { public string FullRegKeyPath { get; } public RegistryKey OpenRegKey(bool writable = false) { return RegistryTools.OpenRegistryKey(FullRegKeyPath, writable); } public string RegKeyParentPath => Path.GetDirectoryName(FullRegKeyPath); public string RegKeyName => Path.GetFileName(FullRegKeyPath); public bool RegKeyExists() { using (var key = OpenRegKey()) return key != null; } public RegistryKeyJunk(string fullRegKeyPath, ApplicationUninstallerEntry application, IJunkCreator source) : base(application, source) { if (string.IsNullOrEmpty(fullRegKeyPath)) throw new ArgumentException(@"Argument is null or empty", nameof(fullRegKeyPath)); FullRegKeyPath = fullRegKeyPath.TrimEnd('\\', '/', ' '); } public override void Backup(string backupDirectory) { var fileName = PathTools.SanitizeFileName(FullRegKeyPath.TrimStart('\\')) + ".reg"; var path = Path.Combine(CreateBackupDirectory(backupDirectory), fileName); RegistryTools.ExportRegistry(path, new[] { FullRegKeyPath }); } public override void Delete() { using (var key = RegistryTools.OpenRegistryKey(RegKeyParentPath, true)) { key?.DeleteSubKeyTree(RegKeyName); } } public override void Open() { if (!RegKeyExists()) throw new IOException($"Key \"{FullRegKeyPath}\" doesn't exist or can't be accessed"); RegistryTools.OpenRegKeyInRegedit(FullRegKeyPath); } public override string GetDisplayName() { return FullRegKeyPath; } } } ================================================ FILE: source/UninstallTools/Junk/Containers/RegistryValueJunk.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System.Collections.Generic; using System.Diagnostics; using System.IO; using Klocman.Extensions; using Klocman.Tools; using Microsoft.Win32; namespace UninstallTools.Junk.Containers { public class RegistryValueJunk : RegistryKeyJunk { public RegistryValueJunk(string containingKeyPath, string valueName, ApplicationUninstallerEntry application, IJunkCreator source) : base(containingKeyPath, application, source) { ValueName = valueName; } public string ValueName { get; } /// /// If not null, overrides ValueName in GetDisplayName /// public string DisplayValueName { get; set; } public override void Backup(string backupDirectory) { using var key = OpenRegKey(); var valueKind = key.GetValueKind(ValueName); switch (valueKind) { case RegistryValueKind.ExpandString: case RegistryValueKind.String: var targetValue = key.GetStringSafe(ValueName); var dir = CreateBackupDirectory(backupDirectory); var fileName = PathTools.SanitizeFileName(string.Concat(FullRegKeyPath, " - ", ValueName) .TrimStart('\\').Replace('.', '_')) + ".reg"; RegistryTools.ExportRegistryStringValues(Path.Combine(dir, fileName), FullRegKeyPath, new KeyValuePair(ValueName, targetValue)); break; case RegistryValueKind.MultiString: case RegistryValueKind.Binary: case RegistryValueKind.DWord: case RegistryValueKind.QWord: case RegistryValueKind.Unknown: default: Debug.Fail($"Unsupported type {valueKind} of value {ValueName}"); break; case RegistryValueKind.None: break; } } public override string GetDisplayName() { return base.GetDisplayName() + " => " + (DisplayValueName ?? ValueName); } public override void Delete() { using (var key = RegistryTools.OpenRegistryKey(FullRegKeyPath, true)) { key?.DeleteValue(ValueName); } } } } ================================================ FILE: source/UninstallTools/Junk/Containers/RunProcessJunk.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Diagnostics; using Klocman.Forms.Tools; using Klocman.Tools; namespace UninstallTools.Junk.Containers { public class RunProcessJunk : JunkResultBase { public ProcessStartCommand ProcessToStart { get; } private readonly string _junkName; public RunProcessJunk(ApplicationUninstallerEntry application, IJunkCreator source, ProcessStartCommand processToStart, string junkName) : base(application, source) { _junkName = junkName; ProcessToStart = processToStart; } public override void Backup(string backupDirectory) { } public override void Delete() { try { var info = ProcessToStart.ToProcessStartInfo(); info.WindowStyle = ProcessWindowStyle.Minimized; info.UseShellExecute = true; Process.Start(info)?.WaitForExit(); } catch (SystemException ex) { Trace.WriteLine($"Failed to delete junk {GetDisplayName()} - {ex}"); } } public override string GetDisplayName() { return $"{_junkName} ({ProcessToStart})"; } public override void Open() { try { WindowsTools.OpenExplorerFocusedOnObject(ProcessToStart.FileName); } catch (SystemException ex) { PremadeDialogs.GenericError(ex); } } } } ================================================ FILE: source/UninstallTools/Junk/Containers/StartupJunkNode.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.IO; using UninstallTools.Junk.Confidence; using UninstallTools.Properties; using UninstallTools.Startup; using UninstallTools.Startup.Normal; namespace UninstallTools.Junk.Containers { public class StartupJunkNode : JunkResultBase { public static readonly ConfidenceRecord ConfidenceStartupIsRunOnce = new(-5, Localisation.Confidence_Startup_IsRunOnce); public static readonly ConfidenceRecord ConfidenceStartupMatched = new(6, Localisation.Confidence_Startup_StartupMatched); internal StartupEntryBase Entry { get; } public override void Backup(string backupDirectory) { var p = Path.Combine(CreateBackupDirectory(backupDirectory), "Startup"); Directory.CreateDirectory(p); Entry.CreateBackup(p); } public override void Delete() { Entry.Delete(); } public override void Open() { StartupManager.OpenStartupEntryLocations(new[] { Entry }); } public override string GetDisplayName() { return Entry.ToString(); } public StartupJunkNode(StartupEntryBase entry, ApplicationUninstallerEntry application, IJunkCreator source) : base(application, source) { Entry = entry ?? throw new ArgumentNullException(nameof(entry)); Confidence.Add(ConfidenceStartupMatched); if (entry is StartupEntry normalStartupEntry && normalStartupEntry.IsRunOnce) { // If the entry is RunOnce, give it some negative points to keep it out of automatic removal. // It might be used to clean up after uninstall on next boot. Confidence.Add(ConfidenceStartupIsRunOnce); } } } } ================================================ FILE: source/UninstallTools/Junk/Finders/Drive/CommonDriveJunkScanner.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using Klocman.Extensions; using Klocman.Tools; using UninstallTools.Junk.Confidence; using UninstallTools.Junk.Containers; using UninstallTools.Properties; namespace UninstallTools.Junk.Finders.Drive { public class CommonDriveJunkScanner : JunkCreatorBase { private static IEnumerable _foldersToCheck; public override void Setup(ICollection allUninstallers) { base.Setup(allUninstallers); var allDirs = UninstallToolsGlobalConfig.JunkSearchDirs.Concat(UninstallToolsGlobalConfig.GetAllProgramFiles()); var validDirs = allDirs.Attempt(dir => { var dirinfo = new DirectoryInfo(dir); return dirinfo.Exists ? dirinfo : null; }).Where(x => x != null); _foldersToCheck = validDirs.DistinctBy(x => x.FullName.ToLowerInvariant()).ToList(); } public override IEnumerable FindJunk(ApplicationUninstallerEntry target) { return _foldersToCheck.SelectMany(x => FindJunkRecursively(x, target)); } public override string CategoryName => Localisation.Junk_Drive_GroupName; private IEnumerable FindJunkRecursively(DirectoryInfo directory, ApplicationUninstallerEntry uninstaller, int level = 0) { var added = new List(); IEnumerable results = added; try { var dirs = directory.GetDirectories(); foreach (var dir in dirs) { if (UninstallToolsGlobalConfig.IsSystemDirectory(dir)) continue; FileSystemJunk newNode = null; if (!UninstallToolsGlobalConfig.IsKnownFolder(dir)) { var generatedConfidence = GenerateConfidence(dir.GetNameWithoutExtension(), directory.FullName, uninstaller, level).ToList(); if (generatedConfidence.Any()) { newNode = new FileSystemJunk(dir, uninstaller, this); newNode.Confidence.AddRange(generatedConfidence); if (CheckIfDirIsStillUsed(dir.FullName, GetOtherInstallLocations(uninstaller))) newNode.Confidence.Add(ConfidenceRecords.DirectoryStillUsed); added.Add(newNode); } } if (level > 1) continue; var junkNodes = FindJunkRecursively(dir, uninstaller, level + 1).ToList(); // ReSharper disable once PossibleMultipleEnumeration results = results.Concat(junkNodes); if (newNode != null) { // Check if the directory will have nothing left after junk removal. if (!dir.GetFiles().Any()) { var subDirs = dir.GetDirectories(); if (!subDirs.Any() || subDirs.All(d => junkNodes.Any(y => PathTools.PathsEqual(d.FullName, y.Path.FullName)))) newNode.Confidence.Add(ConfidenceRecords.AllSubdirsMatched); } } } ConfidenceGenerators.TestForSimilarNames(uninstaller, AllUninstallers, added.Select(x => new KeyValuePair(x, x.Path.GetNameWithoutExtension())).ToList()); } catch (Exception ex) { if (Debugger.IsAttached) throw; Trace.WriteLine(ex); } // ReSharper disable once PossibleMultipleEnumeration return results; } private static IEnumerable GenerateConfidence(string itemName, string itemParentPath, ApplicationUninstallerEntry uninstaller, int level) { var baseOutput = ConfidenceGenerators.GenerateConfidence(itemName, itemParentPath, level, uninstaller).ToList(); if (!baseOutput.Any(x => x.Change > 0)) return Enumerable.Empty(); if (UninstallToolsGlobalConfig.QuestionableDirectoryNames.Contains(itemName, StringComparison.OrdinalIgnoreCase)) baseOutput.Add(ConfidenceRecords.QuestionableDirectoryName); return baseOutput; } } } ================================================ FILE: source/UninstallTools/Junk/Finders/Drive/InstallLocationScanner.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System.Collections.Generic; using UninstallTools.Junk.Confidence; using UninstallTools.Junk.Containers; using UninstallTools.Properties; namespace UninstallTools.Junk.Finders.Drive { public class InstallLocationScanner : JunkCreatorBase { public override IEnumerable FindJunk(ApplicationUninstallerEntry target) { if (!target.IsInstallLocationValid()) yield break; var resultNode = GetJunkNodeFromLocation(GetOtherInstallLocations(target), target.InstallLocation, target); if (resultNode != null) { if (target.UninstallerKind == UninstallerType.StoreApp) resultNode.Confidence.Add(ConfidenceRecords.IsStoreApp); yield return resultNode; } } public override string CategoryName => Localisation.Junk_Drive_GroupName; } } ================================================ FILE: source/UninstallTools/Junk/Finders/Drive/PrefetchScanner.cs ================================================ /* Copyright (c) 2020 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using Klocman.Extensions; using Klocman.Tools; using UninstallTools.Junk.Confidence; using UninstallTools.Junk.Containers; namespace UninstallTools.Junk.Finders.Drive { public class PrefetchScanner : JunkCreatorBase { private ILookup _pfFiles; public override void Setup(ICollection allUninstallers) { base.Setup(allUninstallers); try { var prefetchDir = Path.Combine(WindowsTools.GetEnvironmentPath(Klocman.Native.CSIDL.CSIDL_WINDOWS), "Prefetch"); if (!Directory.Exists(prefetchDir)) return; _pfFiles = Directory.GetFiles(prefetchDir) .Where(x => x.EndsWith(".pf", StringComparison.OrdinalIgnoreCase)) .Select( fullPath => { var fileName = Path.GetFileName(fullPath); var i = fileName.LastIndexOf('-'); if (i < 0) return null; var appFilename = fileName.Substring(0, i); if (!appFilename.EndsWith(".exe", StringComparison.OrdinalIgnoreCase)) return null; return new { fullPath, appFilename }; }) .Where(x => x != null) .ToLookup(arg => arg.appFilename.ToLowerInvariant(), arg => arg.fullPath); } catch (SystemException ex) { Trace.WriteLine("Failed to gather prefetch files - " + ex); } } public override IEnumerable FindJunk(ApplicationUninstallerEntry target) { var results = new List(); if (_pfFiles == null || target.SortedExecutables == null || target.SortedExecutables.Length == 0) return results; var targetExeNames = target.SortedExecutables .Attempt(Path.GetFileName) .Where(x => !string.IsNullOrEmpty(x)) .Select(x => x.ToLowerInvariant()) .ToList(); var pfFileHits = targetExeNames .SelectMany(fileName => _pfFiles[fileName] .Select(fullPath => new { fileName, fullPath })) .ToList(); var usedByOthers = AllUninstallers .Where(x => x != target) .SelectMany(x => x.SortedExecutables ?? Enumerable.Empty()) .Attempt(Path.GetFileName) .Where(x => !string.IsNullOrEmpty(x)) .Select(x => x.ToLowerInvariant()); var usedByOthersLookup = new HashSet(usedByOthers); foreach (var pfHit in pfFileHits) { var node = new FileSystemJunk(new FileInfo(pfHit.fullPath), target, this); node.Confidence.Add(ConfidenceRecords.ExplicitConnection); if (usedByOthersLookup.Contains(pfHit.fileName)) node.Confidence.Add(ConfidenceRecords.UsedBySimilarNamedApp); results.Add(node); } return results; } public override string CategoryName => "Prefetch"; } } ================================================ FILE: source/UninstallTools/Junk/Finders/Drive/SpecificUninstallerKindScanner.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.IO; using UninstallTools.Junk.Confidence; using UninstallTools.Junk.Containers; using UninstallTools.Properties; namespace UninstallTools.Junk.Finders.Drive { public class SpecificUninstallerKindScanner : JunkCreatorBase { public override IEnumerable FindJunk(ApplicationUninstallerEntry target) { if (!File.Exists(target.UninstallerFullFilename)) yield break; FileSystemJunk result; switch (target.UninstallerKind) { case UninstallerType.InstallShield: var dirPath = Path.GetDirectoryName(target.UninstallerFullFilename); if (dirPath == null) yield break; var targetDir = new DirectoryInfo(dirPath); result = new FileSystemJunk(targetDir, target, this); break; case UninstallerType.InnoSetup: case UninstallerType.Nsis: result = new FileSystemJunk(new FileInfo(target.UninstallerFullFilename), target, this); break; case UninstallerType.Msiexec: if(target.UninstallerFullFilename.EndsWith("msiexec.exe", StringComparison.OrdinalIgnoreCase)) yield break; var path = new FileInfo(target.UninstallerFullFilename); if ((path.Attributes & FileAttributes.System) == FileAttributes.System) yield break; result = new FileSystemJunk(path, target, this); break; default: yield break; } result.Confidence.Add(ConfidenceRecords.ExplicitConnection); yield return result; } public override string CategoryName => Localisation.Junk_Drive_GroupName; } } ================================================ FILE: source/UninstallTools/Junk/Finders/Drive/UninstallerLocationScanner.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using Klocman.Extensions; using UninstallTools.Junk.Confidence; using UninstallTools.Junk.Containers; using UninstallTools.Properties; namespace UninstallTools.Junk.Finders.Drive { public class UninstallerLocationScanner : JunkCreatorBase { private IEnumerable _allProgramFiles; public override void Setup(ICollection allUninstallers) { _allProgramFiles = UninstallToolsGlobalConfig.GetAllProgramFiles().ToList(); base.Setup(allUninstallers); } public override IEnumerable FindJunk(ApplicationUninstallerEntry target) { var uninLoc = target.UninstallerLocation; if (string.IsNullOrEmpty(uninLoc)) yield break; if (_allProgramFiles.Any(x => uninLoc.StartsWith(x, StringComparison.InvariantCultureIgnoreCase)) && !CheckIfDirIsStillUsed(uninLoc, GetOtherInstallLocations(target))) { var resultNode = GetJunkNodeFromLocation(Enumerable.Empty(), uninLoc, target); if (resultNode != null) yield return resultNode; } else if (target.UninstallerKind == UninstallerType.Msiexec && !target.BundleProviderKey.IsEmpty()) { FileSystemInfo[] matchedItems; try { var winInstallerDir = new DirectoryInfo(uninLoc); matchedItems = winInstallerDir.GetFileSystemInfos($"*{target.BundleProviderKey}*"); } catch (SystemException e) { Trace.WriteLine(e); yield break; } foreach (var fileSystemInfo in matchedItems) { var junk = new FileSystemJunk(fileSystemInfo, target, this); junk.Confidence.Add(ConfidenceRecords.ExplicitConnection); yield return junk; } } } public override string CategoryName => Localisation.Junk_UninstallerLocation_GroupName; } } ================================================ FILE: source/UninstallTools/Junk/Finders/Drive/WerScanner.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.IO; using System.Linq; using Klocman.Extensions; using Klocman.Tools; using UninstallTools.Junk.Confidence; using UninstallTools.Junk.Containers; using UninstallTools.Properties; namespace UninstallTools.Junk.Finders.Drive { public class WerScanner : JunkCreatorBase { private const string CrashLabel = "AppCrash_"; private static readonly ICollection Archives; private ICollection _werReportPaths; static WerScanner() { Archives = new[] { WindowsTools.GetEnvironmentPath(Klocman.Native.CSIDL.CSIDL_COMMON_APPDATA), WindowsTools.GetEnvironmentPath(Klocman.Native.CSIDL.CSIDL_LOCAL_APPDATA) }.SelectMany(x =>new[] { Path.Combine(x, @"Microsoft\Windows\WER\ReportArchive"), Path.Combine(x, @"Microsoft\Windows\WER\ReportQueue") }).Where(Directory.Exists) .ToArray(); } public override void Setup(ICollection allUninstallers) { base.Setup(allUninstallers); _werReportPaths = Archives.Attempt(Directory.GetDirectories).SelectMany(x => x).ToArray(); } public override IEnumerable FindJunk(ApplicationUninstallerEntry target) { if (target.SortedExecutables == null || target.SortedExecutables.Length == 0) yield break; var appExecutables = target.SortedExecutables.Attempt(Path.GetFileName).ToList(); foreach (var reportPath in _werReportPaths) { var startIndex = reportPath.LastIndexOf(CrashLabel, StringComparison.InvariantCultureIgnoreCase); if (startIndex <= 0) continue; startIndex += CrashLabel.Length; var count = reportPath.IndexOf('_', startIndex) - startIndex; if (count <= 1) continue; var filename = reportPath.Substring(startIndex, count); if (appExecutables.Any(x => x.StartsWith(filename, StringComparison.InvariantCultureIgnoreCase))) { var node = new FileSystemJunk(new DirectoryInfo(reportPath),target, this); node.Confidence.Add(ConfidenceRecords.ExplicitConnection); yield return node; } } } public override string CategoryName => Localisation.Junk_WerReports_GroupName; } } ================================================ FILE: source/UninstallTools/Junk/Finders/JunkCreatorBase.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.IO; using System.Linq; using Klocman.Tools; using UninstallTools.Junk.Confidence; using UninstallTools.Junk.Containers; namespace UninstallTools.Junk.Finders { public abstract class JunkCreatorBase : IJunkCreator { public virtual void Setup(ICollection allUninstallers) { AllUninstallers = allUninstallers; } protected ICollection AllUninstallers { get; private set; } protected IEnumerable GetOtherUninstallers(ApplicationUninstallerEntry exceptThis) { return AllUninstallers.Where(x => x != exceptThis); } protected IEnumerable GetOtherInstallLocations(ApplicationUninstallerEntry target) { return GetOtherUninstallers(target).Select(x => x.InstallLocation).Where(x => !string.IsNullOrEmpty(x)); } public abstract IEnumerable FindJunk(ApplicationUninstallerEntry target); public abstract string CategoryName { get; } /// /// Returns true if the dir is still used by other apps and can't be safely deleted. /// public static bool CheckIfDirIsStillUsed(string location, IEnumerable otherInstallLocations) { return !string.IsNullOrEmpty(location) && otherInstallLocations.Any(x => x.TrimEnd('\\').StartsWith(location, StringComparison.InvariantCultureIgnoreCase)); } private static readonly string FullWindowsDirectoryName = PathTools.GetWindowsDirectory().FullName; // TODO overhaul protected FileSystemJunk GetJunkNodeFromLocation(IEnumerable otherInstallLocations, string directory, ApplicationUninstallerEntry app) { try { var dirInfo = new DirectoryInfo(directory); if (dirInfo.FullName.Contains(FullWindowsDirectoryName) || !dirInfo.Exists || dirInfo.Parent == null) return null; var newNode = new FileSystemJunk(dirInfo, app, this); newNode.Confidence.Add(ConfidenceRecords.ExplicitConnection); if (CheckIfDirIsStillUsed(dirInfo.FullName, otherInstallLocations)) newNode.Confidence.Add(ConfidenceRecords.DirectoryStillUsed); return newNode; } catch { return null; } } } } ================================================ FILE: source/UninstallTools/Junk/Finders/Misc/ShortcutJunk.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using Klocman.Extensions; using Klocman.Native; using Klocman.Tools; using UninstallTools.Junk.Confidence; using UninstallTools.Junk.Containers; using UninstallTools.Properties; namespace UninstallTools.Junk.Finders.Misc { public class ShortcutJunk : JunkCreatorBase { private ICollection _links; public override void Setup(ICollection allUninstallers) { base.Setup(allUninstallers); _links = GetShortcuts(); } private static IEnumerable GetLnkFilesSafe(CSIDL directory, SearchOption option) { try { return Directory.GetFiles(WindowsTools.GetEnvironmentPath(directory), "*.lnk", option); } catch (Exception ex) { Trace.WriteLine(ex); Debug.Fail(ex.ToString()); } return Enumerable.Empty(); } private static List GetShortcuts() { var syspath = WindowsTools.GetEnvironmentPath(CSIDL.CSIDL_WINDOWS); var results = new List(); foreach (var linkFilename in GetLnkFilesSafe(CSIDL.CSIDL_PROGRAMS, SearchOption.AllDirectories) .Concat(GetLnkFilesSafe(CSIDL.CSIDL_COMMON_PROGRAMS, SearchOption.AllDirectories)) .Concat(GetLnkFilesSafe(CSIDL.CSIDL_DESKTOPDIRECTORY, SearchOption.TopDirectoryOnly)) .Concat(GetLnkFilesSafe(CSIDL.CSIDL_COMMON_DESKTOPDIRECTORY, SearchOption.TopDirectoryOnly)) .Distinct()) { try { var target = WindowsTools.ResolveShortcut(linkFilename); if (string.IsNullOrEmpty(target) || PathTools.SubPathIsInsideBasePath(syspath, target, true, true) || PathTools.SubPathIsInsideBasePath(UninstallToolsGlobalConfig.AppLocation, target, true, true)) continue; results.Add(new Shortcut(linkFilename, target)); } catch (Exception ex) { var failMessage = "Failed to resolve shortcut: " + linkFilename; Trace.WriteLine(failMessage); Trace.WriteLine(ex); Debug.Fail(failMessage); } } return results; } public override IEnumerable FindJunk(ApplicationUninstallerEntry target) { var results = new List(); if (!string.IsNullOrEmpty(target.InstallLocation)) { results.AddRange(GetLinksPointingToLocation(entry => entry.InstallLocation, target) .DoForEach(x => x.Confidence.Add(ConfidenceRecords.ExplicitConnection))); } if (target.UninstallerKind == UninstallerType.Steam) { results.AddRange(GetLinksPointingToSteamApp(target)); } else { if (!string.IsNullOrEmpty(target.UninstallerFullFilename)) { results.AddRange(GetLinksPointingToLocation(entry => entry.UninstallerFullFilename, target) .DoForEach(x => x.Confidence.Add(ConfidenceRecords.ExplicitConnection))); } if (!string.IsNullOrEmpty(target.UninstallerLocation)) { var exceptUninstallerShortcut = GetLinksPointingToLocation(entry => entry.UninstallerLocation, target) .Where(possibleResult => results.All(result => !PathTools.PathsEqual(result.Path, possibleResult.Path))) .ToList(); results.AddRange(exceptUninstallerShortcut); } } // Remove shortcuts that we aren't sure about foreach (var junkNode in results.ToList()) { var name = Path.GetFileNameWithoutExtension(junkNode.Path.Name); junkNode.Confidence.AddRange(ConfidenceGenerators.GenerateConfidence(name, target)); if (junkNode.Confidence.IsEmpty) results.Remove(junkNode); } return results; } /// /// Avoids marking all steam application shortcuts as junk (they use same exe path as uninstall commands) /// private IEnumerable GetLinksPointingToSteamApp(ApplicationUninstallerEntry target) { Debug.Assert(target.UninstallerKind == UninstallerType.Steam); var appId = System.Text.RegularExpressions.Regex.Replace(target.RatingId ?? target.RegistryKeyName ?? string.Empty, @"[^0-9]", ""); if (!string.IsNullOrEmpty(appId)) { foreach (var source in _links) { if (source.LinkTarget.Contains(appId, StringComparison.Ordinal) && source.LinkTarget.Contains("steam", StringComparison.OrdinalIgnoreCase)) { var result = CreateJunkNode(source, target); yield return result; } } } else { Debug.Fail("Steam app has an invalid RegistryKeyName, it should contain its ID. Actual value: " + target.RegistryKeyName); } } public override string CategoryName => Localisation.Junk_Shortcut_GroupName; private FileSystemJunk CreateJunkNode(Shortcut source, ApplicationUninstallerEntry entry) { return new FileSystemJunk(new FileInfo(source.LinkFilename), entry, this); } private IEnumerable GetLinksPointingToLocation( Func targetSelector, ApplicationUninstallerEntry entry) { var target = targetSelector(entry); var targetIsSafe = !GetOtherUninstallers(entry).Any(x => PathTools.PathsEqual(targetSelector(x), target)); foreach (var source in _links) { if (source.LinkTarget.Contains(target, StringComparison.InvariantCultureIgnoreCase)) { var result = CreateJunkNode(source, entry); if (!targetIsSafe) result.Confidence.Add(ConfidenceRecords.DirectoryStillUsed); yield return result; } } } private sealed class Shortcut { public Shortcut(string linkFilename, string linkTarget) { LinkFilename = linkFilename; LinkTarget = linkTarget; } public string LinkFilename { get; } public string LinkTarget { get; } public override string ToString() { return LinkTarget; } } } } ================================================ FILE: source/UninstallTools/Junk/Finders/Misc/StartupJunk.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System.Collections.Generic; using System.Linq; using UninstallTools.Junk.Containers; using UninstallTools.Properties; namespace UninstallTools.Junk.Finders.Misc { public sealed class StartupJunk : IJunkCreator { public void Setup(ICollection allUninstallers) { } public string CategoryName => Localisation.Junk_Startup_GroupName; public IEnumerable FindJunk(ApplicationUninstallerEntry target) { if (target.StartupEntries == null) return Enumerable.Empty(); return target.StartupEntries.Where(x => x.StillExists()) .Select(x => (IJunkResult)new StartupJunkNode(x, target, this)); } } } ================================================ FILE: source/UninstallTools/Junk/Finders/Registry/AppCompatFlagScanner.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Linq; using Klocman.Tools; using UninstallTools.Junk.Confidence; using UninstallTools.Junk.Containers; using UninstallTools.Properties; namespace UninstallTools.Junk.Finders.Registry { public class AppCompatFlagScanner : IJunkCreator { private static readonly IEnumerable AppCompatFlags = new[] { @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags", @"HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags" }; public void Setup(ICollection allUninstallers) { } public IEnumerable FindJunk(ApplicationUninstallerEntry target) { if (string.IsNullOrEmpty(target.InstallLocation)) yield break; foreach (var fullCompatKey in AppCompatFlags.SelectMany(compatKey => new[] { compatKey + @"\Layers", compatKey + @"\Compatibility Assistant\Store" })) { using (var key = RegistryTools.OpenRegistryKey(fullCompatKey)) { if (key == null) continue; foreach (var valueName in key.GetValueNames()) { // Check for matches if (valueName.StartsWith(target.InstallLocation, StringComparison.InvariantCultureIgnoreCase)) { var junk = new RegistryValueJunk(key.Name, valueName, target, this); junk.Confidence.Add(ConfidenceRecords.ExplicitConnection); yield return junk; } } } } } public string CategoryName => Localisation.Junk_AppCompat_GroupName; } } ================================================ FILE: source/UninstallTools/Junk/Finders/Registry/AudioPolicyConfigScanner.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using Klocman.Extensions; using Klocman.Tools; using UninstallTools.Junk.Confidence; using UninstallTools.Junk.Containers; using UninstallTools.Properties; namespace UninstallTools.Junk.Finders.Registry { public class AudioPolicyConfigScanner : IJunkCreator { private static readonly string AudioPolicyConfigSubkey = @"Microsoft\Internet Explorer\LowRegistry\Audio\PolicyConfig\PropertyStore"; public void Setup(ICollection allUninstallers) { } public IEnumerable FindJunk(ApplicationUninstallerEntry target) { var returnList = new List(); if (string.IsNullOrEmpty(target.InstallLocation)) return returnList; string pathRoot; try { pathRoot = Path.GetPathRoot(target.InstallLocation) ?? throw new ArgumentException("No path root for " + target.InstallLocation); } catch (SystemException ex) { Trace.WriteLine(ex); return returnList; } var unrootedLocation = pathRoot.Length >= 1 ? target.InstallLocation.Replace(pathRoot, string.Empty) : target.InstallLocation; if (string.IsNullOrEmpty(unrootedLocation.Trim())) return returnList; using (var key = RegistryTools.OpenRegistryKey(Path.Combine(SoftwareRegKeyScanner.KeyCu, AudioPolicyConfigSubkey))) { if (key == null) return returnList; foreach (var subKeyName in key.GetSubKeyNames()) { using (var subKey = key.OpenSubKey(subKeyName)) { if (subKey == null) continue; var defVal = subKey.GetStringSafe(null); if (defVal != null && defVal.Contains(unrootedLocation, StringComparison.InvariantCultureIgnoreCase)) { var junk = new RegistryKeyJunk(subKey.Name, target, this); junk.Confidence.Add(ConfidenceRecords.ExplicitConnection); returnList.Add(junk); } } } } return returnList; } public string CategoryName => Localisation.Junk_AudioPolicy_GroupName; } } ================================================ FILE: source/UninstallTools/Junk/Finders/Registry/ComScanner.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using Klocman.Tools; using Microsoft.Win32; using UninstallTools.Junk.Confidence; using UninstallTools.Junk.Containers; using UninstallTools.Properties; namespace UninstallTools.Junk.Finders.Registry { public class ComScanner : JunkCreatorBase { private static readonly string[] _classesKeys = { @"HKEY_LOCAL_MACHINE\SOFTWARE\Classes", @"HKEY_LOCAL_MACHINE\SOFTWARE\Classes\WOW6432Node", @"HKEY_CURRENT_USER\SOFTWARE\Classes", @"HKEY_CURRENT_USER\SOFTWARE\Classes\WOW6432Node" }; private List _comEntries; private Dictionary _extensionKeyNames; public override string CategoryName => Localisation.Junk_Clsid_GroupName; // "COM Objects"; public override IEnumerable FindJunk(ApplicationUninstallerEntry target) { if (string.IsNullOrEmpty(target.InstallLocation)) yield break; if (UninstallToolsGlobalConfig.IsSystemDirectory(target.InstallLocation)) yield break; foreach (var comEntry in _comEntries.Where(x => PathTools.SubPathIsInsideBasePath(target.InstallLocation, x.FullFilename, true, true))) { foreach (var interfacePath in comEntry.InterfaceNames) { using (var interfaceKey = RegistryTools.OpenRegistryKey(interfacePath, false, true)) { if (interfaceKey != null) yield return JunkFromKey(target, interfaceKey); } } foreach (var classesKeyPath in _classesKeys) { using (var classesKey = RegistryTools.OpenRegistryKey(classesKeyPath, false, true)) { if (classesKey == null) continue; foreach (var targetSubKeyPath in new[] { Path.Combine("CLSID", comEntry.Guid), Path.Combine("TypeLib", comEntry.Guid), comEntry.ProgId, comEntry.VersionIndependentProgId }) { if (targetSubKeyPath != null) { var result = TryGetFromPath(target, classesKey, targetSubKeyPath); if (result != null) yield return result; } } foreach (var extensionKeyName in GetExtensionNames(classesKeyPath)) { using (var extensionKey = classesKey.OpenSubKey(extensionKeyName)) { if (extensionKey == null) continue; // Contains subkeys with default values containing class guids of the extensions using (var shellExKey = extensionKey.OpenSubKey("ShellEx")) { if (shellExKey != null) { foreach (var shellSubKeyName in shellExKey.GetSubKeyNames()) { using (var shellSubKey = shellExKey.OpenSubKey(shellSubKeyName)) { if (string.Equals(shellSubKey?.GetValue(null, null) as string, comEntry.Guid, StringComparison.OrdinalIgnoreCase)) yield return JunkFromKey(target, shellSubKey); } } } } // Contains default value pointing to a class guid using (var persistentHandlerKey = extensionKey.OpenSubKey("PersistentHandler")) { if (string.Equals(persistentHandlerKey?.GetValue(null, null) as string, comEntry.Guid, StringComparison.OrdinalIgnoreCase)) yield return JunkFromKey(target, persistentHandlerKey); } if (comEntry.ProgId != null || comEntry.VersionIndependentProgId != null) { // Contains values with names corresponding to ProgIDs using (var openWithProgidsKey = extensionKey.OpenSubKey("OpenWithProgIDs")) { if (openWithProgidsKey != null) { foreach (var progIdName in openWithProgidsKey.GetValueNames()) { if (string.Equals(progIdName, comEntry.ProgId, StringComparison.OrdinalIgnoreCase) || string.Equals(progIdName, comEntry.VersionIndependentProgId, StringComparison.OrdinalIgnoreCase)) yield return JunkFromValue(target, openWithProgidsKey.Name, progIdName); } } } } } } } } } } public override void Setup(ICollection allUninstallers) { base.Setup(allUninstallers); _comEntries = new List(); _extensionKeyNames = new Dictionary(); foreach (var classesKeyPath in _classesKeys) { using (var classesKey = RegistryTools.OpenRegistryKey(classesKeyPath, false, true)) { if (classesKey == null) continue; _extensionKeyNames.Add(classesKeyPath, classesKey.GetSubKeyNames().Where(x => x.Length > 0 && x[0] == '.').ToArray()); try { GetClsidEntries(_comEntries, classesKey); GetTypeLibEntries(_comEntries, classesKey); } catch (SystemException ex) { Trace.WriteLine(@"Unexpected error while scanning COM entries, the registry might be corrupted. COM junk detection will not work. Error: " + ex); } } } // Gather com interface info // https://docs.microsoft.com/en-us/windows/desktop/com/interface-key foreach (var classesKeyPath in _classesKeys) { using (var interfacesKey = RegistryTools.OpenRegistryKey(Path.Combine(classesKeyPath, "Interface"), false, true)) { if (interfacesKey == null) continue; foreach (var singleInterfaceKey in interfacesKey.GetSubKeyNames()) { using (var proxyKey = interfacesKey.OpenSubKey(Path.Combine(singleInterfaceKey, "ProxyStubClsid32"))) { var proxyGuid = proxyKey?.GetValue(null, null) as string; if (proxyGuid == null) continue; var matchClass = _comEntries.FirstOrDefault(x => string.Equals(x.Guid, proxyGuid, StringComparison.OrdinalIgnoreCase)); matchClass?.InterfaceNames.Add(Path.Combine(interfacesKey.Name, singleInterfaceKey)); } } } } } private static void GetClsidEntries(ICollection results, RegistryKey classes) { // https://docs.microsoft.com/en-us/windows/desktop/com/clsid-key-hklm using (var clsid = RegistryTools.OpenRegistryKey(Path.Combine(classes.Name, "CLSID"), false, true)) { if (clsid == null) return; foreach (var clsidGuid in clsid.GetSubKeyNames()) { // This catches most system classes, rest is caught by IsSystemDirectory check later if (IsSystemGuid(clsidGuid)) continue; RegistryKey guidKey = null; try { guidKey = clsid.OpenSubKey(clsidGuid); if (guidKey == null) continue; var result = results.FirstOrDefault(x => string.Equals(x.Guid, clsidGuid, StringComparison.OrdinalIgnoreCase)) ?? new ComEntry(clsidGuid); using (var inprocKey = guidKey.OpenSubKey("InprocServer32")) { var path = inprocKey?.GetValue(null, null) as string; if (string.IsNullOrEmpty(path)) continue; path = PathTools.NormalizePath(path); if (UninstallToolsGlobalConfig.IsSystemDirectory(path)) continue; result.FullFilename = PathTools.NormalizePath(Environment.ExpandEnvironmentVariables(path)); } using (var progIdKey = guidKey.OpenSubKey("ProgID")) { if (progIdKey != null) result.ProgId = progIdKey.GetValue(null, null) as string; } using (var indepProgIdKey = guidKey.OpenSubKey("VersionIndependentProgID")) { if (indepProgIdKey != null) result.VersionIndependentProgId = indepProgIdKey.GetValue(null, null) as string; } results.Add(result); } catch (SystemException ex) { Trace.WriteLine($@"Crash while processing COM GUID: {clsidGuid} - {ex}"); } finally { guidKey?.Close(); } } } } private static void GetTypeLibEntries(ICollection results, RegistryKey classes) { using (var typeLibKey = RegistryTools.OpenRegistryKey(Path.Combine(classes.Name, "TypeLib"), false, true)) { if (typeLibKey == null) return; foreach (var typeLibKeyGuid in typeLibKey.GetSubKeyNames()) { if (IsSystemGuid(typeLibKeyGuid)) continue; using (var guidKey = typeLibKey.OpenSubKey(typeLibKeyGuid)) { var versionKeyName = guidKey?.GetSubKeyNames().FirstOrDefault(); if (versionKeyName == null) continue; var result = results.FirstOrDefault(x => string.Equals(x.Guid, typeLibKeyGuid, StringComparison.OrdinalIgnoreCase)) ?? new ComEntry(typeLibKeyGuid); foreach (var fileKeyPath in new[] { Path.Combine(versionKeyName, "0\\win32"), Path.Combine(versionKeyName, "0\\win64") }) { using (var fileKey = guidKey.OpenSubKey(fileKeyPath)) { var path = fileKey?.GetValue(null, null) as string; if (string.IsNullOrEmpty(path)) continue; path = PathTools.NormalizePath(path); if (UninstallToolsGlobalConfig.IsSystemDirectory(path)) continue; result.FullFilename = PathTools.NormalizePath(Environment.ExpandEnvironmentVariables(path)); results.Add(result); break; } } } } } } private static bool IsSystemGuid(string guid) { // Treat missing/invalid GUID text as non-target so callers can safely skip it. if (string.IsNullOrEmpty(guid)) return true; return guid.Contains("-0000-") || guid[0] != '{'; } private RegistryKeyJunk JunkFromKey(ApplicationUninstallerEntry target, RegistryKey targetKey) { var junk = new RegistryKeyJunk(targetKey.Name, target, this); junk.Confidence.Add(ConfidenceRecords.ExplicitConnection); return junk; } private IJunkResult JunkFromValue(ApplicationUninstallerEntry target, string key, string valueName) { var junk = new RegistryValueJunk(key, valueName, target, this); junk.Confidence.Add(ConfidenceRecords.ExplicitConnection); return junk; } private RegistryKeyJunk TryGetFromPath(ApplicationUninstallerEntry target, RegistryKey classesKey, string targetSubKeyPath) { using (var targetKey = classesKey.OpenSubKey(targetSubKeyPath)) { if (targetKey == null) return null; return JunkFromKey(target, targetKey); } } private IEnumerable GetExtensionNames(string classesKey) { _extensionKeyNames.TryGetValue(classesKey, out var result); return result ?? Enumerable.Empty(); } private sealed class ComEntry { public readonly string Guid; public readonly List InterfaceNames = new(); public string FullFilename; //https://docs.microsoft.com/en-us/windows/desktop/com/-progid--key public string ProgId; public string VersionIndependentProgId; public ComEntry(string guid) { Guid = guid; } } } } ================================================ FILE: source/UninstallTools/Junk/Finders/Registry/DebugTracingScanner.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Security; using Klocman.Extensions; using UninstallTools.Junk.Confidence; using UninstallTools.Junk.Containers; using UninstallTools.Properties; namespace UninstallTools.Junk.Finders.Registry { public class DebugTracingScanner : IJunkCreator { public void Setup(ICollection allUninstallers) { } public IEnumerable FindJunk(ApplicationUninstallerEntry target) { var returnList = new List(); if (string.IsNullOrEmpty(target.InstallLocation)) return returnList; string pathRoot; try { pathRoot = Path.GetPathRoot(target.InstallLocation) ?? throw new ArgumentException("No path root for " + target.InstallLocation); } catch (SystemException ex) { Trace.WriteLine(ex); return returnList; } var unrootedLocation = pathRoot.Length >= 1 ? target.InstallLocation.Replace(pathRoot, string.Empty) : target.InstallLocation; if (string.IsNullOrEmpty(unrootedLocation.Trim())) return returnList; try { using (var key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Tracing", true)) { if (key != null && target.SortedExecutables != null) { var exeNames = target.SortedExecutables.Select(Path.GetFileNameWithoutExtension).ToList(); foreach (var keyGroup in key.GetSubKeyNames() .Where(x => x.EndsWith("_RASAPI32") || x.EndsWith("_RASMANCS")) .Select(name => new {name, trimmed = name.Substring(0, name.LastIndexOf('_'))}) .GroupBy(x => x.trimmed)) { if (exeNames.Contains(keyGroup.Key, StringComparison.InvariantCultureIgnoreCase)) { foreach (var keyName in keyGroup) { var junk = new RegistryKeyJunk(Path.Combine(key.Name, keyName.name), target, this); junk.Confidence.Add(ConfidenceRecords.ExplicitConnection); returnList.Add(junk); } } } } } } catch (Exception ex) { if (ex is UnauthorizedAccessException || ex is SecurityException || ex is IOException) Trace.WriteLine(ex); else throw; } return returnList; } public string CategoryName => Localisation.Junk_DebugTracing_GroupName; } } ================================================ FILE: source/UninstallTools/Junk/Finders/Registry/EventLogScanner.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System.Collections.Generic; using System.IO; using System.Linq; using Klocman.Extensions; using Klocman.Tools; using UninstallTools.Junk.Confidence; using UninstallTools.Junk.Containers; using UninstallTools.Properties; namespace UninstallTools.Junk.Finders.Registry { public class EventLogScanner : JunkCreatorBase { public override IEnumerable FindJunk(ApplicationUninstallerEntry target) { if (string.IsNullOrEmpty(target.InstallLocation)) yield break; var otherUninstallers = GetOtherUninstallers(target).ToList(); using (var key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey( @"SYSTEM\CurrentControlSet\Services\EventLog\Application")) { if (key == null) yield break; var query = from name in key.GetSubKeyNames() let m = ConfidenceGenerators.MatchStringToProductName(target, name) where m >= 0 && m < 3 //orderby m ascending select name; foreach (var result in query) { using (var subkey = key.OpenSubKey(result)) { var exePath = subkey?.GetStringSafe("EventMessageFile"); if (string.IsNullOrEmpty(exePath) || !PathTools.SubPathIsInsideBasePath(target.InstallLocation, Path.GetDirectoryName(exePath), true, false)) continue; var node = new RegistryKeyJunk(subkey.Name, target, this); // Already matched names above node.Confidence.Add(ConfidenceRecords.ProductNamePerfectMatch); if (otherUninstallers.Any(x => PathTools.SubPathIsInsideBasePath(x.InstallLocation, Path.GetDirectoryName(exePath), true, false))) node.Confidence.Add(ConfidenceRecords.DirectoryStillUsed); yield return node; } } } } public override string CategoryName => Localisation.Junk_EventLog_GroupName; } } ================================================ FILE: source/UninstallTools/Junk/Finders/Registry/FirewallRuleScanner.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Diagnostics; using Klocman.Extensions; using Klocman.Tools; using UninstallTools.Junk.Confidence; using UninstallTools.Junk.Containers; using UninstallTools.Properties; namespace UninstallTools.Junk.Finders.Registry { public class FirewallRuleScanner : JunkCreatorBase { private const string FirewallRulesKey = @"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\FirewallRules"; public override IEnumerable FindJunk(ApplicationUninstallerEntry target) { var results = new List(); if (string.IsNullOrEmpty(target.InstallLocation)) return results; using var key = GetFirewallRulesKey(); if (key != null) { foreach (var valueName in key.TryGetValueNames()) { var value = key.GetStringSafe(valueName); if (string.IsNullOrEmpty(value)) continue; var appIndex = value.IndexOf("|App=", StringComparison.InvariantCultureIgnoreCase); var start = appIndex + 5; if(appIndex == -1 || start >= value.Length) continue; var charCount = value.IndexOf('|', start) - start; if (charCount <= 0) continue; var fullPath = Environment.ExpandEnvironmentVariables(value.Substring(start, charCount)); if (fullPath.StartsWith(target.InstallLocation, StringComparison.InvariantCultureIgnoreCase)) { var node = new RegistryValueJunk(FirewallRulesKey, valueName, target, this); node.Confidence.Add(ConfidenceRecords.ExplicitConnection); results.Add(node); } } } return results; } private static Microsoft.Win32.RegistryKey GetFirewallRulesKey() { try { return RegistryTools.OpenRegistryKey(FirewallRulesKey); } catch (SystemException ex) { Trace.WriteLine("Failed to get firewall rule registry key: " + ex); return null; } } public override string CategoryName => Localisation.Junk_FirewallRule_GroupName; } } ================================================ FILE: source/UninstallTools/Junk/Finders/Registry/HeapLeakDetectionScanner.cs ================================================ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using Klocman.Extensions; using Klocman.Tools; using UninstallTools.Junk.Confidence; using UninstallTools.Junk.Containers; namespace UninstallTools.Junk.Finders.Registry { public class HeapLeakDetectionScanner : IJunkCreator { private const string RegKey = @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\RADAR\HeapLeakDetection\DiagnosedApplications"; private Dictionary _lookup; public void Setup(ICollection allUninstallers) { try { using (var key = RegistryTools.OpenRegistryKey(RegKey)) { if (key != null) { // Reg key names are case insensitive so using tolower key is fine _lookup = key.GetSubKeyNames().ToDictionary(x => x.ToLower(), x => x); } } } catch (SystemException ex) { Trace.WriteLine($"Failed to setup {CategoryName} junk scanner: {ex}"); } } public IEnumerable FindJunk(ApplicationUninstallerEntry target) { if (_lookup == null || target.SortedExecutables == null || target.SortedExecutables.Length == 0) return Enumerable.Empty(); return target.SortedExecutables.Attempt(x => { _lookup.TryGetValue(Path.GetFileName(x).ToLower(), out var hit); return hit; }) .Where(x => x != null) .Select(x => { var junk = new RegistryKeyJunk(Path.Combine(RegKey, x), target, this); junk.Confidence.Add(ConfidenceRecords.ExplicitConnection); return junk; }); } public string CategoryName => "HeapLeakDetection"; } } ================================================ FILE: source/UninstallTools/Junk/Finders/Registry/InstallerFoldersScanner.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System.Collections.Generic; using System.Linq; using Klocman.Tools; using UninstallTools.Junk.Confidence; using UninstallTools.Junk.Containers; using UninstallTools.Properties; namespace UninstallTools.Junk.Finders.Registry { public class InstallerFoldersScanner : JunkCreatorBase { public override IEnumerable FindJunk(ApplicationUninstallerEntry target) { var installLocation = target.InstallLocation; if (string.IsNullOrEmpty(installLocation)) yield break; using (var key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey( @"SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\Folders")) { if (key == null) yield break; foreach (var valueName in key.GetValueNames()) { if (!PathTools.SubPathIsInsideBasePath(installLocation, valueName, true, true)) continue; var node = new RegistryValueJunk(key.Name, valueName, target, this); node.Confidence.Add(ConfidenceRecords.ExplicitConnection); if (GetOtherInstallLocations(target).Any(x => PathTools.SubPathIsInsideBasePath(x, valueName, true, true))) node.Confidence.Add(ConfidenceRecords.DirectoryStillUsed); yield return node; } } } public override string CategoryName => Localisation.Junk_InstalledFolders_GroupName; } } ================================================ FILE: source/UninstallTools/Junk/Finders/Registry/RegisteredApplicationsFinder.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.IO; using System.Linq; using Klocman.Extensions; using Klocman.Tools; using UninstallTools.Junk.Confidence; using UninstallTools.Junk.Containers; namespace UninstallTools.Junk.Finders.Registry { public class RegisteredApplicationsFinder : JunkCreatorBase { private struct RegAppEntry { public RegAppEntry(string valueName, string rootKeyName, string targetSubKeyPath) { ValueName = valueName; RootKeyName = rootKeyName; TargetSubKeyPath = targetSubKeyPath; AppName = AppKey = null; if (valueName.Length == 36 && valueName.StartsWith("App", StringComparison.Ordinal)) { var pathParts = targetSubKeyPath.Split(new[] { '\\' }, StringSplitOptions.RemoveEmptyEntries); for (int i = pathParts.Length - 2; i >= 8; i--) { if (pathParts[i] == "Packages") { AppName = pathParts[i + 1]; AppKey = string.Join("\\", pathParts, 0, i + 2); break; } } } } public string ValueName { get; } public string TargetSubKeyPath { get; } public string RootKeyName { get; } public string TargetFullPath => Path.Combine(RootKeyName, TargetSubKeyPath); public string RegAppFullPath => Path.Combine(RootKeyName, RegAppsSubKeyPath); public string AppName { get; } public string AppKey { get; } } private const string RegAppsSubKeyPath = @"Software\RegisteredApplications"; List _regAppsValueCache; public override void Setup(ICollection allUninstallers) { base.Setup(allUninstallers); // Preload all values into a new cache _regAppsValueCache = new List(); foreach (var targetRootName in TargetRoots) { using (var rootKey = RegistryTools.OpenRegistryKey(targetRootName)) { using (var regAppsKey = rootKey.OpenSubKey(RegAppsSubKeyPath)) { if (regAppsKey == null) continue; var names = regAppsKey.GetValueNames(); var results = names.Attempt(n => new { name = n, value = regAppsKey.GetStringSafe(n) }) .Where(x => !string.IsNullOrEmpty(x.value)) .ToList(); _regAppsValueCache.AddRange(results.Select(x => new RegAppEntry(x.name, targetRootName, x.value.Trim('\\', ' ', '"', '\'')))); } } } } private static readonly string[] TargetRoots = { @"HKEY_CURRENT_USER\", @"HKEY_LOCAL_MACHINE\" }; public override IEnumerable FindJunk(ApplicationUninstallerEntry target) { var isStoreApp = target.UninstallerKind == UninstallerType.StoreApp; if (isStoreApp && string.IsNullOrEmpty(target.RatingId)) throw new ArgumentException("StoreApp entry has no ID"); if (isStoreApp) { foreach (var regAppEntry in _regAppsValueCache) { if (regAppEntry.AppName == null) continue; if (string.Equals(regAppEntry.AppName, target.RatingId, StringComparison.OrdinalIgnoreCase)) { // Handle the value under RegisteredApps itself var regAppResult = new RegistryValueJunk(regAppEntry.RegAppFullPath, regAppEntry.ValueName, target, this); regAppResult.Confidence.Add(ConfidenceRecords.ExplicitConnection); yield return regAppResult; // Handle the key pointed at by the value var appEntryKey = new RegistryKeyJunk(regAppEntry.AppKey, target, this); appEntryKey.Confidence.Add(ConfidenceRecords.ExplicitConnection); appEntryKey.Confidence.Add(ConfidenceRecords.IsStoreApp); yield return appEntryKey; } } } else { foreach (var regAppEntry in _regAppsValueCache) { if (regAppEntry.AppName != null) continue; var generatedConfidence = ConfidenceGenerators.GenerateConfidence(regAppEntry.ValueName, target).ToList(); if (generatedConfidence.Count > 0) { // Handle the value under RegisteredApps itself var regAppResult = new RegistryValueJunk(regAppEntry.RegAppFullPath, regAppEntry.ValueName, target, this); regAppResult.Confidence.AddRange(generatedConfidence); yield return regAppResult; // Handle the key pointed at by the value const string capabilitiesSubkeyName = "\\Capabilities"; if (regAppEntry.TargetSubKeyPath.EndsWith(capabilitiesSubkeyName, StringComparison.Ordinal)) { var capabilitiesKeyResult = new RegistryKeyJunk(regAppEntry.TargetFullPath, target, this); capabilitiesKeyResult.Confidence.AddRange(generatedConfidence); yield return capabilitiesKeyResult; var ownerKey = regAppEntry.TargetFullPath.Substring(0, regAppEntry.TargetFullPath.Length - capabilitiesSubkeyName.Length); var subConfidence = ConfidenceGenerators.GenerateConfidence(Path.GetFileName(ownerKey), target).ToList(); if (subConfidence.Count > 0) { var subResult = new RegistryKeyJunk(ownerKey, target, this); subResult.Confidence.AddRange(subConfidence); yield return subResult; } } } } } } public override string CategoryName => "Registered app capabilities"; } } ================================================ FILE: source/UninstallTools/Junk/Finders/Registry/SoftwareRegKeyScanner.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Security; using Klocman.Extensions; using Klocman.Tools; using Microsoft.Win32; using UninstallTools.Junk.Confidence; using UninstallTools.Junk.Containers; using UninstallTools.Properties; namespace UninstallTools.Junk.Finders.Registry { public class SoftwareRegKeyScanner : JunkCreatorBase { public override string CategoryName => Localisation.Junk_Registry_GroupName; private const string KeynameRegisteredApps = "RegisteredApplications"; private const string KeyVirtualStoreCu = @"HKEY_CURRENT_USER\SOFTWARE\Classes\VirtualStore\MACHINE\SOFTWARE"; private const string KeyVirtualStoreCuWow = @"HKEY_CURRENT_USER\SOFTWARE\Classes\VirtualStore\MACHINE\SOFTWARE\Wow6432Node"; private const string KeyVirtualStoreLm = @"HKEY_LOCAL_MACHINE\SOFTWARE\Classes\VirtualStore\MACHINE\SOFTWARE"; private const string KeyVirtualStoreLmWow = @"HKEY_LOCAL_MACHINE\SOFTWARE\Classes\VirtualStore\MACHINE\SOFTWARE\Wow6432Node"; /// /// Keys to step over when scanning /// private static readonly IEnumerable KeyBlacklist = new[] { "Microsoft", "Wow6432Node", "Windows", "Classes", "Clients", KeynameRegisteredApps }; /// /// Always points to program's directory /// private static readonly IEnumerable InstallDirKeyNames = new[] { "InstallDir", "Install_Dir", "Install Directory", "InstDir", "ApplicationPath", "Install folder", "Last Stable Install Path", "TARGETDIR", "JavaHome" }; /// /// Always points to program's main executable /// private static readonly IEnumerable ExePathKeyNames = new[] { "exe64", "exe32", "Executable", "PathToExe", "ExePath" }; /// /// Can point to programs executable or directory /// private static readonly IEnumerable ExeOrDirPathKeyNames = new[] { "Path", "Path64", "pth", "PlayerPath", "AppPath" }; internal static readonly string KeyCu = @"HKEY_CURRENT_USER\SOFTWARE"; internal static readonly string KeyCuWow = @"HKEY_CURRENT_USER\SOFTWARE\Wow6432Node"; internal static readonly string KeyLm = @"HKEY_LOCAL_MACHINE\SOFTWARE"; internal static readonly string KeyLmWow = @"HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node"; private static readonly ICollection SoftwareRegKeys; private ApplicationUninstallerEntry _uninstaller; static SoftwareRegKeyScanner() { if (ProcessTools.Is64BitProcess) { SoftwareRegKeys = new[] { KeyLm, KeyCu, KeyVirtualStoreCu, KeyVirtualStoreLm, KeyLmWow, KeyCuWow, KeyVirtualStoreCuWow, KeyVirtualStoreLmWow }; } else { SoftwareRegKeys = new[] { KeyLm, KeyCu, KeyVirtualStoreCu, KeyVirtualStoreLm }; } } public override IEnumerable FindJunk(ApplicationUninstallerEntry target) { _uninstaller = target; var output = new List(); foreach (var softwareKeyName in SoftwareRegKeys) { using (var softwareKey = RegistryTools.OpenRegistryKey(softwareKeyName)) { if (softwareKey != null) output.AddRange(FindJunkRecursively(softwareKey)); } } return output.Concat(ScanRelatedKeys(output)); } private IEnumerable FindJunkRecursively(RegistryKey softwareKey, int level = -1) { var added = new List(); IEnumerable returnList = added; try { // Don't try to scan root keys if (level > -1) { var keyName = Path.GetFileName(softwareKey.Name); var keyDir = Path.GetDirectoryName(softwareKey.Name); var confidence = ConfidenceGenerators.GenerateConfidence(keyName, keyDir, level, _uninstaller).ToList(); // Check if application's location is explicitly mentioned in any of the values if (softwareKey.TryGetValueNames().Any(valueName => TestValueForMatches(softwareKey, valueName))) confidence.Add(ConfidenceRecords.ExplicitConnection); if (confidence.Any()) { // TODO Add extra confidence if the key is, or will be empty after junk removal var newNode = new RegistryKeyJunk(softwareKey.Name, _uninstaller, this); newNode.Confidence.AddRange(confidence); added.Add(newNode); } } // Limit recursion depth if (level <= 1) { foreach (var subKeyName in softwareKey.GetSubKeyNames()) { if (KeyBlacklist.Contains(subKeyName, StringComparison.InvariantCultureIgnoreCase)) continue; using (var subKey = softwareKey.OpenSubKey(subKeyName, false)) { if (subKey != null) // ReSharper disable once PossibleMultipleEnumeration returnList = returnList.Concat(FindJunkRecursively(subKey, level + 1)); } } } ConfidenceGenerators.TestForSimilarNames(_uninstaller, AllUninstallers, added.Select(x => new KeyValuePair(x, x.RegKeyName)).ToList()); } // Reg key invalid catch (ArgumentException) { } catch (SecurityException) { } catch (ObjectDisposedException) { } // ReSharper disable once PossibleMultipleEnumeration return returnList; } private bool TestValueForMatches(RegistryKey softwareKey, string valueName) { bool hit; if (InstallDirKeyNames.Contains(valueName, StringComparison.InvariantCultureIgnoreCase)) { hit = PathTools.SubPathIsInsideBasePath(_uninstaller.InstallLocation, softwareKey.GetStringSafe(valueName), true, true); } else if (ExePathKeyNames.Contains(valueName, StringComparison.InvariantCultureIgnoreCase)) { hit = TestPathsMatchExe(softwareKey.GetStringSafe(valueName)); } else if (ExeOrDirPathKeyNames.Contains(valueName, StringComparison.InvariantCultureIgnoreCase)) { var path = softwareKey.GetStringSafe(valueName); hit = File.Exists(path) ? TestPathsMatchExe(softwareKey.GetStringSafe(valueName)) : PathTools.SubPathIsInsideBasePath(_uninstaller.InstallLocation, softwareKey.GetStringSafe(valueName), true, true); } else { hit = PathTools.SubPathIsInsideBasePath(_uninstaller.InstallLocation, softwareKey.GetStringSafe(null), true, true); } return hit; } private IEnumerable ScanRelatedKeys(IEnumerable itemsToCompare) { var input = itemsToCompare.ToList(); var output = new List(); foreach (var registryJunkNode in input) { var nodeName = registryJunkNode.FullRegKeyPath; // Check Wow first because non-wow path will match wow path var softwareKey = new[] { KeyLmWow, KeyCuWow, KeyLm, KeyCu }.First( key => nodeName.StartsWith(key, StringComparison.InvariantCultureIgnoreCase)); nodeName = nodeName.Substring(softwareKey.Length + 1); foreach (var keyToTest in SoftwareRegKeys.Except(new[] { softwareKey })) { var nodePath = Path.Combine(keyToTest, nodeName); // Check if the same node exists in other root keys var node = input.FirstOrDefault(x => PathTools.PathsEqual(x.FullRegKeyPath, nodePath)); if (node != null) { // Add any non-duplicate confidence to the existing node node.Confidence.AddRange(registryJunkNode.Confidence.ConfidenceParts .Where(x => !node.Confidence.ConfidenceParts.Any(x.Equals))); } else { try { // Check if the key acually exists using (var nodeKey = RegistryTools.OpenRegistryKey(nodePath, false)) { if (nodeKey != null) { var newNode = new RegistryKeyJunk(nodePath, _uninstaller, this); newNode.Confidence.AddRange(registryJunkNode.Confidence.ConfidenceParts); output.Add(newNode); } } } catch { // Ignore keys that don't exist } } } } return output; } private bool TestPathsMatchExe(string keyValue) { return PathTools.SubPathIsInsideBasePath(_uninstaller.InstallLocation, Path.GetDirectoryName(keyValue), true, true); } } } ================================================ FILE: source/UninstallTools/Junk/Finders/Registry/TracingScanner.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System.Collections.Generic; using System.IO; using System.Linq; using UninstallTools.Junk.Confidence; using UninstallTools.Junk.Containers; using UninstallTools.Properties; namespace UninstallTools.Junk.Finders.Registry { public class TracingScanner : IJunkCreator { private const string TracingKey = @"SOFTWARE\Microsoft\Tracing"; private const string FullTracingKey = @"HKEY_LOCAL_MACHINE\" + TracingKey; private ICollection _allEntries; public void Setup(ICollection allUninstallers) { _allEntries = allUninstallers; } public IEnumerable FindJunk(ApplicationUninstallerEntry target) { var results = new List(); using (var key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(TracingKey)) { if (key != null) { foreach (var subKeyName in key.GetSubKeyNames()) { var i = subKeyName.LastIndexOf('_'); if (i <= 0) continue; var str = subKeyName.Substring(0, i); var conf = ConfidenceGenerators.GenerateConfidence(str, Path.Combine(FullTracingKey, subKeyName), 0, target).ToList(); if (conf.Any()) { var node = new RegistryKeyJunk(Path.Combine(FullTracingKey, subKeyName), target, this); node.Confidence.AddRange(conf); results.Add(node); } } } } ConfidenceGenerators.TestForSimilarNames(target, _allEntries, results.Select(x => new KeyValuePair(x, x.RegKeyName)).ToList()); return results; } public string CategoryName => Localisation.Junk_Tracing_GroupName; } } ================================================ FILE: source/UninstallTools/Junk/Finders/Registry/UninstallerKeySearcher.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using Klocman.Extensions; using Klocman.IO; using Klocman.Tools; using UninstallTools.Junk.Confidence; using UninstallTools.Junk.Containers; using UninstallTools.Properties; namespace UninstallTools.Junk.Finders.Registry { public class UninstallerKeySearcher : IJunkCreator { private static readonly IEnumerable InstallerSubkeyPaths; /// /// parent key path, upgrade code(key name) /// private IEnumerable> _targetKeys; static UninstallerKeySearcher() { InstallerSubkeyPaths = new[] { @"SOFTWARE\Classes\Installer\Products", @"SOFTWARE\Classes\Installer\Features", @"SOFTWARE\Classes\Installer\Patches" }; try { var currentUserId = WindowsTools.GetUserSid().Value; if (string.IsNullOrEmpty(currentUserId) || currentUserId.Length <= 9) return; var currentUserInstallerDataPath = Path.Combine(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData", currentUserId); InstallerSubkeyPaths = InstallerSubkeyPaths.Concat(new [] { Path.Combine(currentUserInstallerDataPath, "Products"), Path.Combine(currentUserInstallerDataPath, "Patches"), Path.Combine(currentUserInstallerDataPath, "Components") }); } catch (SystemException ex) { Trace.WriteLine(ex); } } public void Setup(ICollection allUninstallers) { _targetKeys = InstallerSubkeyPaths .Using(x => Microsoft.Win32.Registry.LocalMachine.OpenSubKey(x)) .Where(k => k != null) .SelectMany(k => { var parentPath = k.Name; return k.GetSubKeyNames().Select(n => new KeyValuePair(parentPath, n)); }).ToList(); } public IEnumerable FindJunk(ApplicationUninstallerEntry target) { if (target.RegKeyStillExists()) { var regKeyNode = new RegistryKeyJunk(target.RegistryPath, target, this); regKeyNode.Confidence.Add(ConfidenceRecords.IsUninstallerRegistryKey); yield return regKeyNode; } if (target.UninstallerKind == UninstallerType.Msiexec && !target.BundleProviderKey.IsEmpty()) { var upgradeKey = MsiTools.ConvertBetweenUpgradeAndProductCode(target.BundleProviderKey).ToString("N"); var matchedKeyPaths = _targetKeys .Where(x => x.Value.Equals(upgradeKey, StringComparison.OrdinalIgnoreCase)); foreach (var keyPath in matchedKeyPaths) { var fullKeyPath = Path.Combine(keyPath.Key, keyPath.Value); var result = new RegistryKeyJunk(fullKeyPath, target, this); result.Confidence.Add(ConfidenceRecords.ExplicitConnection); yield return result; } } } public string CategoryName => Localisation.Junk_UninstallerKey_GroupName; } } ================================================ FILE: source/UninstallTools/Junk/Finders/Registry/UserAssistScanner.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Linq; using Klocman.Tools; using UninstallTools.Junk.Confidence; using UninstallTools.Junk.Containers; using UninstallTools.Properties; namespace UninstallTools.Junk.Finders.Registry { public class UserAssistScanner : IJunkCreator { public string CategoryName => Localisation.Junk_UserAssist_GroupName; private static readonly IEnumerable UserAssistGuids = new[] { //GUIDs for Windows XP "{75048700-EF1F-11D0-9888-006097DEACF9}", "{5E6AB780-7743-11CF-A12B-00AA004AE837", //GUIDs for Windows 7 "{CEBFF5CD-ACE2-4F4F-9178-9926F41749EA}", "{F4E57C4B-2036-45F0-A9AB-443BCFE33D9F}}" }; public void Setup(ICollection allUninstallers) { } public IEnumerable FindJunk(ApplicationUninstallerEntry target) { if (string.IsNullOrEmpty(target.InstallLocation)) yield break; foreach (var userAssistGuid in UserAssistGuids) { using (var key = RegistryTools.OpenRegistryKey( $@"{SoftwareRegKeyScanner.KeyCu}\Microsoft\Windows\CurrentVersion\Explorer\UserAssist\{userAssistGuid}\Count")) { if (key == null) continue; foreach (var valueName in key.GetValueNames()) { // Convert the value name to a usable form var convertedName = Rot13(valueName); var guidEnd = convertedName.IndexOf('}') + 1; Guid g; if (guidEnd > 0 && GuidTools.GuidTryParse(convertedName.Substring(0, guidEnd), out g)) convertedName = KnownFolders.GetKnownFolderPath(g) + convertedName.Substring(guidEnd); // Check for matches if (convertedName.StartsWith(target.InstallLocation, StringComparison.InvariantCultureIgnoreCase)) { var junk = new RegistryValueJunk(key.Name, valueName, target, this); junk.DisplayValueName = convertedName; junk.Confidence.Add(ConfidenceRecords.ExplicitConnection); yield return junk; } } } } } private static string Rot13(string input) { if (string.IsNullOrEmpty(input)) return input; return new string(input.Select(x => x >= 'a' && x <= 'z' ? (char)((x - 'a' + 13) % 26 + 'a') : (x >= 'A' && x <= 'Z' ? (char)((x - 'A' + 13) % 26 + 'A') : x)).ToArray()); } } } ================================================ FILE: source/UninstallTools/Junk/IJunkCreator.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System.Collections.Generic; using UninstallTools.Junk.Containers; namespace UninstallTools.Junk { public interface IJunkCreator { void Setup(ICollection allUninstallers); IEnumerable FindJunk(ApplicationUninstallerEntry target); string CategoryName { get; } } } ================================================ FILE: source/UninstallTools/Junk/JunkManager.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using Klocman.Extensions; using Klocman.Forms.Tools; using Klocman.Tools; using UninstallTools.Junk.Containers; using UninstallTools.Properties; namespace UninstallTools.Junk { public static class JunkManager { private static IEnumerable CleanUpResults(IEnumerable input) { var prohibitedLocations = GetProhibitedLocations(); return RemoveDuplicates(input) .Where(x => JunkDoesNotPointToDirectories(x, prohibitedLocations)) .Where(JunkDoesNotPointToSelf); } /// /// Make sure that the junk result doesn't point to this application. /// private static bool JunkDoesNotPointToSelf(IJunkResult x) { if (x is FileSystemJunk fileSystemJunk) { return fileSystemJunk.Path == null || !fileSystemJunk.Path.FullName.StartsWith(UninstallToolsGlobalConfig.AppLocation, StringComparison.OrdinalIgnoreCase); } if (x is StartupJunkNode startupJunk) { return startupJunk.Entry?.CommandFilePath == null || !startupJunk.Entry.CommandFilePath.StartsWith(UninstallToolsGlobalConfig.AppLocation, StringComparison.OrdinalIgnoreCase); } return true; } /// /// Merge duplicate junk entries and their confidence parts /// private static IEnumerable RemoveDuplicates(IEnumerable input) { foreach (var appGroup in input.GroupBy(x => x.Application)) { foreach (var group in appGroup.GroupBy(x => PathTools.NormalizePath(x.GetDisplayName()).ToLowerInvariant())) { IJunkResult firstJunkResult = null; foreach (var junkResult in group) { if (firstJunkResult == null) firstJunkResult = junkResult; else firstJunkResult.Confidence.AddRange(junkResult.Confidence.ConfidenceParts); } if (firstJunkResult != null) yield return firstJunkResult; } } } private static bool JunkDoesNotPointToDirectories(IJunkResult arg, HashSet prohibitedDirs) { if (arg is not FileSystemJunk fileSystemJunk) return true; return !prohibitedDirs.Contains(fileSystemJunk.Path.FullName.ToLowerInvariant()); } /// /// Prevent suggesting removing special directories if the app for some reason was installed into them or otherwise used them /// private static HashSet GetProhibitedLocations() { var results = new HashSet(); void AddRange(IEnumerable paths) { foreach (var path in paths .Where(x => !string.IsNullOrWhiteSpace(x)) .Attempt(System.IO.Path.GetFullPath) .Select(x => x.ToLowerInvariant())) { results.Add(path); } } AddRange(Enum.GetValues().Attempt(WindowsTools.GetEnvironmentPath)); var knownFolderstype = Type.GetType("Windows.Storage.KnownFolders, Microsoft.Windows.SDK.NET", false); // Might not be available on some systems if (knownFolderstype != null) { try { AddRange(knownFolderstype.GetProperties().Attempt(p => ((Windows.Storage.StorageFolder)p.GetValue(null))!.Path)); } catch (Exception ex) { Trace.WriteLine("Failed to collect KnownFolders: " + ex); } } return results; } public static IEnumerable FindJunk(IEnumerable targets, ICollection allUninstallers, ListGenerationProgress.ListGenerationCallback progressCallback) { progressCallback(new ListGenerationProgress(-1, 0, Localisation.Junk_Progress_Startup)); var scanners = ReflectionTools.GetTypesImplementingBase() .Attempt(Activator.CreateInstance) .Cast() .ToList(); foreach (var junkCreator in scanners) { junkCreator.Setup(allUninstallers); } var results = new List(); var targetEntries = targets as IList ?? targets.ToList(); var progress = 0; foreach (var junkCreator in scanners) { var scannerProgress = new ListGenerationProgress(progress++, scanners.Count, junkCreator.CategoryName); var entryProgress = 0; foreach (var target in targetEntries) { scannerProgress.Inner = new ListGenerationProgress(entryProgress++, targetEntries.Count, target.DisplayName); progressCallback(scannerProgress); try { results.AddRange(junkCreator.FindJunk(target)); } catch (SystemException ex) { PremadeDialogs.GenericError(ex); } } } progressCallback(new ListGenerationProgress(-1, 0, Localisation.Junk_Progress_Finishing)); foreach (var target in targetEntries) results.AddRange(target.AdditionalJunk); return CleanUpResults(results); } public static IEnumerable FindProgramFilesJunk( ICollection allUninstallers) { var pfScanner = new ProgramFilesOrphans(); pfScanner.Setup(allUninstallers); return CleanUpResults(pfScanner.FindAllJunk().ToList()); } } } ================================================ FILE: source/UninstallTools/Junk/ProgramFilesOrphans.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using Klocman.Extensions; using Klocman.Tools; using UninstallTools.Junk.Confidence; using UninstallTools.Junk.Containers; using UninstallTools.Properties; namespace UninstallTools.Junk { public class ProgramFilesOrphans : IJunkCreator { private string[] _otherInstallLocations; private string[] _otherNames; private string[] _otherPublishers; private List _programFilesDirectories; public IEnumerable FindJunk(ApplicationUninstallerEntry target) { // Do nothing when called by the manager yield break; } public IEnumerable FindAllJunk() { var output = new List(); foreach (var kvp in _programFilesDirectories) FindJunkRecursively(output, kvp, 0); return output; } private void FindJunkRecursively(ICollection returnList, DirectoryInfo parentDirectory, int level) { try { if ((parentDirectory.Attributes & FileAttributes.System) == FileAttributes.System) return; var subDirectories = parentDirectory.GetDirectories(); foreach (var subDirectory in subDirectories) { if (UninstallToolsGlobalConfig.IsSystemDirectory(subDirectory) || UninstallToolsGlobalConfig.IsKnownFolder(subDirectory)) continue; if (subDirectory.FullName.ContainsAny(_otherInstallLocations, StringComparison.CurrentCultureIgnoreCase)) continue; var questionableDirName = subDirectory.Name.ContainsAny(UninstallToolsGlobalConfig.QuestionableDirectoryNames, StringComparison.CurrentCultureIgnoreCase); var nameIsUsed = subDirectory.Name.ContainsAny(_otherNames, StringComparison.CurrentCultureIgnoreCase); var allFiles = subDirectory.GetFiles("*", SearchOption.AllDirectories); var allFilesContainExe = allFiles.Any(x => WindowsTools.IsExectuable(x.Extension, false, true)); var immediateFiles = subDirectory.GetFiles("*", SearchOption.TopDirectoryOnly); ConfidenceRecord resultRecord; if (immediateFiles.Any()) { // No executables, MAYBE safe to remove // Executables present, bad idea to remove resultRecord = allFilesContainExe ? ConfidenceRecords.ExecutablesArePresent : ConfidenceRecords.FilesArePresent; } else if (!allFiles.Any()) { // Empty folder, safe to remove resultRecord = ConfidenceRecords.IsEmptyFolder; } else { // This folder is empty, but insides contain stuff resultRecord = allFilesContainExe ? ConfidenceRecords.ExecutablesArePresent : ConfidenceRecords.FilesArePresent; if (level < 1 && !questionableDirName && !nameIsUsed) { FindJunkRecursively(returnList, subDirectory, level + 1); } } if (resultRecord == null) continue; var newNode = new FileSystemJunk(subDirectory, null, this); newNode.Confidence.Add(resultRecord); if (subDirectory.Name.ContainsAny(_otherPublishers, StringComparison.CurrentCultureIgnoreCase)) newNode.Confidence.Add(ConfidenceRecords.PublisherIsStillUsed); if (nameIsUsed) newNode.Confidence.Add(ConfidenceRecords.ProgramNameIsStillUsed); if (questionableDirName) newNode.Confidence.Add(ConfidenceRecords.QuestionableDirectoryName); if (allFiles.Length > 100) newNode.Confidence.Add(ConfidenceRecords.ManyFilesArePresent); // Remove 2 points for every sublevel newNode.Confidence.Add(level * -2); if (!subDirectory.GetDirectories().Any()) newNode.Confidence.Add(ConfidenceRecords.FolderHasNoSubdirectories); returnList.Add(newNode); } } catch (Exception ex) { if (Debugger.IsAttached) throw; Trace.WriteLine($"Crash while scanning for {CategoryName} junk: {ex}"); } } public void Setup(ICollection allUninstallers) { _programFilesDirectories = UninstallToolsGlobalConfig.GetProgramFilesDirectories(true); var applicationUninstallerEntries = allUninstallers as IList ?? allUninstallers.ToList(); _otherInstallLocations = applicationUninstallerEntries.SelectMany(x => new[] { x.InstallLocation, x.UninstallerLocation }) .Where(x => x.IsNotEmpty()).Distinct().ToArray(); _otherPublishers = applicationUninstallerEntries.Select(x => x.PublisherTrimmed).Where(x => x != null && x.Length > 3) .Distinct().ToArray(); _otherNames = applicationUninstallerEntries.Select(x => x.DisplayNameTrimmed).Where(x => x != null && x.Length > 3) .Distinct().ToArray(); } public string CategoryName => Localisation.Junk_ProgramFilesOrphans_GroupName; } } ================================================ FILE: source/UninstallTools/KnownFolders.cs ================================================ using System; using System.Runtime.InteropServices; namespace UninstallTools; internal static class KnownFolders { /// /// GUIDs can be found here: https://learn.microsoft.com/en-us/windows/win32/shell/knownfolderid /// public static string GetKnownFolderPath(Guid rfid) { IntPtr pPath; SHGetKnownFolderPath(rfid, 0, IntPtr.Zero, out pPath); var path = Marshal.PtrToStringUni(pPath); Marshal.FreeCoTaskMem(pPath); return path; } [DllImport("shell32.dll")] private static extern int SHGetKnownFolderPath([MarshalAs(UnmanagedType.LPStruct)] Guid rfid, uint dwFlags, IntPtr hToken, out IntPtr pszPath); } ================================================ FILE: source/UninstallTools/ListGenerationProgress.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ namespace UninstallTools { public class ListGenerationProgress { internal ListGenerationProgress(int currentCount, int totalCount, string message) { TotalCount = totalCount; Message = message; CurrentCount = currentCount; } public int CurrentCount { get; internal set; } /// /// -1 if unknown /// public int TotalCount { get; internal set; } public string Message { get; internal set; } //public GetUninstallerListProgress Clone() => (GetUninstallerListProgress)MemberwiseClone(); public ListGenerationProgress Inner { get; internal set; } public delegate void ListGenerationCallback(ListGenerationProgress progressReport); } } ================================================ FILE: source/UninstallTools/Lists/ComparisonMethod.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using Klocman.Localising; using UninstallTools.Properties; namespace UninstallTools.Lists { public enum ComparisonMethod { [LocalisedName(typeof (Localisation), "FilterComparisonMethod_Equals")] Equals, [LocalisedName(typeof (Localisation), "FilterComparisonMethod_Any")] Any, [LocalisedName(typeof (Localisation), "FilterComparisonMethod_Contains")] Contains, [LocalisedName(typeof (Localisation), "FilterComparisonMethod_StartsWith")] StartsWith, [LocalisedName(typeof (Localisation), "FilterComparisonMethod_EndsWith")] EndsWith, [LocalisedName(typeof (Localisation), "FilterComparisonMethod_Regex")] Regex } } ================================================ FILE: source/UninstallTools/Lists/ComparisonTargetAttribute.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; namespace UninstallTools.Lists { internal class ComparisonTargetAttribute : Attribute { } } ================================================ FILE: source/UninstallTools/Lists/ComparisonTargetInfo.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using Klocman.Localising; using UninstallTools.Properties; namespace UninstallTools.Lists { public sealed class ComparisonTargetInfo { static ComparisonTargetInfo() { var targets = typeof(ApplicationUninstallerEntry) .GetProperties(BindingFlags.Instance | BindingFlags.Public) .Where(p => p.GetCustomAttributes(typeof(ComparisonTargetAttribute), false).Any()); var boolType = typeof(bool); var boolStrings = new[] { true.ToString(), false.ToString() }; var results = new List(); foreach (var propertyInfo in targets) { string[] possibleStrings = null; var targetType = propertyInfo.PropertyType; if (targetType == boolType) possibleStrings = boolStrings; else if (targetType.IsEnum) possibleStrings = Enum.GetNames(targetType).OrderBy(x => x).ToArray(); results.Add(new ComparisonTargetInfo(propertyInfo.Name, propertyInfo.GetLocalisedName(), entry => propertyInfo.GetValue(entry, null)?.ToString(), possibleStrings)); } ComparisonTargets = results; AllTargetComparison = new ComparisonTargetInfo(null, Localisation.ComparisonTargetInfo_AllProperties, null); } private ComparisonTargetInfo(string id, string displayName, Func getter, string[] possibleStrings = null) { Getter = getter; PossibleStrings = possibleStrings; Id = id; DisplayName = displayName; } internal static ComparisonTargetInfo AllTargetComparison { get; } internal static IEnumerable ComparisonTargets { get; } public string Id { get; } public string DisplayName { get; } public Func Getter { get; } /// /// If not null this target has a very limited amount of valid matches. /// It will not be included in an overall search in that case. /// public string[] PossibleStrings { get; } } } ================================================ FILE: source/UninstallTools/Lists/Filter.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Linq; using Klocman.Extensions; using Klocman.Tools; using UninstallTools.Properties; namespace UninstallTools.Lists { public class Filter : ITestEntry { public Filter() { } public Filter(string name, string filterText) { if (!string.IsNullOrEmpty(name)) Name = name; if (string.IsNullOrEmpty(filterText)) throw new ArgumentException(Localisation.UninstallListItem_ValueEmpty, nameof(filterText)); if (filterText.ContainsAny(StringTools.NewLineChars, StringComparison.Ordinal)) throw new ArgumentException(Localisation.UninstallListItem_NewLineInValue, nameof(filterText)); ComparisonEntries.Add(new FilterCondition { FilterText = filterText }); } public Filter(string name, bool exclude, params FilterCondition[] conditions) { if (!string.IsNullOrEmpty(name)) Name = name; Exclude = exclude; ComparisonEntries.AddRange(conditions); } public string Name { get; set; } = Localisation.UninstallListEditor_NewFilter; /// /// Exclude items matched by this entry from results of the parent uninstall list /// public bool Exclude { get; set; } /// /// Comparison rules of this filter /// public List ComparisonEntries { get; set; } = new(); /// /// Test if the input matches this filter. Returns null if it is impossible to determine. /// public bool? TestEntry(ApplicationUninstallerEntry input) { if (!Enabled || input == null) return null; var filteredCompEntries = ComparisonEntries.Where(x => !string.IsNullOrEmpty(x.FilterText)).ToList(); if (filteredCompEntries.Count < 1) return null; var tests = filteredCompEntries.Select(x => x.TestEntry(input)).Where(x => x.HasValue).Select(x => x.Value).ToList(); if (tests.Count < 1) return null; return tests.All(x => x); } public bool Enabled { get; set; } = true; public override string ToString() { return $"{Name} | {ExcludeToString(Exclude)}"; } public static string ExcludeToString(bool exclude) { return exclude ? "Exclude" : "Include"; } } } ================================================ FILE: source/UninstallTools/Lists/FilterCondition.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Linq; using System.Text.RegularExpressions; using Klocman.Extensions; using UninstallTools.Properties; namespace UninstallTools.Lists { public sealed class FilterCondition : ITestEntry, ICloneable { public FilterCondition() : this(null) { } public FilterCondition(string filterText) : this (filterText, ComparisonMethod.Any, null) { } public FilterCondition(string filterText, ComparisonMethod comparisonMethod, string targetPropertyName) { if (string.IsNullOrEmpty(targetPropertyName)) TargetProperty = ComparisonTargetInfo.AllTargetComparison; else TargetPropertyId = targetPropertyName; FilterText = filterText ?? Localisation.UninstallListEditor_NewCondition; ComparisonMethod = comparisonMethod; } public object Clone() { return new FilterCondition (FilterText, ComparisonMethod, null) { TargetProperty = TargetProperty }; } /// /// Negate results of TestString, null is not affected. /// public bool InvertResults { get; set; } public ComparisonMethod ComparisonMethod { get; set; } public string FilterText { get; set; } public string TargetPropertyId { get { return TargetProperty?.Id ?? string.Empty; } set { if (string.IsNullOrEmpty(value)) { TargetProperty = ComparisonTargetInfo.AllTargetComparison; } else { TargetProperty = ComparisonTargetInfo.ComparisonTargets .FirstOrDefault(x => x.Id.Equals(value, StringComparison.InvariantCultureIgnoreCase)) ?? ComparisonTargetInfo.AllTargetComparison; } } } private ComparisonTargetInfo TargetProperty { get; set; } /// /// Test if the input matches this condition. Returns null if it is impossible to determine. /// public bool? TestEntry(ApplicationUninstallerEntry input) { if (!Enabled) return null; var targets = ReferenceEquals(TargetProperty, ComparisonTargetInfo.AllTargetComparison) ? ComparisonTargetInfo.ComparisonTargets.Where(x => x.PossibleStrings == null) .Select(x => x.Getter(input)) : new[] {TargetProperty.Getter(input)}; bool? result = null; foreach (var target in targets.Where(target => !string.IsNullOrEmpty(target))) { try { switch (ComparisonMethod) { case ComparisonMethod.Equals: result = target.Equals(FilterText, StringComparison.InvariantCultureIgnoreCase); break; case ComparisonMethod.Any: result = target.ContainsAny( FilterText.Split((char[]) null, StringSplitOptions.RemoveEmptyEntries), StringComparison.InvariantCultureIgnoreCase); break; case ComparisonMethod.StartsWith: result = target.StartsWith(FilterText, StringComparison.InvariantCultureIgnoreCase); break; case ComparisonMethod.EndsWith: result = target.EndsWith(FilterText, StringComparison.InvariantCultureIgnoreCase); break; case ComparisonMethod.Contains: result = target.Contains(FilterText, StringComparison.InvariantCultureIgnoreCase); break; case ComparisonMethod.Regex: result = Regex.IsMatch(target, FilterText, RegexOptions.CultureInvariant); break; default: throw new InvalidOperationException("Unknown FilterComparisonMethod"); } } catch (InvalidOperationException) { throw; } catch { //result = null; } if (result == true) return !InvertResults; } if (!result.HasValue) return null; return InvertResults ? !result.Value : result.Value; } public bool Enabled { get; set; } = true; public override string ToString() { return $"{FilterText}"; // | {ComparisonMethod.GetLocalisedName()} {TargetProperty.DisplayName}"; } } } ================================================ FILE: source/UninstallTools/Lists/ITestEntry.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ namespace UninstallTools.Lists { public interface ITestEntry { /// /// Test if the input matches this filter. Returns null if result is impossible to determine or if filter is disabled. /// If there are only exclude filters assumes that everything is included. /// bool? TestEntry(ApplicationUninstallerEntry input); bool Enabled { get; set; } } } ================================================ FILE: source/UninstallTools/Lists/UninstallList.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System.Collections.Generic; using System.Linq; using System.Text; using System.Xml; using System.Xml.Serialization; namespace UninstallTools.Lists { public class UninstallList : ITestEntry { public UninstallList() { } public UninstallList(IEnumerable items) { AddItems(items); } public List Filters { get; set; } = new(); /// /// Test if the input matches this filter. Returns null if it did not hit any filter. /// If there are only exclude filters this assumes that everything is included. /// public bool? TestEntry(ApplicationUninstallerEntry input) { if (!Enabled || input == null || Filters.Count < 1) return null; var excludes = new List(); var includes = new List(); foreach (var uninstallListItem in Filters) { if (uninstallListItem.Exclude) excludes.Add(uninstallListItem); else includes.Add(uninstallListItem); } bool? excluded = null; foreach (var uninstallListItem in excludes) { if (uninstallListItem.TestEntry(input) == true) return false; excluded = false; } bool? included = null; foreach (var uninstallListItem in includes) { if (uninstallListItem.TestEntry(input) == true) { included = true; break; } included = false; } if (!included.HasValue) return excluded.HasValue ? true : null; return included.Value; } public bool Enabled { get; set; } = true; public static UninstallList ReadFromFile(string fileName) { var serializer = new XmlSerializer(typeof (UninstallList)); using (var reader = new XmlTextReader(fileName)) { return serializer.Deserialize(reader) as UninstallList; } } public void AddItems(IEnumerable items) { Filters.AddRange(items.Select(x => new Filter(null, x))); } public void Add(Filter item) { Filters.Add(item); } public void AddItems(IEnumerable items) { Filters.AddRange(items); } public void SaveToFile(string fileName) { var serializer = new XmlSerializer(typeof (UninstallList)); using (var writer = new XmlTextWriter(fileName, Encoding.Unicode)) { writer.Formatting = Formatting.Indented; serializer.Serialize(writer, this); } } internal void Remove(Filter item) { if (Filters.Contains(item)) Filters.Remove(item); } } } ================================================ FILE: source/UninstallTools/Properties/Localisation.Designer.cs ================================================ //------------------------------------------------------------------------------ // // This code was generated by a tool. // Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ namespace UninstallTools.Properties { using System; /// /// A strongly-typed resource class, for looking up localized strings, etc. /// // This class was auto-generated by the StronglyTypedResourceBuilder // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Localisation { private static global::System.Resources.ResourceManager resourceMan; private static global::System.Globalization.CultureInfo resourceCulture; [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] internal Localisation() { } /// /// Returns the cached ResourceManager instance used by this class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("UninstallTools.Properties.Localisation", typeof(Localisation).Assembly); resourceMan = temp; } return resourceMan; } } /// /// Overrides the current thread's CurrentUICulture property for all /// resource lookups using this strongly typed resource class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Globalization.CultureInfo Culture { get { return resourceCulture; } set { resourceCulture = value; } } /// /// Looks up a localized string similar to Webpage. /// internal static string AboutUrl { get { return ResourceManager.GetString("AboutUrl", resourceCulture); } } /// /// Looks up a localized string similar to Product code. /// internal static string BundleProviderKey { get { return ResourceManager.GetString("BundleProviderKey", resourceCulture); } } /// /// Looks up a localized string similar to Uninstall in Chocolatey. /// internal static string ChocolateyFactory_UninstallInChocolateyJunkName { get { return ResourceManager.GetString("ChocolateyFactory_UninstallInChocolateyJunkName", resourceCulture); } } /// /// Looks up a localized string similar to Comment. /// internal static string Comment { get { return ResourceManager.GetString("Comment", resourceCulture); } } /// /// Looks up a localized string similar to All properties. /// internal static string ComparisonTargetInfo_AllProperties { get { return ResourceManager.GetString("ComparisonTargetInfo_AllProperties", resourceCulture); } } /// /// Looks up a localized string similar to Bad. /// internal static string Confidence_Bad { get { return ResourceManager.GetString("Confidence_Bad", resourceCulture); } } /// /// Looks up a localized string similar to Located directly inside a Known Folder. /// internal static string Confidence_DirectlyInsideKnownFolder { get { return ResourceManager.GetString("Confidence_DirectlyInsideKnownFolder", resourceCulture); } } /// /// Looks up a localized string similar to Good. /// internal static string Confidence_Good { get { return ResourceManager.GetString("Confidence_Good", resourceCulture); } } /// /// Looks up a localized string similar to Empty folder. /// internal static string Confidence_PF_EmptyFolder { get { return ResourceManager.GetString("Confidence_PF_EmptyFolder", resourceCulture); } } /// /// Looks up a localized string similar to Executables are present. /// internal static string Confidence_PF_ExecsPresent { get { return ResourceManager.GetString("Confidence_PF_ExecsPresent", resourceCulture); } } /// /// Looks up a localized string similar to Files are present. /// internal static string Confidence_PF_FilesPresent { get { return ResourceManager.GetString("Confidence_PF_FilesPresent", resourceCulture); } } /// /// Looks up a localized string similar to Many files are present. /// internal static string Confidence_PF_ManyFilesPresent { get { return ResourceManager.GetString("Confidence_PF_ManyFilesPresent", resourceCulture); } } /// /// Looks up a localized string similar to Program name is recognized. /// internal static string Confidence_PF_NameIsUsed { get { return ResourceManager.GetString("Confidence_PF_NameIsUsed", resourceCulture); } } /// /// Looks up a localized string similar to No sub directories. /// internal static string Confidence_PF_NoSubdirs { get { return ResourceManager.GetString("Confidence_PF_NoSubdirs", resourceCulture); } } /// /// Looks up a localized string similar to Publisher is recognized. /// internal static string Confidence_PF_PublisherIsUsed { get { return ResourceManager.GetString("Confidence_PF_PublisherIsUsed", resourceCulture); } } /// /// Looks up a localized string similar to Questionable. /// internal static string Confidence_Questionable { get { return ResourceManager.GetString("Confidence_Questionable", resourceCulture); } } /// /// Looks up a localized string similar to Entry will be ran only once. /// internal static string Confidence_Startup_IsRunOnce { get { return ResourceManager.GetString("Confidence_Startup_IsRunOnce", resourceCulture); } } /// /// Looks up a localized string similar to Entry is matched to the application. /// internal static string Confidence_Startup_StartupMatched { get { return ResourceManager.GetString("Confidence_Startup_StartupMatched", resourceCulture); } } /// /// Looks up a localized string similar to Unknown. /// internal static string Confidence_Unknown { get { return ResourceManager.GetString("Confidence_Unknown", resourceCulture); } } /// /// Looks up a localized string similar to Might belong to a different app with a similar name. /// internal static string Confidence_UsedBySimilarNamedApp { get { return ResourceManager.GetString("Confidence_UsedBySimilarNamedApp", resourceCulture); } } /// /// Looks up a localized string similar to Very good. /// internal static string Confidence_VeryGood { get { return ResourceManager.GetString("Confidence_VeryGood", resourceCulture); } } /// /// Looks up a localized string similar to Directory is, or will be empty after removing junk.. /// internal static string ConfidencePart_AllSubdirsMatched { get { return ResourceManager.GetString("ConfidencePart_AllSubdirsMatched", resourceCulture); } } /// /// Looks up a localized string similar to Company name did not match. /// internal static string ConfidencePart_CompanyNameDidNotMatch { get { return ResourceManager.GetString("ConfidencePart_CompanyNameDidNotMatch", resourceCulture); } } /// /// Looks up a localized string similar to Company name matched. /// internal static string ConfidencePart_CompanyNameMatch { get { return ResourceManager.GetString("ConfidencePart_CompanyNameMatch", resourceCulture); } } /// /// Looks up a localized string similar to Directory is used by other installed applications. /// internal static string ConfidencePart_DirectoryStillUsed { get { return ResourceManager.GetString("ConfidencePart_DirectoryStillUsed", resourceCulture); } } /// /// Looks up a localized string similar to Item is explicitly mentioned in the uninstaller. /// internal static string ConfidencePart_ExplicitConnection { get { return ResourceManager.GetString("ConfidencePart_ExplicitConnection", resourceCulture); } } /// /// Looks up a localized string similar to Removal of Store App data is problematic. /// internal static string ConfidencePart_IsStoreApp { get { return ResourceManager.GetString("ConfidencePart_IsStoreApp", resourceCulture); } } /// /// Looks up a localized string similar to Registry entry of the uninstaller. /// internal static string ConfidencePart_IsUninstallerRegistryKey { get { return ResourceManager.GetString("ConfidencePart_IsUninstallerRegistryKey", resourceCulture); } } /// /// Looks up a localized string similar to Item seems to be a whole publisher category. /// internal static string ConfidencePart_ItemNameEqualsCompanyName { get { return ResourceManager.GetString("ConfidencePart_ItemNameEqualsCompanyName", resourceCulture); } } /// /// Looks up a localized string similar to Product name did not match very well. /// internal static string ConfidencePart_ProductNameDodgyMatch { get { return ResourceManager.GetString("ConfidencePart_ProductNameDodgyMatch", resourceCulture); } } /// /// Looks up a localized string similar to Product name matched perfectly. /// internal static string ConfidencePart_ProductNamePerfectMatch { get { return ResourceManager.GetString("ConfidencePart_ProductNamePerfectMatch", resourceCulture); } } /// /// Looks up a localized string similar to Directory name is questionable. /// internal static string ConfidencePart_QuestionableDirectoryName { get { return ResourceManager.GetString("ConfidencePart_QuestionableDirectoryName", resourceCulture); } } /// /// Looks up a localized string similar to Displayed icon. /// internal static string DisplayIcon { get { return ResourceManager.GetString("DisplayIcon", resourceCulture); } } /// /// Looks up a localized string similar to Display name. /// internal static string DisplayName { get { return ResourceManager.GetString("DisplayName", resourceCulture); } } /// /// Looks up a localized string similar to Trimmed display name. /// internal static string DisplayNameTrimmed { get { return ResourceManager.GetString("DisplayNameTrimmed", resourceCulture); } } /// /// Looks up a localized string similar to Version. /// internal static string DisplayVersion { get { return ResourceManager.GetString("DisplayVersion", resourceCulture); } } /// /// Looks up a localized string similar to Invalid path. /// internal static string Error_InvalidPath { get { return ResourceManager.GetString("Error_InvalidPath", resourceCulture); } } /// /// Looks up a localized string similar to Invalid or unknown startup registry key(s):. /// internal static string Error_InvalidRegKeys { get { return ResourceManager.GetString("Error_InvalidRegKeys", resourceCulture); } } /// /// Looks up a localized string similar to Estimated size. /// internal static string EstimatedSize { get { return ResourceManager.GetString("EstimatedSize", resourceCulture); } } /// /// Looks up a localized string similar to Contains any. /// internal static string FilterComparisonMethod_Any { get { return ResourceManager.GetString("FilterComparisonMethod_Any", resourceCulture); } } /// /// Looks up a localized string similar to Contains. /// internal static string FilterComparisonMethod_Contains { get { return ResourceManager.GetString("FilterComparisonMethod_Contains", resourceCulture); } } /// /// Looks up a localized string similar to Ends with. /// internal static string FilterComparisonMethod_EndsWith { get { return ResourceManager.GetString("FilterComparisonMethod_EndsWith", resourceCulture); } } /// /// Looks up a localized string similar to Equals. /// internal static string FilterComparisonMethod_Equals { get { return ResourceManager.GetString("FilterComparisonMethod_Equals", resourceCulture); } } /// /// Looks up a localized string similar to Regex. /// internal static string FilterComparisonMethod_Regex { get { return ResourceManager.GetString("FilterComparisonMethod_Regex", resourceCulture); } } /// /// Looks up a localized string similar to Starts with. /// internal static string FilterComparisonMethod_StartsWith { get { return ResourceManager.GetString("FilterComparisonMethod_StartsWith", resourceCulture); } } /// /// Looks up a localized string similar to Can start automatically. /// internal static string HasStartupEntries { get { return ResourceManager.GetString("HasStartupEntries", resourceCulture); } } /// /// Looks up a localized string similar to Date of installation. /// internal static string InstallDate { get { return ResourceManager.GetString("InstallDate", resourceCulture); } } /// /// Looks up a localized string similar to Installation location. /// internal static string InstallLocation { get { return ResourceManager.GetString("InstallLocation", resourceCulture); } } /// /// Looks up a localized string similar to Installation source. /// internal static string InstallSource { get { return ResourceManager.GetString("InstallSource", resourceCulture); } } /// /// Looks up a localized string similar to Is a 64bit application. /// internal static string Is64Bit { get { return ResourceManager.GetString("Is64Bit", resourceCulture); } } /// /// Looks up a localized string similar to Is unregistered. /// internal static string IsOrphaned { get { return ResourceManager.GetString("IsOrphaned", resourceCulture); } } /// /// Looks up a localized string similar to Is protected. /// internal static string IsProtected { get { return ResourceManager.GetString("IsProtected", resourceCulture); } } /// /// Looks up a localized string similar to Application is registered. /// internal static string IsRegistered { get { return ResourceManager.GetString("IsRegistered", resourceCulture); } } /// /// Looks up a localized string similar to Is an update. /// internal static string IsUpdate { get { return ResourceManager.GetString("IsUpdate", resourceCulture); } } /// /// Looks up a localized string similar to Is valid. /// internal static string IsValid { get { return ResourceManager.GetString("IsValid", resourceCulture); } } /// /// Looks up a localized string similar to Is a web browser. /// internal static string IsWebBrowser { get { return ResourceManager.GetString("IsWebBrowser", resourceCulture); } } /// /// Looks up a localized string similar to Application compatibility. /// internal static string Junk_AppCompat_GroupName { get { return ResourceManager.GetString("Junk_AppCompat_GroupName", resourceCulture); } } /// /// Looks up a localized string similar to Audio policy config. /// internal static string Junk_AudioPolicy_GroupName { get { return ResourceManager.GetString("Junk_AudioPolicy_GroupName", resourceCulture); } } /// /// Looks up a localized string similar to CLSID classes. /// internal static string Junk_Clsid_GroupName { get { return ResourceManager.GetString("Junk_Clsid_GroupName", resourceCulture); } } /// /// Looks up a localized string similar to Debug Tracing/Logging Configuration. /// internal static string Junk_DebugTracing_GroupName { get { return ResourceManager.GetString("Junk_DebugTracing_GroupName", resourceCulture); } } /// /// Looks up a localized string similar to Files and directories. /// internal static string Junk_Drive_GroupName { get { return ResourceManager.GetString("Junk_Drive_GroupName", resourceCulture); } } /// /// Looks up a localized string similar to Event Log logs. /// internal static string Junk_EventLog_GroupName { get { return ResourceManager.GetString("Junk_EventLog_GroupName", resourceCulture); } } /// /// Looks up a localized string similar to Firewall rule. /// internal static string Junk_FirewallRule_GroupName { get { return ResourceManager.GetString("Junk_FirewallRule_GroupName", resourceCulture); } } /// /// Looks up a localized string similar to Installed folder list. /// internal static string Junk_InstalledFolders_GroupName { get { return ResourceManager.GetString("Junk_InstalledFolders_GroupName", resourceCulture); } } /// /// Looks up a localized string similar to Program Files orphan. /// internal static string Junk_ProgramFilesOrphans_GroupName { get { return ResourceManager.GetString("Junk_ProgramFilesOrphans_GroupName", resourceCulture); } } /// /// Looks up a localized string similar to Finishing up.... /// internal static string Junk_Progress_Finishing { get { return ResourceManager.GetString("Junk_Progress_Finishing", resourceCulture); } } /// /// Looks up a localized string similar to Setting up junk scanners.... /// internal static string Junk_Progress_Startup { get { return ResourceManager.GetString("Junk_Progress_Startup", resourceCulture); } } /// /// Looks up a localized string similar to Registry. /// internal static string Junk_Registry_GroupName { get { return ResourceManager.GetString("Junk_Registry_GroupName", resourceCulture); } } /// /// Looks up a localized string similar to Shortcut. /// internal static string Junk_Shortcut_GroupName { get { return ResourceManager.GetString("Junk_Shortcut_GroupName", resourceCulture); } } /// /// Looks up a localized string similar to Startup. /// internal static string Junk_Startup_GroupName { get { return ResourceManager.GetString("Junk_Startup_GroupName", resourceCulture); } } /// /// Looks up a localized string similar to Tracing information. /// internal static string Junk_Tracing_GroupName { get { return ResourceManager.GetString("Junk_Tracing_GroupName", resourceCulture); } } /// /// Looks up a localized string similar to Uninstaller reference. /// internal static string Junk_UninstallerKey_GroupName { get { return ResourceManager.GetString("Junk_UninstallerKey_GroupName", resourceCulture); } } /// /// Looks up a localized string similar to Uninstaller location. /// internal static string Junk_UninstallerLocation_GroupName { get { return ResourceManager.GetString("Junk_UninstallerLocation_GroupName", resourceCulture); } } /// /// Looks up a localized string similar to User assist. /// internal static string Junk_UserAssist_GroupName { get { return ResourceManager.GetString("Junk_UserAssist_GroupName", resourceCulture); } } /// /// Looks up a localized string similar to Windows Error Reporting reports. /// internal static string Junk_WerReports_GroupName { get { return ResourceManager.GetString("Junk_WerReports_GroupName", resourceCulture); } } /// /// Looks up a localized string similar to Confidence. /// internal static string JunkRemover_Confidence { get { return ResourceManager.GetString("JunkRemover_Confidence", resourceCulture); } } /// /// Looks up a localized string similar to Uninstall worker stopped prematurely. /// internal static string ManagerError_PrematureWorkerStop { get { return ResourceManager.GetString("ManagerError_PrematureWorkerStop", resourceCulture); } } /// /// Looks up a localized string similar to Skipped by user. /// internal static string ManagerError_Skipped { get { return ResourceManager.GetString("ManagerError_Skipped", resourceCulture); } } /// /// Looks up a localized string similar to Modify path. /// internal static string ModifyPath { get { return ResourceManager.GetString("ModifyPath", resourceCulture); } } /// /// Looks up a localized string similar to Parent uninstaller. /// internal static string ParentKeyName { get { return ResourceManager.GetString("ParentKeyName", resourceCulture); } } /// /// Looks up a localized string similar to Scanning application stores.... /// internal static string Progress_AppStores { get { return ResourceManager.GetString("Progress_AppStores", resourceCulture); } } /// /// Looks up a localized string similar to Searching for Chocolatey packages. /// internal static string Progress_AppStores_Chocolatey { get { return ResourceManager.GetString("Progress_AppStores_Chocolatey", resourceCulture); } } /// /// Looks up a localized string similar to Searching for Oculus Apps. /// internal static string Progress_AppStores_Oculus { get { return ResourceManager.GetString("Progress_AppStores_Oculus", resourceCulture); } } /// /// Looks up a localized string similar to Searching for Scoop packages. /// internal static string Progress_AppStores_Scoop { get { return ResourceManager.GetString("Progress_AppStores_Scoop", resourceCulture); } } /// /// Looks up a localized string similar to Searching for Steam Apps. /// internal static string Progress_AppStores_Steam { get { return ResourceManager.GetString("Progress_AppStores_Steam", resourceCulture); } } /// /// Looks up a localized string similar to Searching for application templates. /// internal static string Progress_AppStores_Templates { get { return ResourceManager.GetString("Progress_AppStores_Templates", resourceCulture); } } /// /// Looks up a localized string similar to Searching for Windows Features. /// internal static string Progress_AppStores_WinFeatures { get { return ResourceManager.GetString("Progress_AppStores_WinFeatures", resourceCulture); } } /// /// Looks up a localized string similar to Searching for Windows Store Apps. /// internal static string Progress_AppStores_WinStore { get { return ResourceManager.GetString("Progress_AppStores_WinStore", resourceCulture); } } /// /// Looks up a localized string similar to Searching for Windows Updates. /// internal static string Progress_AppStores_WinUpdates { get { return ResourceManager.GetString("Progress_AppStores_WinUpdates", resourceCulture); } } /// /// Looks up a localized string similar to Scanning drives for applications.... /// internal static string Progress_DriveScan { get { return ResourceManager.GetString("Progress_DriveScan", resourceCulture); } } /// /// Looks up a localized string similar to Gathering directories. /// internal static string Progress_DriveScan_Gathering { get { return ResourceManager.GetString("Progress_DriveScan_Gathering", resourceCulture); } } /// /// Looks up a localized string similar to Generating missing uninstaller information.... /// internal static string Progress_GatherUninstallerInfo { get { return ResourceManager.GetString("Progress_GatherUninstallerInfo", resourceCulture); } } /// /// Looks up a localized string similar to Generating missing information.... /// internal static string Progress_GeneratingInfo { get { return ResourceManager.GetString("Progress_GeneratingInfo", resourceCulture); } } /// /// Looks up a localized string similar to Merging discovered applications.... /// internal static string Progress_Merging { get { return ResourceManager.GetString("Progress_Merging", resourceCulture); } } /// /// Looks up a localized string similar to Merging applications from drives. /// internal static string Progress_Merging_Drives { get { return ResourceManager.GetString("Progress_Merging_Drives", resourceCulture); } } /// /// Looks up a localized string similar to Merging applications from stores. /// internal static string Progress_Merging_Stores { get { return ResourceManager.GetString("Progress_Merging_Stores", resourceCulture); } } /// /// Looks up a localized string similar to Scanning installed MSI products.... /// internal static string Progress_MSI { get { return ResourceManager.GetString("Progress_MSI", resourceCulture); } } /// /// Looks up a localized string similar to Found {0} application GUIDs. /// internal static string Progress_MSI_sub { get { return ResourceManager.GetString("Progress_MSI_sub", resourceCulture); } } /// /// Looks up a localized string similar to Scanning registry for uninstallers.... /// internal static string Progress_Registry { get { return ResourceManager.GetString("Progress_Registry", resourceCulture); } } /// /// Looks up a localized string similar to Gathering registry keys. /// internal static string Progress_Registry_Gathering { get { return ResourceManager.GetString("Progress_Registry_Gathering", resourceCulture); } } /// /// Looks up a localized string similar to Processing {0}. /// internal static string Progress_Registry_Processing { get { return ResourceManager.GetString("Progress_Registry_Processing", resourceCulture); } } /// /// Looks up a localized string similar to Searching for start-up entries. /// internal static string Progress_Startup { get { return ResourceManager.GetString("Progress_Startup", resourceCulture); } } /// /// Looks up a localized string similar to Publisher name. /// internal static string Publisher { get { return ResourceManager.GetString("Publisher", resourceCulture); } } /// /// Looks up a localized string similar to Trimmed publisher name. /// internal static string PublisherTrimmed { get { return ResourceManager.GetString("PublisherTrimmed", resourceCulture); } } /// /// Looks up a localized string similar to Quiet uninstall is possible. /// internal static string QuietUninstallPossible { get { return ResourceManager.GetString("QuietUninstallPossible", resourceCulture); } } /// /// Looks up a localized string similar to Quiet uninstall string. /// internal static string QuietUninstallString { get { return ResourceManager.GetString("QuietUninstallString", resourceCulture); } } /// /// Looks up a localized string similar to Registry key name. /// internal static string RegistryKeyName { get { return ResourceManager.GetString("RegistryKeyName", resourceCulture); } } /// /// Looks up a localized string similar to Registry path. /// internal static string RegistryPath { get { return ResourceManager.GetString("RegistryPath", resourceCulture); } } /// /// Looks up a localized string similar to Browser Helper Object. /// internal static string Startup_Shortname_BrowserHelper { get { return ResourceManager.GetString("Startup_Shortname_BrowserHelper", resourceCulture); } } /// /// Looks up a localized string similar to Service. /// internal static string Startup_ShortName_Service { get { return ResourceManager.GetString("Startup_ShortName_Service", resourceCulture); } } /// /// Looks up a localized string similar to Task. /// internal static string Startup_ShortName_Task { get { return ResourceManager.GetString("Startup_ShortName_Task", resourceCulture); } } /// /// Looks up a localized string similar to Startup commands. /// internal static string StartupEntries { get { return ResourceManager.GetString("StartupEntries", resourceCulture); } } /// /// Looks up a localized string similar to Failed to enable this entry, the following file was not found:. /// internal static string StartupManager_FailedEnable_FileNotFound { get { return ResourceManager.GetString("StartupManager_FailedEnable_FileNotFound", resourceCulture); } } /// /// Looks up a localized string similar to Loading.... /// internal static string StartupManager_Loading { get { return ResourceManager.GetString("StartupManager_Loading", resourceCulture); } } /// /// Looks up a localized string similar to They will no longer be opened during boot. Make sure the selected items are not required before removing them.. /// internal static string StartupManager_Message_Delete_Details { get { return ResourceManager.GetString("StartupManager_Message_Delete_Details", resourceCulture); } } /// /// Looks up a localized string similar to Remove selected programs from startup?. /// internal static string StartupManager_Message_Delete_Header { get { return ResourceManager.GetString("StartupManager_Message_Delete_Header", resourceCulture); } } /// /// Looks up a localized string similar to Startup Manager. /// internal static string StartupManager_Message_Delete_Title { get { return ResourceManager.GetString("StartupManager_Message_Delete_Title", resourceCulture); } } /// /// Looks up a localized string similar to Is a system component. /// internal static string SystemComponent { get { return ResourceManager.GetString("SystemComponent", resourceCulture); } } /// /// Looks up a localized string similar to Uninstaller file name. /// internal static string UninstallerFullFilename { get { return ResourceManager.GetString("UninstallerFullFilename", resourceCulture); } } /// /// Looks up a localized string similar to Uninstaller type. /// internal static string UninstallerKind { get { return ResourceManager.GetString("UninstallerKind", resourceCulture); } } /// /// Looks up a localized string similar to Uninstaller location. /// internal static string UninstallerLocation { get { return ResourceManager.GetString("UninstallerLocation", resourceCulture); } } /// /// Looks up a localized string similar to There is no valid way of uninstalling this entry. /// internal static string UninstallError_Nowaytouninstall { get { return ResourceManager.GetString("UninstallError_Nowaytouninstall", resourceCulture); } } /// /// Looks up a localized string similar to Uninstaller returned error code: . /// internal static string UninstallError_UninstallerReturnedCode { get { return ResourceManager.GetString("UninstallError_UninstallerReturnedCode", resourceCulture); } } /// /// Looks up a localized string similar to Uninstaller timed out. /// internal static string UninstallError_UninstallerTimedOut { get { return ResourceManager.GetString("UninstallError_UninstallerTimedOut", resourceCulture); } } /// /// Looks up a localized string similar to Chocolatey. /// internal static string UninstallerType_Chocolatey { get { return ResourceManager.GetString("UninstallerType_Chocolatey", resourceCulture); } } /// /// Looks up a localized string similar to Inno Setup. /// internal static string UninstallerType_InnoSetup { get { return ResourceManager.GetString("UninstallerType_InnoSetup", resourceCulture); } } /// /// Looks up a localized string similar to InstallShield. /// internal static string UninstallerType_InstallShield { get { return ResourceManager.GetString("UninstallerType_InstallShield", resourceCulture); } } /// /// Looks up a localized string similar to Windows Installer. /// internal static string UninstallerType_Msiexec { get { return ResourceManager.GetString("UninstallerType_Msiexec", resourceCulture); } } /// /// Looks up a localized string similar to Nullsoft Scriptable Install System . /// internal static string UninstallerType_NSIS { get { return ResourceManager.GetString("UninstallerType_NSIS", resourceCulture); } } /// /// Looks up a localized string similar to Oculus. /// internal static string UninstallerType_Oculus { get { return ResourceManager.GetString("UninstallerType_Oculus", resourceCulture); } } /// /// Looks up a localized string similar to PowerShell script. /// internal static string UninstallerType_PowerShell { get { return ResourceManager.GetString("UninstallerType_PowerShell", resourceCulture); } } /// /// Looks up a localized string similar to SDBInst. /// internal static string UninstallerType_SdbInst { get { return ResourceManager.GetString("UninstallerType_SdbInst", resourceCulture); } } /// /// Looks up a localized string similar to Simple Delete. /// internal static string UninstallerType_SimpleDelete { get { return ResourceManager.GetString("UninstallerType_SimpleDelete", resourceCulture); } } /// /// Looks up a localized string similar to Steam. /// internal static string UninstallerType_Steam { get { return ResourceManager.GetString("UninstallerType_Steam", resourceCulture); } } /// /// Looks up a localized string similar to Windows Store App. /// internal static string UninstallerType_StoreApp { get { return ResourceManager.GetString("UninstallerType_StoreApp", resourceCulture); } } /// /// Looks up a localized string similar to Unknown. /// internal static string UninstallerType_Unknown { get { return ResourceManager.GetString("UninstallerType_Unknown", resourceCulture); } } /// /// Looks up a localized string similar to Windows Feature. /// internal static string UninstallerType_WindowsFeature { get { return ResourceManager.GetString("UninstallerType_WindowsFeature", resourceCulture); } } /// /// Looks up a localized string similar to Windows Update. /// internal static string UninstallerType_WindowsUpdate { get { return ResourceManager.GetString("UninstallerType_WindowsUpdate", resourceCulture); } } /// /// Looks up a localized string similar to Invalid filter. /// internal static string UninstallListEditor_InvalidFilter { get { return ResourceManager.GetString("UninstallListEditor_InvalidFilter", resourceCulture); } } /// /// Looks up a localized string similar to New condition. /// internal static string UninstallListEditor_NewCondition { get { return ResourceManager.GetString("UninstallListEditor_NewCondition", resourceCulture); } } /// /// Looks up a localized string similar to New filter. /// internal static string UninstallListEditor_NewFilter { get { return ResourceManager.GetString("UninstallListEditor_NewFilter", resourceCulture); } } /// /// Looks up a localized string similar to No matches. /// internal static string UninstallListEditor_NothingMatched { get { return ResourceManager.GetString("UninstallListEditor_NothingMatched", resourceCulture); } } /// /// Looks up a localized string similar to Value cannot contain newlines. /// internal static string UninstallListItem_NewLineInValue { get { return ResourceManager.GetString("UninstallListItem_NewLineInValue", resourceCulture); } } /// /// Looks up a localized string similar to Value cannot be null or empty. /// internal static string UninstallListItem_ValueEmpty { get { return ResourceManager.GetString("UninstallListItem_ValueEmpty", resourceCulture); } } /// /// Looks up a localized string similar to Uninstall is possible. /// internal static string UninstallPossible { get { return ResourceManager.GetString("UninstallPossible", resourceCulture); } } /// /// Looks up a localized string similar to Completed. /// internal static string UninstallStatus_Completed { get { return ResourceManager.GetString("UninstallStatus_Completed", resourceCulture); } } /// /// Looks up a localized string similar to Failed. /// internal static string UninstallStatus_Failed { get { return ResourceManager.GetString("UninstallStatus_Failed", resourceCulture); } } /// /// Looks up a localized string similar to Invalid. /// internal static string UninstallStatus_Invalid { get { return ResourceManager.GetString("UninstallStatus_Invalid", resourceCulture); } } /// /// Looks up a localized string similar to Paused. /// internal static string UninstallStatus_Paused { get { return ResourceManager.GetString("UninstallStatus_Paused", resourceCulture); } } /// /// Looks up a localized string similar to Protected. /// internal static string UninstallStatus_Protected { get { return ResourceManager.GetString("UninstallStatus_Protected", resourceCulture); } } /// /// Looks up a localized string similar to Skipped. /// internal static string UninstallStatus_Skipped { get { return ResourceManager.GetString("UninstallStatus_Skipped", resourceCulture); } } /// /// Looks up a localized string similar to Uninstalling. /// internal static string UninstallStatus_Uninstalling { get { return ResourceManager.GetString("UninstallStatus_Uninstalling", resourceCulture); } } /// /// Looks up a localized string similar to Waiting. /// internal static string UninstallStatus_Waiting { get { return ResourceManager.GetString("UninstallStatus_Waiting", resourceCulture); } } /// /// Looks up a localized string similar to Uninstall string. /// internal static string UninstallString { get { return ResourceManager.GetString("UninstallString", resourceCulture); } } } } ================================================ FILE: source/UninstallTools/Properties/Localisation.ar.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 صفحة الويب رمز المنتج اسم العرض اسم العرض المشذب الاصدار الحجم المقدر تاريخ التثبيت موقع التثبيت مصدر التثبيت هو تطبيق 64بت محمي هو محدث صالحه تعديل المسار اسم الناشر اسم الناشر المشذب الغاء التثبيت بهدوء ممكن سلسله الغاء التثبيت بهدوء اسم مفتاح مكتب التسجيل مسار مكتب التسجيل هو مكون النظام اسم ملف الغاء التثبيت نوع الغاء التثبيت الغاء التثبيت ممكن الغاء تثبيت السلسلة تعليق الايقونة المعروضة مسار غير صالح ثقة ايقاف عامل الغاء التثبيت قبل الاوان تخطي بواسطة المستخدم موقع الغاء التثبيت لا توجد طريقه صالحه لالغاء تثبيت هذا الادخال اعاده رمز الغاء التثبيت الخطا: سيئه جيد مشكوك معروف جيد جدا لم يتطابق اسم الشركة اسم الشركة مطابق يتم استخدام الدليل من قبل التطبيقات الاخرى المثبتة المادة المذكورة صراحة في الغاء التثبيت ادخال مكتب التسجيل من الغاء التثبيت يبدو ان المادة عبارة عن فئة ناشر كاملة اسم المنتج لا تتطابق بشكل جيد للغاية مطابقه اسم المنتج تماما اسم الدليل مشكوك فيه مجهول مثبت الوندوز Inno Setup يتبخر نظام التثبيت النصي القابل للقيم الخالية InstallShield SDBInst مكتمل فشل باطل محمي متخطى الغاء التثبيت الانتظار يتم تسجيل التطبيق فلتر باطل فلتر جديد غير متطابقات يحتوي ينتهي مع يساوي Regex يبدا ميزة ويندوز Used to mark windows features on the uninstaller list يحتوي على اي As in "matches any word from this string" مسح المحركات للتطبيقات... تجميع الدلائل يتم الان مسح مخازن التطبيقات... بحث عن قوالب التطبيقات بحث عن تطبيقات البخار بحث عن تطبيقات مخزن وندوز بحث عن ميزات وندوز دمج التطبيقات المكتشفة... دمج التطبيقات من المخازن دمج التطبيقات من المحركات يتم الان انشاء معلومات مفقوده... تحديث ويندوز البحث عن تحديثات وندوز قاعده جدار الحماية مساعده المستخدم تقارير عن اخطاء الوندوز يتم الان اعداد الماسحات الضوئية الغير هامه... الانتهاء... توافق التطبيق CLSID فئات مرجع الغاء التثبيت موقع الغاء التثبيت اختصار تكوين نهج الصوت سجلات تسجيل الاحداث معلومات التتبع قائمه المجلدات المثبتة الغاء التثبيت الاصلي Most of the time used to show parent application of an update اوامر بدء التشغيل لن تكون مفتوحة بعد الان اثناء الاقلاع. تاكد من ان المواد المحددة غير مطلوبه قبل ازالتها. ازاله البرامج المحددة عند بدء التشغيل ؟ مدير بدء التشغيل يتم الان تحميل... مجلد فارغ الملفات التنفيذية موجودة الملفات موجودة العديد من الملفات موجودة يتم التعرف على اسم البرنامج لا توجد دلائل فرعيه يتم التعرف على الناشر سيتم تشغيل الادخال مره واحده فقط الادخال مطابق للتطبيق الملفات والدلائل ملفات البرنامج اليتيمة مكتب التسجيل بدء فشل تمكين هذا الادخال ، لم يتم العثور على الملف التالي: انتهت مهله الغاء التثبيت مهمة Fom Task Scheduler كائن مساعد المستعرض لا يمكن ان تكون القيمة خاليه او فارغه لا يمكن ان تحتوي القيمة على سطور جديده مفاتيح مكتب التسجيل بدء تشغيل باطل او مجهول: نوافذ متجر التطبيق حاله جديده غير مسجل Present on the HDD but is not properly reported anywhere ازاله بيانات تطبيق مخزن الاشكاليه حذف بسيط الدليل ، او سيكون فارغا بعد ازاله الخردة. خدمه كافة الخصائص Used in the search box to specify what's being compared المثبتة MSI مسح منتجات... GUIDs تم العثور على {0} تطبيق مسح مكتب التسجيل لالغاء التثبيت... جمع مفاتيح مكتب التسجيل معالجه {0} يتم الان انشاء معلومات الغاء التثبيت مفقود... متوقف البحث عن ادخالات بدء التشغيل Chocolatey Oculus ================================================ FILE: source/UninstallTools/Properties/Localisation.cs.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Webová stránka Kód produktu Nazev Zkrácení názvu Verze Odhadovaná velikost Datum instalace Místo instalace Zdroj instalace Je to 64-bitová aplikace Je chráněn Je aktualizace Je platný Upravit cestu Jméno vydavatele Zkrácené jméno vydavatele Tiché odinstalování je možný Tiché odinstalování řetězce Název klíče registru Cesta k registru Je součástí systému Název souboru odinstalátoru Typ odinstalátoru Odinstalace je možná Řetězec odinstalace Komentář Zobrazí se ikona Neplatná cesta Spolehlivost Předčasně ukončena odinstalace Přeskočeno uživatelem Umístění odinstalátoru Neexistuje žádný platný způsob, jak odinstalovat tento záznam Odinstalace vrátila kód chyby: Špatná Dobrá Sporná Neznámá Velmi dobrá Nadřazený odinstalátoru Most of the time used to show parent application of an update Název společnosti neodpovídá Název společnosti souhlasí Adresáře jsou využívány jinými nainstalovanými aplikacemi Položka je výslovně uvedena v odinstalaci Položka registru na odinstalaci Položka se zdá být celá vydavatele kategorie Název produktu neodpovídá velmi dobře Název produktu naprosto souhlasí Název adresáře je sporný Neznámý Windows Installer Inno Setup Steam Nullsoft Scriptable Install System InstallShield SDBInst Komplet Neúspěšné Neplatné Chráněné Vynecháno Odinstalace Čeká Aplikace je registrována Neplatný filtr Nový filtr Žádné zápasy Obsahuje Končí na Rovná se Regex Spuštět s Vlastnosti Windows Used to mark windows features on the uninstaller list Obsahující jakýkoli As in "matches any word from this string" Příkaz po spuštění Tyto již nebudou otevřeny během startu. Ujistěte se, že vybrané položky nejsou vyžadovány před jejich odstraněním. Vyjmout vybrané programy z po spouštění? Správce po spuštění Načítání... Prázdné složky Aktuální spustitelné soubory Aktuální soubory Jsou přítomno mnoho souborů Název programu je rozpoznán Žádné podadresáře Vydavatel je rozpoznán Vstup proběhne jen jednou Vstup je přiřazen k aplikaci Pozůstatky v Program Files Registry Autostart Nepodařilo se povolit tuto položku, následující soubor nebyl nalezen: Vypršel časový limit odinstalátoru Úlohy Fom Task Scheduler Prohlížeče pomocníka objektu Hodnota nemůže být null nebo prázdná Hodnota nemůže obsahovat znaky nového řádku Všechny vlastnosti Used in the search box to specify what's being compared Neregistrovaný Present on the HDD but is not properly reported anywhere Soubory a adresáře Neplatný nebo neznámý spouštěcí klíč(e) registru: Windows Store Aplikace Nová podmínka Odstranění aplikací Store je problematické Jednoduché Odstranení Adresář bude po odstranění nepotřebných prázdný. Service Skenování nainstalovaných produktů MSI... Nalezeno {0} aplikací GUIDs Prohledávání registru pro odinstalaci... Sbírání klíčů registru Zpracováno {0} Generování chybějící odinstalačních informace... Hledání aplikací na jednotce... Získávání adresáře Uložení skenování aplikací ... Hledání šablon aplikací Hledání aplikací Steam Vyhledávání aplikací Windows Store Hledání funkcí systému Windows Slučování nalezených aplikací... Slučování aplikací z úložiště Slučování aplikací z jednotek Generování chybějících informací... Windows Update Vyhledat aktualizace systému Windows Pravidla brány firewall Uživatelská pomoc Hlášení o chybách systému Windows Nastavení nevyžádaných skenerů ... Dokončeno ... Kompatibilita aplikací CLSID třída Odkaz na odinstalátor Umístění odinstalátoru Zkratka Konfigurace politiky Audia Záznamy protokolu událostí Sledování informací Seznam složek instalací Pauza Hledání položek po spouštění Chocolatey Oculus ================================================ FILE: source/UninstallTools/Properties/Localisation.de.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Webseite Produktcode Anzeigename Kurzname Version Geschätzte Größe Installationsdatum Installationspfad Installationsquelle 64bit Anwendung Geschützt Aktualisierung Gültig Pfad ändern Herausgeber Kurzname Herausgeber Stille Deinstallation möglich Anweisung zur stillen Deinstallation Registryschlüssel Registrypfad Systemkomponente Dateiname des Uninstallers Typ des Uninstallers Deinstallation möglich Anweisung zur Deinstallation Kommentar Angezeigtes Symbol Ungültiger Pfad Vertrauensgrad Deinstallationsvorgang vorzeitig beendet Vom Benutzer übersprungen Uninstaller-Pfad Es gibt keine gültige Methode, diesen Eintrag zu deinstallieren Uninstaller-Fehlercode: Abzuraten Hoch Bedenklich Unbestimmt Sehr hoch Übergeordneter Uninstaller Most of the time used to show parent application of an update Keine Übereinstimmung beim Firmennamen Übereinstimmung beim Firmennamen Verzeichnis wird von anderen installierten Anwendungen verwendet. Element wird im Uninstaller explizit erwähnt. Registryeintrag des Uninstallers Element scheint einer ganzen Programm-Kategorie anzugehören Der Produktname stimmt nicht sehr gut überein. Perfekte Übereinstimmung beim Produktnamen Verzeichnisname ist fraglich Unbekannt Vollendet Gescheitert Ungültig Geschützt Übersprungen Deinstallieren Warten Windows Installer Inno setup Steam Nullsoft Scriptable Install System InstallShield SDBInst Anwendung ist registriert Ungültiger Filter Neuer Filter Keine Übereinstimmung Enthält Endet mit Ist gleich Regex Beginnt mit Windows Funktion Used to mark windows features on the uninstaller list Enthält irgendeines As in "matches any word from this string" Autostart Befehle Sie werden beim Booten nicht mehr geöffnet. Stellen Sie sicher, dass die ausgewählten Elemente nicht mehr erforderlich sind, bevor sie entfernt werden. Ausgewählte Programme aus dem Autostart entfernen? Autostart Manager Laden... Leerer Ordner Ausführbare Dateien sind vorhanden Dateien sind vorhanden Viele Dateien sind vorhanden Programmname erkannt Keine Unterverzeichnisse Herausgeber erkannt Eintrag wird nur einmal ausgeführt Eintrag stimmt mit der Anwendung überein Verwaiste Programmdateien Registry Autostart Eintrag konnte nicht aktiviert werden, weil die folgende Datei fehlt: Zeitüberschreitung beim Uninstaller Aufgabe Fom Task Scheduler Browser Helper Objekt Wert darf nicht Null oder leer sein Wert darf keine Zeilenumbrüche enthalten Alle Eigenschaften Used in the search box to specify what's being compared Ist unregistriert Present on the HDD but is not properly reported anywhere Chocolatey Oculus Dateien und Ordner Ungültiger oder unbekannter startup registrierungs schlüssel Windows Store Programm Neue Bedingung Die Entfernung der Store App Data kann zu Problemen führen Einfaches Löschen Das Verzeichnis ist oder wird nach dem Entfernen von Junk leer sein. Service Windows Update Suche nach Windows Updates Firewall Regel Angehalten Ist ein Web Browser Durchsuche installierte MSI Produkte... Anwendungens GUIDs {0} gefunden Durchsuche Registry nach Uninstallern... Registrierungsschlüssel sammeln Ausführen {0} Fehlende Deinstallationsinformationen werden generiert ... Laufwerke nach Anwendungen scannen ... Nach Anwendungsvorlagen suchen Suche nach Steam Anwendungen Suche nach Windows Store Anwendungen Suche nach Windows Eigenschaften Zusammenführen gefundener Anwendungen ... Zusammenführen von Anwendungen aus Store Anwendungen von Laufwerken zusammenführen Fehlende Informationen erzeugen ... Benutzer Unterstützung Windows Fehlerberichterstattung melden. Junk-Scanner einrichten ... Beenden Anwendungs Kompatibilität CLSID Klassen Deinstallationsprogramm-Referenz Standort des Deinstallationsprogramms Kurzbefehl Audio policy Einstellungen Ereignisprotokoll erzeugen Spur Information Liste der Installierten Ordner Suche nach Chocolatey Paketen Deinstallation durch Chocolatey Shown in junk results window Besitzt Autostarteintrag Suche nach Starteinträgen Oculus Anwendungen PowerShell script Gruppierung von Dateien Überprüfe Anwendungs Store Debug-Tracing/Protokollierung Konfiguration Auf der Suche nach Scoop-Paketen Könnte zu einer anderen Anwendung mit einem ähnlichen Namen gehören For example `AppX Extended` matching `AppX` when it belongs to the AppX application ================================================ FILE: source/UninstallTools/Properties/Localisation.es.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Página web Código del producto Nombre para mostrar Nombre corto para mostrar Versión Tamaño estimado Fecha de la instalación Ubicación de la instalación Origen de la instalación Es una aplicación de 64 bits Está protegida Está actualizada Es válida Ruta de modificación Nombre del editor Nombre corto del editor Es posible la desinstalación silenciosa Cadena de desinstalación silenciosa Nombre de la clave de registro Ruta de registro Es un componente del sistema Nombre del archivo desinstalador Tipo de desinstalador La desinstalación es posible Cuerda de desinstalación Comentario Icono mostrado Ruta inválida Confianza Ubicación del desinstalador Mala Buena Cuestionable Desconocida Muy buena Desinstalador padre Most of the time used to show parent application of an update El nombre de la empresa no coincide El nombre de la empresa coincide El directorio está siendo usado por otras aplicaciones instaladas El elemento se menciona explícitamente en el desinstalador Entrada de registro del desinstalador Instalador de Windows Desconocido Configuración de Inno Steam Sistema de instalación Nullsoft Scriptable InstallShield SDBInst Completado Fallido Inválido Protegido Omitido Desinstalando Esperando La aplicación está registrada Filtro inválido Nuevo filtro No hay coincidencias Termina con Iguales Regex Comienza con Característica de Windows Used to mark windows features on the uninstaller list Contiene cualquier As in "matches any word from this string" Comandos de inicio ¿Eliminar los programas seleccionados del inicio? Administrador del Inicio Cargando... Carpeta vacía No hay subdirectorios El editor es reconocido Registro Inicio Tarea Fom Task Scheduler App de Windows Store Nueva condición Omitido por el usuario No hay un modo válido de desinstalar esta entrada Desinstalación detenida prematuramente El desinstalador devolvió el código de error: El elemento parece ser una categoría completa de editores El nombre del producto no coincide muy bien El nombre del producto coincide perfectamente El nombre del directorio es cuestionable Contiene Ya no se abrirán durante el arranque. Asegúrese de que los elementos seleccionados no sean necesarios antes de quitarlos. Los ejecutables están presentes Los archivos están presentes Muchos archivos están presentes El nombre del programa es reconocido La entrada se ejecutará una sola vez La entrada se corresponde con la solicitud Archivos de programa huérfanos Error al habilitar esta entrada, no se encontró el siguiente archivo: El desinstalador no responde Objeto del Ayudante del Navegador El valor no puede ser nulo o vacío El valor no puede contener líneas nuevas Clave de registro de inicio no válida o desconocida(s): Is no registrado Present on the HDD but is not properly reported anywhere La eliminación de los datos de la App Store es problemático Borrado simple Todas las propiedades Used in the search box to specify what's being compared Archivos y directorios El directorio está, o estará, vacío después de eliminar la basura. Analizando productos MSI instalados... Halladas {0} aplicaciones GUID Registro de escaneo para desinstaladores... Recopilación de claves del registro Procesando {0} Generación de información de desinstalación que falta... Analizando unidades por aplicaciones... Recopilando directorios Analizando aplicaciones de tiendas... Buscando plantillas de aplicaciones Buscando aplicaciones de Steam Buscando aplicaciones de Windows Store Buscando características de Windows Fusionando aplicaciones descubiertas... Fusionando aplicaciones de tiendas Fusionando aplicaciones de unidades Generando información que falta... Windows Update Servicio Buscando actualizaciones de Windows Regla de Firewall Asistente de usuario Informes de errores de Windows Configurando escáneres basura... Finalizando... Compatibilidad de aplicaciones Clases de CLSID Referencia del desinstalador Ubicación del desinstalador Acceso directo Configuración de política de audio Registros del registro de eventos Información de rastreo Lista de carpetas instaladas Pausado Buscando entradas de inicio Chocolatey Oculus Buscando paquetes de Chocolatey Desinstalar en Chocolatey Shown in junk results window Puede iniciarse automáticamente Buscando Aplicaciones de Oculus Es un navegador web Script de PowerShell Rastreo de Depuración/Configuración del Registro Buscando paquetes de Scoop Podría pertenecer a una aplicación diferente con un nombre similar For example `AppX Extended` matching `AppX` when it belongs to the AppX application ================================================ FILE: source/UninstallTools/Properties/Localisation.fr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Bon Chaîne de désinstallation Chaîne de désinstallation silencieuse Chemin du registre Chemin invalide Commentaire Confiance Date d'installation Désinstallation possible Désinstallation silencieuse possible Discutable Emplacement d'installation Emplacement du désinstalleur Passé par l'utilisateur Est protégé Est un composant système Est une application 64bits Est une mise à jour Est valide Icône affichée Inconnu Le désinstalleur a retourné un code erreur : Mauvais Modifer le chemin Nom d'affichage Nom d'affichage abrégé Nom de fichier du désinstalleur Nom de la clé du registre Nom de l'éditeur Nom de l'éditeur abrégé Page web Pas de manière valide de désinstaller cette entrée Source d'installation Taille estimée Travail de désinstallation arrêté prématurément Très bon Type de désinstalleur Version Désinstalleur parent Most of the time used to show parent application of an update Le nom de compagnie ne correspondait pas Le nom de compagnie correspondait Le dossier est utilisé par d'autres applications installées L'élément est explicitement mentionné dans le désinstalleur Entrée de registre du désinstalleur L'élément semble être une catégorie entière d'éditeur Le nom de produit ne correspondait pas très bien Le nom de produit correspondait parfaitement Le nom du dossier est discutable Code produit Inconnu Terminé Échoué Invalide Protégé Passé Désinstallation En attente Windows Installer Inno Setup Steam Nullsoft Scriptable Install System InstallShield SDBInst L'application est enregistrée Filtre invalide Nouveau filtre Pas de correspondance Contient Finit par Égal Regex Commence par Fonctionnalité Windows Used to mark windows features on the uninstaller list Contient tout As in "matches any word from this string" Commandes de démarrage Ils ne seront plus ouverts pendant le démarrage. Vérifiez que les éléments sélectionnés ne sont pas requis avant de les supprimer. Supprimer les programmes sélectionnés du démarrage ? Gestionnaire de Démarrage Chargement... Dossier vide Des exécutables sont présents Des fichiers sont présents Beaucoup de fichiers sont présents Le nom du programme est reconnu Pas de sous-dossier L'éditeur est reconnu L'entrée sera lancée une seule fois L'entrée correspond à l'application Orphelin de Program Files Registre Démarrage Échec en activation de cette entrée, le fichier suivant est introuvable : Le désinstalleur a dépassé le temps Tâche Fom Task Scheduler Extension de navigateur La valeur ne peut être nulle ou vide La valeur ne peut contenir de nouvelles lignes Clé(s) de registre de démarrage invalide(s) ou inconnue(s) Est non enregistré Present on the HDD but is not properly reported anywhere Appli Windows Store Nouvelle condition Suppression problématique des données du Store Effacer simplement Toutes propriétés Used in the search box to specify what's being compared Fichiers et dossiers Le dossier est ou sera vide après suppression des résidus. Service Balayage des produits MSI installés... Trouvé {0} GUIDs d'applications Balayage du registre pour les désinstalleurs Regroupement des clés de registre Traitement de {0} Génération de l'information de désinstalleur manquante Balayage des lecteurs pour les applications... Regroupement des dossiers Balayage des magasins d'applications... Recherche des modèles d'applications Recherche des Applis Steam Recherche des Applis du Windows Store Recherche des Fonctionnalités Windows Fusion des applications découvertes... Fusion des applications depuis les magasins Fusion des applications depuis les lecteurs Génération de l'information manquante... Windows Update Recherche de Mises à jour Windows Règle de pare-feu Assistant utilisateur Rapports de Windows Error Reporting Réglage des scanners de résidus... En train de finir... Compatibilité d'application Classes CLSID Référence de désinstalleur Emplacement de désinstalleur Raccourci Config de stratégie audio Journaux d'Event Log Traçage d'information Liste de dossiers d'installation En pause Recherche des entrées de démarrage Chocolatey Oculus Recherche de paquets Chocolatey Désinstaller dans Chocolatey Shown in junk results window Peut démarrer automatiquement Recherche des Applis Oculus Est un navigateur web Script PowerShell Configuration du débogage de Traçage/Journalisation Recherche de paquets Scoop Peut appartenir à une autre appli avec un nom similaire For example `AppX Extended` matching `AppX` when it belongs to the AppX application Situé directement à l'intérieur d'un Dossier Connu ================================================ FILE: source/UninstallTools/Properties/Localisation.hu.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Weblap Termékkód Megjelenítendő név Rövidített megjelenítendő név Verzió Becsült méret Telepítés dátuma Telepítési hely Telepítőforrás 64-bites alkalmazás Védett Frissítés Érvényes Útvonal módosítás Kiadó neve Rövidített kiadó-név A csendes eltávolítás lehetséges Csendes eltávolító karakterlánc Beállításkulcs név Registry útvonal Ez egy rendszerösszetevő Eltávolítófájl-név Eltávolító típusa Az eltávolítás lehetséges Eltávolítási karakterlánc Megjegyzés Megjelenített ikon Érvénytelen útvonal Biztonságosság Az eltávolító működése idő előtt leállításra került Kihagyta a felhasználó Eltávolító helye Nincs érvényes mód eltávolítani ezt a bejegyzést Az eltávolító ezt a hibakódot adta vissza: Rossz Kétséges Ismeretlen Nagyon jó Szülő eltávolító Most of the time used to show parent application of an update A cégnév nem egyezik A cégnév egyezik A könyvtárat egyéb telepített alkalmazások használják Az elem nincs megemlítve az eltávolítóban Eltávolító bejegyzése a Beállításjegyzékben Úgy tűnik, hogy az összes kiadó egy kategóriába tartozik A terméknév nem egyezik meg teljesen A terméknév tökéletesen megegyezik A könyvtárnév kérdéses Ismeretlen Windows Installer Inno Setup Steam Nullsoft Scriptable Install System InstallShield SDBInst Befejezve Sikertelen Érvénytelen Védett Kihagyva Eltávolítás Várakozás A program regisztrálva van Érvénytelen szűrő Új szűrő Nincs találat Tartalmazza Ezzel végződik Egyenlő Regex Ezzel kezdődik Windows szolgáltatás Used to mark windows features on the uninstaller list Bármit tartalmazhat As in "matches any word from this string" Indítópult parancsok Ezek már nem lesznek megnyithatók a rendszerindítás közben. Ellenőrizze, hogy a kiválasztott elemek nem szükségesek-e, mielőtt törli azokat. Eltávolítja a kijelölt programokat az Indítópultból? Indítópult kezelő Betöltés... Üres mappa Jelen levő futtathatók Jelen levő fájlok Túl sok fájl van jelen A program neve azonosítva Nincsenek alkönyvtárak A kiadó azonosítva A bejegyzés csak egyszer fog végrehajtódni A bejegyzés illeszkedik az alkalmazáshoz Fájlok és könyvtárak Elárvultak a Program Files mappában Beállításjegyzék Indítópult Nem sikerült engedélyezni ezt a bejegyzést, a következő fájl nem található: Eltávolító időtúllépés Feladat Fom Task Scheduler Böngésző segítő objektuma Az érték nem lehet nulla, vagy üres Az érték nem tartalmazhat új sorokat Érvénytelen, vagy ismeretlen Indítópult registry kulcs: Windows Áruházbeli alkalmazás Új feltétel Nem regisztrált Present on the HDD but is not properly reported anywhere Az Áruházbeli alkalmazás adatainak eltávolítása problémás Egyszerű törlés A könyvtár a felesleg eltávolítása után üres lesz. Szolgáltatás Minden tulajdonság Used in the search box to specify what's being compared Telepített MSI termékek ellenőrzése... Beazonosítva{0} program GUID Eltávolítók ellenőrzése a beállításjegyzékben... Beállításkulcsok összegyűjtése Feldolgozás {0} Hiányzó eltávolítási információk összeállítása... Meghajtókon levő programok ellenőrzése... Könyvtárak összegyűjtése Programtárolók ellenőrzése... Alkalmazássablonok keresése Steam alkalmazások keresése Windows áruházbeli alkalmazások keresése Windows szolgáltatások keresése Azonosított programok egyesítése... Tárolókban levő programok egyesítése Meghajtókon levő programok egyesítése Hiányzó információk létrehozása... Windows frissítés Indítópult bejegyzések keresése Chocolatey Oculus Windows frissítések keresése Tűzfal szabály Felhasználósegéd Windows hibajelentések Befejezés... Alkalmazáskompatibilitás CLSID osztályok Parancsikon Eltávolító helye Eseménynaplók Szüneteltetve Chocolatey csomagok keresése Eltávolítás a Chocolatey-vel Shown in junk results window Oculus alkalmazások keresése Böngésző e PowerShell szkript Scoop csomagok keresése Szemétkeresők beállítása... Eltávolító hivatkozása Hangházirend konfiguráció Nyomkövetési információ Telepített mappa lista Automatikusan indítható ================================================ FILE: source/UninstallTools/Properties/Localisation.it.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Pagina web Codice del prodotto Nome mostrato Abbreviazione da mostrare Versione Grandezza stimata Data di installazione Cartella di installazione Origine di installazione E' una applicazione a 64bit E' protetta E' un aggiornamento E' valido Modifica percorso Nome dell'editore Abbreviazione del nome dell'editore L'installazione silenziosa è applicabile Stringa di disinstallazione silenziosa Nome della chiave di registro Percorso del registro E' un componente di sistema Nome del file di disinstallazione Tipo di disinstallatore Disinstallazione possibile Stringa di disinstallazione Commenti Icona mostrata Percorso invalido Affidabilità La disinstallazione si è fermata prima del termine Saltato dall'utente Posizione del disinstallatore Non ci sono valide possibilità di disinstallare questa voce Il disinstallatore ha restituito il codice di errore: Cattivo Buono Discutibile Sconosciuto Molto buono Dipendenze del disinstallatore Most of the time used to show parent application of an update Il nome dell'impresa non coincide Il nome dell'impresa coincide La cartella è usata da altre applicazioni installate L'oggetto è esplicitamente menzionato nel disinstallatore Voce del registro del disinstallatore L'elemento sembra essere una intera categoria dell'editore Il nome del prodotto non coincide esattamente Il nome del prodotto coincide perfettamente Il nome della cartella è discutibile Sconosciuto Windows Installer Inno setup Steam Nullsoft Scriptable Install System InstallShield SDBInst Completato Fallito Invalido Protetto Saltato Disinstallando Attendi L'applicazione è registrata Filtro invalido Nuovo filtro Non coincide Contiene Finisce con Uguale Espressione regolare Inizia con Caratteristica di windows Used to mark windows features on the uninstaller list Contiene qualunque As in "matches any word from this string" Comandi di avvio Non saranno più aperti in fase di avvio. Assicurati che gli elementi selezionati non siano necessari prima di rimuoverli. Rimuovere i programmi selezionati dall'avvio? Gestore dell'avvio Caricando... Cartella vuota Gli eseguibili sono presenti I files sono presenti Sono presenti molti file Il nome del programma è stato riconosciuto Non ci sono sottocartelle L'editore è stato riconosciuto La voce sarà eseguita una sola volta La voce corrisponde ad una applicazione File e cartelle File del programma orfani Registro Avvio Non è possibile abilitare questa voce, i seguenti file non sono sono stati trovati: Il disinstallatore non risponde Operazione Fom Task Scheduler Estensione del navigatore Il valore non può essere nullo o vuoto Il valore non può contenere nuove linee Chiave(i) di registro invalida(e) o sconosciuta(e): App di Windows Store Nuova condizione Non è registrato Present on the HDD but is not properly reported anywhere La rimozione dei dati dell'App Store è difficoltosa Eliminazione semplice La cartella è o resterà vuota dopo la rimozione degli scarti Servizio Tutte le proprietà Used in the search box to specify what's being compared Controllando i prodotti con installatore MSI... Trovate {0} applicazioni GUIDs Ricerca nel registro dei disinstallatori... Selezione delle chiavi di registro Processando {0} Creazione delle informazioni di disinstallazione mancanti... Ricerca delle applicazioni nel disco... Selezionando le cartelle Ricerca nello store delle applicazioni... RIcerca di modelli per applicazioni Ricerca per Steam Apps Ricerca per Windows Store Apps Ricerca per funzionalità di Windows Unione applicazioni trovate... Unione applicazioni dagli store Unione applicazioni dai dischi Generazione informazioni mancanti... Windows Update Ricerca di aggiornamenti di Windows Regola del firewall Aiuto utente Resoconto di Windows Error Reporting Configurando la ricerca degli scarti... Completando... Compatibilità dell'applicazione Classe di CLSID Riferimento del disinstallatore Posizione del disinstallatore Scorciatoria Configurazione dei criteri (policy) dell'audio Eventi del registro eventi Informazioni di tracciamento Elenco delle cartelle installate Pausa Ricerca delle voci all'avvio Chocolatey Oculus Ricerca dei pacchetti Chocolatey Disinstalla con Chocolatey Shown in junk results window Può avviarsi automaticamente Oculus App E' un browser web Script PowerShell Debug Tracing/Registrazione Configurazione Ricerca di pacchetti Scoop Potrebbe appartenere a un'altra applicazione con un nome simile. For example `AppX Extended` matching `AppX` when it belongs to the AppX application ================================================ FILE: source/UninstallTools/Properties/Localisation.ja.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ウェブページ 製品コード 表示名 トリムされた表示名 バージョン 推定サイズ インストール日 インストール場所 インストールソース 64ビットアプリケーションかどうか 保護されているか アップデートかどうか 有効かどうか パスを修正する 発行者名 トリムされた発行者名 静かなアンインストールが可能です 静かなアンインストール文字列 レジストリキー名 レジストリパス システムコンポーネントかどうか アンインストーラーファイル名 アンインストーラータイプ アンインストールが可能 アンインストール文字列 コメント 表示されたアイコン 無効なパス 確信度 アンインストールが手動で停止しました ユーザーによってスキップされました アンインストーラーの場所 このエントリをアンインストールする有効な方法はありません アンインストーラーはエラーコードを返しました: 悪い 良好 疑わしい 不明 非常に良好 親アンインストーラー Most of the time used to show parent application of an update 会社名が一致しませんでした 会社名が一致しました ディレクトリは他のインストールされたアプリケーションによって使用されています アイテムはアンインストーラーに明示的に記載されています アンインストーラーのレジストリエントリ アイテムは全体のパブリッシャーカテゴリに属しているようです 製品名があまり一致していません 製品名が完全に一致 ディレクトリ名は疑わしいです 不明 Windowsインストーラー Inno Setup Steam Nullsoftスクリプタブルインストールシステム InstallShield SDBInst 完了 失敗 無効 保護されている スキップされました アンインストール中 待機中 アプリケーションが登録されています 無効なフィルター 新しいフィルター 一致するものはありません 含む で終わる 等しい 正規表現 で始まる Windowsの機能 Used to mark windows features on the uninstaller list いずれかを含む As in "matches any word from this string" スタートアップコマンド 起動時にこれらは開かれなくなります。削除する前に、選択したアイテムが必要ないことを確認してください。 選択したプログラムをスタートアップから削除しますか? スタートアップマネージャー 読み込み中... 空のフォルダー 実行可能ファイルが存在します ファイルが存在します 多くのファイルが存在します プログラム名が認識されています サブディレクトリはありません パブリッシャーが認識されています エントリーは一度だけ実行されます エントリーはアプリケーションに一致しています ファイルとディレクトリ プログラムファイルの孤立 レジストリ スタートアップ このエントリを有効にできませんでした。次のファイルが見つかりませんでした: アンインストーラーのタイムアウト タスク Fom Task Scheduler ブラウザヘルパーオブジェクト 値は null または空であってはなりません 値には改行を含めることはできません 無効または不明なスタートアップレジストリキー: Windows ストアアプリ 新しい条件 未登録かどうか Present on the HDD but is not properly reported anywhere ストアアプリのデータ削除に問題があります シンプルな削除 ディレクトリは、またはジャンクを削除した後に空になります。 サービス プロパティ Used in the search box to specify what's being compared インストールされたMSI製品をスキャン中... {0} のアプリケーション GUID が見つかりました アンインストーラーのためにレジストリをスキャン中... レジストリキーを収集中 {0} を処理中 不足しているアンインストーラー情報を生成中... アプリケーションのためにドライブをスキャン中... ディレクトリを収集中 アプリケーションストアをスキャン中... アプリケーションテンプレートを検索中 Steam アプリを検索中 Windows ストアアプリを検索中 Windows 機能を検索中 発見されたアプリケーションをマージ中... ストアからアプリケーションをマージ中 ドライブからアプリケーションをマージ中 不足している情報を生成中... Windows アップデート Windows アップデートを検索中 ファイアウォールルール ユーザー支援 Windows エラー報告レポート ジャンクスキャナーを設定中... 終了中... アプリケーションの互換性 CLSID クラス アンインストーラーの参照 アンインストーラーの場所 ショートカット オーディオポリシー設定 イベントログ トレース情報 インストールされたフォルダーのリスト 一時停止 Chocolatey Chocolatey パッケージを検索中 Chocolatey でアンインストール Shown in junk results window 自動的に起動できる スタートアップエントリを検索中 Oculus アプリを検索中 Oculus ウェブブラウザかどうか PowerShell スクリプト デバッグトレース/ロギング設定 Scoop パッケージを検索中 類似の名前を持つ別のアプリに属している可能性があります。 For example `AppX Extended` matching `AppX` when it belongs to the AppX application ================================================ FILE: source/UninstallTools/Properties/Localisation.nl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Web pagina Productcode Toon naam Korte naam Versie Geschatte grootte Installatie datum Installatie pad Installatie bron Is een 64bit programma Is beveiligd Is een update Is geldig Pad wijzigen Uitgever Korte naam uitgever Stille de-installatie is mogelijk Stille de-installatie string Registersleutel Register pad Is een systeem component Bestandsnaam v/d uninstaller De-installatie type De-installatie is mogelijk De-installatie string Commentaar Weergegeven symbool Ongeldig pad Vertrouwd Het de-installatieproces werd voortijdig beëindigd Overgeslagen door gebruiker De-installer pad Er is geen geldige methode om deze registratie te de-installeren De-installer retourneert een foutcode: Slecht Goed Twijfelachtig Onbekend Zeer goed Bovenliggende de-installer Most of the time used to show parent application of an update Bedrijfsnamen komen niet overeen Bedrijfsnamen komen overeen De map wordt door andere geïnstalleerde toepassingen gebruikt. Het onderdeel wordt expliciet genoemd in de de-installer. Register registratie van de de-installer Het onderdeel schijnt aan een totale uitgevers categorie toe te behoren De productnaam komt niet volledig overeen. Perfecte overeenstemming tussen de productnamen De naam van de map is twijfelachtig Onbekend Windows Installer Inno Setup Steam Nullsoft Scriptable Install System InstallShield SDBInst Voltooid Mislukt Ongeldig Beveiligd Overgeslagen De-installeren Wachten Het programma is geregistreerd Ongeldig filter Nieuw filter Geen overeenkomst Bevat Eindigd met Is gelijk aan Regex Begint met Windows functie Used to mark windows features on the uninstaller list Bevat wat ... dan ook As in "matches any word from this string" Opstart opdrachten Deze worden bij het 'opstarten' niet meer geopend. Overtuig u ervan, dat de gekozen onderdelen niet langer vereist zijn, voordat deze zijn verwijderd. Gekozen programma's verwijderen uit opstarten? Opstartmanager Laden... Lege map Uitvoerbare bestanden zijn aanwezig Bestanden zijn aanwezig Veel bestanden zijn aaanwezig Programma naam werd herkend Geen sub-mappen Uitgever werd herkend Registratie wordt slechts eenmaal uitgevoerd Registratie komt overeen met de toepassing Bestanden en mappen Verweesde programma bestanden Register Autostart De registratie kon niet worden geactiveerd, omdat het volgende bestand ontbreekt: Tijd overschrijding bij de uninstaller Taak Fom Task Scheduler Browser Helper Objekt Waarde mag niet leeg of null zijn Waarde mag geen nieuwe regels bevatten Ongeldige of onbekende opstart registersleutel(s): Windows Store App Nieuwe voorwaarde Is niet geregistreerd Present on the HDD but is not properly reported anywhere Verwijderen van Store App gegevens is een probleem Eenvoudig verwijderen De map is of zal leeg zijn na het verwijderen van rommel. Service Alle eigenschappen Used in the search box to specify what's being compared Scannen op geïnstalleerde MSI producten... Gevonden {0} programma GUID's Register scannen op de-installers... Windows Update Zoeken naar Windows updates Ontbrekende informatie genereren... Verzamelen registersleutels Verwerking {0} Genereren ontbrekende de-installer informatie Schijven scannen op programma's Verzamelen mappen Scannen programma opslag plaatsen... Zoeken naar programma templates Zoeken naar Steam Apps Zoeken naar Windows Store Apps Zoeken naar Windows onderdelen Samenvoegen ontdekte programma's... Programma's samenvoegen uit stores Programma's samenvoegen van schijven Firewall regel Gebruikers assistentie Windows foutrapportage rapport Instellen rommel scanners... Afronden... Programma compatibiliteit CLSID klassen De-installer verwijzing De-installer lokatie Snelkoppeling Configuratie audiobeleid Gebeurtenis logbestanden Traceer informatie Geïnstalleerde maplijst Gepauzeerd Zoeken naar opstart registraties Chocolatey Oculus Zoeken naar Chocolatey pakketten De-installeren in Chocolatey Shown in junk results window Kan automatisch starten Oculus Apps Is een web browser PowerShell script Debug tracing/Loggging Configuratie Zoeken naar Scoop pakketten Kan bij een andere app horen met een vergelijkbare naam For example `AppX Extended` matching `AppX` when it belongs to the AppX application ================================================ FILE: source/UninstallTools/Properties/Localisation.pl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Strona internetowa Kod produktu Nazwa Przycięta nazwa Wersja Przybliżony rozmiar Data instalacji Miejsce zainstalowania Źródło instalacji Jest aplikacją 64-bitową Jest chroniona Jest aktualizacją Jest prawidłowa Ścieżka modyfikacji Nazwa wydawcy Przycięta nazwa wydawcy Cicha dezinstalacja jest możliwa Ścieżka cichej deisntalacji Nazwa klucza rejestru Ścieżka w rejestrze Jest elementem systemowym Nazwa pliku dezinstalatora Typ dezinstalatora Dezinstalacja jest możliwa Ścieżka dezinstalacji Komentarz Wyświetlana ikona Nieprawidłowa ścieżka Pewność Deinstalator nieoczekiwanie przerwał pracę Pominięte przez urzytkownika Ścieżka dezinstalatora Żadna metoda dezinstalacji nie jest dostępna Dezinstalator zwrócił kod: Zła Dobra Wątpliwa Nieznana Bardzo dobra Deinstalator nadrzędny Most of the time used to show parent application of an update Nazwa firmy nie pasuje Nazwa firmy dopasowana Katalog jest używany przez inne zainstalowane aplikacje Pozycja jest wyraźnie wymieniona w dezinstalatorze Wpis rejestru z dezinstalatora Pozycja wydaje się być cała w kategorii wydawcy Nazwa produktu nie pasuje bardzo dobrze Nazwa produktu idealnie dopasowana Nazwa katalogu jest wątpliwa Nieznany Zakończono Niepowodzenie Nieprawidłowy Zabezpieczony Pominięty Dezinstalacja Oczekiwanie Funkcja Windows Used to mark windows features on the uninstaller list Windows Installer Inno setup Steam Nullsoft Scriptable Install System InstallShield SDBInst Aplikacja jest zarejestrowana Nieprawidłowy filtr Nowy filtr Brak wyników Zawiera Kończy się na Równa się Regex Zaczyna się na Zawiera dowolny As in "matches any word from this string" Komendy autostartu Nie będą one już otwierane podczas startu systemu. Upewnij się że wybrane elementy nie są wymagane przed ich usunięciem. Usunąć wybrane programy z autostartu? Menedżer Autostartu Ładowanie... Pusty folder Obecne są pliki wykonywalne Obecne są pliki Wiele plików jest obecnych Nazwa programu jest rozpoznana Brak podfolderów Wydawca jest rozpoznany Zostanie uruchomiony tylko raz Wpis jest przypisany do aplikacji Pozostałość w Program Files Rejestr Autostart Włączenie tej pozycji się nie powiodło, następujący plik nie został znaleziony: Upłynął limit czasu dezinstalatora Zadanie Fom Task Scheduler Wartość nie może być zerowa lub pusta Wartość nie może zawierać znaków nowej linii Browser Helper Object Nieprawidłowy lub nieznany klucz startowy: Nowy warunek Jest niezarejestrowany Present on the HDD but is not properly reported anywhere Usuwanie danych Store App jest problematyczne Aplikacja Windows Store Proste usunięcie Folder jest lub będzie pusty po usunięciu śmieci Usługa Wszystkie właściwości Used in the search box to specify what's being compared Pliki i katalogi Skanowanie zainstalowanych produktów MSI ... Znaleziono {0} GUIDów aplikacji Skanowanie dezinstalatorów w rejestrze... Gromadzenie kluczy rejestru Przetwarzanie {0} Generowanie brakujacych informacji o deinstalatorach... Skanowanie aplikacji na dyskach... Zbieranie folderów Skanowanie magazynów aplikacji... Wyszukiwanie szablonów aplikacji Szukanie Steam Apps Szukanie programów Windows Store Szukanie funkcji systemu Windows Łączenie odkrytych aplikacji... Łączenie aplikacji z magazynów Łączenie aplikacji z dysków Generowanie brakujących informacji... Aktualizacja systemu Windows Wyszukiwanie aktualizacji systemu Windows Regula zapory User assist Raportowanie błędów systemu Windows Konfigurowanie skanerów śmieci ... Kończenie... Zgodność aplikacji Klasy CLSID Klucz dezinstalatora Lokalizacja dezinstalatora Skrót Konfiguracja zasad dźwięku Dzienniki zdarzeń Informacje śledzenia Lista folderów instalacyjnych Wstrzymany Wyszukiwanie wpisów startowych Chocolatey Wyszukiwanie pakietów Chocolatey Odinstaluj w Chocolatey Shown in junk results window Może uruchomić się automatycznie Aplikacje Oculus Oculus Przeglądarka internetowa Skrypt PowerShell Szukanie paczek Scoop Może należeć do innej aplikacji o podobnej nazwie For example `AppX Extended` matching `AppX` when it belongs to the AppX application ================================================ FILE: source/UninstallTools/Properties/Localisation.pt-BR.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Página Web Código do produto Mostrar nome Mostrar nome abreviado Versão Tamanho estimado Data da instalação Local da instalação Origem da instalação É uma aplicação de 64bit Está protegido Está atualizado É válido Modificar caminho Nome do editor Nome abreviado do editor Desinstalação silenciosa é possível Sequência de desinstalação silenciosa Nome da chave do registro Caminho do registro É um componente do sistema Nome do arquivo do desinstalador Tipo de desinstalador A desinstalação é possível Sequência de desinstalação Comentário Ícone exibido Caminho inválido Confiança Tarefa da desinstalação interrompida prematuramente Ignorado pelo usuário Local do desinstalador Não existe uma maneira válida de desinstalar esta entrada Desinstalador retornou o código de erro: Mau Bom Duvidoso Desconhecido Muito bom Desinstalador de origem Most of the time used to show parent application of an update O nome da empresa não coincidiu O nome da empresa não correspondeu O diretório é usado por outros aplicativos instalados O item é explicitamente mencionado no desinstalador Entrada do registro do desinstalador O item parece ser uma categoria de editor integral O nome do produto não combinou muito bem Nome do produto combinou perfeitamente O nome do diretório é questionável Desconhecido Windows Installer Inno Setup Steam Nullsoft Scriptable Install System InstallShield SDBInst Concluído Falhou Inválido Protegido Ignorado Desinstalando Esperando O aplicativo está registrado Filtro inválido Novo filtro Sem correspondência Contém Termina com É igual a Regex Começa com Recurso do Windows Used to mark windows features on the uninstaller list Contém qualquer As in "matches any word from this string" Comandos de inicialização Eles não serão mais abertos durante a inicialização. Verifique se os itens selecionados não são necessários antes de removê-los. Remover programas selecionados da inicialização? Gerenciador de Inicialização Carregando... Pasta vazia Executáveis estão presentes Arquivos estão presentes Muitos arquivos estão presentes O nome do programa é reconhecido Não há subdiretórios O editor é reconhecido A entrada será executada apenas uma vez A entrada é compatível com o aplicativo Arquivos e diretórios Arquivo de programas órfão Registro Inicialização Falha ao habilitar essa entrada, o seguinte arquivo não foi encontrado: Desinstalador expirou Tarefa Fom Task Scheduler Objeto Auxiliar do Navegador O valor não pode ser nulo ou estar vazio O valor não pode conter linhas novas Chave(s) de registro de inicialização inválida ou desconhecida: Windows Store App Nova condição Não está registrado Present on the HDD but is not properly reported anywhere Remoção dos dados da App Store é problemática Eliminação Simples O diretório é, ou estará vazio após a remoção de lixo. Serviço Todas as propriedades Used in the search box to specify what's being compared Analisando produtos MSI instalados... Encontradas {0} aplicações GUID Escaneando o registro para desinstaladores... Reunindo as chaves do Registro Processando {0} Gerando informações de desinstalador em falta... Escaneando drives em busca de aplicativos... Reunindo diretórios Escaneando armazenagem de aplicativos... Procurando modelos de aplicativos Procurando aplicativos do Steam Procurando aplicativos da Windows Store Procurando por Recurss do Windows Combinando aplicações descobertas... Mesclando aplicações de lojas Mesclando aplicações das unidades Gerando informações em falta... Atualização do Windows Procurando atualizações do Windows Regra do Firewall Assistente do usuário Relatórios de erro do Windows Configurando scanners de lixo ... Terminando... Compatibilidade de aplicativos Classes CLSID Referência do desinstalador Localização do Instalador Atalho Configuração de política de áudio Registros de eventos Informação de rastreamento Lista de pastas instaladas Pausado Chocolatey Oculus Procurando por pacotes Chocolatey Desinstalar pelo Chocolatey Shown in junk results window Pode iniciar automaticamente Procurando por entradas de inicialização Procurando por Apps Oculus É um navegador Powershell script Configuração de Rastreio/Registro de Depuração Procurando por pacotes Scoop Pode pertencer a um app diferente com nome parecido For example `AppX Extended` matching `AppX` when it belongs to the AppX application ================================================ FILE: source/UninstallTools/Properties/Localisation.pt.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Página Web Código do produto Mostrar nome Mostrar nome abreviado Versão Tamanho estimado Data da instalação Localização da instalação Origem da instalação É uma aplicação de 64bit Está protegido Está actualizado Está válido Modificar o percurso Nome do editor Trimmed publisher name Desinstalação em segundo plano impossível Corrente da desinstalação em segundo plano Nome da chave do registo Percurso do registo É um componente do sistema Nome do ficheiro do desinstalador Tipo de desinstalador A desinstalação é possível Cadeia da desinstalação Comentário Ícone exibido Caminho inválido Confiança Tarefa da desinstalação interrompida prematuramente Ignorado pelo utilizador Localização do desinstalador Não existe uma maneira válida para desinstalar esta entrada Código de erro exibido pelo desinstalador: Mau Bom Duvidoso Desconhecido Muito bom Desinstalador semelhante Most of the time used to show parent application of an update O nome da empresa não coincide O nome da empresa corresponde O directório está a ser usado por outras aplicações instaladas O item está mencionado explicitamente no desinstalador Entrada do registo do desinstalador O elemento aparenta ser uma categoria completa de editor O nome do produto não corresponde muito bem O nome do produto coincide perfeitamente O nome do directório é duvidoso Desconhecido Instalador Windows Inicialização Inno Steam Nullsoft Scriptable Install System InstallShield SDBInst Completado Fracassou Inválido Protegido Ignorado Desinstalando Em espera A aplicação está registada Filtro inválido Novo filtro Sem correspondência Contém Termina com Equivale Regex Começa por Funcionalidade Windows Used to mark windows features on the uninstaller list Contém tudo As in "matches any word from this string" Comandos de inicialização Já não serão abertos durante o carregamento. Certifique-se de que os itens selecionados não serão necessários antes de os remover. Remover os programas seleccionados da inicialização? Gestor da inicialização A carregar... Pasta vazia Executables are present Estão presentes executáveis Estão presentes muitos ficheiros O nome do programa está reconhecido Não existem subdirectórios O editor está reconhecido A entrada correrá apenas uma vez A entrada corresponde à aplicação Arquivos de Programas órfãos Registo Inicialização Falha ao activar esta entrada, o arquivo seguinte não foi encontrado: O desinstalador ultrapassou o tempo Tarefa Fom Task Scheduler Objectivo do Navegador Auxiliar O valor não pode ser nulo ou estar vazio O valor não admite novas linhas Chave(s) do registo de inicialização inválida(s) ou desconhecida(s) Windows Store App Nova condição Encontra-se não registada Present on the HDD but is not properly reported anywhere Remoção dos dados App Store é problemática Excluir simplesmente Todas as propriedades Used in the search box to specify what's being compared Arquivos e Directórios O Directório está, ou estará, vazio após a eliminação do lixo residual. Serviço A analisar os produtos MSI instalados... Encontradas {0} aplicações GUID A analisar o registo de desinstalação ... Reunindo as chaves do registo A processar {0} A criar informações do desinstalador em falta... A analisar unidades para aplicações... A recolher Directórios A procurar lojas de aplicativos... A procurar modelos de aplicativos A procurar Aplicações de Steam Procurando por aplicações de Windows Store Procurando por funcionalidades do Windows Juntando aplicações encontradas Juntando aplicações das lojas Juntando aplicações das unidades A gerar informação em falta... Actualização do Windows Procurando por actualizações do Windows Pesquisa de itens de inicialização Chocolatey Oculus ================================================ FILE: source/UninstallTools/Properties/Localisation.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Webpage Product code Display name Trimmed display name Version Estimated size Date of installation Installation location Installation source Is a 64bit application Is protected Is an update Is valid Modify path Publisher name Trimmed publisher name Quiet uninstall is possible Quiet uninstall string Registry key name Registry path Is a system component Uninstaller file name Uninstaller type Uninstall is possible Uninstall string Comment Displayed icon Invalid path Confidence Uninstall worker stopped prematurely Skipped by user Uninstaller location There is no valid way of uninstalling this entry Uninstaller returned error code: Bad Good Questionable Unknown Very good Parent uninstaller Most of the time used to show parent application of an update Company name did not match Company name matched Directory is used by other installed applications Item is explicitly mentioned in the uninstaller Registry entry of the uninstaller Item seems to be a whole publisher category Product name did not match very well Product name matched perfectly Directory name is questionable Unknown Windows Installer Inno Setup Steam Nullsoft Scriptable Install System InstallShield SDBInst Completed Failed Invalid Protected Skipped Uninstalling Waiting Application is registered Invalid filter New filter No matches Contains Ends with Equals Regex Starts with Windows Feature Used to mark windows features on the uninstaller list Contains any As in "matches any word from this string" Startup commands They will no longer be opened during boot. Make sure the selected items are not required before removing them. Remove selected programs from startup? Startup Manager Loading... Empty folder Executables are present Files are present Many files are present Program name is recognized No sub directories Publisher is recognized Entry will be ran only once Entry is matched to the application Files and directories Program Files orphan Registry Startup Failed to enable this entry, the following file was not found: Uninstaller timed out Task Fom Task Scheduler Browser Helper Object Value cannot be null or empty Value cannot contain newlines Invalid or unknown startup registry key(s): Windows Store App New condition Is unregistered Present on the HDD but is not properly reported anywhere Removal of Store App data is problematic Simple Delete Directory is, or will be empty after removing junk. Service All properties Used in the search box to specify what's being compared Scanning installed MSI products... Found {0} application GUIDs Scanning registry for uninstallers... Gathering registry keys Processing {0} Generating missing uninstaller information... Scanning drives for applications... Gathering directories Scanning application stores... Searching for application templates Searching for Steam Apps Searching for Windows Store Apps Searching for Windows Features Merging discovered applications... Merging applications from stores Merging applications from drives Generating missing information... Windows Update Searching for Windows Updates Firewall rule User assist Windows Error Reporting reports Setting up junk scanners... Finishing up... Application compatibility CLSID classes Uninstaller reference Uninstaller location Shortcut Audio policy config Event Log logs Tracing information Installed folder list Paused Chocolatey Searching for Chocolatey packages Uninstall in Chocolatey Shown in junk results window Can start automatically Searching for start-up entries Searching for Oculus Apps Oculus Is a web browser PowerShell script Debug Tracing/Logging Configuration Searching for Scoop packages Might belong to a different app with a similar name For example `AppX Extended` matching `AppX` when it belongs to the AppX application Located directly inside a Known Folder ================================================ FILE: source/UninstallTools/Properties/Localisation.ru.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Официальный сайт Код продукта Название Короткое имя Версия Ожидаемый размер Дата установки Место установки Источник установки 64-бит Защищен Обновление Действителен Изменить путь Имя издателя Короткое имя издателя Тихое удаление Команда тихого удаления Имя ключа реестра Путь реестра Системный компонент Имя деинсталлятора Тип деинсталлятора Удаление возможно Команда удаления Комментарий Иконка Недопустимый путь Уверенность Удаление прервано Пропущено пользователем Путь деинсталлятора Недействительный метод удаления Деинсталлятор возвратил ошибку: Плохо Хорошо Сомнительно Неизвестно Очень хорошо Родительское приложение Most of the time used to show parent application of an update Имя компании не соответствует Имя компании соответствует Каталог установки используется другими приложениями Элемент прямо упоминается в деинсталляторе Запись реестра деинсталлятора Элемент кажется соответствующим издателю Имя продукта не совсем соответствует Имя продукта полностью соответствует Имя каталога сомнительно Неизвестно Windows Installer Inno Setup Steam Nullsoft Scriptable Install System InstallShield SDBInst Завершено Не удалось Недопустимый Защищённый Пропущен Деинсталляция Ждите Зарегистрировано Недопустимый фильтр Новый фильтр Нет совпадений Содержит Заканчивается Равно Регулярное выражение Начинается с Компонент Windows Used to mark windows features on the uninstaller list Любое из As in "matches any word from this string" Команда запуска Они больше не будут стартовать при запуске системы. Убедитесь, что выбранные элементы не обязательные перед их удалением. Удалить выбранные программы из автозагрузки? Менеджер автозагрузки Загрузка... Пустая папка Исполняемые файлы присутствуют Файлы присутствуют Многие файлы присутствуют Имя программы проверено Нет вложенных папок Издатель проверен Будет запущено один раз Запись соответствует приложению Остатки в Program Files Реестр Автозагрузка Не удалось включить эту запись, следующий файл не был обнаружен: Истекло время удаления Задача планировщика Fom Task Scheduler Вспомогательный объект браузера Значение не может быть нулевым или пустым Значение не может содержать символ новой строки Неверный или неизвестный ключ реестра: Приложение Windows Новое состояние Незарегистрированный Present on the HDD but is not properly reported anywhere Удаление приложений магазина является проблематичным Простое удаление Все свойства Used in the search box to specify what's being compared Файлы и папки Папка уже или будет пуста после удаления мусора. Служба Сканирование установленных MSI... Найдено {0} GUID приложений Сканирование реестра на деинсталляторы... Сбор ключей реестра Обработка {0} Создание инфо об отсутствующем деинсталляторе... Сканирование дисков на приложения... Сбор каталогов Сканирование приложений... Поиск шаблонов приложений Поиск Steam приложений Поиск приложений Windows Store Поиск компонентов Windows Слияние обнаруженных приложений... Слияние приложений магазина Слияние приложений с дисков Создание недостающей информации... Обновления Windows Поиск обновлений Windows Правило файрвола Помощник пользователя Отчёты об ошибках Windows Настройка сканеров мусора... Заканчиваю... Совместимость приложений Классы CLSID Ссылка на удаление Расположение деинсталлятора Ярлык Конфигурация звуковой политики Журналы событий Информация о трассировке Список папок установки Пауза Поиск загрузочных записей Chocolatey Oculus Поиск пакетов Chocolatey Удалить в Chocolatey Shown in junk results window Возможен автозапуск Поиск приложений Oculus Является ли веб-браузером Скрипт PowerShell Поиск пакетов Scoop Может принадлежать другому приложению с похожим названием For example `AppX Extended` matching `AppX` when it belongs to the AppX application ================================================ FILE: source/UninstallTools/Properties/Localisation.sl.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Spletna stran Koda izdelka Prikazno ime Skrajšano prikazno ime Različica Ocenjena velikost Datum namestitve Mesto namestitve Vir namestitve Je 64 bitna aplikacija Je zaščitena Je posodobljena Je veljavna Spremeni pot Ime založnika Obrezano ime založnika Možna je tiha odstranitev Niz tihe odstranitve Ime registrskega ključa Pot v registru Je sistemska sestavina Ime datoteke odstranjevalca Vrsta odstranjevalca Možno je odstranjevanje Odstranjevalni niz Komentar Prikazana ikona Neveljavna pot Zaupanje Predčasno ustavljeno delo odstranjevalca Preskočil je uporabnik Mesto odstranjevalca Za odstranjevanje tega vnosa, tukaj ni veljavnega načina Odstranjevalec je vrnil kodo napake: Slabo Dobro Vprašljivo Neznano Zelo dobro Nadrejeni odstranjevalec Most of the time used to show parent application of an update Ime podjetja se ni ujemalo Ime podjetja se je ujemalo Imenik je uporabljen z drugimi, nameščenimi aplikacijami Vnos je izrecno naveden v odstranjevalcu Registrski vnos odstranjevalca Videti je, da je niz celotna kategorija založnika Ime izdelka se zelo dobro ne ujema Ime izdelka se popolnoma ujema Vprašljivo je ime imenika Neznano Windows namestitveni program Inno Setup Steam Nullsoft Scriptable Install System InstallShield SDBInst Zaključeno Spodletelo Neveljavno Zaščiteno Preskočeno Odstranjevanje Čakanje Aplikacija je registrirana Neveljaven filter Nov filter Ni ujemanja Vsebuje Konča z Enako Regex Začne z Windows funkcija Used to mark windows features on the uninstaller list Vsebuje karkoli As in "matches any word from this string" Zagonski ukazi Ne bodo več odprti med zagonom sistema. Preden jih odstranite se prepričajte, da izbrani vnosi niso potrebni. Ob zagonu, naj odstranim izbrane programe? Upravitelj zagona Nalaganje... Prazna mapa Prisotne so izvršljive datoteke Prisotne so datoteke Prisotnih je veliko datotek Ime programa je prepoznano Ni podimenikov Založnik je prepoznan Vnos bo zagnan samo enkrat Vnos se ujema z aplikacijo Sirota programskih datotek Register Zagon Spodletelo je omogočanje tega vnosa. Naslednja datoteka ni bila najdena: Odstranjevalec je potekel Opravilo Fom Task Scheduler Pomožni predmet brskalnika (BHO) Vrednost ne sme niti null ali prazna Vrednost ne sme vsebovati novih vrstic Je neregistriran Present on the HDD but is not properly reported anywhere Neveljavni ali neznani zagonski ključi v registru: Windows Store Aplikacija Nov pogoj Odstranitev Store Aplikacije je problematično Preprosto izbriši Datoteke in imeniki Imenik je ali bo prazen po odstranjevanju odpadkov. Storitev Vse lastnosti Used in the search box to specify what's being compared Pregledovanje nameščenih izdelkov MSI ... Najdeno {0} GUIDov aplikacije Pregled registra za iskanje odstranjevalcev... Zbiranjev ključev registra Obdelava {0} Ustvarjanje manjkajočih informacij o odstranjevalcu... Pregled pogonov za iskanje aplikacij... Zbiranje imenikov Iskanje shranjenih aplikacij ... Iskanje predlog za aplikacijo Iskanje Steam Apps Iskanje Windows Store Apps Iskanje funkcij sistema Windows Združevanje odkritih aplikacij ... Združevanje aplikacij iz trgovin Združevanje aplikacij iz pogonov Ustvarjanje manjkajočih podatkov... Posodobitev Windows Iskanje posodobitev Windows Pravilo požarnega zidu Pomoč uporabnikom Poročila o poročanju o napakah v sistemu Windows Nastavitev iskalnikov smetja... Dokončanje... Združljivost aplikacije CLSID razredi Priporočilo odstranjevalca Mesto odstranjevalca Bližnjica Konfiguracija zvočnih politik Dnevniki dnevnika dogodkov Podatki o sledenju Pavzirano Seznam nameščenih map Iskanje zagonskih vnosov Chocolatey Oculus Iskanje Chocolatey paketov Odstrani v Chocolatey Shown in junk results window Lahko se zažene samodejno Oculus aplikacije Je spletni brskalnik PowerShell skripta ================================================ FILE: source/UninstallTools/Properties/Localisation.sv.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Webbsida Produktkod Visningsnamn Kort visningsnamn Version Uppskattad storlek Installationsdatum Installationsplats Installationskälla Är en 64-bitars app Är skyddad Är en uppdatering Är giltig Ändra sökväg Utgivarens namn Kort förlagsnamn Tyst avinstallation möjlig Tyst avinstallations-sträng Registernyckel Register sökväg Är en systemkomponent Avinstallation filnamn Avinstallationstyp Avinstallation möjlig Avinstallations-sträng Kommentar Visad ikon Ogiltig sökväg Tillförlitlighet Avinstallationsarbetaren stoppades i förtid Överhoppad av användaren Avinstallationsplats Det finns inget giltigt sätt att avinstallera denna post Avinstallationsprogrammet returnerade felkod: Dålig God Tveksam Okänd Väldigt god Förälder avinstallationsprogram Most of the time used to show parent application of an update Företagsnamn matchade inte Företagsnamn matchade Katalogen används av andra installerade appar Objektet är uttryckligen nämnt i avinstallationsprogrammet Registerpost för avinstallationsprogrammet Objektet verkar vara en hel förlagskategori Produktnamnet matchade inte så bra Produktnamnet matchade perfekt Katalognamnet är tveksamt Okänd Windows Installer Inno Setup Steam Nullsoft Scriptable Install System InstallShield SDBInst Slutförd Misslyckad Ogiltig Skyddad Överhoppad Avinstallerar Väntar Appen är registrerad Ogiltigt filter Nytt filter Inga matchningar Innehåller Slutar med Är lika med Regex Börjar med Windowsfunktion Used to mark windows features on the uninstaller list Innehåller något av As in "matches any word from this string" Startkommandon De kommer inte längre att öppnas under uppstart. Se till att de valda objekten inte krävs innan du tar bort dem. Ta bort valda program från uppstarten? Uppstartshanterare Laddar... Tom mapp Exekverbara filer finns tillgängliga. Filer finns Många filer finns Programnamnet är känt. Inga underkataloger. Utgivaren är identifierad. Posten kommer endast att köras en gång. Posten är kopplad till applikationen. Filer och mappar Programfiler utan överordnad. Register Uppstart Det gick inte att aktivera denna post, följande fil hittades inte: Avinstallationsprogrammet svarade inte. Uppgift Fom Task Scheduler Webbläsarhjälpobjekt Värde kan inte vara null eller tomt Värde kan inte innehålla radbrytningar Ogiltig eller okänd uppstarts-registernyckel Windows Store App Ny villkor Är oregistrerad Present on the HDD but is not properly reported anywhere Borttagning av Store App data är problematiskt Enkel Radering Mappen är, eller blir tom efter borttagning av skräp. Tjänst Alla egenskaper Used in the search box to specify what's being compared Scannar installerade MSI produkter... Hittade {0} app GUIDs Scanna registret efter avinstallationsprogram... Samlar registernycklar Bearbetar {0} Genererar saknad avinstallations-info Scannar enheter efter appar... Samlar kataloger Scannar app-stores Söker efter applikationsmallar. Söker efter Steam Appar Söker efter Windows Store Apps Söker efter Windows-funktioner Sammanfogar upptäckta appar… Sammanfogar appar från Stores Sammanfogar appar från enheter Generar saknad information... Windows Update Söker efter Windows Updates Brandväggsregel Användar-assistans Windows felrapporterings-rapporter Konfigurerar skräp-skannrar… Avslutar… App kompatibilitet CLSID klasser Referens för avinstallationsprogrammet Plats för avinstallationsprogrammet Genväg Ljudpolicy konfiguration Händelseloggar Spårnings-information Installationsmapp-lista Pausad Chocolatey Söker efter Chocolatey paket Avinstallera i Chocolatey Shown in junk results window Kan starta automatiskt Söker efter uppstarts-poster Söker efter Oculus Apps Oculus Är en webbläsare PowerShell script Debug Spårning/Loggning Konfiguration Söker efter Scoop paket Kanske tillhör en annan app med liknande namn For example `AppX Extended` matching `AppX` when it belongs to the AppX application ================================================ FILE: source/UninstallTools/Properties/Localisation.tr.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 İnternet sayfası Ürün kodu Görüntülenen ad Kesilmiş görünen ad Versiyon Tahmini boyut Kurulum tarihi Kurulum yeri Kurulum kaynağı 64 bit uygulama Korunuyor Bir güncelleme Geçerli Düzenleme yolu Yayıncı adı Kesilmiş yayıncı adı Sessiz kaldırma mümkün Sessiz kaldırma dizesi Kayıt defteri anahtarı adı Kayıt defteri yolu Bir sistem bileşeni mi Kaldırıcı dosya adı Kaldırıcı türü Kaldırma mümkündür Uninstall string Yorum Yap Görüntülenen simge Geçersiz yol Güven Kaldırma erken durduruldu Kullanıcı tarafından atlandı Kaldırıcı konumu Bu girişi kaldırmanın geçerli bir yolu yok Kaldırıcı hata kodu döndürdü: Kötü İyi Kuşkulu Bilinmeyen Çok iyi Ebeveyn kaldırıcı Most of the time used to show parent application of an update Şirket adı eşleşmedi Şirket adı eşleşti Dizin diğer yüklü uygulamalar tarafından kullanılır Öğe, kaldırıcıda açıkça belirtilmiştir Kaldırıcı kayıt defteri girişi Öğe, bir yayıncı kategorisi gibi görünüyor Ürün adı çok iyi uyuşmuyor Ürün adı mükemmel bir şekilde eşleşti Dizin adı sorgulanabilir Bilinmeyen Windows yükleyici Inno Kurulumu Steam Nullsoft Scriptable Yükleme Sistemi InstallShield SDBInst Tamamlandı Başarısız oldu Geçersiz Korumalı Atlandı Kaldırılıyor Bekleniyor Uygulama kayıtlı Geçersiz filtre Yeni filtre Eşleşme yok İçeren İle biten Eşittir Düzenli ifade İle başlar Windows Özelliği Used to mark windows features on the uninstaller list Herhangi biri As in "matches any word from this string" Başlangıç komutları Artık önyükleme sırasında açılmayacaklar. Çıkarmadan önce seçilen öğelerin gerekli olmadığından emin olun. Seçilen programlar başlangıçtan kaldırılsın mı? Başlangıç Yöneticisi Yükleniyor... Boş klasör Yürütülebilir dosyalar mevcut Dosyalar mevcut Birçok dosya mevcut Program adı doğrulandı Alt klasör yok Yayıncı Doğrulandı Bir kez başlatılacak Giriş uygulama ile eşleşti Dosyalar ve dizinler Program dosyalarında kalır Kayıt defteri Başlangıç Bu giriş etkinleştirilemedi, aşağıdaki dosya bulunamadı: Kaldırıcı zaman aşımına uğradı Görev Fom Task Scheduler Tarayıcı Yardımcı Nesnesi Değer, içeriksiz veya boş olamaz Değer yeni satırlar içeremez Geçersiz veya bilinmeyen başlangıç kayıt defteri anahtar(ları)ı: Windows Mağazası Uygulaması Yeni durum Kayıtsız Present on the HDD but is not properly reported anywhere Mağaza Uygulama verilerinin kaldırılması sorunludur Basit Sil Dizin gereksiz veya kaldırıldıktan sonra boş olacaktır. Servis Tüm özellikler Used in the search box to specify what's being compared Yüklü MSI ürünleri taranıyor... {0} uygulama GUID'si bulundu Kaldırma amaçlı yüklemeler için kayıt tarama ... Kayıt defteri anahtarlarını toplanıyor {0} işleniyor Eksik kaldırıcı bilgileri oluşturuluyor ... Uygulamalar için sürücüler taranıyor ... Dizinler toplanıyor Tarama uygulamaları depolanıyor ... Uygulama şablonları aranıyor Steam Uygulamaları Aranıyor Windows Mağazası Uygulamaları aranıyor Windows Özellikleri aranıyor Keşfedilen uygulamalar birleştiriliyor... Uygulamaları mağazalardan birleştirme Uygulamaları sürücülerden birleştirme Kayıp bilgileri üretiliyor Windows Güncelleme Windows Güncellemeleri aranıyor Güvenlik duvarı kuralı Kullanıcı yardımı Windows Hata Bildirimi raporları Önemsiz tarayıcıların ayarlanması ... Bitiriliyor... Uygulama uyumluluğu CLSID sınıfları Kaldırıcı referansı Kaldırıcı konumu Kısayol Ses politikası yapılandırması Olay Günlüğü günlükleri İzleme bilgileri Yüklü klasör listesi Durduruldu Chocolatey Chocolatey paketleri aranıyor Chocolatey ile kaldır Shown in junk results window Otomatik olarak başlayabilir Başlangıç girişleri aranıyor Oculus Uygulamaları Oculus Bir web tarayıcısı mı PowerShell betiği Hata Ayıklama İzleme/Günlüğe Kaydetme Yapılandırması Scoop paketleri aranıyor Benzer isimli farklı bir uygulamaya ait olabilir For example `AppX Extended` matching `AppX` when it belongs to the AppX application ================================================ FILE: source/UninstallTools/Properties/Localisation.vi.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Trang web Mã sản phẩm Tên hiển thị Tên hiển thị được rút gọn Phiên bản Kích thước ước tính Ngày cài đặt Vị trí cài đặt Nguồn cài đặt Ứng dụng 64bit Được bảo vệ Một ứng dụng cập nhật Hợp lệ Sửa đổi đường dẫn Tên nhà phát hành Tên rút gọn của nhà phát hành Có thể gỡ cài đặt âm thầm Câu lệnh gỡ cài đặt âm thầm Tên khoá registry Đường dẫn registry Một thành phần hệ thống Tên tệp trình gỡ cài đặt Loại trình gỡ cài đặt Có thể gỡ cài đặt Câu lệnh gỡ cài đặt Chú thích Biểu tượng hiển thị Đường dẫn không hợp lệ Độ tin cậy Tiến trình gỡ cài đặt đã dừng đột ngột Bị người dùng bỏ qua Vị trí trình cài đặt Không có cách hợp lệ nào để gỡ cài đặt mục này. Trình gỡ cài đặt trả về mã lỗi: Kém Tốt Rất đáng nghi Không xác định Rất tốt Trình gỡ cài đặt gốc Most of the time used to show parent application of an update Tên công ty không khớp Tên công ty trùng khớp Thư mục đang được sử dụng bởi một ứng dụng khác Mục được đề cập rõ ràng trong trình gỡ cài đặt Mục registry của trình gỡ cài đặt Mục này dường như là toàn bộ danh mục của nhà xuất bản Tên sản phẩm không khớp lắm Tên sản phẩm trùng khớp hoàn toàn Tên thư mục rất đáng ngờ Không xác định Trình gỡ cài đặt Windows Inno Setup Steam Nullsoft Scriptable Install System InstallShield SDBInst Đã hoàn thành Thất bại Không hợp lệ Được bảo vệ Đã bỏ qua Đang gỡ cài đặt Đang chờ Ứng dụng đã đăng ký Bộ lọc không hợp lệ Bộ lọc mới Không trùng khớp Chứa tất cả ký tự Kết thúc bằng Giống hệt Regex Bắt đầu bằng Windows Feature Used to mark windows features on the uninstaller list Chứa bất kỳ ký tự As in "matches any word from this string" Câu lệnh khởi động cùng hệ thống Các mục đã chọn sẽ không còn được mở tự động trong quá trình khởi động. Hãy đảm bảo các mục này không cần thiết trước khi xóa chúng. Loại bỏ các chương trình đã chọn khỏi quá trình khởi động cùng hệ thống? Trình quản lý Khởi động cùng hệ thống Đang nạp... Thư mục trống Các tệp thực thi hiện có Các tệp hiện có Rất nhiều tệp tin hiện có Tên chương trình được công nhận Không có thư mục con Nhà phát hành được công nhận Mục nhập chỉ được thực thi một lần Mục nhập trùng khớp với ứng dụng Các tệp và thư mục Các tệp chương trình mồ côi Registry Khởi động cùng hệ thống Không thể kích hoạt mục này, các tệp sau không được tìm thấy: Trình gỡ cài đặt đã hết thời gian chờ Tác vụ Fom Task Scheduler Đối tượng Trợ giúp Trình duyệt Giá trị không thể là NULL hoặc bỏ trống. Giá trị không thể chứa ký tự thoát dòng mới (\n) (Các) khóa registry khởi động cùng hệ thống không hợp lệ hoặc không xác định: Windows Store App Điều kiện mới Chưa đăng ký Present on the HDD but is not properly reported anywhere Việc xóa dữ liệu Store App có vấn đề Xoá đơn giản Thư mục trống hoặc vẫn trống ngay cả sau khi loại bỏ rác. Dịch vụ Tất cả thuộc tính Used in the search box to specify what's being compared Đang quét các sản phẩm MSI đã cài đặt... Đã tìm thấy {0} GUID ứng dụng Đang quét registry để tìm các trình gỡ cài đặt... Đang thu thập các khoá registry... Đang quét {0} Đang tạo thông tin trình gỡ cài đặt bị thiếu... Đang quét ổ đĩa để tìm các ứng dụng... Đang thu thập thư mục... Đang quét các kho ứng dụng... Đang tìm kiếm các mẫu ứng dụng... Đang kiểm tra Steam App... Đang kiểm tra Windows Store App... Đang kiểm tra Windows Features... Đang hợp nhất các ứng dụng được phát hiện... Đang hợp nhất các ứng dụng từ các kho ứng dụng... Đang hợp nhất các ứng dụng từ các ổ đĩa... Đang tạo thông tin còn thiếu... Windows Update Đang kiểm tra Windows Update... Quy tắc tường lửa Khả năng tiếp cận Báo cáo lỗi Windows Đang thiết lập máy quét rác... Sắp hoàn thành... Khả năng tương thích ứng dụng Lớp CLSID Tài liệu tham khảo về trình gỡ cài đặt Vị trí trình gỡ cài đặt Lối tắt Cấu hình chính sách âm thanh Nhật ký sự kiện Thông tin truy vết Danh sách thư mục cài đặt Chocolatey Tạm dừng Tìm kiểm tra các gói Chocolatey... Gỡ cài đặt bằng Chocolatey Shown in junk results window Có thể tự động khởi động Đang kiểm tra các mục khởi động cùng hệ thống... Đang kiểm tra Oculus App... Oculus Một trình duyệt Tập lệnh PowerShell Đang kiểm tra các gói Scoop... Cấu hình theo dõi/ghi nhật ký gỡ lỗi Có thể thuộc về một ứng dụng khác có tên tương tự For example `AppX Extended` matching `AppX` when it belongs to the AppX application ================================================ FILE: source/UninstallTools/Properties/Localisation.zh-Hans.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 网页 产品代码 显示名 修饰后的显示名 版本 估计大小 安装日期 安装位置 安装源 是否64位应用程序 是否受保护 是否更新 是否有效 修改路径 发布者名称 修饰后的发布者名称 能否静默卸载 静默卸载字母串 注册表键名称 注册表路径 是否系统组件 卸载程序文件名 卸载程序类型 能否卸载 卸载字符串 注释 显示图标 无效路径 置信度 卸载进程过早停止 被用户跳过 卸载程序位置 没有有效的方法卸载此条目 卸载应用程序返回错误代码: 有问题 未知 非常好 母卸载程序 Most of the time used to show parent application of an update 公司名不匹配 公司名匹配 目录被其他已安装应用程序使用 项目在卸载程序中明确提到 卸载程序的注册表项 项目似乎是一个完整的发布者类别 产品名称不完全匹配 产品名称完全匹配 目录名称有问题 未知 Windows Installer Inno Setup Steam Nullsoft Scriptable Install System InstallShield SDBInst 已完成 失败 无效 受保护 已跳过 卸载中 等待中 应用程序已注册 无效的筛选器 新筛选器 没有匹配 包含 结尾是 完全相同 正则表达式 开头是 Windows特性 Used to mark windows features on the uninstaller list 包含任一个 As in "matches any word from this string" 启动命令 它们开机时不再启动。在删除前请确保选中项不再需要。 从开机启动项中删除选中程序? 开机启动项管理器 加载中... 空文件夹 存在可执行文件 文件存在 许多文件存在 识别到程序名称 无子目录 识别到发布者 条目只会运行一次 条目与应用程序匹配 文件和目录 孤立程序文件 注册表 开机启动项 启用此条目失败,找不到以下文件: 卸载程序超时 任务 Fom Task Scheduler 浏览器辅助对象(BHO) 值不能为null或empty 值不能包含新行 无效或未知开机启动项注册表键: Windows商店应用 New condition 未注册 Present on the HDD but is not properly reported anywhere 删除应用商店数据时有问题 简单删除 目录为空,或在删除垃圾后将为空。 服务 所有属性 Used in the search box to specify what's being compared 扫描已安装MSI产品... 查找{0}应用程序全局唯一标识符(GUID) 扫描注册表以查找卸载程序... 正在收集注册表键 正在处理{0} 正在生成丢失的卸载程序信息... 正在扫描驱动器以查找应用程序... 正在收集目录 正在扫描应用程序商店... 正在搜索应用程序模板 正在搜索Steam应用程序 正在搜索Windows商店应用 正在搜索Windows功能 正在合并发现的应用程序... 正在合并商店应用程序 正在合并驱动器上的应用程序 正在生成丢失的信息... Windows更新 正在搜索Windows更新 防火墙规则 用户助手 Windows错误报告 正在设置垃圾扫描器... 正在完成... 应用程序兼容性 CLSID类 卸载程序引用 卸载程序未知 快捷方式 音频策略配置 事件日志 跟踪信息 安装文件夹列表 暂停 Chocolatey 正在搜索Chocolatey包 在Chocolatey中卸载 Shown in junk results window 是否能自动启动 正在搜索开机启动项 正在搜索Oculus应用程序 Oculus 是否网页浏览器 PowerShell脚本 调试跟踪/日志配置 正在搜索Scoop包 可能属于名称相似的其他应用程序 For example `AppX Extended` matching `AppX` when it belongs to the AppX application ================================================ FILE: source/UninstallTools/Properties/Localisation.zh-Hant.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 網頁 產品代碼 顯示名稱 修飾後的顯示名稱 版本 預估大小 安裝日期 安裝位置 安裝來源 是否為64位元應用程式 是否受保護 是否更新 是否有效 修改路徑 發布人員名稱 修飾後的發布人員名稱 能否最小化移除 最小化移除字串 註冊表鍵名稱 註冊表路徑 是否為系統元件 移除程式檔案名稱 移除程式類型 能否移除 移除字串 註飾 顯示圖示 無效路徑 信任度 移除程序提前停止 被使用者跳過 移除程式位置 沒有有效的方法移除此項目 移除程式返回錯誤代碼: 有問題 未知 非常好 母移除程式 Most of the time used to show parent application of an update 公司不相同 公司相同 目錄已被其他已安裝應用程式使用 項目於移除程式中提醒 移除程式的註冊表項目 項目似乎是一個完整的發布人員類別 產品名稱完全不相同 產品名稱相同 目錄名稱有問題 未知 Windows Installer Inno Setup Steam Nullsoft Scriptable Install System InstallShield SDBInst 已完成 失敗 無效 受保護 已略過 移除中 等待中 應用程式已註冊 無效的選項 新尋找 沒有找到 包含 结尾是 完全相同 開始是 Windows特性 Used to mark windows features on the uninstaller list 包含任一個 As in "matches any word from this string" 啟動指令 它們於開機時不再執行。在刪除前確認選中項目不再需要 從開機啟動項目中刪除選中程序? 開機啟動項目管理員 載入中 空資料夾 存在可執行檔案 檔案存在 許多檔案存在 識別到程式名稱 沒有子目錄 識別到發布人員 項目只會執行一次 項目與應用程式相同 資料和目錄 獨立程式文件 註冊表 開機啟動項目 啟用此項目失敗,找不到以下檔案: 移除程式逾時 任務 Fom Task Scheduler 瀏覽器輔助對象(BHO) 不能為空值或Null 不能包含新行 無效或未知的開機啟動項目註冊表鍵: Windows商店應用程式 新條件 未註冊 Present on the HDD but is not properly reported anywhere 刪除商店應用程式資料時有問題 簡單刪除 為空目錄,或在刪除垃圾後是空目錄 服務 所有屬性 Used in the search box to specify what's being compared 掃瞄已安裝的MSI產品 尋找應用程式GUID 掃描註冊表以尋找移除程式... 正在收集註冊表鍵 正在處理{0} 正在產生遺失的移除程式資訊... 正在掃描硬碟以尋找應用程式... 正在收集目錄 正在掃描應用程式商店... 正在尋找應用程式模板 正在尋找Steam應用程式 正在尋找Windows商店應用程式 正在尋找Windows功能 正在合併發現的應用程式 正在合併商店應用程式 正在合併硬碟上的應用程式 正在產生遺失的資訊 Windows更新 正在尋找Windows更新 防火牆規則 使用者幫手 Windows錯誤報告 正在設定垃圾掃描... 正在完成... 應用程式相容性 CLSID類別 應用程式參照 移除程式位置 捷徑 音頻政策配置 事件日誌 跟蹤資訊 安裝資料夾清單 暫停 Chocolatey 正在尋找Chocolatey包 在Chocolatey中移除 Shown in junk results window 是否能自動啟動 正在尋找開機啟動項目 正在尋找Oculus應用程式 Oculus 是否為網頁瀏覽器 PowerShell腳本 測試跟蹤/日誌設置 正在尋找Scoop包 可能屬於名稱相似的其他應用程式 For example `AppX Extended` matching `AppX` when it belongs to the AppX application Regex 直接從已知的資料夾裡面尋找 ================================================ FILE: source/UninstallTools/Properties/Resources.Designer.cs ================================================ //------------------------------------------------------------------------------ // // This code was generated by a tool. // Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ namespace UninstallTools.Properties { using System; /// /// A strongly-typed resource class, for looking up localized strings, etc. /// // This class was auto-generated by the StronglyTypedResourceBuilder // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { private static global::System.Resources.ResourceManager resourceMan; private static global::System.Globalization.CultureInfo resourceCulture; [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] internal Resources() { } /// /// Returns the cached ResourceManager instance used by this class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("UninstallTools.Properties.Resources", typeof(Resources).Assembly); resourceMan = temp; } return resourceMan; } } /// /// Overrides the current thread's CurrentUICulture property for all /// resource lookups using this strongly typed resource class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Globalization.CultureInfo Culture { get { return resourceCulture; } set { resourceCulture = value; } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap add { get { object obj = ResourceManager.GetObject("add", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap app { get { object obj = ResourceManager.GetObject("app", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap arrow_right { get { object obj = ResourceManager.GetObject("arrow.right", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap delete { get { object obj = ResourceManager.GetObject("delete", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap folder_open { get { object obj = ResourceManager.GetObject("folder.open", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap link { get { object obj = ResourceManager.GetObject("link", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap minus { get { object obj = ResourceManager.GetObject("minus", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap page_copy { get { object obj = ResourceManager.GetObject("page.copy", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap page_duplicate { get { object obj = ResourceManager.GetObject("page.duplicate", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } } } ================================================ FILE: source/UninstallTools/Properties/Resources.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ..\Resources\folder.open.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\link.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\page.copy.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\arrow.right.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\delete.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\app.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\page.duplicate.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\add.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\minus.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ================================================ FILE: source/UninstallTools/SimplifiedClassDiagram.cd ================================================  EAAAAACAAAAAAAAAAICAAAAAAAAABQAAAAIAAAAAAAA= Junk\JunkManager.cs AAAAAABAAAAAEAAAAAABAAAACAAAAAQAAAIAAAAAAAA= Factory\ApplicationUninstallerFactory.cs JgAAAgAAAAAAAAAAAAAAAAAAAAAAARAAAhAAAMAAAAA= Factory\InfoAdders\InfoAdderManager.cs AAAAAAAAAACAAAAEAkCABgAgAAUAQAAACAEABAACABA= Startup\StartupEntryBase.cs AAAAAAAAAAAAAAABEAAAAAIEAAAAAAAAAAAAAAAAAAA= Startup\StartupManager.cs AAAAAAAAAABAAAAAAAADAAAAAIAAAAAAAAAAAAgAAAA= Uninstaller\BulkUninstallConfiguration.cs Uninstaller\BulkUninstallEntry.cs Uninstaller\BulkUninstallEntry.cs Uninstaller\BulkUninstallEntry.cs AIAiAAAgCAAAlAACBBQAQgAIaAAAEAAgAICAgAgAwAA= Uninstaller\BulkUninstallEntry.cs gAAAAAAAACAAAMgChB0AAACAACAAABAAgAAgCAAABoI= Uninstaller\BulkUninstallTask.cs AgAAIAAAABAAAAAAAAAAAgAAAAAAAAAAEAAAQAAIggA= Uninstaller\UninstallManager.cs CBAwUYoEAQhOIMAMLAgwYHQEwAQAViaEUMNBwEgBAEA= ApplicationUninstallerEntry.cs AAAAAAAACAAAAAAAAAAAAAAAACAABAAAAAAAAAAAAAA= Junk\IJunkCreator.cs AgAAAAAAAhAAIAABAAAAAAAAAIUAAAAAAAAAAAAAAAA= Junk\Containers\IJunkResult.cs AAAAEAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAA= Factory\IUninstallerFactory.cs AAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= Factory\IUninstallerFactory.cs AAAAAAAAAAAAAAAEAAAAAAAAAAAAABEQAABAAAEAAAA= Factory\InfoAdders\IMissingInfoAdder.cs AAAAAAAAEAgAAAABAAAAAAAAAAAAAAAAAAAAAAAAABE= Junk\Confidence\ConfidenceLevel.cs CAAAAAAAAAAAAAAAEAAAAAAAAAgIAAAAAAAAAAAAAAA= Factory\InfoAdders\InfoAdderPriority.cs AAAgAAAAEAAAAAIAAAEAAQAAAAAAAAAAABAAQAABAAA= Uninstaller\UninstallStatus.cs AABACCAAEAFACAAEIAAAAAAAADAAAwAAAAAAAAAAABA= UninstallerType.cs ================================================ FILE: source/UninstallTools/Startup/Browser/BrowserEntryFactory.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Diagnostics; using Klocman.Extensions; using Klocman.Tools; using Microsoft.Win32; namespace UninstallTools.Startup.Browser { public static class BrowserEntryFactory { internal const string AutorunsDisabledKeyName = "AutorunsDisabled"; private static readonly string[] RegistryStartupPoints = { @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Browser Helper Objects", @"HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\explorer\Browser Helper Objects" }; private static readonly string ClsidPath = @"HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID"; public static IEnumerable GetBrowserHelpers() { using (var clsidKey = RegistryTools.OpenRegistryKey(ClsidPath)) { foreach (var registryStartupPoint in RegistryStartupPoints) { RegistryKey mainKey; try { mainKey = RegistryTools.CreateSubKeyRecursively(registryStartupPoint); } catch (UnauthorizedAccessException e) { Trace.WriteLine($"Failed to read reg key {registryStartupPoint}: " + e); continue; } using (mainKey) { foreach (var browserHelperEntry in GatherBrowserHelpersFromKey(mainKey, clsidKey, registryStartupPoint, false)) yield return browserHelperEntry; using (var disabledKey = mainKey.OpenSubKey(AutorunsDisabledKeyName)) { if (disabledKey == null) continue; foreach (var browserHelperEntry in GatherBrowserHelpersFromKey(disabledKey, clsidKey, registryStartupPoint, true)) yield return browserHelperEntry; } } } } } private static IEnumerable GatherBrowserHelpersFromKey(RegistryKey workingKey, RegistryKey clsidKey, string registryStartupPoint, bool disabled) { foreach (var registryKey in workingKey.GetSubKeyNames()) { using (var classKey = clsidKey.OpenSubKey(registryKey)) { var name = classKey?.GetStringSafe(null); if (string.IsNullOrEmpty(name)) continue; string command; using (var runKey = classKey.OpenSubKey("InProcServer32") ?? classKey.OpenSubKey("InProcServer")) { command = runKey?.GetStringSafe(null); } yield return new BrowserHelperEntry(name, command, registryStartupPoint, registryKey, disabled, workingKey.Name.Contains("Wow6432Node")); } } } } } ================================================ FILE: source/UninstallTools/Startup/Browser/BrowserHelperEntry.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System.IO; using System.Linq; using Klocman.Tools; using UninstallTools.Properties; namespace UninstallTools.Startup.Browser { public sealed class BrowserHelperEntry : StartupEntryBase { private bool _disabled; public BrowserHelperEntry(string programName, string command, string parentKeyPath, string className, bool disabled, bool isWow) { ProgramName = programName; Command = command; ParentLongName = parentKeyPath; EntryLongName = className; _disabled = disabled; IsWow = isWow; CommandFilePath = ProcessCommandString(Command); if(CommandFilePath != null) FillInformationFromFile(CommandFilePath); } private bool IsWow { get; } public override bool Disabled { get { return _disabled; } set { if (_disabled == value) return; using (var key = RegistryTools.OpenRegistryKey(GetRealParentPath(), true)) using (var newKey = RegistryTools.CreateSubKeyRecursively(GetRealParentPath(true))) key.MoveSubKey(EntryLongName, newKey, EntryLongName); _disabled = value; } } public override string ParentShortName { get { return Localisation.Startup_Shortname_BrowserHelper + (IsWow ? " (Wow)" : string.Empty); } protected set { } } public string GetRealParentPath(bool opposite = false) { return (opposite ? !_disabled : _disabled) ? Path.Combine(ParentLongName, BrowserEntryFactory.AutorunsDisabledKeyName) : ParentLongName; } public override void Delete() { using (var key = RegistryTools.OpenRegistryKey(GetRealParentPath(), true)) key?.DeleteSubKey(EntryLongName); } public override bool StillExists() { using (var key = RegistryTools.OpenRegistryKey(GetRealParentPath())) return key != null && key.GetSubKeyNames().Contains(EntryLongName); } public override void CreateBackup(string backupPath) { RegistryTools.ExportRegistry(Path.Combine(backupPath, $@"{Localisation.Startup_Shortname_BrowserHelper} - {ProgramName}.reg"), Path.Combine(GetRealParentPath(), EntryLongName)); } } } ================================================ FILE: source/UninstallTools/Startup/Normal/IStartupDisable.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System.Collections.Generic; namespace UninstallTools.Startup.Normal { internal interface IStartupDisable { void Disable(StartupEntry startupEntry); void Enable(StartupEntry startupEntry); bool StillExists(StartupEntry startupEntry); IEnumerable AddDisableInfo(IList existingEntries); /// /// Get backup store path for the link. The backup extension is appended as well. /// Works only for links, file doesn't have to exist. /// string GetDisabledEntryPath(StartupEntry startupEntry); } } ================================================ FILE: source/UninstallTools/Startup/Normal/NewStartupDisable.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using Klocman.Extensions; using Klocman.Tools; using Microsoft.Win32; namespace UninstallTools.Startup.Normal { internal sealed class NewStartupDisable : IStartupDisable { /// /// Only the first byte matters, following bytes contain data that there is no documentation for (at least I didn't /// find any) /// private static readonly byte[] DisabledBytes = { 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; /// /// So far I've only seen enabled values filled with 0's except for the first byte /// private static readonly byte[] EnabledBytes = { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; public IEnumerable AddDisableInfo(IList existingEntries) { return existingEntries.DoForEach(x => { if (GetDisabled(x)) x.DisabledStore = true; }); } public void Disable(StartupEntry startupEntry) { SetDisabled(startupEntry, true); } public void Enable(StartupEntry startupEntry) { SetDisabled(startupEntry, false); } public string GetDisabledEntryPath(StartupEntry startupEntry) { return startupEntry.FullLongName; } public bool StillExists(StartupEntry startupEntry) { if (startupEntry.IsRegKey) { using (var key = RegistryTools.OpenRegistryKey(startupEntry.ParentLongName)) return key != null && !string.IsNullOrEmpty(key.GetStringSafe(startupEntry.EntryLongName)); } return File.Exists(startupEntry.FullLongName); } private static bool GetDisabled(StartupEntry startupEntry) { try { using (var key = RegistryTools.CreateSubKeyRecursively(GetStartupApprovedKey(startupEntry))) { return key.GetValue(startupEntry.EntryLongName) is byte[] bytes && bytes.Length > 0 && !bytes[0].Equals(0x02); } } catch (SystemException ex) { Trace.WriteLine($"Failed to get Disabled start-up state for {startupEntry.ProgramName}: {ex}"); return false; } } private static string GetStartupApprovedKey(StartupEntry startupEntry) { if (!startupEntry.IsRegKey) return startupEntry.AllUsers ? @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\StartupApproved\StartupFolder" : @"HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\StartupApproved\StartupFolder"; if (startupEntry.IsRunOnce) { if (startupEntry.AllUsers) { return startupEntry.ParentLongName.Contains("Wow6432Node") ? @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\StartupApproved\RunOnce32" : @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\StartupApproved\RunOnce"; } return @"HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\StartupApproved\RunOnce"; } if (startupEntry.AllUsers) { return startupEntry.ParentLongName.Contains("Wow6432Node") ? @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\StartupApproved\Run32" : @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\StartupApproved\Run"; } return @"HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\StartupApproved\Run"; } private static void SetDisabled(StartupEntry startupEntry, bool disabled) { using (var key = RegistryTools.CreateSubKeyRecursively(GetStartupApprovedKey(startupEntry))) { key.SetValue(startupEntry.EntryLongName, disabled ? DisabledBytes : EnabledBytes, RegistryValueKind.Binary); } } } } ================================================ FILE: source/UninstallTools/Startup/Normal/OldStartupDisable.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using Klocman.Extensions; using Klocman.Native; using Klocman.Tools; using Microsoft.Win32; using UninstallTools.Properties; namespace UninstallTools.Startup.Normal { internal sealed class OldStartupDisable : IStartupDisable { /// /// Extension used for link backup of the disabled entry /// (it is appended to the end of the filename, after the original extension). /// private static readonly string BackupExtension = ".Startup"; /// /// Path used to store link backups of disabled entries /// private static readonly string DriveDisableBackupPath = Path.Combine(WindowsTools.GetEnvironmentPath(CSIDL.CSIDL_WINDOWS), "pss"); /// /// Registry key used to store information about disabled links /// private static readonly StartupPointData DriveDisabledKey = new( true, false, false, false, string.Empty, @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\MSConfig\startupfolder"); /// /// Registry key used to store information about disabled registry values /// private static readonly StartupPointData RegistryDisabledKey = new( true, true, false, false, string.Empty, @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\MSConfig\startupreg"); /// /// Look for entries in the disabled startup backup store. /// public IEnumerable AddDisableInfo(IList existingEntries) { foreach (var entry in existingEntries) yield return entry; using (var regDisKey = RegistryTools.CreateSubKeyRecursively(RegistryDisabledKey.Path)) { var badLocations = new List(); foreach (var subKeyName in regDisKey.GetSubKeyNames()) { using (var subKey = regDisKey.OpenSubKey(subKeyName)) { if (subKey == null) continue; var key = subKey.GetStringSafe("key"); var hkey = subKey.GetStringSafe("hkey"); var item = subKey.GetStringSafe("item"); var command = subKey.GetStringSafe("command"); if (string.IsNullOrEmpty(key) || string.IsNullOrEmpty(hkey) || string.IsNullOrEmpty(item) || string.IsNullOrEmpty(command)) continue; string location; try { location = Path.Combine(RegistryTools.GetKeyRoot(hkey, false), key); } catch (ArgumentException) { continue; } if (string.IsNullOrEmpty(location.Trim())) continue; var runLocation = StartupEntryFactory.RunLocations .FirstOrDefault(x => PathTools.PathsEqual(location, x.Path)); if (runLocation != null) { StartupEntry startupEntry; try { startupEntry = new StartupEntry(runLocation, item, command) { DisabledStore = true }; } catch { badLocations.Add(location); continue; } yield return startupEntry; } else { badLocations.Add(location); } } } if (badLocations.Any()) { var errorString = Localisation.Error_InvalidRegKeys + "\n" + string.Join("\n", badLocations.Distinct().OrderBy(x => x).ToArray()); #if DEBUG Debug.Fail(errorString); #else Trace.WriteLine(errorString); #endif } } using (var hddDisKey = RegistryTools.CreateSubKeyRecursively(DriveDisabledKey.Path)) { foreach (var subKeyName in hddDisKey.GetSubKeyNames()) { using (var subKey = hddDisKey.OpenSubKey(subKeyName)) { if (subKey == null) continue; var path = subKey.GetStringSafe("path"); var location = subKey.GetStringSafe("location"); var backup = subKey.GetStringSafe("backup"); var command = subKey.GetStringSafe("command"); if (backup == null || location == null || path == null || command == null) continue; var runLocation = StartupEntryFactory.RunLocations .FirstOrDefault(x => PathTools.PathsEqual(x.Path, location)); if (runLocation == null) continue; yield return new StartupEntry(runLocation, Path.GetFileName(path), command) { BackupPath = backup, DisabledStore = true }; } } } } public void Disable(StartupEntry startupEntry) { if (startupEntry.DisabledStore) return; var newPath = CreateDisabledEntryPath(startupEntry); // Remove the startup entry / move the file to the backup folder if (startupEntry.IsRegKey) { try { startupEntry.Delete(); } catch { // Key doesn't exist } } else { if (File.Exists(startupEntry.FullLongName)) { File.Delete(newPath); Directory.CreateDirectory(DriveDisableBackupPath); File.Move(startupEntry.FullLongName, newPath); startupEntry.BackupPath = newPath; } else throw new InvalidOperationException(Localisation.StartupManager_FailedEnable_FileNotFound + "\n\n" + startupEntry.FullLongName); } CreateDisabledEntry(startupEntry, newPath); startupEntry.DisabledStore = true; } public void Enable(StartupEntry startupEntry) { if (!startupEntry.DisabledStore) return; // Reconstruct the startup entry if (!startupEntry.IsRegKey) { // Move the backup file back to its original location var oldPath = GetDisabledEntryPath(startupEntry); if (File.Exists(oldPath)) { File.Delete(startupEntry.FullLongName); File.Move(oldPath, startupEntry.FullLongName); } else throw new InvalidOperationException(Localisation.StartupManager_FailedEnable_FileNotFound + "\n\n" + oldPath); } else { // Recreate the registry key StartupEntryManager.CreateRegValue(startupEntry); } Delete(startupEntry); startupEntry.BackupPath = string.Empty; // Entry is no longer disabled startupEntry.DisabledStore = false; } /// /// Create backup store path for the link. The backup extension is appended as well. /// Works only for links, returns garbage for registry values. /// public string GetDisabledEntryPath(StartupEntry startupEntry) { return string.IsNullOrEmpty(startupEntry.BackupPath) ? CreateDisabledEntryPath(startupEntry) : startupEntry.BackupPath; } public bool StillExists(StartupEntry startupEntry) { try { using (var key = RegistryTools.OpenRegistryKey( startupEntry.IsRegKey ? RegistryDisabledKey.Path : DriveDisabledKey.Path)) { var disabledSubKeyName = startupEntry.IsRegKey ? startupEntry.EntryLongName : startupEntry.FullLongName.Replace('\\', '^'); return key.GetSubKeyNames() .Any(x => disabledSubKeyName.Equals(x, StringComparison.InvariantCultureIgnoreCase)); } } catch { return false; } } public void Delete(StartupEntry startupEntry) { RemoveDisabledRegEntry(startupEntry); // Remove the backup file if (!startupEntry.IsRegKey) File.Delete(GetDisabledEntryPath(startupEntry)); } /// /// Create a new record in the appropriate disabled entry store. If the entry already exists it is overwritten. /// /// Startup entry to create the record for /// Full path to the new backup file private static void CreateDisabledEntry(StartupEntry startupEntry, string newEntryPath) { using (var disabledStartupEntryStore = RegistryTools.CreateSubKeyRecursively( startupEntry.IsRegKey ? RegistryDisabledKey.Path : DriveDisabledKey.Path)) { var disabledSubKeyName = startupEntry.IsRegKey ? startupEntry.EntryLongName : startupEntry.FullLongName.Replace('\\', '^'); var disabledSubkeyKey = disabledStartupEntryStore.GetSubKeyNames() .FirstOrDefault(x => disabledSubKeyName.Equals(x, StringComparison.InvariantCultureIgnoreCase)); // Clean up old disabled entry if any if (!string.IsNullOrEmpty(disabledSubkeyKey)) { disabledStartupEntryStore.DeleteSubKey(disabledSubkeyKey); } using ( var storeSubkey = disabledStartupEntryStore.CreateSubKey(disabledSubKeyName, RegistryKeyPermissionCheck.ReadWriteSubTree)) { if (storeSubkey == null) return; if (startupEntry.IsRegKey) { storeSubkey.SetValue("key", RegistryTools.StripKeyRoot(startupEntry.ParentLongName), RegistryValueKind.String); storeSubkey.SetValue("item", startupEntry.EntryLongName, RegistryValueKind.String); storeSubkey.SetValue("hkey", RegistryTools.GetKeyRoot(startupEntry.ParentLongName, true), RegistryValueKind.String); storeSubkey.SetValue("inimapping", 0, RegistryValueKind.String); } else { storeSubkey.SetValue("item", Path.GetFileNameWithoutExtension(startupEntry.EntryLongName) ?? string.Empty, RegistryValueKind.String); storeSubkey.SetValue("path", startupEntry.FullLongName, RegistryValueKind.String); storeSubkey.SetValue("location", startupEntry.ParentLongName, RegistryValueKind.String); storeSubkey.SetValue("backup", newEntryPath, RegistryValueKind.String); storeSubkey.SetValue("backupExtension", BackupExtension, RegistryValueKind.String); } // Command stays the same for both storeSubkey.SetValue("command", startupEntry.Command, RegistryValueKind.String); // Set the disable date var now = DateTime.Now; storeSubkey.SetValue("YEAR", now.Year, RegistryValueKind.DWord); storeSubkey.SetValue("MONTH", now.Month, RegistryValueKind.DWord); storeSubkey.SetValue("DAY", now.Day, RegistryValueKind.DWord); storeSubkey.SetValue("HOUR", now.Hour, RegistryValueKind.DWord); storeSubkey.SetValue("MINUTE", now.Minute, RegistryValueKind.DWord); storeSubkey.SetValue("SECOND", now.Second, RegistryValueKind.DWord); } } } private static string CreateDisabledEntryPath(StartupEntryBase startupEntry) { return Path.Combine(DriveDisableBackupPath, startupEntry.EntryLongName + BackupExtension); } /// /// Remove registry key of a disabled startup entry. Link file is not touched if it exists. /// private static void RemoveDisabledRegEntry(StartupEntry startupEntry) { using (var disabledStartupEntryStore = RegistryTools.OpenRegistryKey( startupEntry.IsRegKey ? RegistryDisabledKey.Path : DriveDisabledKey.Path, true)) { var disabledSubKeyName = startupEntry.IsRegKey ? startupEntry.EntryLongName : startupEntry.FullLongName.Replace('\\', '^'); var disabledSubkeyKey = disabledStartupEntryStore.GetSubKeyNames() .FirstOrDefault(x => disabledSubKeyName.Equals(x, StringComparison.InvariantCultureIgnoreCase)); if (!string.IsNullOrEmpty(disabledSubkeyKey)) { disabledStartupEntryStore.DeleteSubKey(disabledSubkeyKey); } } } } } ================================================ FILE: source/UninstallTools/Startup/Normal/StartupEntry.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System.IO; using Klocman.Extensions; using Klocman.Resources; using Klocman.Tools; namespace UninstallTools.Startup.Normal { /// /// Starup entries stored in Startup folders and Run/RunOnce registry keys /// public sealed class StartupEntry : StartupEntryBase { internal bool AllUsersStore; internal bool DisabledStore; internal StartupEntry(StartupPointData dataPoint, string fileName, string targetString) { AllUsersStore = dataPoint.AllUsers; IsRegKey = dataPoint.IsRegKey; IsRunOnce = dataPoint.IsRunOnce; EntryLongName = fileName; ParentShortName = dataPoint.Name; ParentLongName = dataPoint.Path?.TrimEnd('\\'); Command = targetString ?? string.Empty; if (!string.IsNullOrEmpty(EntryLongName)) ProgramName = IsRegKey ? EntryLongName : Path.GetFileNameWithoutExtension(EntryLongName); if (!string.IsNullOrEmpty(targetString)) { CommandFilePath = ProcessCommandString(Command); if (CommandFilePath != null) FillInformationFromFile(CommandFilePath); if (string.IsNullOrEmpty(ProgramName)) ProgramName = ProgramNameTrimmed; } if (string.IsNullOrEmpty(ProgramName)) ProgramName = targetString ?? dataPoint.Name ?? CommonStrings.Unknown; if (string.IsNullOrEmpty(ProgramNameTrimmed)) ProgramNameTrimmed = StringTools.StripStringFromVersionNumber(ProgramName); } /// /// True if the entry is not processed during startup. /// It is stored in the backup reg key and optionally backup directory if it's a link file. /// public override bool Disabled { get { return DisabledStore; } set { if (value != DisabledStore) { if (value) { StartupEntryManager.Disable(this); } else { StartupEntryManager.Enable(this); } DisabledStore = value; } } } /// /// True if this entry is executed during logon of all users, false if it is only for the current user. /// public bool AllUsers { get { return AllUsersStore; } set { if (AllUsersStore != value) { StartupEntryManager.SetAllUsers(this, value); } } } /// /// True if entry is a registry value, false if it's a link file /// public bool IsRegKey { get; internal set; } /// /// True if the entry will be removed after running /// public bool IsRunOnce { get; internal set; } /// /// Filename of the link (with extension), or name of the registry value. /// public override string EntryLongName { get; protected set; } /// /// Full path to the link file backup /// internal string BackupPath { get; set; } /// /// Delete this startup entry from the system /// public override void Delete() { StartupEntryManager.Delete(this); } /// /// Check if the startup entry still exists in registry or on disk. /// If the entry is disabled, but it exists in the backup store, this method will return true. /// public override bool StillExists() { try { if (Disabled) return StartupEntryManager.DisableFunctions.StillExists(this); if (!IsRegKey) return File.Exists(FullLongName); using (var key = RegistryTools.OpenRegistryKey(ParentLongName)) return key != null && !string.IsNullOrEmpty(key.GetStringSafe(EntryLongName)); } catch { return false; } } //TODO temporary hack internal void SetParentFancyName(string newValue) { ParentShortName = newValue; } //TODO temporary hack internal void SetParentLongName(string newValue) { ParentLongName = newValue; } /// /// $"{ProgramName} | {Company} | {ParentLongName} | {Command}" /// public override string ToLongString() { return $"{ProgramName} | {Company} | {ParentLongName} | {Command}"; } public override void CreateBackup(string backupPath) { StartupEntryManager.CreateBackup(this, backupPath); } } } ================================================ FILE: source/UninstallTools/Startup/Normal/StartupEntryFactory.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Security; using Klocman.Extensions; using Klocman.Forms.Tools; using Klocman.Native; using Klocman.Tools; namespace UninstallTools.Startup.Normal { public static class StartupEntryFactory { /// /// Ordinal locations that contain startup entries /// internal static readonly IEnumerable RunLocations = new[] { // Normally those keys should not exist, they are not scanned by windows /*new StartupPointData(false, true, false, true, @"HKCU\Wow\Run", @"HKEY_CURRENT_USER\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Run\"), new StartupPointData(false, true, true, true, @"HKCU\Wow\RunOnce", @"HKEY_CURRENT_USER\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\RunOnce\"),*/ new StartupPointData(true, true, false, true, @"HKLM\Wow\Run", @"HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Run"), new StartupPointData(true, true, true, true, @"HKLM\Wow\RunOnce", @"HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\RunOnce"), new StartupPointData(true, true, false, false, @"HKLM\Run", @"HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run"), new StartupPointData(false, true, false, false, @"HKCU\Run", @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run"), new StartupPointData(true, true, true, false, @"HKLM\RunOnce)", @"HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnce"), new StartupPointData(false, true, true, false, @"HKCU\RunOnce)", @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce"), new StartupPointData(false, false, false, false, @"User\Startup", WindowsTools.GetEnvironmentPath(CSIDL.CSIDL_STARTUP)), new StartupPointData(true, false, false, false, @"Common\Startup", WindowsTools.GetEnvironmentPath(CSIDL.CSIDL_COMMON_STARTUP)) }.AsEnumerable(); /// /// Look for and return all of the startup entries stored in Startup folders and Run/RunOnce registry keys. /// public static IEnumerable GetStartupItems() { var results = new List(); foreach (var point in RunLocations) { results.AddRange(point.IsRegKey ? GetRegStartupItems(point) : GetDriveStartupItems(point)); } return StartupEntryManager.DisableFunctions.AddDisableInfo(results); } /// /// Look for links in startup folders /// private static IEnumerable GetDriveStartupItems(StartupPointData point) { if (!Directory.Exists(point.Path)) yield break; foreach (var name in Directory.GetFiles(point.Path) .Where(name => ".lnk".Equals(Path.GetExtension(name), StringComparison.CurrentCultureIgnoreCase))) { StartupEntry result; try { result = new StartupEntry(point, Path.GetFileName(name), WindowsTools.ResolveShortcut(name)); } catch (Exception ex) { PremadeDialogs.GenericError(ex); continue; } yield return result; } } /// /// Look for registry values in the run keys /// private static IEnumerable GetRegStartupItems(StartupPointData point) { var results = new List(); try { using (var rKey = RegistryTools.OpenRegistryKey(point.Path)) { if (rKey != null) { foreach (var name in rKey.GetValueNames()) { var result = rKey.GetStringSafe(name); if (string.IsNullOrEmpty(result)) continue; try { results.Add(new StartupEntry(point, name, result)); } catch (Exception ex) { PremadeDialogs.GenericError(ex); } } } } } catch (ArgumentException) { // Key doesn't exist, create it RegistryTools.CreateSubKeyRecursively(point.Path)?.Close(); } catch (SecurityException ex) { Trace.WriteLine(@"Failed to process startup entries: " + ex); } return results; } } } ================================================ FILE: source/UninstallTools/Startup/Normal/StartupEntryManager.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.IO; using System.Linq; using System.Text; using Klocman.Tools; using Microsoft.Win32; namespace UninstallTools.Startup.Normal { public static class StartupEntryManager { private static IStartupDisable _disableFunctions; // 6.2 is windows 8 and 2012, they are using a new startup disable scheme internal static IStartupDisable DisableFunctions => _disableFunctions ??= Environment.OSVersion.Version < WindowsTools.Windows8 ? new OldStartupDisable() : new NewStartupDisable(); /// /// Delete startup entry data from registry and file system. /// Only needed items are removed, for example if entry is disabled the entry from "Run" key is /// not removed if it exists, same for the "Startup" folder. To remove them change the Disabled /// property and run this command again. /// /// Entry to delete public static void Delete(StartupEntry startupEntry) { if (startupEntry.Disabled) DisableFunctions.Enable(startupEntry); if (startupEntry.IsRegKey) RegistryTools.RemoveRegistryValue(startupEntry.ParentLongName, startupEntry.EntryLongName); else File.Delete(startupEntry.FullLongName); } public static void MoveToRegistry(StartupEntry startupEntry) { if (startupEntry.IsRegKey) return; // Don't want to deal with the disable wizardry var wasDisabled = startupEntry.Disabled; if (wasDisabled) Enable(startupEntry); // Delete old entry startupEntry.Delete(); // Plug in new data startupEntry.IsRegKey = true; var newPoint = StartupEntryFactory.RunLocations.First(x => x.IsRegKey && (x.AllUsers == startupEntry.AllUsers) && !x.IsRunOnce && !x.IsWow); startupEntry.SetParentLongName(newPoint.Path); startupEntry.SetParentFancyName(newPoint.Name); // Recreate registry entry CreateRegValue(startupEntry); // Restore disable status if (wasDisabled) Disable(startupEntry); } /// /// Disable startup entry to stop it from being processed at startup. It is stored in the backup store. /// /// public static void Disable(StartupEntry startupEntry) { if (startupEntry.DisabledStore) return; DisableFunctions.Disable(startupEntry); } /// /// Restore the entry from the backup store, so that it can be executed again. /// /// public static void Enable(StartupEntry startupEntry) { if (!startupEntry.DisabledStore) return; DisableFunctions.Enable(startupEntry); } /// /// Set if this startup entry should run for all users or only for the current user. /// public static void SetAllUsers(StartupEntry startupEntry, bool allUsers) { // Find the suitable replacement var target = StartupEntryFactory.RunLocations.First(x => (x.IsRegKey == startupEntry.IsRegKey) && (x.IsRunOnce == startupEntry.IsRunOnce) && (x.AllUsers == allUsers) && !x.IsWow); // Don't want to deal with the disable wizardry var wasDisabled = startupEntry.Disabled; if (wasDisabled) Enable(startupEntry); // Remove old entry or move the link to the new directory. if (startupEntry.IsRegKey) { try { // Can't do this with links as they would get deleted startupEntry.Delete(); } catch { // Key doesn't exist } } else { if (File.Exists(startupEntry.FullLongName)) { var newPath = Path.Combine(target.Path, startupEntry.EntryLongName); File.Delete(newPath); File.Move(startupEntry.FullLongName, newPath); } } // Plug in new data startupEntry.SetParentLongName(target.Path); startupEntry.AllUsersStore = allUsers; // Update registry stuff if (startupEntry.IsRegKey) CreateRegValue(startupEntry); // Restore disable status if (wasDisabled) Disable(startupEntry); } /// /// Create a registry value for the specified entry. Works for drive links as well. /// /// internal static void CreateRegValue(StartupEntry startupEntry) { if (string.IsNullOrEmpty(startupEntry.Command)) return; using (var runKey = RegistryTools.CreateSubKeyRecursively(startupEntry.ParentLongName)) { runKey.SetValue(startupEntry.EntryLongName, startupEntry.Command, RegistryValueKind.String); } } /// /// Crate backup of the entry in the specified directory. If backup file already exists, it is overwritten. /// public static void CreateBackup(StartupEntry startupEntry, string backupPath) { var newPath = Path.Combine(backupPath, "Startup - " + startupEntry.EntryLongName); if (startupEntry.IsRegKey) { var sb = new StringBuilder(); sb.AppendLine("Windows Registry Editor Version 5.00"); sb.AppendLine(); sb.AppendLine($@"[{startupEntry.ParentLongName}]"); sb.AppendLine( $"\"{startupEntry.EntryLongName}\"=\"{startupEntry.Command.Replace("\\", "\\\\").Replace("\"", "\\\"")}\""); File.WriteAllText(newPath + ".reg", sb.ToString()); } else { if (!File.Exists(newPath)) File.Delete(newPath); if (startupEntry.Disabled) { var disabledFile = DisableFunctions.GetDisabledEntryPath(startupEntry); if (File.Exists(disabledFile)) File.Copy(disabledFile, newPath); } else { if (File.Exists(startupEntry.FullLongName)) File.Copy(startupEntry.FullLongName, newPath); } } } } } ================================================ FILE: source/UninstallTools/Startup/Normal/StartupPointData.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ namespace UninstallTools.Startup.Normal { internal sealed class StartupPointData { public readonly bool AllUsers; public readonly bool IsRegKey; public readonly bool IsRunOnce; public readonly bool IsWow; public readonly string Name; public readonly string Path; public StartupPointData(bool allUsers, bool isRegKey, bool isRunOnce, bool isWow, string name, string path) { AllUsers = allUsers; IsRegKey = isRegKey; IsRunOnce = isRunOnce; IsWow = isWow; Name = name; Path = path; } } } ================================================ FILE: source/UninstallTools/Startup/Service/ServiceEntry.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System.IO; using System.Management; using Klocman.Tools; using UninstallTools.Properties; namespace UninstallTools.Startup.Service { public sealed class ServiceEntry : StartupEntryBase { public ServiceEntry(string serviceName, string displayName, string command) { ProgramName = serviceName; EntryLongName = displayName; Command = command; if (ProcessStartCommand.TryParse(command, out var pc)) CommandFilePath = pc.FileName; else if (File.Exists(command)) CommandFilePath = command; FillInformationFromFile(CommandFilePath); } public override string ParentShortName { get { return Localisation.Startup_ShortName_Service; } protected set { } } public override string ParentLongName { get { return Localisation.Startup_ShortName_Service; } protected set { } } public override bool Disabled { get { try { return ServiceEntryFactory.CheckServiceEnabled(ProgramName); } catch (ManagementException) { return false; } } set { ServiceEntryFactory.EnableService(ProgramName, !value); } } public override void Delete() { ServiceEntryFactory.DeleteService(ProgramName); } public override bool StillExists() { try { ServiceEntryFactory.CheckServiceEnabled(ProgramName); return true; } catch (ManagementException) { return false; } } public override void CreateBackup(string backupPath) { var path = @"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\" + ProgramName; using (var key = RegistryTools.OpenRegistryKey(path)) { if (key == null) throw new IOException(); } var filename = PathTools.SanitizeFileName(FullLongName) + ".reg"; RegistryTools.ExportRegistry(Path.Combine(backupPath, filename), new[] { path }); } } } ================================================ FILE: source/UninstallTools/Startup/Service/ServiceEntryFactory.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Management; using System.Runtime.InteropServices; using System.Security; using Klocman.Native; using Klocman.Tools; namespace UninstallTools.Startup.Service { internal static class ServiceEntryFactory { internal enum StartMode { Auto, Manual, Disabled } /* ServiceType Kernel Driver File System Driver Adapter Recognizer Driver Own Process Share Process Interactive Process */ public static IEnumerable GetServiceEntries() { var results = new List(); try { var searcher = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_Service"); foreach (var queryObj in searcher.Get()) { // Skip drivers and adapters if (queryObj["ServiceType"] is not string serviceType || !serviceType.Contains("Process")) continue; // Don't show system services if (queryObj["PathName"] is not string filename || filename.Contains( WindowsTools.GetEnvironmentPath(CSIDL.CSIDL_WINDOWS), StringComparison.InvariantCultureIgnoreCase)) continue; var e = new ServiceEntry((string)queryObj["Name"], queryObj["DisplayName"] as string, filename); //queryObj["Caption"]); //queryObj["Description"]); //queryObj["ProcessId"] results.Add(e); } } catch (Exception ex) when (ex is TypeInitializationException || ex is ManagementException || ex is ExternalException || ex is PlatformNotSupportedException) { Trace.WriteLine(@"Error while gathering services - " + ex); } return results.ToArray(); } private static bool GetEnabledState(ManagementBaseObject queryObj) { return queryObj["StartMode"] as string != nameof(StartMode.Auto); } public static void EnableService(string serviceName, bool newState) { var classInstance = GetServiceObject(serviceName); // Obtain in-parameters for the method var inParams = classInstance.GetMethodParameters("ChangeStartMode"); // Add the input parameters. inParams["StartMode"] = newState ? "Automatic" : "Disabled"; // Execute the method and obtain the return values. var outParams = classInstance.InvokeMethod("ChangeStartMode", inParams, new InvokeMethodOptions { Timeout = TimeSpan.FromMinutes(1) }); CheckReturnValue(outParams); } public static bool CheckServiceEnabled(string serviceName) { var classInstance = GetServiceObject(serviceName); return GetEnabledState(classInstance); } public static void DeleteService(string serviceName) { try { EnableService(serviceName, false); } catch (ManagementException) { } var classInstance = GetServiceObject(serviceName); // Execute the method and obtain the return values. var outParams = classInstance.InvokeMethod("Delete", null, new InvokeMethodOptions { Timeout = TimeSpan.FromMinutes(1) }); CheckReturnValue(outParams, 16); // 16 - Service Marked For Deletion } private static void CheckReturnValue(ManagementBaseObject outParams, params UInt32[] ignoredCodes) { if (outParams == null) return; var exitCode = (UInt32)outParams["ReturnValue"]; if (exitCode == 0 || ignoredCodes.Any(x => x == exitCode)) return; if (exitCode == 2) // 2 - Access Denied throw new SecurityException("The user does not have the necessary access."); throw new ManagementException("Action failed with return value " + outParams["ReturnValue"] + ". Check return codes of Win32_Service class methods for more information."); } private static ManagementObject GetServiceObject(string serviceName) { return new ManagementObject("root\\CIMV2", $"Win32_Service.Name='{serviceName}'", new ObjectGetOptions { Timeout = TimeSpan.FromMinutes(1) }); } } } ================================================ FILE: source/UninstallTools/Startup/StartupEntryBase.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System.Diagnostics; using System.IO; using Klocman.Tools; namespace UninstallTools.Startup { public abstract class StartupEntryBase { /// /// Command executed by the startup entry /// public virtual string Command { get; protected set; } /// /// Full path to the executable pointed by the startup entry /// public virtual string CommandFilePath { get; protected set; } /// /// Company info extracted from the target executable (if possible) /// public virtual string Company { get; protected set; } /// /// True if the entry is not processed during startup. /// It is stored in the backup reg key and optionally backup directory if it's a link file. /// public abstract bool Disabled { get; set; } /// /// Name of the called program extracted from the link or the target executable (if possible) /// public virtual string ProgramName { get; protected set; } /// /// Program name without version info and such /// public virtual string ProgramNameTrimmed { get; protected set; } /// /// Custom name of the parent location /// public virtual string ParentShortName { get; protected set; } /// /// Full name of the parent location /// public virtual string ParentLongName { get; protected set; } /// /// Full name of the entry /// public virtual string EntryLongName { get; protected set; } /// /// Combined ParentLongName and EntryLongName /// public virtual string FullLongName => ParentLongName != null && EntryLongName != null ? PathTools.GenerousCombine(ParentLongName, EntryLongName) : null; /// /// Delete this startup entry from the system /// public abstract void Delete(); /// /// Check if this entry still exists in the system /// public abstract bool StillExists(); /// /// $"{ProgramName} | {Company} | {Command}" /// public virtual string ToLongString() { return $"{ProgramName} | {Company} | {Command}"; } /// /// Create beckup of this entry in specified folder /// public abstract void CreateBackup(string backupPath); /// /// Returns FullLongName, unless it's empty. In that case returns ProgramName, or Command if that is empty too. /// public override string ToString() { return FullLongName ?? ProgramName ?? Command; } protected static string ProcessCommandString(string command) { if (string.IsNullOrEmpty(command)) return null; return ProcessStartCommand.TryParse(command, out var temp) ? temp.FileName : null; } /// /// Fill in fields with version information from specified file /// protected void FillInformationFromFile(string commandFilename) { if (!File.Exists(commandFilename)) return; try { var info = FileVersionInfo.GetVersionInfo(commandFilename); Company = info.CompanyName; var fileDesc = StringTools.StripStringFromVersionNumber(info.FileDescription); if (!string.IsNullOrEmpty(fileDesc)) ProgramNameTrimmed = fileDesc; else ProgramNameTrimmed = !string.IsNullOrEmpty(info.ProductName) ? info.ProductName : StringTools.StripStringFromVersionNumber(ProgramName); } catch { // Ignore file access errors errors } } } } ================================================ FILE: source/UninstallTools/Startup/StartupManager.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using Klocman.Tools; using Microsoft.Win32.TaskScheduler; using UninstallTools.Properties; using UninstallTools.Startup.Browser; using UninstallTools.Startup.Normal; using UninstallTools.Startup.Service; using UninstallTools.Startup.Task; namespace UninstallTools.Startup { public static class StartupManager { static StartupManager() { Factories = new Dictionary>> { { Localisation.StartupEntries, StartupEntryFactory.GetStartupItems }, { Localisation.Startup_ShortName_Task, TaskEntryFactory.GetTaskStartupEntries }, { Localisation.Startup_Shortname_BrowserHelper, BrowserEntryFactory.GetBrowserHelpers }, { Localisation.Startup_ShortName_Service, ServiceEntryFactory.GetServiceEntries } }; } public static Dictionary>> Factories { get; } /// /// Fill in the ApplicationUninstallerEntry.StartupEntries property with a list of related StartupEntry objects. /// Old data is not cleared, only overwritten if necessary. /// /// Uninstaller entries to assign to /// Startup entries to assign public static void AssignStartupEntries(IEnumerable allUninstallerEntries, IEnumerable allStartupEntries) { //if (startupEntries == null || uninstallers == null) // return; var startups = allStartupEntries.ToList(); var uninstallers = allUninstallerEntries.ToList(); if (startups.Count == 0) return; foreach (var uninstaller in uninstallers) { var positives = startups.Where(startup => { if (startup.ProgramNameTrimmed?.Equals(uninstaller.DisplayNameTrimmed, StringComparison.OrdinalIgnoreCase) == true) return true; if (startup.CommandFilePath == null) return false; var instLoc = uninstaller.InstallLocation; if (uninstaller.IsInstallLocationValid() && startup.CommandFilePath.StartsWith(instLoc, StringComparison.OrdinalIgnoreCase)) { // Don't assign if there are any applications with more specific/deep install locations (same depth is fine) var instLocations = uninstallers .Where(e => e.IsInstallLocationValid()) .Select(e => e.InstallLocation) .Where(i=>startup.CommandFilePath.StartsWith(i, StringComparison.OrdinalIgnoreCase)); if (!instLocations.Any(i => i.Length > instLoc.Length)) return true; } var uninLoc = uninstaller.UninstallerLocation; if (!string.IsNullOrEmpty(uninLoc) && startup.CommandFilePath.StartsWith(uninLoc, StringComparison.OrdinalIgnoreCase)) { // Don't assign if there are any applications with more specific/deep install locations (same depth is fine) var uninLocations = uninstallers .Where(e => !string.IsNullOrEmpty(e.UninstallerLocation)) .Select(e => e.UninstallerLocation) .Where(i => startup.CommandFilePath.StartsWith(i, StringComparison.OrdinalIgnoreCase)); if (!uninLocations.Any(i => i.Length > uninLoc.Length)) return true; } return false; }).ToList(); if (positives.Count > 0) uninstaller.StartupEntries = positives; } } /// /// Look for and return all of the startup items present on this computer. /// public static IEnumerable GetAllStartupItems() { return Factories.Values.Aggregate(Enumerable.Empty(), (result, factory) => result.Concat(factory())); } /// /// Open locations of the startup entries in respective applications. (regedit, win explorer, task scheduler) /// public static void OpenStartupEntryLocations(IEnumerable selection) { var startupEntryBases = selection as IList ?? selection.ToList(); var regOpened = false; if (startupEntryBases.Any(x => x is TaskEntry)) TaskService.Instance.StartSystemTaskSchedulerManager(); var browserAddon = startupEntryBases.OfType().FirstOrDefault(); if (browserAddon != null) { RegistryTools.OpenRegKeyInRegedit(browserAddon.FullLongName); regOpened = true; } foreach (var item in startupEntryBases) { if (item is StartupEntry s && s.IsRegKey) { if (!regOpened) { RegistryTools.OpenRegKeyInRegedit(item.ParentLongName); regOpened = true; } } else if (!string.IsNullOrEmpty(item.FullLongName)) WindowsTools.OpenExplorerFocusedOnObject(item.FullLongName); else if (!string.IsNullOrEmpty(item.CommandFilePath)) WindowsTools.OpenExplorerFocusedOnObject(item.CommandFilePath); } } } } ================================================ FILE: source/UninstallTools/Startup/Task/TaskEntry.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.IO; using Klocman.Forms.Tools; using Microsoft.Win32.TaskScheduler; using UninstallTools.Properties; namespace UninstallTools.Startup.Task { public sealed class TaskEntry : StartupEntryBase { internal TaskEntry(string name, string command, string commandFilename, Microsoft.Win32.TaskScheduler.Task task) { ProgramName = name; Command = command; CommandFilePath = Environment.ExpandEnvironmentVariables(commandFilename); SourceTask = task; ParentLongName = Localisation.Startup_ShortName_Task + task.Path; EntryLongName = task.Name; FillInformationFromFile(CommandFilePath); } private Microsoft.Win32.TaskScheduler.Task SourceTask { get; } public override bool Disabled { get { try { return !SourceTask.Enabled; } catch (FileNotFoundException) { } catch (InvalidCastException) { } catch (System.Runtime.InteropServices.COMException) { } // If it's impossible to check disabled state, assume not disabled return false; } set { try { SourceTask.Enabled = !value; } catch (Exception e) { PremadeDialogs.GenericError(e); } } } public override string ParentShortName { get { return Localisation.Startup_ShortName_Task; } protected set { } } public override void Delete() { SourceTask.Folder.DeleteTask(SourceTask.Name, false); } public override bool StillExists() { return TaskService.Instance.FindTask(SourceTask.Name) != null; } public override void CreateBackup(string backupPath) { File.WriteAllText( Path.Combine(backupPath, Localisation.Startup_ShortName_Task + " - " + EntryLongName + ".xml"), SourceTask.Xml); } } } ================================================ FILE: source/UninstallTools/Startup/Task/TaskEntryFactory.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System.Collections.Generic; using System.Xml.Linq; using Klocman.Tools; using Microsoft.Win32.TaskScheduler; namespace UninstallTools.Startup.Task { public static class TaskEntryFactory { public static IEnumerable GetTaskStartupEntries() { TaskCollection tasks; try { tasks = TaskService.Instance.RootFolder.Tasks; } catch { yield break; } foreach (var task in tasks) { XNamespace xmlNamespace; XElement actionRoot; try { var rootElement = XDocument.Parse(task.Xml).Root; xmlNamespace = rootElement?.Name.Namespace ?? XNamespace.None; actionRoot = rootElement?.Element(xmlNamespace + "Actions"); } catch { continue; } if (actionRoot == null || actionRoot.IsEmpty || xmlNamespace == XNamespace.None) continue; foreach (var actionElement in actionRoot.Elements()) { var command = actionElement.Element(xmlNamespace + "Command"); if (string.IsNullOrEmpty(command?.Value)) continue; var arguments = actionElement.Element(xmlNamespace + "Arguments"); var cmdCommand = new ProcessStartCommand(command.Value, arguments?.Value ?? string.Empty); yield return new TaskEntry(task.Name, cmdCommand.ToCommandLine(), cmdCommand.FileName, task); } } } } } ================================================ FILE: source/UninstallTools/ThreadedWorkSpreader.cs ================================================ /* Copyright (c) 2018 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading; namespace UninstallTools { internal class ThreadedWorkSpreader where TState : class { private readonly List _workers = new(); public ThreadedWorkSpreader(int maxThreadsPerBucket, Action workLogic, Func, TState> stateGenerator, Func dataNameGetter) { if (maxThreadsPerBucket <= 0) throw new ArgumentOutOfRangeException(nameof(maxThreadsPerBucket), maxThreadsPerBucket, @"Minimum value is 1"); MaxThreadsPerBucket = maxThreadsPerBucket; StateGenerator = stateGenerator ?? throw new ArgumentNullException(nameof(stateGenerator)); WorkLogic = workLogic ?? throw new ArgumentNullException(nameof(workLogic)); DataNameGetter = dataNameGetter ?? throw new ArgumentNullException(nameof(dataNameGetter)); } public Func, TState> StateGenerator { get; } public Func DataNameGetter { get; } public Action WorkLogic { get; } public int MaxThreadsPerBucket { get; } public void Start(IList> dataBuckets, ListGenerationProgress.ListGenerationCallback progressCallback) { if (dataBuckets == null) throw new ArgumentNullException(nameof(dataBuckets)); if (progressCallback == null) throw new ArgumentNullException(nameof(progressCallback)); var totalCount = dataBuckets.Aggregate(0, (i, list) => i + list.Count); var progress = 0; void OnItemDone(string itemName) { progressCallback(new ListGenerationProgress(progress++, totalCount, itemName)); } foreach (var itemBucket in dataBuckets) { if (itemBucket.Count == 0) continue; var threadCount = Math.Min(MaxThreadsPerBucket, itemBucket.Count / 10 + 1); var threadWorkItemCount = itemBucket.Count / threadCount + 1; for (var i = 0; i < threadCount; i++) { var firstUnique = i * threadWorkItemCount; var workerItems = itemBucket.Skip(firstUnique).Take(threadWorkItemCount).ToList(); var worker = new Thread(WorkerThread) { Name = nameof(ThreadedWorkSpreader) + "_worker", IsBackground = false }; var workerData = new WorkerData(workerItems, worker, OnItemDone, StateGenerator(itemBucket)); _workers.Add(workerData); worker.Start(workerData); } } } public IEnumerable Join() { foreach (var workerData in _workers) try { workerData.Worker.Join(); } catch (Exception ex) { Trace.WriteLine("Exception in worker thread: " + ex); } return _workers.Select(x => x.State); } private void WorkerThread(object obj) { if (obj is not WorkerData workerInterface) throw new ArgumentException(@"obj is not WorkerData", nameof(obj)); foreach (var data in workerInterface.Input) { try { workerInterface.OnInputItemDone(DataNameGetter?.Invoke(data) ?? data?.ToString()); } catch (OperationCanceledException) { return; } WorkLogic.Invoke(data, workerInterface.State); } } private sealed class WorkerData { public WorkerData(List input, Thread worker, Action onInputItemDone, TState state) { Input = input; Worker = worker; OnInputItemDone = onInputItemDone; State = state; } public List Input { get; } public Thread Worker { get; } public Action OnInputItemDone { get; } public TState State { get; } } } } ================================================ FILE: source/UninstallTools/UninstallTools.csproj ================================================  Library Core application discovery and uninstallation code {420B2830-E718-11CF-893D-00A0C9054228} 1 0 0 tlbimp False false True True Localisation.resx True True Resources.resx ResXFileCodeGenerator Localisation.Designer.cs ResXFileCodeGenerator Resources.Designer.cs ================================================ FILE: source/UninstallTools/UninstallToolsGlobalConfig.cs ================================================ using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.IO; using System.Linq; using System.Reflection; using Klocman.Extensions; using Klocman.Native; using Klocman.Tools; using UninstallTools.Factory; namespace UninstallTools { public static class UninstallToolsGlobalConfig { static UninstallToolsGlobalConfig() { AssemblyLocation = Assembly.GetExecutingAssembly().Location; if (AssemblyLocation.ContainsAny(new[] { ".dll", ".exe" }, StringComparison.OrdinalIgnoreCase)) AssemblyLocation = PathTools.GetDirectory(AssemblyLocation); var dir = new DirectoryInfo(AssemblyLocation); if (dir.Name.StartsWith("win-x") && dir.Parent != null) dir = dir.Parent; AppLocation = dir.FullName; UninstallerAutomatizerPath = Path.Combine(AssemblyLocation, @"UninstallerAutomatizer.exe"); UninstallerAutomatizerExists = File.Exists(UninstallerAutomatizerPath); QuestionableDirectoryNames = new[] { "install", "settings", "config", "configuration", "users", "data" }; var allKnownFolders = Enum.GetValues().Attempt(WindowsTools.GetEnvironmentPath) .Where(x => !string.IsNullOrWhiteSpace(x)).Attempt(Path.GetFullPath) .Distinct(StringComparer.OrdinalIgnoreCase).ToList(); _downloadsDir = KnownFolders.GetKnownFolderPath(new Guid("374DE290-123F-4565-9164-39C4925E467B")); if (!string.IsNullOrWhiteSpace(_downloadsDir)) { _downloadsDir = Path.GetFullPath(_downloadsDir); allKnownFolders.Add(_downloadsDir); } else _downloadsDir = null; KnownFolderList = allKnownFolders; DirectoryNameBlacklist = new[] { "Microsoft", "Microsoft Games", "Temp", "Programs", "Common", "Common Files", "Clients", "Downloads", "Desktop", "Internet Explorer", "Windows", "Windows NT", "Windows Photo Viewer", "Windows Mail", "Windows Defender", "Windows Media Player", "Uninstall Information", "Reference Assemblies", "InstallShield Installation Information", "Installer", "winsxs", "WindowsApps", "DirectX", "DirectXRedist" }; WindowsDirectory = WindowsTools.GetEnvironmentPath(CSIDL.CSIDL_WINDOWS); StockProgramFiles = new[] { WindowsTools.GetEnvironmentPath(CSIDL.CSIDL_PROGRAM_FILES), WindowsTools.GetProgramFilesX86Path() }.Distinct().ToList(); // JunkSearchDirs -------------- var localData = WindowsTools.GetEnvironmentPath(CSIDL.CSIDL_LOCAL_APPDATA); var paths = new List { WindowsTools.GetEnvironmentPath(CSIDL.CSIDL_PROGRAMS), WindowsTools.GetEnvironmentPath(CSIDL.CSIDL_COMMON_PROGRAMS), WindowsTools.GetEnvironmentPath(CSIDL.CSIDL_APPDATA), WindowsTools.GetEnvironmentPath(CSIDL.CSIDL_COMMON_APPDATA), localData //Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) danger? }; var appDataParentDir = Path.GetDirectoryName(localData.TrimEnd('\\', '/', ' ')); if (!string.IsNullOrEmpty(appDataParentDir)) { var lowDir = Path.Combine(appDataParentDir, "LocalLow"); if (Directory.Exists(lowDir)) paths.Add(lowDir); } var vsPath = Path.Combine(localData, "VirtualStore"); if (Directory.Exists(vsPath)) paths.AddRange(Directory.GetDirectories(vsPath)); JunkSearchDirs = paths.Distinct().ToList(); AppInfoCachePath = Path.Combine(AssemblyLocation, "InfoCache.xml"); _pf32 = WindowsTools.GetProgramFilesX86Path(); _pf64 = WindowsTools.GetEnvironmentPath(CSIDL.CSIDL_PROGRAM_FILES); if (string.IsNullOrWhiteSpace(_pf64) || PathTools.PathsEqual(_pf32, _pf64)) _pf64 = null; } public static bool EnableAppInfoCache { get => UninstallerFactoryCache != null; set { if (value == EnableAppInfoCache) return; if (value) ReloadCache(); else ClearChache(); } } private static void ReloadCache() { var cachePath = AppInfoCachePath; try { UninstallerFactoryCache = new ApplicationUninstallerFactoryCache(cachePath); if (File.Exists(cachePath)) UninstallerFactoryCache.Read(); } catch (SystemException e) { UninstallerFactoryCache = new ApplicationUninstallerFactoryCache(cachePath); Trace.WriteLine("Cache reload failed: " + e); } } public static void ClearChache() { UninstallerFactoryCache?.Delete(); UninstallerFactoryCache = null; } public static string AppInfoCachePath { get; } internal static ApplicationUninstallerFactoryCache UninstallerFactoryCache { get; private set; } /// /// Path to directory this assembly sits in. /// internal static string AssemblyLocation { get; } internal static string AppLocation { get; } public static bool AutoDetectCustomProgramFiles { get; set; } public static bool AutoDetectScanRemovable { get; set; } /// /// Custom "Program Files" directories. Use with dirs that get used to install applications to. /// public static string[] CustomProgramFiles { get; set; } /// /// Directory names that should be ignored for safety. /// internal static IEnumerable DirectoryNameBlacklist { get; } internal static IEnumerable KnownFolderList { get; } internal static string WindowsDirectory { get; } /// /// Directories that can contain program junk. /// internal static IEnumerable JunkSearchDirs { get; } /// /// Directory names that probably aren't top-level or contain applications. /// internal static IEnumerable QuestionableDirectoryNames { get; } /// /// Automatize non-quiet uninstallers. /// public static bool QuietAutomatization { get; set; } /// /// Kill stuck automatized uninstallers. /// public static bool QuietAutomatizationKillStuck { get; set; } public static bool ScanRegistry { get; set; } = true; public static bool ScanDrives { get; set; } = true; public static bool ScanPreDefined { get; set; } = true; public static bool ScanSteam { get; set; } = true; public static bool ScanStoreApps { get; set; } = true; public static bool ScanOculus { get; set; } = true; public static bool ScanWinFeatures { get; set; } = true; public static bool ScanWinUpdates { get; set; } = true; public static bool ScanChocolatey { get; set; } = true; public static bool ScanScoop { get; set; } = true; /// /// Built-in program files paths. /// internal static IEnumerable StockProgramFiles { get; } public static bool UseQuietUninstallDaemon { get; set; } /// /// Directiories containing programs, both built in "Program Files" and user-defined ones. Fast. /// internal static IEnumerable GetAllProgramFiles() { if (CustomProgramFiles == null || CustomProgramFiles.Length == 0) return StockProgramFiles; // Create copy of custom dirs in case they change return StockProgramFiles.Concat(CustomProgramFiles).ToList(); } private static readonly string _pf64, _pf32; private static readonly string _downloadsDir; /// /// Get a list of directiories containing programs. Optionally user-defined directories are added. /// The boolean value is true if the directory is confirmed to contain 64bit applications, false if 32bit. /// /// Add user-defined directories. internal static List GetProgramFilesDirectories(bool includeUserDirectories) { var pfDirectories = new List(2); pfDirectories.Add(_pf32); if (_pf64 != null) pfDirectories.Add(_pf64); if (includeUserDirectories && CustomProgramFiles != null) pfDirectories.AddRange(CustomProgramFiles.Where(x => !pfDirectories.Any(y => PathTools.PathsEqual(x, y)))); pfDirectories.Add(Path.Combine(WindowsTools.GetEnvironmentPath(CSIDL.CSIDL_APPDATA), "Programs")); pfDirectories.Add(Path.Combine(WindowsTools.GetEnvironmentPath(CSIDL.CSIDL_LOCAL_APPDATA), "Programs")); pfDirectories.Add(Path.Combine(WindowsTools.GetEnvironmentPath(CSIDL.CSIDL_COMMON_APPDATA), "Programs")); var output = new List(pfDirectories.Count); foreach (var directory in pfDirectories) { // Ignore missing or inaccessible directories try { var di = new DirectoryInfo(directory); if (di.Exists) output.Add(di); } catch (Exception ex) { Debug.Fail("Failed to open dir", ex.Message); } } return output; } /// /// Check if the path is inside of 64 or 32 bit program files /// public static MachineType IsPathInsideProgramFiles(string fullPath) { if (fullPath.StartsWith(_pf32, StringComparison.InvariantCultureIgnoreCase)) return MachineType.X86; if (_pf64 != null && fullPath.StartsWith(_pf64, StringComparison.InvariantCultureIgnoreCase)) return MachineType.X64; return MachineType.Unknown; } public static bool IsKnownFolder(string itemParentPath) => KnownFolderList.Any(y => PathTools.PathsEqual(y, itemParentPath)); public static bool IsKnownFolder(DirectoryInfo dir) => KnownFolderList.Any(y => PathTools.PathsEqual(y, dir.FullName)); /// /// Check if dir is a system directory and should be left alone. /// public static bool IsSystemDirectory(DirectoryInfo dir) { return (dir.Attributes & FileAttributes.System) == FileAttributes.System || dir.FullName.StartsWith(WindowsDirectory, StringComparison.OrdinalIgnoreCase) || _downloadsDir != null && dir.FullName.StartsWith(_downloadsDir, StringComparison.OrdinalIgnoreCase) || DirectoryNameBlacklist.Any(y => y.Equals(dir.Name, StringComparison.InvariantCultureIgnoreCase)); } /// /// Check if dir is a system directory and should be left alone. /// public static bool IsSystemDirectory(string installLocation) { if (string.IsNullOrEmpty(installLocation)) return false; try { return IsSystemDirectory(new DirectoryInfo(installLocation)); } catch (ArgumentException ex) { Trace.WriteLine(ex); // Treat this as a no-touch directory just to be safe return true; } catch (IOException ex) { Trace.WriteLine(ex); // Treat this as a no-touch directory just to be safe return true; } } /// /// Safely try to extract icon from specified file. Return null if failed. /// internal static Icon TryExtractAssociatedIcon(string path) { if (path != null && File.Exists(path)) { try { return DrawingTools.ExtractAssociatedIcon(path); } catch (Exception ex) { Debug.Fail(ex.Message); } } return null; } public static string UninstallerAutomatizerPath { get; } public static bool UninstallerAutomatizerExists { get; } } } ================================================ FILE: source/UninstallTools/Uninstaller/BulkUninstallConfiguration.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ namespace UninstallTools.Uninstaller { public sealed class BulkUninstallConfiguration { /*public BulkUninstallConfiguration() { IgnoreProtection = false; PreferQuiet = false; QuietMsi = false; IntelligentSort = false; Simulate = false; }*/ public BulkUninstallConfiguration(bool ignoreProtection, bool preferQuiet, bool simulate, bool autoKillStuckQuiet, bool retryFailedQuiet) { IgnoreProtection = ignoreProtection; PreferQuiet = preferQuiet; Simulate = simulate; AutoKillStuckQuiet = autoKillStuckQuiet; RetryFailedQuiet = retryFailedQuiet; } public bool AutoKillStuckQuiet { get; set; } public bool RetryFailedQuiet { get; set; } public bool IgnoreProtection { get; set; } public bool PreferQuiet { get; set; } public bool Simulate { get; set; } } } ================================================ FILE: source/UninstallTools/Uninstaller/BulkUninstallEntry.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Linq; using System.Threading; using Klocman.Extensions; using Klocman.IO; using Klocman.Tools; using UninstallTools.Factory; using UninstallTools.Properties; namespace UninstallTools.Uninstaller { public class BulkUninstallEntry { private static readonly string[] NamesOfIgnoredProcesses = WindowsTools.GetInstalledWebBrowsers().Select(s => { try { return Path.GetFileNameWithoutExtension(s); } catch (ArgumentException) { try { var dash = s.LastIndexOf('\\'); return s.Substring(dash + 1, s.LastIndexOf('.') - dash - 1); } catch { return null; } } }).Where(x => !string.IsNullOrEmpty(x)).Concat(new[] { "explorer" }).Distinct().ToArray(); private readonly object _operationLock = new(); private readonly Dictionary _perfCounterBuffer = new(); private bool _canRetry = true; private SkipCurrentLevel _skipLevel = SkipCurrentLevel.None; private Thread _worker; public BulkUninstallEntry(ApplicationUninstallerEntry uninstallerEntry, bool isSilentPossible, UninstallStatus startingStatus) { CurrentStatus = startingStatus; IsSilentPossible = isSilentPossible; UninstallerEntry = uninstallerEntry; } public Exception CurrentError { get; private set; } public UninstallStatus CurrentStatus { get; private set; } public bool Finished { get; private set; } public int Id { get; internal set; } public bool IsRunning { get { lock (_operationLock) return _worker != null && _worker.IsAlive; } } public bool IsSilentPossible { get; set; } public ApplicationUninstallerEntry UninstallerEntry { get; } private static void KillProcesses(IEnumerable processes) { foreach (var process in processes) { try { process.Kill(); } catch (InvalidOperationException) { } catch (Win32Exception) { } } } public void Reset() { //bug handle already running CurrentError = null; CurrentStatus = UninstallStatus.Waiting; Finished = false; } /// /// Run the uninstaller on a new thread. /// internal void RunUninstaller(RunUninstallerOptions options) { lock (_operationLock) { if (Finished || IsRunning || CurrentStatus != UninstallStatus.Waiting) return; if (UninstallerEntry.IsRegistered && !UninstallerEntry.RegKeyStillExists()) { CurrentStatus = UninstallStatus.Completed; Finished = true; return; } if (UninstallerEntry.UninstallerKind == UninstallerType.Msiexec) { var uninstallString = IsSilentPossible && UninstallerEntry.QuietUninstallPossible ? UninstallerEntry.QuietUninstallString : UninstallerEntry.UninstallString; // Always reenumerate products in case any were uninstalled if (ApplicationEntryTools.PathPointsToMsiExec(uninstallString) && MsiTools.MsiEnumProducts().All(g => !g.Equals(UninstallerEntry.BundleProviderKey))) { CurrentStatus = UninstallStatus.Completed; Finished = true; return; } } CurrentStatus = UninstallStatus.Uninstalling; try { _worker = new Thread(UninstallThread) { Name = "RunBulkUninstall_Worker", IsBackground = false }; _worker.Start(options); } catch { CurrentStatus = UninstallStatus.Failed; Finished = true; throw; } } } public void SkipWaiting(bool terminate) { lock (_operationLock) { if (Finished) return; if (!IsRunning && CurrentStatus == UninstallStatus.Waiting) CurrentStatus = UninstallStatus.Skipped; // Do not allow skipping of Msiexec uninstallers because they will hold up the rest of Msiexec uninstallers in the task if (CurrentStatus == UninstallStatus.Uninstalling && UninstallerEntry.UninstallerKind == UninstallerType.Msiexec && !terminate) return; _skipLevel = terminate ? SkipCurrentLevel.Terminate : SkipCurrentLevel.Skip; } } /// /// Try to mark this entry as finished. If it is running and can't be safely skipped, mark it for termination instead. /// Do not use unless the entry was uninstalled externally. /// public void ForceFinished() { lock (_operationLock) { if (Finished) return; if (IsRunning) { // Do not allow skipping of Msiexec uninstallers because they will hold up the rest of Msiexec uninstallers in the task if (CurrentStatus == UninstallStatus.Uninstalling && UninstallerEntry.UninstallerKind == UninstallerType.Msiexec) { SkipWaiting(true); return; } } CurrentStatus = UninstallStatus.Completed; Finished = true; } } /// /// Returns true if uninstaller appears to be stalled. Blocks for 1000ms to gather data. /// private bool TestUninstallerForStalls(IEnumerable childProcesses) { var childProcessNames = childProcesses as IList ?? childProcesses.ToList(); foreach (var perfCounterEntry in _perfCounterBuffer.ToList()) { if (!childProcessNames.Contains(perfCounterEntry.Key)) { _perfCounterBuffer.Remove(perfCounterEntry.Key); perfCounterEntry.Value.Dispose(); } } foreach (var childProcessName in childProcessNames) { PerformanceCounter[] perfCounters = null; try { perfCounters = new[] { new PerformanceCounter("Process", "% Processor Time", childProcessName, true), new PerformanceCounter("Process", "IO Data Bytes/sec", childProcessName, true) }; // Important to NextSample now, they will collect data when we sleep _perfCounterBuffer.Add(childProcessName, new PerfCounterEntry( perfCounters, new[] { perfCounters[0].NextSample(), perfCounters[1].NextSample() })); } catch { // Ignore errors caused by counters derping if (perfCounters != null && perfCounters.Length == 2) { perfCounters[0].Dispose(); perfCounters[1].Dispose(); } } } // Let the counters gather some data Thread.Sleep(1100); bool? anyWorking = null; foreach (var perfCounterEntry in _perfCounterBuffer.ToList()) { try { var new0 = perfCounterEntry.Value.Counter[0].NextSample(); var new1 = perfCounterEntry.Value.Counter[1].NextSample(); var c0 = CounterSample.Calculate(perfCounterEntry.Value.Sample[0], new0); var c1 = CounterSample.Calculate(perfCounterEntry.Value.Sample[1], new1); perfCounterEntry.Value.Sample[0] = new0; perfCounterEntry.Value.Sample[1] = new1; Debug.WriteLine("CPU " + c0 + "%, IO " + c1 + "B"); // Check if process seems to be doing anything. Use 1% for CPU and 10KB for I/O if (c0 <= 1 && c1 <= 10240) { anyWorking = false; } else { anyWorking = true; break; } } catch { perfCounterEntry.Value.Dispose(); _perfCounterBuffer.Remove(perfCounterEntry.Key); } } // Only return true if we had at least one process to test and it tested negatively return anyWorking.HasValue && !anyWorking.Value; } private void UninstallThread(object parameters) { var options = parameters as RunUninstallerOptions; Debug.Assert(options != null, "options != null"); Exception error = null; var retry = false; try { var processSnapshot = Process.GetProcesses().Select(x => x.Id).ToArray(); using (var uninstaller = UninstallerEntry.RunUninstaller(options.PreferQuiet, options.Simulate, _canRetry)) { // Can be null during simulation if (uninstaller == null) return; if (options.PreferQuiet && UninstallerEntry.QuietUninstallPossible) { try { uninstaller.PriorityClass = ProcessPriorityClass.BelowNormal; } catch { // Don't care if setting this fails } } var checkCounters = options.PreferQuiet && options.AutoKillStuckQuiet && UninstallerEntry.QuietUninstallPossible; var watchedProcesses = new List { uninstaller }; int[] previousWatchedProcessIds = { }; var idleCounter = 0; while (true) { if (_skipLevel == SkipCurrentLevel.Skip) break; foreach (var watchedProcess in watchedProcesses.ToList()) watchedProcesses.AddRange(watchedProcess.GetChildProcesses()); if (UninstallerEntry.UninstallerKind == UninstallerType.Msiexec) { foreach (var watchedProcess in Process.GetProcessesByName("msiexec")) watchedProcesses.AddRange(watchedProcess.GetChildProcesses()); } watchedProcesses = CleanupDeadProcesses(watchedProcesses, processSnapshot).ToList(); // Check if we are done, or if there are some proceses left that we missed. // We are done when the entry process and all of its spawns exit. if (watchedProcesses.Count == 0) { if (string.IsNullOrEmpty(UninstallerEntry.InstallLocation)) break; FindAndAddProcessesToWatch(watchedProcesses, processSnapshot); if (watchedProcesses.Count == 0) break; } // Only try to automate first try. If it fails, don't try to automate // the rerun in case user or app itself can resolve the issue. if (IsSilentPossible && UninstallToolsGlobalConfig.UseQuietUninstallDaemon && _canRetry) { // There is no point in trying to automatize command line interface programs, or our own helpers if (!UninstallerEntry.QuietUninstallerIsCLI() && !UninstallerEntry.QuietUninstallString .Contains(UninstallToolsGlobalConfig.AppLocation, StringComparison.OrdinalIgnoreCase)) { var processIds = SafeGetProcessIds(watchedProcesses).ToArray(); options.Owner.SendProcessesToWatchToDeamon(processIds.Except(previousWatchedProcessIds)); previousWatchedProcessIds = processIds; } } // Check for deadlocks during silent uninstall. Prevents the task from getting stuck // idefinitely on stuck uninstallers and unrelated processes spawned by uninstallers. if (checkCounters) { var processNames = SafeGetProcessNames(watchedProcesses); if (TestUninstallerForStalls(processNames)) idleCounter++; else idleCounter = 0; // Kill the uninstaller (and children) if they were idle/stalled for too long if (idleCounter > 30) { KillProcesses(watchedProcesses); throw new IOException(Localisation.UninstallError_UninstallerTimedOut); } } else Thread.Sleep(1000); // Kill the uninstaller (and children) if user told us to or if it was idle for too long if (_skipLevel == SkipCurrentLevel.Terminate) { if (UninstallerEntry.UninstallerKind == UninstallerType.Msiexec) watchedProcesses.AddRange(Process.GetProcessesByName("Msiexec")); KillProcesses(watchedProcesses); break; } } if (_skipLevel == SkipCurrentLevel.None) { var exitVar = uninstaller.ExitCode; if (exitVar != 0) { if (UninstallerEntry.UninstallerKind == UninstallerType.Msiexec && exitVar == 1602) { // 1602 ERROR_INSTALL_USEREXIT - The user has cancelled the installation. _skipLevel = SkipCurrentLevel.Skip; } else if (UninstallerEntry.UninstallerKind == UninstallerType.Nsis && (exitVar == 1 || exitVar == 2)) { // 1 - Installation aborted by user (cancel button) // 2 - Installation aborted by script (often after user clicks cancel) _skipLevel = SkipCurrentLevel.Skip; } else if (UninstallerEntry.UninstallerKind == UninstallerType.Nsis && exitVar == 1627) { // Nsis OK return code } else if (UninstallerEntry.UninstallerKind == UninstallerType.SimpleDelete && exitVar == 1) { // 1 - Installation aborted by user (cancel button) _skipLevel = SkipCurrentLevel.Skip; } else if (exitVar == -1073741510) { /* 3221225786 / 0xC000013A / -1073741510 The application terminated as a result of a CTRL+C. Indicates that the application has been terminated either by user's keyboard input CTRL+C or CTRL+Break or closing command prompt window. */ _skipLevel = SkipCurrentLevel.Terminate; } else { switch (exitVar) { case 2: throw new Exception("The system cannot find the file specified. Indicates that the file can not be found in specified location."); case 3: throw new Exception("The system cannot find the path specified. Indicates that the specified path can not be found."); case 5: throw new Exception("Access is denied. Indicates that user has no access right to specified resource."); case 9009: throw new Exception("Program is not recognized as an internal or external command, operable program or batch file."); case -2147024846: throw new Exception("0x80070032 - This app is part of Windows and cannot be uninstalled on a per-user basis."); default: if (options.RetryFailedQuiet || (UninstallerEntry.UninstallerKind == UninstallerType.Nsis && !options.PreferQuiet)) retry = true; throw new IOException(Localisation.UninstallError_UninstallerReturnedCode + exitVar); } } } } } } catch (Exception ex) { error = ex; Trace.WriteLine(@$"Exception when uninstalling {UninstallerEntry.DisplayName}: {ex}"); } finally { try { _perfCounterBuffer.ForEach(x => x.Value.Dispose()); } catch { // Ignore any errors to make sure rest of this code runs } _perfCounterBuffer.Clear(); // Take care of the aftermath if (_skipLevel != SkipCurrentLevel.None) { _skipLevel = SkipCurrentLevel.None; CurrentStatus = UninstallStatus.Skipped; CurrentError = new OperationCanceledException(Localisation.ManagerError_Skipped); } else if (error != null) { //Localisation.ManagerError_PrematureWorkerStop is unused CurrentStatus = UninstallStatus.Failed; CurrentError = error; } else { CurrentStatus = UninstallStatus.Completed; } if (retry && _canRetry) { CurrentStatus = UninstallStatus.Waiting; _canRetry = false; } else { Finished = true; } } } private static IEnumerable SafeGetProcessNames(IEnumerable processes) { return processes.Select(x => { try { return x.ProcessName; } catch { // Ignore errors caused by processes that exited return null; } }).Where(x => !string.IsNullOrEmpty(x)); } private static IEnumerable SafeGetProcessIds(IEnumerable processes) { return processes.Select(x => { try { x.Refresh(); if (x.MainWindowHandle == IntPtr.Zero) return -1; Debug.WriteLine("Process ID " + x.Id + " is running: " + !Process.GetProcessById(x.Id).HasExited); return x.Id; } catch { // Ignore errors caused by processes that exited return -1; } }).Where(x => x >= 0); } private void FindAndAddProcessesToWatch(ICollection watchedProcesses, int[] runningProcessIds) { var candidates = Process.GetProcesses().Where(x => !runningProcessIds.Contains(x.Id)); foreach (var process in candidates) { try { if (process.MainModule!.FileName!.Contains( UninstallerEntry.InstallLocation, StringComparison.InvariantCultureIgnoreCase) || process.GetCommandLine().Contains( UninstallerEntry.InstallLocation, StringComparison.InvariantCultureIgnoreCase)) { watchedProcesses.Add(process); } } catch { // Ignore permission and access errors } } } /// /// Remove duplicate, dead, and blacklisted processes /// private static IEnumerable CleanupDeadProcesses(IEnumerable watchedProcesses, int[] runningProcessIds) { return watchedProcesses.DistinctBy(x => x.Id).Where(p => { try { if (p.HasExited) return false; var pName = p.ProcessName; if (NamesOfIgnoredProcesses.Any(n => pName.Equals(n, StringComparison.InvariantCultureIgnoreCase))) return false; } catch (Win32Exception) { return false; } catch (InvalidOperationException) { return false; } return !runningProcessIds.Contains(p.Id); }); } private sealed class PerfCounterEntry : IDisposable { public PerfCounterEntry(PerformanceCounter[] counter, CounterSample[] sample) { Counter = counter; Sample = sample; } public PerformanceCounter[] Counter { get; } public CounterSample[] Sample { get; } public void Dispose() { foreach (var performanceCounter in Counter) { performanceCounter?.Dispose(); } } } internal sealed class RunUninstallerOptions { public RunUninstallerOptions(bool autoKillStuckQuiet, bool retryFailedQuiet, bool preferQuiet, bool simulate, BulkUninstallTask owner) { AutoKillStuckQuiet = autoKillStuckQuiet; RetryFailedQuiet = retryFailedQuiet; PreferQuiet = preferQuiet; Simulate = simulate; Owner = owner; } public bool AutoKillStuckQuiet { get; } public bool PreferQuiet { get; } public bool RetryFailedQuiet { get; } public bool Simulate { get; } public BulkUninstallTask Owner { get; } } internal enum SkipCurrentLevel { None = 0, Terminate, Skip } public void Pause() { lock (_operationLock) { if (CurrentStatus == UninstallStatus.Waiting) CurrentStatus = UninstallStatus.Paused; } } public void Resume() { lock (_operationLock) { if (CurrentStatus == UninstallStatus.Paused) CurrentStatus = UninstallStatus.Waiting; } } } } ================================================ FILE: source/UninstallTools/Uninstaller/BulkUninstallTask.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.IO.Pipes; using System.Linq; using System.Threading; using Klocman.Extensions; using Klocman.Localising; namespace UninstallTools.Uninstaller { public sealed class BulkUninstallTask : IDisposable { private readonly object _operationLock = new(); private int _concurrentUninstallerCount = 1; private bool _finished; private Thread _workerThread; /// is null. /// /// The number of elements in is larger than /// . /// internal BulkUninstallTask(IReadOnlyList taskList, BulkUninstallConfiguration configuration) { Configuration = configuration ?? throw new ArgumentNullException(nameof(configuration)); if (taskList == null) throw new ArgumentNullException(nameof(taskList)); if (taskList.Count < 1) throw new ArgumentException("Task list can't be empty"); AllUninstallersList = new List(); for (var index = 0; index < taskList.Count; index++) { var bulkUninstallEntry = taskList[index]; bulkUninstallEntry.Id = index + 1; AllUninstallersList.Add(bulkUninstallEntry); } _finished = false; Aborted = false; } public bool Aborted { get; set; } public BulkUninstallConfiguration Configuration { get; } public bool Finished { get { return _finished; } private set { if (_finished == value) return; _finished = value; OnStatusChanged?.Invoke(this, EventArgs.Empty); } } public IList AllUninstallersList { get; } public int ConcurrentUninstallerCount { get { return _concurrentUninstallerCount; } set { _concurrentUninstallerCount = Math.Min(1000, Math.Max(1, value)); } } public bool OneLoudLimit { get; set; } = true; public void Dispose() { OnStatusChanged = null; _finished = true; } public event EventHandler OnStatusChanged; public static object DisplayNameAspectGetter(object rowObj) { var temp = rowObj as BulkUninstallEntry; return temp?.UninstallerEntry.DisplayName; } public static object IsSilentAspectGetter(object rowObj) { var temp = rowObj as BulkUninstallEntry; return temp?.IsSilentPossible.ToYesNo(); } public static object StatusAspectGetter(object rowObj) { if (rowObj is not BulkUninstallEntry temp) return null; var name = temp.CurrentStatus.GetLocalisedName(); if (temp.CurrentError != null) name = string.Concat(name, " - ", temp.CurrentError.Message); return name; } public void Start() { lock (_operationLock) { if (_workerThread != null && _workerThread.IsAlive) { if (!_workerThread.Join(TimeSpan.FromSeconds(10)) && !Finished) return; //if (Finished) //{ // if (!_workerThread.Join(TimeSpan.FromSeconds(10))) // _workerThread.Abort(); // else // return; //} //else // return; } Aborted = false; Finished = false; _workerThread = new Thread(UninstallWorkerThread) { Name = "RunBulkUninstall_Worker" }; _workerThread.Start(); } } private void UninstallWorkerThread() { var targetList = AllUninstallersList; var configuration = Configuration; if (targetList == null || configuration == null) throw new ArgumentException("BulkUninstallTask is incomplete, this should not have happened."); if (UninstallToolsGlobalConfig.UseQuietUninstallDaemon && configuration.PreferQuiet && AllUninstallersList.Any(x => x.IsSilentPossible)) StartAutomationDaemon(); try { StartOfLoop: while (AllUninstallersList.Any(x => x.CurrentStatus == UninstallStatus.Waiting || x.IsRunning)) { do { if (Aborted) { AllUninstallersList.ForEach(x => x.SkipWaiting(false)); break; } Thread.Sleep(500); } while (AllUninstallersList.Count(x => x.IsRunning) >= ConcurrentUninstallerCount); var running = AllUninstallersList.Where(x => x.CurrentStatus == UninstallStatus.Uninstalling).ToList(); var runningTypes = running.Select(y => y.UninstallerEntry.UninstallerKind).ToList(); var loudBlocked = OneLoudLimit && running.Any(y => !y.IsSilentPossible); var result = AllUninstallersList.FirstOrDefault(x => { if (x.CurrentStatus != UninstallStatus.Waiting || (loudBlocked && !x.IsSilentPossible)) return false; if (CheckForTypeCollisions(x.UninstallerEntry.UninstallerKind, runningTypes)) return false; if (CheckForAdvancedCollisions(x.UninstallerEntry, running.Select(y => y.UninstallerEntry))) return false; return true; }); if (result != null) { result.RunUninstaller( new BulkUninstallEntry.RunUninstallerOptions(configuration.AutoKillStuckQuiet, configuration.RetryFailedQuiet, configuration.PreferQuiet, configuration.Simulate, this)); // Fire the event now so the interface can be updated OnStatusChanged?.Invoke(this, EventArgs.Empty); } } if (AllUninstallersList.Any(x => x.CurrentStatus == UninstallStatus.Paused)) { Thread.Sleep(100); goto StartOfLoop; } } finally { StopAutomationDaemon(); Finished = true; } } private void StopAutomationDaemon() { try { using (_client) using (_writer) { _writer?.WriteLine(@"stop"); _client = null; _writer = null; } if (_quietUninstallDaemonProcess != null && !_quietUninstallDaemonProcess.HasExited) _quietUninstallDaemonProcess.WaitForExit(7000); } catch (SystemException ex) { Trace.WriteLine(@"Failed to peacefully close automatizer daemon: " + ex); try { _quietUninstallDaemonProcess?.Kill(); } catch (SystemException) { } } _quietUninstallDaemonProcess = null; } Process _quietUninstallDaemonProcess; private void StartAutomationDaemon() { if (!UninstallToolsGlobalConfig.UninstallerAutomatizerExists) UninstallToolsGlobalConfig.UseQuietUninstallDaemon = false; else { try { _quietUninstallDaemonProcess = Process.Start(UninstallToolsGlobalConfig.UninstallerAutomatizerPath, "/d"); try { _client = new NamedPipeClientStream(".", "UninstallAutomatizerDaemon", PipeDirection.Out); _writer = new StreamWriter(_client); _client.Connect(7000); _writer.AutoFlush = true; } catch (SystemException ex) { UninstallToolsGlobalConfig.UseQuietUninstallDaemon = false; Trace.WriteLine(@"Failed to connect to automatization daemon: " + ex); StopAutomationDaemon(); } } catch (SystemException ex) { UninstallToolsGlobalConfig.UseQuietUninstallDaemon = false; Trace.WriteLine(@"Failed to start automatization daemon:" + ex); } } } private NamedPipeClientStream _client; private StreamWriter _writer; internal void SendProcessesToWatchToDeamon(IEnumerable processIdsToAutomate) { if (_writer == null || _client == null || !_client.IsConnected) return; var pidList = processIdsToAutomate.ToList(); foreach (var pid in pidList) { Debug.WriteLine("Sending pid: " + pid + " to automatizer daemon"); _writer.WriteLine(pid.ToString(CultureInfo.InvariantCulture)); } } private static bool CheckForAdvancedCollisions(ApplicationUninstallerEntry target, IEnumerable running) { var entries = running.ToList(); if (entries.Any(x => x.PublisherTrimmed.Equals( target.PublisherTrimmed, StringComparison.InvariantCultureIgnoreCase))) return true; if (target.InstallLocation.IsNotEmpty() && entries.Any(x => x.InstallLocation.IsNotEmpty() && (x.InstallLocation.StartsWith(target.InstallLocation, StringComparison.InvariantCultureIgnoreCase) || target.InstallLocation.StartsWith(x.InstallLocation, StringComparison.InvariantCultureIgnoreCase)))) return true; if (target.UninstallerKind == UninstallerType.Msiexec) { var processes = Process.GetProcessesByName("msiexec"); if (processes.Length > 1) return true; } return false; } private static bool CheckForTypeCollisions(UninstallerType target, IEnumerable running) { switch (target) { // Might cause collisions with Msiexec, don't run concurrently case UninstallerType.Msiexec: case UninstallerType.InstallShield: case UninstallerType.SdbInst: case UninstallerType.WindowsFeature: case UninstallerType.WindowsUpdate: case UninstallerType.Unknown: // Chocolatey can use app's original uninstaller, so it's essentially unknown case UninstallerType.Chocolatey: // Scripts can do many things that could interfere case UninstallerType.PowerShell: target = UninstallerType.Msiexec; break; // Can be ran concurrently case UninstallerType.InnoSetup: case UninstallerType.Steam: case UninstallerType.Nsis: case UninstallerType.StoreApp: case UninstallerType.SimpleDelete: break; default: Debug.Fail("Unhandled UninstallerType - " + target); goto case UninstallerType.Unknown; } foreach (var item in running) { var x = item; if (x == UninstallerType.InstallShield || x == UninstallerType.WindowsFeature || x == UninstallerType.SdbInst || x == UninstallerType.Unknown) x = UninstallerType.Msiexec; if (x == target) { return true; } } return false; } } } ================================================ FILE: source/UninstallTools/Uninstaller/MsiUninstallModes.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ namespace UninstallTools.Uninstaller { public enum MsiUninstallModes { InstallModify, Uninstall, QuietUninstall } } ================================================ FILE: source/UninstallTools/Uninstaller/UninstallManager.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Threading; using Klocman.Extensions; using Klocman.Tools; using UninstallTools.Factory; using UninstallTools.Properties; namespace UninstallTools.Uninstaller { public static class UninstallManager { private const int SimulationDelay = 2500; /// /// Rename the uninstaller entry by changing registry data. The entry is not refreshed in the process. /// public static bool Rename(this ApplicationUninstallerEntry entry, string newName) { if (string.IsNullOrEmpty(newName) || newName.ContainsAny(StringTools.InvalidPathChars)) return false; using (var key = entry.OpenRegKey(true)) { key.SetValue(RegistryFactory.RegistryNameDisplayName, newName); } return true; } /// /// Uninstall multiple items in sequence. Items are uninstalled in order specified by the configuration. /// This is a non-blocking method, a controller object is returned for monitoring of the task. /// The task waits until an uninstaller fully exits before running the next one. /// /// Uninstallers to run. /// How the uninstallers should be ran. public static BulkUninstallTask CreateBulkUninstallTask(IReadOnlyList targets, BulkUninstallConfiguration configuration) { return new BulkUninstallTask(targets, configuration); } /// /// Start the default uninstaller with normal UI /// /// Uninstaller returned error code. /// There are no usable ways of uninstalling this entry /// Exception while decoding or attempting to run the uninstaller command. public static Process RunUninstaller(this ApplicationUninstallerEntry entry) { return RunUninstaller(entry, false, false); } /// /// Start selected uninstaller type. If selected type is not available, fall back to the default. /// /// Application to uninstall /// Choose quiet uninstaller if it's available. /// If true, nothing will actually be uninstalled /// Don't modify the uninstall command to try avoid problems. Use when normal run fails. /// Uninstaller returned error code. /// There are no usable ways of uninstalling this entry /// Exception while decoding or attempting to run the uninstaller command. public static Process RunUninstaller(this ApplicationUninstallerEntry entry, bool silentIfAvailable, bool simulate, bool safeMode = false) { if (entry == null) throw new ArgumentNullException(nameof(entry)); try { ProcessStartInfo startInfo = null; string fallBack = null; if (silentIfAvailable && entry.QuietUninstallPossible) { // Use supplied quiet uninstaller if any try { startInfo = ProcessTools.SeparateArgsFromCommand(entry.QuietUninstallString).ToProcessStartInfo(); Debug.Assert(!startInfo.FileName.Contains(' ') || File.Exists(startInfo.FileName)); if (QuietUninstallerIsCLI(entry)) { // Safe to minimize quiet command windows startInfo.WindowStyle = ProcessWindowStyle.Minimized; } } catch (FormatException) { fallBack = entry.QuietUninstallString; } } else if (entry.UninstallPossible) { // Fall back to the non-quiet uninstaller try { startInfo = ProcessTools.SeparateArgsFromCommand(entry.UninstallString).ToProcessStartInfo(); Debug.Assert(!startInfo.FileName.Contains(' ') || File.Exists(startInfo.FileName)); if (entry.UninstallerKind == UninstallerType.Nsis && !safeMode) UpdateNsisStartInfo(startInfo, entry.DisplayName); } catch (FormatException) { fallBack = entry.UninstallString; } } else { // Cant do shit, capt'n throw new InvalidOperationException(Localisation.UninstallError_Nowaytouninstall); } if (simulate) { Thread.Sleep(SimulationDelay); if (Debugger.IsAttached && new Random().Next(0, 2) == 0) throw new IOException("Random failure for debugging"); return null; } if (fallBack != null) return Process.Start(new ProcessStartInfo(fallBack) { UseShellExecute = true }); if (startInfo != null) { startInfo.UseShellExecute = true; return Process.Start(startInfo); } // Cant do shit, capt'n throw new InvalidOperationException(Localisation.UninstallError_Nowaytouninstall); } catch (IOException) { throw; } catch (InvalidOperationException) { throw; } catch (Exception ex) { throw new FormatException(ex.Message, ex); } } public static bool QuietUninstallerIsCLI(this ApplicationUninstallerEntry entry) { if (!entry.QuietUninstallPossible) return false; switch (entry.UninstallerKind) { case UninstallerType.PowerShell: case UninstallerType.Steam: case UninstallerType.WindowsFeature: case UninstallerType.WindowsUpdate: case UninstallerType.StoreApp: case UninstallerType.Oculus: return true; default: return entry.QuietUninstallString.StartsWith("cmd ", StringComparison.OrdinalIgnoreCase) || entry.QuietUninstallString.Contains("cmd.exe", StringComparison.OrdinalIgnoreCase); } } /// /// Check if NSIS needs to be executed directly to get the return code. If yes, update the ProcessStartInfo /// http://nsis.sourceforge.net/Docs/AppendixD.html#errorlevels /// private static void UpdateNsisStartInfo(ProcessStartInfo startInfo, string entryName) { var dirName = Path.GetFileName(Path.GetDirectoryName(startInfo.FileName)); if (!string.IsNullOrEmpty(startInfo.Arguments) // Only works reliably if uninstaller doesn't use any Arguments already. // Filter out non-standard uninstallers that might pose problems || !Path.GetFileNameWithoutExtension(startInfo.FileName).Contains("uninst", StringComparison.InvariantCultureIgnoreCase) || (dirName != null && dirName.Equals("uninstall", StringComparison.InvariantCultureIgnoreCase))) return; var newName = PathTools.SanitizeFileName(entryName); if (newName.Length > 8) newName = newName.Substring(0, 8); newName += "_" + Path.GetFileName(startInfo.FileName); var originalDirectory = Path.GetDirectoryName(startInfo.FileName)?.TrimEnd('\\'); Debug.Assert(originalDirectory != null); startInfo.Arguments = "_?=" + originalDirectory; var tempPath = Path.Combine(Path.GetTempPath(), newName); File.Copy(startInfo.FileName, tempPath, true); startInfo.FileName = tempPath; } /// /// Uninstall using msiexec in selected mode. If no guid is present nothing is done and -1 is returned. /// /// Application to uninstall /// Mode of the MsiExec run. /// If true, nothing will be actually uninstalled /// Uninstaller returned error code. /// There are no usable ways of uninstalling this entry /// Exception while decoding or attempting to run the uninstaller command. public static int UninstallUsingMsi(this ApplicationUninstallerEntry entry, MsiUninstallModes mode, bool simulate) { try { var uninstallPath = GetMsiString(entry.BundleProviderKey, mode); if (string.IsNullOrEmpty(uninstallPath)) return -1; var startInfo = ProcessTools.SeparateArgsFromCommand(uninstallPath).ToProcessStartInfo(); startInfo.UseShellExecute = false; if (simulate) { Thread.Sleep(SimulationDelay); return 0; } return startInfo.StartAndWait(); } catch (IOException) { throw; } catch (InvalidOperationException) { throw; } catch (Exception ex) { throw new FormatException(ex.Message, ex); } } internal static string GetMsiString(Guid bundleProviderKey, MsiUninstallModes mode) { if (bundleProviderKey == Guid.Empty) return string.Empty; switch (mode) { case MsiUninstallModes.InstallModify: return $@"MsiExec.exe /I{bundleProviderKey:B}"; case MsiUninstallModes.QuietUninstall: return $@"MsiExec.exe /qb /X{bundleProviderKey:B} REBOOT=ReallySuppress /norestart"; case MsiUninstallModes.Uninstall: return $@"MsiExec.exe /X{bundleProviderKey:B}"; default: throw new ArgumentOutOfRangeException(nameof(mode), mode, @"Unknown mode"); } } public static int Modify(this ApplicationUninstallerEntry entry, bool simulate) { try { if (string.IsNullOrEmpty(entry.ModifyPath)) return -1; var startInfo = ProcessTools.SeparateArgsFromCommand(entry.ModifyPath).ToProcessStartInfo(); startInfo.UseShellExecute = false; if (simulate) { Thread.Sleep(SimulationDelay); return 0; } return startInfo.StartAndWait(); } catch (IOException) { throw; } catch (InvalidOperationException) { throw; } catch (Exception ex) { throw new FormatException(ex.Message, ex); } } } } ================================================ FILE: source/UninstallTools/Uninstaller/UninstallStatus.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using Klocman.Localising; using UninstallTools.Properties; namespace UninstallTools.Uninstaller { public enum UninstallStatus { [LocalisedName(typeof(Localisation), "UninstallStatus_Uninstalling")] Uninstalling, [LocalisedName(typeof(Localisation), "UninstallStatus_Waiting")] Waiting, [LocalisedName(typeof(Localisation), "UninstallStatus_Completed")] Completed, [LocalisedName(typeof(Localisation), "UninstallStatus_Failed")] Failed, [LocalisedName(typeof(Localisation), "UninstallStatus_Skipped")] Skipped, [LocalisedName(typeof(Localisation), "UninstallStatus_Protected")] Protected, [LocalisedName(typeof(Localisation), "UninstallStatus_Invalid")] Invalid, [LocalisedName(typeof(Localisation), "UninstallStatus_Paused")] Paused } } ================================================ FILE: source/UninstallTools/UninstallerType.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using Klocman.Localising; using UninstallTools.Properties; namespace UninstallTools { public enum UninstallerType { [LocalisedName(typeof(Localisation), "UninstallerType_Unknown")] Unknown = 0, [LocalisedName(typeof(Localisation), "UninstallerType_Msiexec")] Msiexec, [LocalisedName(typeof(Localisation), "UninstallerType_InnoSetup")] InnoSetup, [LocalisedName(typeof(Localisation), "UninstallerType_Steam")] Steam, [LocalisedName(typeof(Localisation), "UninstallerType_NSIS")] Nsis, [LocalisedName(typeof(Localisation), "UninstallerType_InstallShield")] InstallShield, [LocalisedName(typeof(Localisation), "UninstallerType_SdbInst")] SdbInst, [LocalisedName(typeof(Localisation), "UninstallerType_WindowsFeature")] WindowsFeature, [LocalisedName(typeof(Localisation), "UninstallerType_WindowsUpdate")] WindowsUpdate, [LocalisedName(typeof(Localisation), "UninstallerType_StoreApp")] StoreApp, [LocalisedName(typeof(Localisation), "UninstallerType_SimpleDelete")] SimpleDelete, [LocalisedName(typeof(Localisation), "UninstallerType_Chocolatey")] Chocolatey, [LocalisedName(typeof(Localisation), "UninstallerType_Oculus")] Oculus, [LocalisedName(typeof(Localisation), nameof(Localisation.UninstallerType_PowerShell))] PowerShell } } ================================================ FILE: source/UninstallerAutomatizer/Automation/AutomatedUninstallManager.cs ================================================ /* Copyright (c) 2017 Marcin Szeniak (https://github.com/Klocman/) Apache License Version 2.0 */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Resources; using System.Threading; using System.Windows.Forms; using FlaUI.Adapter.White; using FlaUI.Core.AutomationElements; using FlaUI.Core.Definitions; using FlaUI.Core.WindowsAPI; using FlaUI.UIA3; using Klocman.Extensions; using Klocman.Tools; using TestStack.White.UIItems; using TestStack.White.UIItems.Finders; using TestStack.White.WindowsAPI; using UninstallerAutomatizer.Properties; using Application = FlaUI.Core.Application; using Button = FlaUI.Core.AutomationElements.Button; namespace UninstallerAutomatizer { public static class AutomatedUninstallManager { private const string NsisRebootNowRadioAutomationId = "1203"; private const string NsisRebootLaterRadioAutomationId = "1204"; private const string NsisForwardAutomationId = "1"; private const string NsisCancelAutomationId = "2"; private const string NsisYesAutomationId = "6"; private const string NsisNoAutomationId = "7"; private static readonly string[] GoodRadioIds = { NsisRebootLaterRadioAutomationId }; private static readonly string[] BadRadioIds = { NsisRebootNowRadioAutomationId }; private static readonly string[] BadButtonIds = { NsisNoAutomationId }; private static readonly string[] CancelButtonIds = { NsisCancelAutomationId }; private static readonly string[] GoodButtonIds = { NsisForwardAutomationId, NsisYesAutomationId }; private static readonly string[] ControlBoxButtonIds = { "Minimize", "Maximize", "Close" }; private static readonly string[] GoodButtonNames; private static readonly string[] CancelButtonNames; private static readonly string[] BadButtonNames; private static bool _hideAutomatizedWindows = true; static AutomatedUninstallManager() { var loc = Localization.Culture; var rm = new ResourceManager(typeof(Localization)); var validCultureInfos = CultureInfo.GetCultures(CultureTypes.AllCultures) .Where(c => rm.GetResourceSet(c, true, false) != null) .ToList(); string[] GetValuesFromAllLanguages(IEnumerable cultureInfos, Func targetFieldSelector) { return cultureInfos .Do(c => Localization.Culture = c) .SelectMany(_ => targetFieldSelector().Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries)) .Select(x => x.Trim().ToLowerInvariant()) .Where(x => !string.IsNullOrWhiteSpace(x)) .Distinct() .ToArray(); } GoodButtonNames = GetValuesFromAllLanguages(validCultureInfos, () => Localization.Auto_GoodButtons); CancelButtonNames = GetValuesFromAllLanguages(validCultureInfos, () => Localization.Auto_CancelButtons); BadButtonNames = GetValuesFromAllLanguages(validCultureInfos, () => Localization.Auto_BadButtons); Localization.Culture = loc; WhiteAdapter.Initialize(new UIA3Automation()); } public static event EventHandler HideAutomatizedWindowsChanged; public static bool HideAutomatizedWindows { get => _hideAutomatizedWindows; set { if (_hideAutomatizedWindows == value) return; _hideAutomatizedWindows = value; HideAutomatizedWindowsChanged?.Invoke(null, EventArgs.Empty); } } /// /// Automate uninstallation of an NSIS uninstaller. /// /// Command line used to launch the NSIS uninstaller. (Usually path to uninstall.exe.) /// Information about the process is relayed here public static void UninstallNsisQuietly(string uninstallerCommand, Action statusCallback) { Process pr = null; Application app = null; try { pr = ProcessTools.SeparateArgsFromCommand(uninstallerCommand).ToProcessStartInfo().Start(); if (pr == null) throw new IOException(Localization.Message_Automation_ProcessFailedToStart); // NSIS uninstallers are first extracted by the executable to a temporary directory, and then ran from there. // Wait for the extracting exe to close and grab the child process that it started. statusCallback(Localization.Message_Automation_WaitingForNsisExtraction); pr.WaitForExit(); // Attempt to get the extracted exe by looking up child processes, might not work in some cases var prs = ProcessTools.GetChildProcesses(pr.Id).FirstOrDefault(); if (prs != 0) { app = Application.Attach(prs); } else { // Get all processes with name in format [A-Z]u_ (standard NSIS naming scheme, e.g. "Au_.exe") // and select the last one to launch. (Most likely to be ours) var uninstallProcess = Process.GetProcesses() .Where(x => x.ProcessName.Length == 3 && x.ProcessName.EndsWith("u_", StringComparison.Ordinal)) .OrderByDescending(x => x.StartTime).First(); app = Application.Attach(uninstallProcess); } } catch (Exception e) { var process = app != null ? ProcessTools.GetProcessByIdSafe(app.ProcessId) : null; throw new AutomatedUninstallException(Localization.Message_Automation_Failed, e, uninstallerCommand, process ?? pr); } if (app != null) AutomatizeApplication(app, statusCallback); } public static void AutomatizeApplication(Application app, Action statusCallback) { if (app == null) throw new ArgumentNullException(nameof(app)); if (statusCallback == null) throw new ArgumentNullException(nameof(statusCallback)); var windows = new List(); void VisibleChangedHandler(object sender, EventArgs args) => SetWindowVisibility(windows, HideAutomatizedWindows); HideAutomatizedWindowsChanged += VisibleChangedHandler; try { statusCallback(string.Format(Localization.Message_Automation_AppAttached, app.Name)); WaitForApplication(app); var seenWindows = new List(); while (!app.HasExited) { statusCallback(Localization.Message_Automation_WindowSearching); // NSIS uninstallers always have only one window open (by default) windows.Clear(); windows.AddRange(app.GetAllTopLevelWindows(WhiteAdapter.Automation)); SetWindowVisibility(windows, HideAutomatizedWindows); var target = windows.FirstOrDefault(); if (target == null) { Thread.Sleep(1000); continue; } statusCallback(string.Format(Localization.Message_Automation_WindowFound, target.Title)); WaitForWindow(target); while (target.IsAvailable && target.IsEnabled) { TryClickNextNsisButton(target, statusCallback); WaitForWindow(target); ProcessNsisPopups(app, target, seenWindows, statusCallback); } statusCallback(Localization.Message_Automation_WindowClosed); WaitForApplication(app); } } catch (Exception e) { var process = ProcessTools.GetProcessByIdSafe(app.ProcessId); if (app.HasExited || process?.HasExited == true) return; throw new AutomatedUninstallException(Localization.Message_Automation_Failed, e, string.Empty, process); } finally { HideAutomatizedWindowsChanged -= VisibleChangedHandler; } } private static void SetWindowVisibility(IEnumerable windows, bool hide) { var primaryScreenBounds = Screen.PrimaryScreen.Bounds; foreach (var window in windows) { try { if (hide) { // Move window mostly off-screen. A part of it has to be on some screen for teststack to work properly. window.Move(primaryScreenBounds.Right - 1, primaryScreenBounds.Bottom - 1); } else { var b = window.BoundingRectangle; // Move window to main screen center window.Move(primaryScreenBounds.X + primaryScreenBounds.Width / 2 - b.Width / 2, primaryScreenBounds.Y + primaryScreenBounds.Height / 2 - b.Height / 2); } } catch (SystemException e) { Console.WriteLine(e); } } } /// /// Wait for the application to become ready for input. /// private static void WaitForApplication(Application app) { app.WaitWhileBusy(); Thread.Sleep(100); } /// /// Wait for the window to become ready for input. /// private static void WaitForWindow(Window target) { var totalTimeouts = 0; while (target.IsAvailable && target.IsEnabled && totalTimeouts < 60) // wait for at most 1 minute { try { target.WaitUntilClickable(TimeSpan.FromSeconds(1)); break; } catch (TimeoutException) { totalTimeouts++; } } Thread.Sleep(100); } private static void ProcessNsisPopups(Application app, Window mainWindow, ICollection seenWindows, Action statusCallback) { // Check for popups, they are opened as an extra window. var currentWindows = app.GetAllTopLevelWindows(WhiteAdapter.Automation); var popupWindow = currentWindows.SingleOrDefault(x => !x.Equals(mainWindow)); if (popupWindow == null) { popupWindow = mainWindow.ModalWindows.FirstOrDefault(); if (popupWindow == null) return; } var footprint = string.Join(";", popupWindow.FindAllChildren().Select(x => x.Name)) + popupWindow.Title + popupWindow.ActualWidth + popupWindow.ActualHeight; if (seenWindows.Contains(footprint)) throw new InvalidOperationException(Localization.Message_Automation_PopupRecurringFound); seenWindows.Add(footprint); statusCallback(string.Format(Localization.Message_Automation_PopupFound, popupWindow.Title)); while (!popupWindow.IsAvailable) { TryClickNextNsisButton(popupWindow, statusCallback); app.WaitWhileBusy(); popupWindow.WaitUntilClickable(); Thread.Sleep(100); } statusCallback(Localization.Message_Automation_PopupClosed); } private static void TryClickNextNsisButton(Window target, Action statusCallback) { statusCallback("Looking for buttons to press..."); var allButtons = target.FindAllChildren(SearchCriteria.ConditionFactory.ByControlType(ControlType.Button)) .Select(x => x.AsButton()) .ToList(); var filteredButtons = allButtons .Where(x => x.IsEnabled) .Where(NotControlBoxButton) .ToList(); var cancelButtons = FilterButtonsByName(filteredButtons, CancelButtonNames) .Concat(FilterButtonsById(filteredButtons, CancelButtonIds) .Except(FilterButtonsByName(filteredButtons, GoodButtonNames)) .Except(FilterButtonsByName(filteredButtons, BadButtonNames))) .ToList(); filteredButtons.RemoveAll(cancelButtons); var badButtons = FilterButtonsById(filteredButtons, BadButtonIds) .Concat(FilterButtonsByName(filteredButtons, BadButtonNames)).ToList(); var applicableButtons = filteredButtons.Count == 1 ? filteredButtons : filteredButtons.Except(badButtons).ToList(); if (applicableButtons.Any()) { var nextButton = FilterButtonsByName(applicableButtons, GoodButtonNames) .Concat(FilterButtonsById(applicableButtons, GoodButtonIds)) .FirstOrDefault(); if (nextButton == null) { if (applicableButtons.Count == 1 && cancelButtons.Any() && allButtons.All(x => x.IsEnabled)) { // If there is only one valid button, and the rest are cancel buttons, // assume the valid button is the correct choice. nextButton = applicableButtons.Single(); } else { //Debug.Fail("Nothing to press!"); return; } } ProcessRadioButtons(target, statusCallback); statusCallback(string.Format(Localization.Message_Automation_ClickingButton, nextButton.AutomationId)); // Finally press the button, doesn't require messing with the mouse. //nextButton.RaiseClickEvent(); target.Focus(); nextButton.Focus(); nextButton.KeyIn(KeyboardInput.SpecialKeys.RETURN); } } private static void ProcessRadioButtons(Window target, Action statusCallback) { var allRadios = target.FindAllChildren(SearchCriteria.ConditionFactory.ByControlType(ControlType.RadioButton)) .Select(x => x.AsRadioButton()).ToList(); if (allRadios.Any()) { statusCallback(string.Format(Localization.Message_Automation_FoundButtons, allRadios.Count)); // Select all known good radio buttons first var goodRadios = allRadios.Where(x => GoodRadioIds.Any( y => y.Equals(x.AutomationId, StringComparison.OrdinalIgnoreCase))); foreach (var radioButton in goodRadios) { if (radioButton.IsEnabled) { statusCallback(string.Format(Localization.Message_Automation_SelectingGoodButton, radioButton.Name)); radioButton.IsChecked = true; } } // Check if any known bad radio buttons are still enabled. If yes, select other, non-bad buttons. var badRadios = allRadios.Where(x => BadRadioIds.Any( y => y.Equals(x.AutomationId, StringComparison.OrdinalIgnoreCase))).ToList(); if (badRadios.Any(x => x.IsEnabled && x.IsChecked)) { foreach (var notBadRadio in allRadios.Except(badRadios)) { if (notBadRadio.IsEnabled) { statusCallback(string.Format(Localization.Message_Automation_SelectingNotBadButton, notBadRadio.Name)); notBadRadio.IsChecked = true; } } } } } private static IEnumerable