使用 FullTrustProcessLauncher 在 UWP 中添加环境变量
Posted
技术标签:
【中文标题】使用 FullTrustProcessLauncher 在 UWP 中添加环境变量【英文标题】:Add environment variables in UWP with FullTrustProcessLauncher 【发布时间】:2021-11-19 21:21:35 【问题描述】:我正在尝试使用 SetEnvironmentVariable method 通过 UWP 应用程序在 Windows 中创建环境变量,但似乎 UWP 在沙盒中运行时会阻止应用程序创建环境变量。
所以我创建了一个控制台应用程序来从 UWP 调用它:
var value = Environment.GetEnvironmentVariable("Test1", EnvironmentVariableTarget.User);
if (value == null)
var path = "pathTest";
Environment.SetEnvironmentVariable("Test1", path, EnvironmentVariableTarget.User);
Console.WriteLine("The environment variable has been created successfully");
else
Console.WriteLine("Environment variable already exists");
运行我在应用程序包中添加的控制台应用程序的 UWP 代码:
public class TestService : ITestService
public async Task ExecuteSampleApp()
await FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync();
我已经在同一个 UWP 应用程序包中添加了 .exe,并且我在 Package.appxmanifest 中添加了必要的权限 (runFullTrust) 以便能够运行外部应用程序(位于应用程序包中),最多这一点一切都很好,我可以从我的 UWP 应用程序运行控制台应用程序,但似乎从 UWP 应用程序运行时控制台应用程序无法创建环境变量,就像访问被带走了一样(我认为应用程序沙箱 UWP甚至对应用程序包中添加的 .exe 添加了相同的安全限制),但是如果我在编译 UWP 应用程序时创建的 bin 文件夹中运行相同的控制台应用程序,它可以工作,只有当 UWP 应用程序调用。EXE文件。任何人对如何使用我遵循的这种方法或其他方法在 UWP 中创建环境变量有任何其他想法?
使用这个控制台应用程序,是否可以绕过 UWP 沙盒安全限制运行 cmd 命令?
回复@RoyLi-MSFT: 不,没有例外,UWP应用程序执行控制台应用程序并显示消息“环境变量已存在”检测好像它已经存在,但是它没有在任何时候创建它,似乎控制台应用程序当它由 UWP 应用程序执行,它无法真正获取操作系统中是否存在环境变量,并返回错误状态(不存在时表示存在)。但是,如果控制台应用程序无论如何都运行,它确实可以工作,这表明这是一个 UWP 问题,它在由 UWP 应用程序执行时以某种方式将控制台应用程序隔离到与 UWP 应用程序相同的沙箱中。关于将exe文件放在应用程序包中的其他问题,我的意思是我在Assets文件夹中添加了负责注册环境变量的控制台应用程序,以便能够通过UWP使用FullTrustProcessLauncher执行它,因为它是唯一的从沙盒环境中运行 win32 应用程序的方式。
2º 对@RoyLi-MSFT 的回答: 我在我的代码中使用 EnvironmentVariableTarget.User,我放在这里的代码是一个示例(我已经更新了示例以澄清它),但我尝试使用 3 个可用的枚举:进程、用户和机器,用户类型是一个可以正常工作并且是我在控制台应用程序中使用的那个,但是正如我之前提到的,当 UWP 应用程序是运行控制台应用程序的那个时,它无法创建环境变量并且控制台显示:“环境变量已经存在" 尽管使用了 EnvironmentVariableTarget.User。
我澄清一点:当控制台应用程序手动运行时,如果它工作,它只在UWP应用程序负责执行它时显示“环境变量已存在”的消息@ 987654323@.
【问题讨论】:
您是否尝试将 EnvironmentVariableTarget 更改为 User? Environment.SetEnvironmentVariable("Test1", path, EnvironmentVariableTarget.User); 我想先确认一下。can't create the environment variable
是什么意思?它是否给出了例外或其他什么?你得到什么行为?还有就是你的意思是直接把exe文件放到app包里,而不是使用Windows Application Package Project(WAPP)?
@jerry 是的,我尝试使用 3 个可用的枚举:进程、用户和机器,但正如我提到的控制台应用程序单独工作正常,当 UWP 应用程序运行控制台应用程序时会出现问题无法注册环境变量。
@RoyLi-MSFT 我已经用你的问题的答案更新了帖子,因为它很长。
【参考方案1】:
根据文档-SetEnvironmentVariable(String, String),你创建的环境变量存储在当前进程中,即进程环境块。我在控制台应用程序中测试了您的代码。每次我启动控制台应用程序时,它都会显示The environment variable has been created successfully
。如果我在写入后尝试读取该值,我可以获得正确的值。此行为与文档匹配。
所以你提到的行为应该是可以预料的。您可以尝试在没有关闭控制台应用程序时直接读取环境变量,并且您应该能够获得您设置的值。 @jerry 的评论应该是有道理的,您可能需要尝试 SetEnvironmentVariable(String, String, EnvironmentVariableTarget)
与 EnvironmentVariableTarget.User 等其他选项。
更新:
根据您之前的评论,您提到您将 .exe 文件放在 UWP 应用的 Assets 文件夹中。我建议您使用Windows Application Package Project
将控制台应用程序与 UWP 应用程序打包在一起。这样在我的测试下,控制台应用程序会正确地将环境变量添加到当前用户块中,您可以随心所欲地获取它。
步骤如下:
-
在 UWP 应用的解决方案下创建一个新的控制台应用。添加您需要的代码。
创建一个 Windows 应用程序包项目,并将控制台应用和 UWP 作为应用程序引用添加到包项目。
在包项目的包清单中声明扩展
从 UWP 应用启动它。
您可以参考Stafen's blog了解更多详情。
结果:
【讨论】:
我已经在帖子中添加了我的答案,因为它很长。 @Tecnopresley 所以您在问题中发布的代码不是您在应用中使用的代码? 是的,它是相同的,但稍微简化了一些,我省略了真正的路径:“pathTest”,我忘记在帖子中添加 EnvironmentVariableTarget 参数,但除此之外它是相同的。 @Tecnopresley 如果您错过了EnvironmentVariableTarget
,那将是一个很大的不同。测试后,如果您使用 Windows 应用程序包项目将控制台应用程序与您的 UWP 应用程序打包在一起,则该控制台应用程序将工作。我稍后会更新我的答案以分享有关它的更多详细信息。
@Tecnopresley 请检查更新【参考方案2】:
最后我设法创建了环境变量。通过 UWP 应用程序我们必须执行控制台应用程序,并通过控制台应用程序通过 Process 类执行 CMD setx 命令,这是代码:
Process cmd = new Process();
cmd.StartInfo.FileName = "cmd.exe";
cmd.StartInfo.RedirectStandardInput = true;
cmd.StartInfo.RedirectStandardOutput = true;
cmd.StartInfo.CreateNoWindow = true;
cmd.StartInfo.UseShellExecute = false;
cmd.Start();
var testPath = "c:\...";
cmd.StandardInput.WriteLine(@"setx testName + " \"" + testPath + "\"");
因此,我们设法绕过了 UWP 在执行应用程序的沙箱中的限制:
【讨论】:
以上是关于使用 FullTrustProcessLauncher 在 UWP 中添加环境变量的主要内容,如果未能解决你的问题,请参考以下文章
在使用加载数据流步骤的猪中,使用(使用 PigStorage)和不使用它有啥区别?
Qt静态编译时使用OpenSSL有三种方式(不使用,动态使用,静态使用,默认是动态使用)