392 lines
13 KiB
C#
392 lines
13 KiB
C#
/********************************************************************++
|
|
Copyright (c) Microsoft Corporation. All rights reserved.
|
|
--********************************************************************/
|
|
using System;
|
|
using System.Globalization;
|
|
using System.IO;
|
|
using System.Management.Automation.Internal;
|
|
using System.Management.Automation;
|
|
using System.Text;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
|
|
namespace Microsoft.PowerShell.Commands
|
|
{
|
|
/// <summary>
|
|
/// The implementation of the "import-localizeddata" cmdlet
|
|
/// </summary>
|
|
///
|
|
[Cmdlet(VerbsData.Import, "LocalizedData", HelpUri = "http://go.microsoft.com/fwlink/?LinkID=113342")]
|
|
public sealed class ImportLocalizedData : PSCmdlet
|
|
{
|
|
#region Parameters
|
|
|
|
/// <summary>
|
|
/// The path from which to import the aliases
|
|
/// </summary>
|
|
///
|
|
[Parameter(Position = 0)]
|
|
[Alias("Variable")]
|
|
[ValidateNotNullOrEmpty]
|
|
public string BindingVariable
|
|
{
|
|
get
|
|
{
|
|
return _bindingVariable;
|
|
}
|
|
|
|
set
|
|
{
|
|
_bindingVariable = value;
|
|
}
|
|
}
|
|
private string _bindingVariable;
|
|
|
|
/// <summary>
|
|
/// The scope to import the aliases to.
|
|
/// </summary>
|
|
///
|
|
[Parameter(Position = 1)]
|
|
public string UICulture
|
|
{
|
|
get
|
|
{
|
|
return _uiculture;
|
|
}
|
|
|
|
set
|
|
{
|
|
_uiculture = value;
|
|
}
|
|
}
|
|
private string _uiculture;
|
|
|
|
/// <summary>
|
|
/// The scope to import the aliases to.
|
|
/// </summary>
|
|
///
|
|
[Parameter]
|
|
public string BaseDirectory
|
|
{
|
|
get
|
|
{
|
|
return _baseDirectory;
|
|
}
|
|
|
|
set
|
|
{
|
|
_baseDirectory = value;
|
|
}
|
|
}
|
|
private string _baseDirectory;
|
|
|
|
/// <summary>
|
|
/// The scope to import the aliases to.
|
|
/// </summary>
|
|
///
|
|
[Parameter]
|
|
public string FileName
|
|
{
|
|
get
|
|
{
|
|
return _fileName;
|
|
}
|
|
|
|
set
|
|
{
|
|
_fileName = value;
|
|
}
|
|
}
|
|
private string _fileName;
|
|
|
|
/// <summary>
|
|
/// The command allowed in the data file. If unspecified, then ConvertFrom-StringData
|
|
/// is allowed.
|
|
/// </summary>
|
|
[Parameter]
|
|
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Justification = "Cmdlets use arrays for parameters.")]
|
|
public string[] SupportedCommand
|
|
{
|
|
get
|
|
{
|
|
return _commandsAllowed;
|
|
}
|
|
set
|
|
{
|
|
setSupportedCommand = true;
|
|
_commandsAllowed = value;
|
|
}
|
|
}
|
|
private string[] _commandsAllowed = new string[] { "ConvertFrom-StringData" };
|
|
private bool setSupportedCommand = false;
|
|
|
|
#endregion Parameters
|
|
|
|
#region Command code
|
|
|
|
/// <summary>
|
|
/// The main processing loop of the command.
|
|
/// </summary>
|
|
///
|
|
protected override void ProcessRecord()
|
|
{
|
|
string path = GetFilePath();
|
|
|
|
if (path == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!File.Exists(path))
|
|
{
|
|
InvalidOperationException ioe =
|
|
PSTraceSource.NewInvalidOperationException(
|
|
ImportLocalizedDataStrings.FileNotExist,
|
|
path);
|
|
WriteError(new ErrorRecord(ioe, "ImportLocalizedData", ErrorCategory.ObjectNotFound, path));
|
|
return;
|
|
}
|
|
|
|
// Prevent additional commands in ConstrainedLanguage mode
|
|
if (Context.LanguageMode == PSLanguageMode.ConstrainedLanguage)
|
|
{
|
|
if (setSupportedCommand)
|
|
{
|
|
NotSupportedException nse =
|
|
PSTraceSource.NewNotSupportedException(
|
|
ImportLocalizedDataStrings.CannotDefineSupportedCommand);
|
|
ThrowTerminatingError(
|
|
new ErrorRecord(nse, "CannotDefineSupportedCommand", ErrorCategory.PermissionDenied, null));
|
|
}
|
|
}
|
|
|
|
string script = GetScript(path);
|
|
if (script == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
try
|
|
{
|
|
var scriptBlock = Context.Engine.ParseScriptBlock(script, false);
|
|
scriptBlock.CheckRestrictedLanguage(SupportedCommand, null, false);
|
|
object result;
|
|
PSLanguageMode oldLanguageMode = Context.LanguageMode;
|
|
Context.LanguageMode = PSLanguageMode.RestrictedLanguage;
|
|
try
|
|
{
|
|
result = scriptBlock.InvokeReturnAsIs();
|
|
if (result == AutomationNull.Value)
|
|
{
|
|
result = null;
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
Context.LanguageMode = oldLanguageMode;
|
|
}
|
|
|
|
if (_bindingVariable != null)
|
|
{
|
|
VariablePath variablePath = new VariablePath(_bindingVariable);
|
|
if (variablePath.IsUnscopedVariable)
|
|
{
|
|
variablePath = variablePath.CloneAndSetLocal();
|
|
}
|
|
|
|
if (string.IsNullOrEmpty(variablePath.UnqualifiedPath))
|
|
{
|
|
InvalidOperationException ioe = PSTraceSource.NewInvalidOperationException(
|
|
ImportLocalizedDataStrings.IncorrectVariableName, _bindingVariable);
|
|
WriteError(new ErrorRecord(ioe, "ImportLocalizedData", ErrorCategory.InvalidArgument,
|
|
_bindingVariable));
|
|
return;
|
|
}
|
|
|
|
SessionStateScope scope = null;
|
|
PSVariable variable = SessionState.Internal.GetVariableItem(variablePath, out scope);
|
|
|
|
if (variable == null)
|
|
{
|
|
variable = new PSVariable(variablePath.UnqualifiedPath, result, ScopedItemOptions.None);
|
|
Context.EngineSessionState.SetVariable(variablePath, variable, false, CommandOrigin.Internal);
|
|
}
|
|
else
|
|
{
|
|
variable.Value = result;
|
|
}
|
|
} // end _bindingvariable != null
|
|
|
|
// If binding variable is null, write the object to stream
|
|
else
|
|
{
|
|
WriteObject(result);
|
|
}
|
|
}
|
|
catch (RuntimeException e)
|
|
{
|
|
PSInvalidOperationException ioe = PSTraceSource.NewInvalidOperationException(e,
|
|
ImportLocalizedDataStrings.ErrorLoadingDataFile,
|
|
path,
|
|
e.Message);
|
|
|
|
throw ioe;
|
|
}
|
|
|
|
return;
|
|
} // ProcessRecord
|
|
|
|
private string GetFilePath()
|
|
{
|
|
if (String.IsNullOrEmpty(_fileName))
|
|
{
|
|
if (InvocationExtent == null || String.IsNullOrEmpty(InvocationExtent.File))
|
|
{
|
|
throw PSTraceSource.NewInvalidOperationException(ImportLocalizedDataStrings.NotCalledFromAScriptFile);
|
|
}
|
|
}
|
|
|
|
string dir = _baseDirectory;
|
|
|
|
if (String.IsNullOrEmpty(dir))
|
|
{
|
|
if (InvocationExtent != null && !String.IsNullOrEmpty(InvocationExtent.File))
|
|
{
|
|
dir = Path.GetDirectoryName(InvocationExtent.File);
|
|
}
|
|
else
|
|
{
|
|
dir = ".";
|
|
}
|
|
}
|
|
|
|
dir = PathUtils.ResolveFilePath(dir, this);
|
|
|
|
string fileName = _fileName;
|
|
if (String.IsNullOrEmpty(fileName))
|
|
{
|
|
fileName = InvocationExtent.File;
|
|
}
|
|
else
|
|
{
|
|
if (!String.IsNullOrEmpty(Path.GetDirectoryName(fileName)))
|
|
{
|
|
throw PSTraceSource.NewInvalidOperationException(ImportLocalizedDataStrings.FileNameParameterCannotHavePath);
|
|
}
|
|
}
|
|
|
|
fileName = Path.GetFileNameWithoutExtension(fileName);
|
|
|
|
CultureInfo culture = null;
|
|
if(_uiculture == null)
|
|
{
|
|
culture = CultureInfo.CurrentUICulture;
|
|
}
|
|
else
|
|
{
|
|
try
|
|
{
|
|
culture = ClrFacade.GetCultureInfo(_uiculture);
|
|
}
|
|
catch (ArgumentException)
|
|
{
|
|
throw PSTraceSource.NewArgumentException("Culture");
|
|
}
|
|
}
|
|
|
|
CultureInfo currentCulture = culture;
|
|
StringBuilder stringBuilder;
|
|
string filePath;
|
|
while (currentCulture != null && !String.IsNullOrEmpty(currentCulture.Name))
|
|
{
|
|
stringBuilder = new StringBuilder(dir);
|
|
stringBuilder.Append("\\");
|
|
stringBuilder.Append(currentCulture.Name);
|
|
stringBuilder.Append("\\");
|
|
stringBuilder.Append(fileName);
|
|
stringBuilder.Append(".psd1");
|
|
|
|
filePath = stringBuilder.ToString();
|
|
|
|
if (File.Exists(filePath))
|
|
{
|
|
return filePath;
|
|
}
|
|
|
|
currentCulture = currentCulture.Parent;
|
|
}
|
|
|
|
stringBuilder = new StringBuilder(dir);
|
|
stringBuilder.Append("\\");
|
|
stringBuilder.Append(fileName);
|
|
stringBuilder.Append(".psd1");
|
|
|
|
filePath = stringBuilder.ToString();
|
|
|
|
if (File.Exists(filePath))
|
|
{
|
|
return filePath;
|
|
}
|
|
|
|
InvalidOperationException ioe =
|
|
PSTraceSource.NewInvalidOperationException(
|
|
ImportLocalizedDataStrings.CannotFindPsd1File,
|
|
fileName + ".psd1",
|
|
dir + "\\" + culture.Name + "\\"
|
|
);
|
|
WriteError(new ErrorRecord(ioe, "ImportLocalizedData", ErrorCategory.ObjectNotFound,
|
|
dir + "\\" + culture.Name + "\\" + fileName + ".psd1"));
|
|
return null;
|
|
}
|
|
|
|
private string GetScript(string filePath)
|
|
{
|
|
InvalidOperationException ioe = null;
|
|
try
|
|
{
|
|
// 197751: WR BUG BASH: Powershell: localized text display as garbage
|
|
// leaving the encoding to be decided by the StreamReader. StreamReader
|
|
// will read the preamable and decide proper encoding.
|
|
using (FileStream scriptStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
|
|
using (StreamReader scriptReader = new StreamReader(scriptStream))
|
|
{
|
|
return scriptReader.ReadToEnd();
|
|
}
|
|
}
|
|
catch (ArgumentException e)
|
|
{
|
|
ioe = PSTraceSource.NewInvalidOperationException(
|
|
ImportLocalizedDataStrings.ErrorOpeningFile,
|
|
filePath,
|
|
e.Message);
|
|
}
|
|
catch (IOException e)
|
|
{
|
|
ioe = PSTraceSource.NewInvalidOperationException(
|
|
ImportLocalizedDataStrings.ErrorOpeningFile,
|
|
filePath,
|
|
e.Message);
|
|
}
|
|
catch (NotSupportedException e)
|
|
{
|
|
ioe = PSTraceSource.NewInvalidOperationException(
|
|
ImportLocalizedDataStrings.ErrorOpeningFile,
|
|
filePath,
|
|
e.Message);
|
|
}
|
|
catch (UnauthorizedAccessException e)
|
|
{
|
|
ioe = PSTraceSource.NewInvalidOperationException(
|
|
ImportLocalizedDataStrings.ErrorOpeningFile,
|
|
filePath,
|
|
e.Message);
|
|
}
|
|
|
|
WriteError(new ErrorRecord(ioe, "ImportLocalizedData", ErrorCategory.OpenError, filePath));
|
|
return null;
|
|
}
|
|
|
|
#endregion Command code
|
|
} // class ImportLocalizedData
|
|
}//Microsoft.PowerShell.Commands
|
|
|