-
Notifications
You must be signed in to change notification settings - Fork 59
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
External translations, Refactored Silent mode
Refactored silent mode code before pull #12 arrived, but integrated some features from it. Translations will be available shortly.
- Loading branch information
1 parent
2388732
commit 65094ee
Showing
19 changed files
with
541 additions
and
273 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
namespace SuperFishRemovalTool.Localization | ||
{ | ||
public class AppStrings | ||
{ | ||
public string UtilityAbout { get; set; } | ||
public string UtilityName { get; set; } | ||
public string Version { get; set; } | ||
|
||
public string AboutSuperfish { get; set; } | ||
public string AboutThisTool { get; set; } | ||
|
||
public string DetectorNameApp { get; set; } | ||
public string DetectorNameReg { get; set; } | ||
public string DetectorNameCert { get; set; } | ||
public string DetectorNameFile { get; set; } | ||
public string DetectorNameMozilla { get; set; } | ||
|
||
public string SelectRemoveToStart { get; set; } | ||
|
||
public string StatusRegNotExists { get; set; } | ||
public string Remove { get; set; } | ||
public string CloseWebBrowsers { get; set; } | ||
public string LearnMoreText { get; set; } | ||
public string LearnMoreLocation { get; set; } | ||
public string RemovalCompleteMessage { get; set; } | ||
|
||
public string ResultFoundAndRemoved { get; set; } | ||
public string ResultFoundButNotRemoved { get; set; } | ||
public string ResultNotFound { get; set; } | ||
public string Error { get; set; } | ||
|
||
public string OverallStatusAppRemoved { get; set; } | ||
public string OverallStatusError { get; set; } | ||
public string OverallStatusNotOnSystem { get; set; } | ||
|
||
public string RestartNow { get; set; } | ||
public string RestartLater { get; set; } | ||
|
||
public string MoreInformationText { get; set; } | ||
public string ManualRemovalInstructionsText { get; set; } | ||
public string ManualRemovalInstructionsLink { get; set; } | ||
public string LenovoSecurityAdvisoryLink { get; set; } | ||
public string LenovoSecurityAdvisoryText { get; set; } | ||
public string LenovoStatementText { get; set; } | ||
public string LenovoStatementLink { get; set; } | ||
public string LicenseAgreementText { get; set; } | ||
public string LicenseAgreementLink { get; set; } | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
<?xml version="1.0" encoding="utf-8" ?> | ||
<LocalizationSet language="en"> | ||
<ItemList> | ||
<Item key="DetectorNameApp">Superfish Application</Item> | ||
<Item key="DetectorNameReg">Superfish Registry entries</Item> | ||
<Item key="DetectorNameCert">SuperFish Root Certificate</Item> | ||
<Item key="DetectorNameFile">SuperFish Files</Item> | ||
<Item key="DetectorNameMozilla">SuperFish Root Certificate for Mozilla products</Item> | ||
<Item key="Version">Version</Item> | ||
<Item key="AboutSuperfish">SuperFish was pre-installed on a limited group of Lenovo branded notebooks beginning September, 2014. Lenovo recommends removing SuperFish and the SuperFish certificates from all systems.</Item> | ||
|
||
<Item key="AboutThisTool">This utility will completely analyze your system for this problem and remove the SuperFish application, associated registry entries, files and security certificates, if needed.</Item> | ||
<Item key="UtilityName">SuperFish Removal Utility</Item> | ||
<Item key="SelectRemoveToStart">Select 'Remove' to start</Item> | ||
<Item key="CloseWebBrowsers">Please close all browsers before continuing</Item> | ||
<Item key="Remove">Analyze and Remove SuperFish Now</Item> | ||
<Item key="LearnMoreText">Click here to learn about this tool</Item> | ||
<Item key="LearnMoreLocation">http://forums.lenovo.com/t5/Lenovo-P-Y-and-Z-series/Removal-Instructions-for-VisualDiscovery-Superfish-application/ta-p/2029206</Item> | ||
<Item key="RemovalCompleteMessage"></Item> | ||
<Item key="OverallStatusAppRemoved">SuperFish was removed from this system. We recommend restarting your system.</Item> | ||
<Item key="OverallStatusError">Error: We could not remove one or more components. We recommend you follow the manual removal instructions below.</Item> | ||
<Item key="OverallStatusNotOnSystem">Complete: SuperFish was not found on this system and no action is required.</Item> | ||
<Item key="RestartNow">Restart now</Item> | ||
<Item key="RestartLater">Restart later</Item> | ||
<Item key="ResultFoundAndRemoved">Found and removed</Item> | ||
<Item key="ResultFoundButNotRemoved">Found but not removed</Item> | ||
<Item key="ResultNotFound">Not Found</Item> | ||
<Item key="Error">Error</Item> | ||
<Item key="MoreInformationText">More information:</Item> | ||
<Item key="ManualRemovalInstructionsText">Manual Removal Instructions</Item> | ||
<Item key="LenovoSecurityAdvisoryText">Lenovo Security Advisory</Item> | ||
<Item key="LenovoStatementText">Lenovo Statement</Item> | ||
<Item key="LenovoStatementLink">http://news.lenovo.com/article_display.cfm?article_id=1929</Item> | ||
<Item key="ManualRemovalInstructionsLink">http://support.lenovo.com/us/en/product_security/superfish_uninstall</Item> | ||
<Item key="LenovoSecurityAdvisoryLink">http://support.lenovo.com/us/en/product_security/superfish</Item> | ||
<Item key="LicenseAgreementLink">http://support.lenovo.com/us/en/documents/ht100141</Item> | ||
<Item key="LicenseAgreementText">Lenovo License Agreement</Item> | ||
</ItemList> | ||
</LocalizationSet> |
161 changes: 161 additions & 0 deletions
161
SuperFishRemovalTool/Localization/LocalizationManager.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
namespace SuperFishRemovalTool.Localization | ||
{ | ||
/// <summary> | ||
/// Responsible for loading strongly typed localizations from embedded XML translation files | ||
/// </summary> | ||
/// <remarks> | ||
/// The primary reason for not using standard localization (resx) is to avoid satellite assemblies | ||
/// </remarks> | ||
internal static class LocalizationManager | ||
{ | ||
/// <summary> | ||
/// Gets a set of translations for the most applicable user language | ||
/// </summary> | ||
/// <returns></returns> | ||
public static AppStrings Get() | ||
{ | ||
if (_cachedAppStrings == null) | ||
{ | ||
AppStrings appStrings = null; | ||
try | ||
{ | ||
LocalizationSet localizations = LocateIdealTranslationFile(translationFilePrefix: "AppStrings"); | ||
appStrings = MapTranslationItemsToStronglyTypedInstance<AppStrings>(localizations); | ||
} | ||
catch(Exception ex) | ||
{ | ||
Logging.Logger.Log(ex, "Unable to locate translations"); | ||
} | ||
|
||
_cachedAppStrings = appStrings ?? new AppStrings(); // prevent from trying again | ||
} | ||
return _cachedAppStrings; | ||
} | ||
|
||
private static AppStrings _cachedAppStrings; | ||
|
||
/// <summary> | ||
/// Examines embedded translation files and looks for the most ideal one based on current culture | ||
/// </summary> | ||
/// <returns></returns> | ||
private static LocalizationSet LocateIdealTranslationFile(string translationFilePrefix) | ||
{ | ||
LocalizationSet localizationSet = null; | ||
var currentCulture = System.Threading.Thread.CurrentThread.CurrentUICulture; | ||
var listOfTranslationFiles = GetLocalizationFilePaths(); | ||
if(listOfTranslationFiles == null || !listOfTranslationFiles.Any()) | ||
{ | ||
throw new Exception("No localization files found"); | ||
} | ||
|
||
List<string> prioritizedLanguages = new List<string>() | ||
{ | ||
currentCulture.Name, // "en-US" | ||
currentCulture.TwoLetterISOLanguageName, // "en" | ||
"en", // en is default | ||
}; | ||
|
||
foreach(var priority in prioritizedLanguages) | ||
{ | ||
string predictedFileName = String.Format("{0}_{1}.xml", translationFilePrefix, priority); | ||
try | ||
{ | ||
string foundMatchingTranslationFile = listOfTranslationFiles.FirstOrDefault(filePath => | ||
!String.IsNullOrWhiteSpace(filePath) && | ||
filePath.EndsWith(predictedFileName, StringComparison.InvariantCultureIgnoreCase)); | ||
|
||
if (!String.IsNullOrWhiteSpace(foundMatchingTranslationFile)) | ||
{ | ||
localizationSet = LoadStringsFromFile(foundMatchingTranslationFile); | ||
if(localizationSet != null) | ||
{ | ||
break; | ||
} | ||
} | ||
} | ||
catch(Exception ex) | ||
{ | ||
Logging.Logger.Log(ex, "Unable to process localization file {0} ", predictedFileName); | ||
} | ||
} | ||
|
||
if(localizationSet == null) | ||
{ | ||
throw new System.IO.FileNotFoundException("No valid translation files matching expected values"); | ||
} | ||
return localizationSet; | ||
} | ||
|
||
/// <summary> | ||
/// Maps each item in a localized set into a strongly typed stringtable | ||
/// </summary> | ||
/// <typeparam name="T">The type that contains properties for each string</typeparam> | ||
/// <param name="translations"></param> | ||
/// <returns></returns> | ||
private static T MapTranslationItemsToStronglyTypedInstance<T>(LocalizationSet translations) where T : class | ||
{ | ||
T result = (T)Activator.CreateInstance(typeof(T)); | ||
|
||
var properties = typeof(T).GetProperties(); | ||
foreach(var property in properties) | ||
{ | ||
string name = property.Name; | ||
var matchingTranslatedItem = translations.ItemList.FirstOrDefault(item => | ||
item.Key != null && | ||
item.Key.Equals(property.Name, StringComparison.InvariantCultureIgnoreCase)); | ||
if (matchingTranslatedItem != null) | ||
{ | ||
property.SetMethod.Invoke(result, new object[] { matchingTranslatedItem.Value }); | ||
} | ||
} | ||
|
||
|
||
return result; | ||
} | ||
|
||
/// <summary> | ||
/// Deserializes a translation xml file into an instance | ||
/// </summary> | ||
/// <param name="filePath"></param> | ||
/// <returns></returns> | ||
private static LocalizationSet LoadStringsFromFile(string filePath) | ||
{ | ||
LocalizationSet set = null; | ||
using (var stream = (System.Reflection.Assembly.GetExecutingAssembly() | ||
.GetManifestResourceStream(filePath))) | ||
{ | ||
using (var reader = new System.IO.StreamReader(stream)) | ||
{ | ||
string xmlFileContents = reader.ReadToEnd(); | ||
var deserializedObject = Serializer.Deserialize<LocalizationSet>(xmlFileContents); | ||
set = deserializedObject; | ||
|
||
} | ||
} | ||
return set; | ||
} | ||
|
||
/// <summary> | ||
/// Locates all xml files that may be translation files | ||
/// </summary> | ||
/// <returns></returns> | ||
private static IEnumerable<string> GetLocalizationFilePaths() | ||
{ | ||
var dataFiles = System.Reflection.Assembly.GetExecutingAssembly() | ||
.GetManifestResourceNames() | ||
.Where(s => | ||
s.StartsWith(typeof(LocalizationManager).Namespace) && | ||
s.EndsWith(".xml")); | ||
return dataFiles; | ||
} | ||
|
||
} | ||
|
||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
using System.Xml.Serialization; | ||
|
||
namespace SuperFishRemovalTool.Localization | ||
{ | ||
[XmlRoot(ElementName = "LocalizationSet", Namespace = null)] | ||
public class LocalizationSet | ||
{ | ||
[XmlAttribute(AttributeName = "language")] | ||
public string Language { get; set; } | ||
|
||
[XmlArray("ItemList")] | ||
[XmlArrayItem("Item")] | ||
public Item[] ItemList { get; set; } | ||
} | ||
|
||
public class Item | ||
{ | ||
[XmlAttribute(AttributeName = "key")] | ||
public string Key { get; set; } | ||
[XmlText] | ||
public string Value { get; set; } | ||
|
||
} | ||
} |
Oops, something went wrong.