【发布时间】:2014-09-22 20:46:10
【问题描述】:
我想在用户登录时使用 PowerShell 脚本自动执行与用户相关的任务。
有时用户会从默认位置移动他的文档文件夹。如何使用适用于所有特殊文件夹的方法确定用户在 PowerShell 中的 Documents 文件夹的位置?
我尝试使用基于 Lee Holmes work 的来自 PowerShell 的 SHGetKnownFolderPath 调用
由于 pinvoke 网站 C# 示例不使用 StringBuilder,我认为它不是必需的,并剥离了 builder +“-Using”引用
param($KNOWNFOLDERID)
$Pinvoke = @’
[DllImport("shell32.dll")]
public static extern int SHGetKnownFolderPath(
[MarshalAs(UnmanagedType.LPStruct)] Guid rfid,
uint dwFlags,
IntPtr hToken,
out String pszPath // API uses CoTaskMemAlloc
);
‘@
$type = Add-Type -MemberDefinition $Pinvoke
-Name Win32Utils -Namespace SHGetKnownFolderPath
-PassThru
$type::SHGetKnownFolderPath($KNOWNFOLDERID)
我还尝试使用来自here 的 New-PInvoke 以“shell32.dll”为库值和
int SHGetKnownFolderPath( [MarshalAs(UnmanagedType.LPStruct)] Guid rfid, uint dwFlags, IntPtr hToken, out String pszPath )
作为签名值,然后在powershell中使用
SHGetKnownFolderPath FDD39AD0-238F-46AF-ADB4-6C85480369C7 0 0 [ref]$path
我以这个错误结束
Argument: '4' should be a System.Management.Automation.PSReference. Use [ref].
At line:1 char:56
+ New-Item Function:Global:SHGetKnownFolderPath -Value { [Microsoft.PowerShell.Com ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodException
+ FullyQualifiedErrorId : NonRefArgumentToRefParameterMsg
我不明白我在两次试验中哪里出错了。
解决方案:
Kayasax 在 codeplex 上找到的 Windows7Library 二进制文件适用于像我这样的懒人,或者 David Heffernan 的允许更多自定义的 scriptlet,但如果您使用自定义特殊文件夹可能需要一些手工操作,但更可自定义,这两个答案都是有效的!
【问题讨论】:
-
请注意,禁止使用 CSIDL 的解决方案,因为它们无法获取 ANY 特殊文件夹,CSIDL 已过时,根据微软官方网站msdn.microsoft.com/en-us/library/windows/desktop/…
-
用户可以自己更改特殊文件夹的位置,包括文档、保存的游戏,并且认为文件夹将位于用户配置文件路径中,如果我在不使用默认值的机器上运行脚本,稍后会导致问题.我不能使用任何假设文件夹位于默认路径的解决方案,但这不会成为问题,因为 GUID 解决方案将提供文件夹的完整路径。
-
所以这适用于 Vista 及更高版本,对吧?
-
它适用于可以运行 Powershell V3 的系统,因为它标记了问题,包括 Windows 7/Windows Server 2008R2 及更高版本。不知道能不能在Vista上安装Powershell V3。
-
我的意思是,如果您想要已知的文件夹 ID,那么 XP 是不可能的
标签: powershell pinvoke powershell-3.0