我有一个 DLL,导出了以下函数。
extern void Finalize(void (*WriteEntry)(const char* entry));
Run Code Online (Sandbox Code Playgroud)
我正在使用 P-Invoke 从 PowerShell 调用 DLL。
在 PowerShell 脚本中,我定义了一个函数,每当调用函数指针WriteEntry时都需要调用该函数。FinalizeWriteEntry
似乎正确的方法是围绕WriteEntryPowerShell 函数创建一个 C 风格的包装器,其中包装器Finalize作为函数指针传递到其中。
经过一些调查后,我发现可以创建一个可以与非托管代码互操作的委托(请参阅如何将函数指针从 C# 传递到 C++ Dll?)。我创建了以下CallbackDelegate类型。我能够将它从 C# 代码传递到 DLL。现在,我需要一种方法让 PowerShell 应用程序能够构造委托并将其传递给 DLL。
$delegateTypeDefinition = @'
[System.Runtime.InteropServices.UnmanagedFunctionPointer(System.Runtime.InteropServices.CallingConvention.Cdecl)]
public delegate void CallbackDelegate([System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPTStr)] string entry);
'@
Run Code Online (Sandbox Code Playgroud)
我不确定如何将 CallbackDelegate 委托包装在WriteEntryPowerShell 函数中。
因此,我认为需要回答的问题是,我们如何从 PowerShell 函数构造委托。如果事实证明这是一个 XY 问题,我希望我已经提供了足够的细节来指出正确的方向。
我有一个类,其中包含一个字符串作为私有成员。该类具有公共成员函数,它们都将const ref返回给std :: wstring。
返回的所有const-ref字符串都是私有成员的子字符串。
我可以将每个子字符串存储为成员,然后将const ref返回给那些成员,但这并不是最佳选择,因为它会复制内存。
假设我确实存储了足够的内存来知道每个子字符串的开始和结束索引。
如何在不复制任何成员字符串的情况下实现上述类?
记住XY 问题,这是我的 X 和 Y 问题。
有一些 PowerShell 脚本,我已经对其内容进行了混淆。不过,我仍然可以运行该脚本。
其工作原理是脚本存储在可执行文件内。PowerShell 可以执行可执行文件,通过将脚本名称作为 CLI 参数传递来请求特定脚本。然后,可执行文件的进程将通过 stdout 转发 PowerShell 脚本的内容。PowerShell 将 stdout 存储在字符串变量中,然后调用Invoke-Expression,传入字符串,运行混淆的脚本。
问题是$PSScriptRoot当它出现在混淆脚本中时,被评估为$null。
当 PowerShell 脚本script.ps1将 PowerShell 脚本作为字符串执行时$scriptString,如何$PSScriptRoot像在script.ps1.
测试1
# script.ps1
$PSScriptRoot
# Output: Path to directory containing `script.ps1`.
Run Code Online (Sandbox Code Playgroud)
这表明至少在一种情况下$PSScriptRoot是非的。$null
测试2
# script.ps1
Invoke-Expression '$PSScriptRoot'
# Output: Nothing
Run Code Online (Sandbox Code Playgroud)
表明我当前执行字符串的方式不起作用。
测试3
# script.ps1
. { $PSScriptRoot }
# Output: Path to …Run Code Online (Sandbox Code Playgroud) 我有一个 Go 应用程序,它接受 PowerShell 命令作为输入,创建一个新的 ps1 文件,将命令写入该文件,然后执行脚本文件。
如果该文件对用户不可见,那就太好了。
如果有某种方法将脚本文件创建为内存映射文件,然后执行该内存映射文件,那将是一个很好的解决方案。
使用 CGo,我可以从 Go 应用程序调用 C 或 C++。由于 PowerShell 可以使用 C# 对象,我想也许我们可以以某种方式调用 C# 代码(来自 C/C++ 或 Go)并创建一个 C# 内存映射文件对象,然后 PowerShell 可以使用该对象作为脚本执行。
诚然,我对如何从非托管代码调用托管代码的工作原理一无所知。
那么,是否有某种方法可以获取包含 PowerShell 命令的字符串并将其作为脚本执行,而无需创建磁盘文件?