Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Link and IO C# utils #56547

Open
wants to merge 2 commits into
base: devel
from
Open
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file or symbol
Failed to load files and symbols.

Always

Just for now

@@ -1266,12 +1266,57 @@ private object RemoveValueConditions(object value, HashSet<string> noLogStrings,

private void CleanupFiles(object s, EventArgs ev)
{
// The builtin .NET methods to manage files choke on certain scenarios. We check if the Ansible.IO util
// has been loaded and use that if possible. Because this is extra code to ship around we only use it if
// the module or reference module_util already relies on this. We fallback to the System.IO namespace.
MethodInfo fileExists = null;
MethodInfo fileDelete = null;
MethodInfo dirExists = null;
MethodInfo dirDelete = null;

Type ansibleIO = Type.GetType("Ansible.IO.FileSystem");
BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Static;
if (ansibleIO != null)
{
fileExists = ansibleIO.GetMethod("FileExists", bindingFlags);
fileDelete = ansibleIO.GetMethod("DeleteFile", bindingFlags);
dirExists = ansibleIO.GetMethod("DirectoryExists", bindingFlags);
dirDelete = ansibleIO.GetMethod("RemoveDirectory", bindingFlags);
}

// If we can't find any of the methods above we just use the builtin .NET method instead.
if (fileExists == null || fileDelete == null || dirExists == null || dirDelete == null)
{
fileExists = typeof(File).GetMethod("Exists", bindingFlags);
fileDelete = typeof(File).GetMethod("Delete", bindingFlags);
dirExists = typeof(Directory).GetMethod("Exists", bindingFlags);
dirDelete = typeof(Directory).GetMethod(
"Delete",
bindingFlags,
null,
new Type[] { typeof(string), typeof(bool) },
null
);
}

foreach (string path in cleanupFiles)
{
if (File.Exists(path))
File.Delete(path);
else if (Directory.Exists(path))
Directory.Delete(path, true);
// Even when using Ansible.IO to check and delete files, it still needs the \\?\ prefix to be able to
// manage paths that exceed MAX_PATH. We check whether the path to delete is an absolute path and
// prepend the prefix if necessary.
string tmpPath = path;
if (ansibleIO != null && Path.IsPathRooted(tmpPath) && !tmpPath.StartsWith(@"\\?\"))
{
if (tmpPath.StartsWith(@"\\")) // UNC Path
tmpPath = String.Format(@"\\?\UNC\{0}", tmpPath.Substring(2));
else
tmpPath = String.Format(@"\\?\{0}", tmpPath);
}

if ((bool)fileExists.Invoke(null, new object[]{ tmpPath }))
fileDelete.Invoke(null, new object[]{ tmpPath });
else if ((bool)dirExists.Invoke(null, new object[]{ tmpPath }))
dirDelete.Invoke(null, new object[]{ tmpPath, true });
}
cleanupFiles = new List<string>();
}

Large diffs are not rendered by default.

Large diffs are not rendered by default.

@@ -1,43 +1,54 @@
# Copyright (c) 2017 Ansible Project
# Simplified BSD License (see licenses/simplified_bsd.txt or https://opensource.org/licenses/BSD-2-Clause)

<#
Test-Path/Get-Item cannot find/return info on files that are locked like
C:\pagefile.sys. These 2 functions are designed to work with these files and
provide similar functionality with the normal cmdlets with as minimal overhead
as possible. They work by using Get-ChildItem with a filter and return the
result from that.
#>
#AnsibleRequires -CSharpUtil Ansible.IO

Function Test-AnsiblePath {
<#
.SYNOPSIS
Checks if the item at Path exists or not.
.PARAMETER Path
The path to the item to check for its existence.
.NOTES
This is mean to replace Test-Path as it works with special files like pagefile.sys and files exceeding MAX_PATH.
#>
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true)][string]$Path
)
# Replacement for Test-Path
try {
$file_attributes = [System.IO.File]::GetAttributes($Path)
} catch [System.IO.FileNotFoundException], [System.IO.DirectoryNotFoundException] {
return $false
} catch [NotSupportedException] {
# When testing a path like Cert:\LocalMachine\My, System.IO.File will
# not work, we just revert back to using Test-Path for this

# When testing a path like Cert:\LocalMachine\My, our C# functions will
# not work, we just revert back to using Test-Path for this
$ps_providers = (Get-PSDrive).Name | Where-Object {
$_ -notmatch "^[A-Za-z]$" -and $Path.StartsWith("$($_):", $true, [System.Globalization.CultureInfo]::InvariantCulture)
}
if ($null -ne $ps_providers) {
return Test-Path -Path $Path
}

if ([Int32]$file_attributes -eq -1) {
return $false
} else {
try {
[Ansible.IO.FileSystem]::GetFileAttributeData($Path) > $null
return $true
} catch [System.IO.FileNotFoundException], [System.IO.DirectoryNotFoundException] {
return $false
}
}

Function Get-AnsibleItem {
<#
.SYNOPSIS
Replacement for Get-Item to work with special files that are locked like pagefile.sys.
.PARAMETER Path
The path to the file to get the info for.
#>
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true)][string]$Path
)
# Replacement for Get-Item

try {
$file_attributes = [System.IO.File]::GetAttributes($Path)
} catch {
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.