10

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

假设我有一个文件夹的路径,%appdata%\MyApp\Plugins或者%ProgramFiles%\MyCompany\MyApp\Plugins我想列出该文件夹中的文件以供审核。唯一的问题是我想在远程机器上执行此操作,但是我有管理员访问权限。

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

4

4 回答 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和 Program Files 的HKLM\Software\Microsoft\Windows\CurrentVersion, 下找到ProgramfilesDir

于 2011-02-17T16:04:24.530 回答
2

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

于 2011-02-17T15:45:47.297 回答
2

环境变量是“计算机范围和每个用户设置”的合并。正在运行的进程可能会修改其环境,当它产生另一个进程时,该进程会继承创建它的进程的环境。

除非您可以访问远程机器上运行的进程(或可以启动一个进程),否则不存在“环境”之类的东西:它的上下文根本不存在。特定进程的环境是以下所有因素的函数:

  • 从父进程的环境继承的环境(可能在与子进程不同的用户帐户下运行。)
  • 计算机范围的环境设置。
  • 用户指定的任何环境设置。
  • 过程本身所做的任何更改。

话虽如此,Windows 将其环境变量设置保留在注册表中:

  • 用户变量。
    HKEY_CURRENT_USER\Environment
  • 系统变量。
    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment

如果您对远程机器的注册表有适当的访问权限,您应该能够找出您需要的东西。

请注意,环境变量可以根据其他环境变量来定义:我相信您可能会自己处理适当的扩展。

于 2011-02-17T18:40:36.473 回答
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,我想这将相当容易......

于 2011-09-09T01:27:08.163 回答