如何让下载的PowerShell脚本在C# ClickOnce应用中获得运行权限?
我有一个C# ClickOnce应用,用来运行MyScript.ps1 PowerShell脚本,开发机上一切正常,但在另一台电脑上安装后,下载解压脚本压缩包、配置本地路径后运行时,出现以下错误:
check_script err:File C:\Users\User\Desktop\MyFolder\MyScript.ps1 cannot be loaded because running scripts is disabled on this system. For more information, see about_Execution_Policies at https:/go.microsoft.com/fwlink/?LinkID=135170.
+ CategoryInfo : SecurityError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : UnauthorizedAccess
我已经通过管理员PowerShell尝试修改执行策略:
PS C:\WINDOWS\system32> Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned Execution Policy Change The execution policy helps protect you from scripts that you do not trust. Changing the execution policy might expose you to the security risks described in the about_Execution_Policies help topic at https:/go.microsoft.com/fwlink/?LinkID=135170. Do you want to change the execution policy? [Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "N"): y PS C:\WINDOWS\system32> Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Unrestricted Execution Policy Change The execution policy helps protect you from scripts that you do not trust. Changing the execution policy might expose you to the security risks described in the about_Execution_Policies help topic at https:/go.microsoft.com/fwlink/?LinkID=135170. Do you want to change the execution policy? [Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "N"): y PS C:\WINDOWS\system32> Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass Execution Policy Change The execution policy helps protect you from scripts that you do not trust. Changing the execution policy might expose you to the security risks described in the about_Execution_Policies help topic at https:/go.microsoft.com/fwlink/?LinkID=135170. Do you want to change the execution policy? [Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "N"): y
但这些操作都没用,之前我用Unblock-File解除了文件标记,脚本已经能在cmd里通过powershell .\MyScript.ps1正常运行,用dir /r也确认Zone.Identifier已经移除,但C#应用里还是跑不了。想问普通用户启动的C#应用,还有什么办法让脚本获得运行权限?
1. 在C#调用PowerShell时指定执行策略
直接在启动PowerShell进程的参数里加入执行策略配置,绕过当前系统的执行策略限制,这是最直接的办法。示例代码:
ProcessStartInfo psi = new ProcessStartInfo { FileName = "powershell.exe", Arguments = $"-ExecutionPolicy Bypass -File \"{scriptPath}\"", UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true, CreateNoWindow = true }; using (Process process = Process.Start(psi)) { string output = process.StandardOutput.ReadToEnd(); string error = process.StandardError.ReadToEnd(); process.WaitForExit(); // 处理输出和错误逻辑 }
这里通过-ExecutionPolicy Bypass参数,让当前PowerShell进程直接绕过执行策略,不需要修改系统全局或用户级的配置,对普通用户也生效。
2. 调整ClickOnce应用的信任级别
ClickOnce应用默认在部分信任沙箱中运行,可能没有足够权限执行PowerShell脚本:
- 打开项目属性的「安全」选项卡,勾选「这是一个完全信任的应用程序」,重新发布ClickOnce包。
- 注意:完全信任会提升应用权限,需确保应用的安全性,避免被滥用。
3. 检查脚本文件的NTFS权限
即使解除了Zone.Identifier,文件的NTFS权限可能限制了ClickOnce应用的访问:
- 右键脚本文件 → 属性 → 安全 → 检查当前用户是否有「读取和执行」权限,若没有则添加对应权限。
4. 以命令字符串方式执行脚本内容
如果调用脚本文件仍有问题,可以把脚本内容读取到C#中,作为命令字符串传递给PowerShell执行,绕过文件执行的限制:
string scriptContent = File.ReadAllText(scriptPath); // 转义脚本中的特殊字符,避免语法错误 scriptContent = scriptContent.Replace("\"", "\\\"").Replace("\n", "`n"); ProcessStartInfo psi = new ProcessStartInfo { FileName = "powershell.exe", Arguments = $"-ExecutionPolicy Bypass -Command \"{scriptContent}\"", UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true, CreateNoWindow = true }; // 后续进程处理逻辑同上
内容的提问来源于stack exchange,提问作者sdbbs

