如何使用.NET远程扩展环境变量?该问题涉及IT技术。

10

我需要一种在远程机器上扩展环境变量的方法。

假设我有一个指向文件夹的路径%appdata%\MyApp\Plugins或者%ProgramFiles%\MyCompany\MyApp\Plugins,我想为审计目的列出该文件夹中的文件。唯一的问题是我想在一个远程机器上完成这个操作,不过我拥有管理员权限。

额外的问题(但不是必要的)是如何为远程机器上的特定用户执行此操作?

4个回答

8

您可以使用GetFolderPath方法。有许多不同的SpecialFolder值可供选择,包括ProgramFilesApplicationData

string path = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles);

然后,你可以将其与路径的其余部分组合。
string full_path = Path.Combine(path, "\MyApp\Plugins");

在远程机器上,看起来你可以尝试类似这样的操作。
ConnectionOptions co = new ConnectionOptions();
// user with sufficient privileges to connect to the cimv2 namespace
co.Username = "administrator"; 
// his password
co.Password = "adminPwd";
ManagementScope scope = new ManagementScope(@"\\BOBSMachine\root\cimv2", co);
SelectQuery query = new SelectQuery("Select windowsdirectory from Win32_OperatingSystem");
ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
foreach (ManagementObject windir in searcher.Get())
   Console.WriteLine("Value = {0}", windir["windowsdirectory"]);

或者获取所有远程环境变量及其值的列表,请从这里查看。

public static void GetSysInfo(string domain, string machine, string username, string password)
{
    ManagementObjectSearcher query = null;
    ManagementObjectCollection queryCollection = null;

    ConnectionOptions opt = new ConnectionOptions(); 

    opt.Impersonation = ImpersonationLevel.Impersonate; 
    opt.EnablePrivileges = true; 
    opt.Username = username; 
    opt.Password = password; 
    try 
    { 
        ManagementPath p = new ManagementPath("\\\\" +machine+ "\\root\\cimv2");   

        ManagementScope msc = new ManagementScope(p, opt); 

        SelectQuery q= new SelectQuery("Win32_Environment");

        query = new ManagementObjectSearcher(msc, q, null); 
        queryCollection = query.Get(); 

        Console.WriteLine(queryCollection.Count);

        foreach (ManagementBaseObject envVar in queryCollection) 
        {
            Console.WriteLine("System environment variable {0} = {1}", 
            envVar["Name"], envVar["VariableValue"]);
        }
    } 
    catch(ManagementException e) 
    { 
        Console.WriteLine(e.Message); 
        Environment.Exit(1); 
    } 
    catch(System.UnauthorizedAccessException e) 
    { 
        Console.WriteLine(e.Message); 
        Environment.Exit(1); 
    } 
}

OP编辑: 此外,可以在注册表中找到%AppData%(可以远程完成),路径为 HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders,而程序文件位于HKLM\Software\Microsoft\Windows\CurrentVersion下的ProgramfilesDir


这将扩展到本地机器的(甚至是当前用户的)程序文件,我需要将其扩展到远程机器。 - zzandy
很遗憾,无论是Win32_OperatingSystem还是Win32_Environment都不包含%programfiles%,至少在我所看的Win 2003系统中没有... - piers7

2
这个问题没有意义。环境变量不是针对机器的变量。例如,您可以期望%appdata%指向C:\users\目录内部,但具体位置显然取决于用户。以管理员身份登录仍然无法帮助您;那只会告诉您管理员的%appdata%在哪里。

也许 %appdata% 不是一个好的例子。那 %ProgramFiles% 呢? - zzandy
1
同样的观点仍然适用,这些是%%变量,它们允许在系统中常见路径的配置级别差异化。除非您对系统有控制权并且可以合法地假定%Program Files%始终为C:\program files\,否则您真的需要为特定用户运行此操作... - Taylor Bird
如果是这种情况,那还有什么必要呢?如果 %Program Files%N:\SharedPrograms\Secretaries\,那你又会遇到麻烦。由于这些环境变量可以从漫游配置文件和/或登录脚本中派生出来,除非在实际机器上进行真正的登录,否则你将无法获取它们。 - MSalters

2
环境变量是计算机范围和用户个人设置的综合体。一个正在运行的进程可能修改它的环境变量,并且当它创建另一个进程时,后者会继承创建它的进程的环境变量。
除非您可以访问在远程计算机上运行的进程(或者可以启动一个进程),否则不存在所谓的“环境”:它的上下文简单地不存在。特定进程的环境取决于以下所有因素的函数:
- 从父进程环境继承的环境(可能正在以不同用户账户的身份运行) - 计算机范围的环境设置 - 用户指定的任何环境设置 - 进程本身所做的任何更改
话虽如此,Windows将其环境变量设置保存在注册表中:
- 用户变量。
HKEY_CURRENT_USER\Environment - 系统变量。
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment 如果您有适当的访问权限来访问远程计算机的注册表,您应该能够找到您需要的内容。
请注意,环境变量可能按照其他环境变量的方式定义:我相信您可能需要自己处理正确的扩展。

1
据我所知,解析%ProgramFiles%的唯一方法是通过注册表,因为在Win32_Environment中没有暴露它(尽管文档表明相反)。 所以这很好用:
$key = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine,$serverName);
$versionKey = $key.OpenSubKey('SOFTWARE\Microsoft\Windows\CurrentVersion');
$versionKey.GetValue('ProgramFilesDir')

然而,我似乎无法使用此方法获取Program Files(x86)文件夹 - 我可以在注册表中看到的密钥不会使用注册表API“显示”。奇怪。

当然,如果您在远程计算机上运行Powershell Remoting,我想这将相当容易...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接