Hoping I can get some assistance. I'm working on a little project of importing some win32 functions into powershell so I can natively use them.
As awesome as Powershell is, one frustrating/annoying limitation I am running into is the filename\path limitation of 260 characters...
For anyone unfamiliar with what I am talking about; if you have a file or a path to a directory that exceeds 260 characters; windows will have a difficult time deleting that file.

As a way around this limitation, I am trying to import some useful win32 functions to perform the task I need...
For starters, I am natively using DeleteFileW(). https://docs.microsoft.com/en-us/win...pi-deletefilew

Here is my code:

CLS

$script:nativeMethods = @();
function Register-NativeMethod([Parameter(Mandatory=$true)][string]$dll, [Parameter(Mandatory=$true)][string]$methodSignature, [string]$OptionalParameters)
{
if($OptionalParameters -ne "")
{
$OptionalParameters = (", " + $OptionalParameters)
$dll = $dll + $OptionalParameters
}

#$script:nativeMethods += [PSCustomObject]@{ Dll = $dll; Signature = $methodSignature; Optional = $OptionalParameters; }
$script:nativeMethods += [PSCustomObject]@{ Dll = $dll; Signature = $methodSignature; }
}

<#
function Add-NativeMethods()
{
$nativeMethodsCode = $script:nativeMethods | % { "
[DllImport(`"$($_.Dll)$($_.Optional)`")]
public static extern $($_.Signature);
" }

Add-Type @"
using System;
using System.Runtime.InteropServices;
public class NativeMethods {
$nativeMethodsCode
}
"@
}
#>
function Add-NativeMethods()
{
$nativeMethodsCode = $script:nativeMethods | % { "
[DllImport(`"$($_.Dll)`")]
public static extern $($_.Signature);
" }

Add-Type @"
using System;
using System.Runtime.InteropServices;
public class NativeMethods {
$nativeMethodsCode
}
"@
}
###########################################################################################

# Add your Win32 API here:
###########################################################################################
Register-NativeMethod "kernel32.dll" "bool DeleteFileW(string lpFileName)" "CharSet = CharSet.Unicode, SetLastError = true"
###########################################################################################

#Build class and registers them:

Try
{
Add-NativeMethods
}
catch [System.Exception]
{
#$Error
#$error[0].Exception | gm
}

[NativeMethods]::DeleteFileW("C:\TEST\test.txt")
[ComponentModel.Win32Exception][Runtime.InteropServices.Marshal]::GetLastWin32Error()


The issue I am running in to is the output shows it was successfully completed, but the file doesn't get deleted. And to answer any question, no the file isn't opened up, and yes I have full access to it.

Here is the error
Code:
Exception calling "DeleteFileW" with "1" argument(s): "Unable to load DLL 'kernel32.dll, CharSet = CharSet.Unicode, SetLastError = true': The specified module could 
not be found. (Exception from HRESULT: 0x8007007E)"
At C:\TEST\testB.ps1:68 char:1
+ [NativeMethods]::DeleteFileW("C:\TEST\test.txt
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : DllNotFoundException
 
The operation completed successfully

PS C:\TEST>
I'm taking a guess here, but I think part of the problem is the "optional parameters" I am passing into the dllimport, which is this piece

"CharSet = CharSet.Unicode, SetLastError = true"


Because the raw code should look something like this:

[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool DeleteFileW(string lpFileName);


Do any of you have any thoughts?

BTW, if I write everything out in raw form, it works fine, but ideally, I'd like to create a "quick" importer so I don't have to do it long hand for every function I want to import, I just write it in my "Register-NativeMethod" section, and it imports automatically.

Here is the raw form that works perfectly

CLS

$signature = @'
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool DeleteFileW(string lpFileName);
'@

$type = Add-Type -MemberDefinition $signature -Name Win32Utils -Namespace Win32 -Using System.Text -PassThru

$type::DeleteFileW("C:\TEST\test.txt");
[ComponentModel.Win32Exception][Runtime.InteropServices.Marshal]::GetLastWin32Error()