2

Windows では、COM が見える C# アセンブリがあります。他のアセンブリを参照して、マシン内のアプリケーションを制御します。それは正常に動作します。

ただし、Apache Web サーバーで CGI を使用すると、機能しません。デバッグを行った後、問題は、Apache の CGI の下で実行しているときに、明らかに参照されたアセンブリで必要とされる環境変数 SYSTEMROOT および SYSTEMDRIVE が読み込まれていないことであることがわかりました。

これらの環境変数を渡すように Apache を構成することもできますが、その前に、C# COM 可視アセンブリに環境変数をロードするコマンドがあるかどうかを知りたいと思います。たとえば、 SYSTEM ユーザーまたはそのようなものであるため、開始アプリケーションによって渡された環境を中継する必要はありません。

現在のプロセスでITが設定されていない場合(または起動プロセスによってプロセス削除された場合)、C#で既存のシステム環境変数を強制的にロードするにはどうすればよいですか?

提案をお寄せいただきありがとうございます!

EDIT 1 - 追加情報:より明確にするために (現在の回答でわかるように、それほど明確ではありません): Apache は、CGI プロセスの多くの環境変数を意図的に削除します。Apache がそれらを認識できないわけではありませんが、認識できますが、それらを CGI プロセスに渡しません。

4

5 に答える 5

2

解決策:マルコの答えは素晴らしく、技術的に私の質問に答えました-ただし、環境変数SYSTEMROOTとSYSTEMDRIVEは、すべての環境変数が設定されているレジストリに実際には設定されていないことがわかったため、選択した答えはこれら2つを除くすべての変数に対して機能します、OPで指定しました。

SYSTEMROOT は HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SystemRoot のレジストリで定義されており、明らかに (さらに調査した結果)、SYSTEMDRIVE は SYSTEMDRIVE の部分文字列として生成されます。

したがって、レジストリから SYSTEMDRIVE と SYSTEMROOT を取得して環境にロードするには、次のようにします。

using Microsoft.Win32;

namespace MySpace
{
    public class Setup
    {
        public Setup()
        {
            SetUpEnvironment();
        }
        private void SetUpEnvironment()
        {
            string test_a = Environment.GetEnvironmentVariable("SYSTEMDRIVE", EnvironmentVariableTarget.Process);
            string test_b = Environment.GetEnvironmentVariable("SYSTEMROOT", EnvironmentVariableTarget.Process);
            if (test_a == null || test_a.Length == 0 || test_b == null || test_b.Length == 0)
            {
                string RegistryPath = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion";
                string SYSTEMROOT = (string) Registry.GetValue(RegistryPath, "SystemRoot", null);
                if (SYSTEMROOT == null)
                {
                    throw new System.ApplicationException("Cannot access registry key " + RegistryPath);
                }
                string SYSTEMDRIVE = SYSTEMROOT.Substring(0, SYSTEMROOT.IndexOf(':') + 1);
                Environment.SetEnvironmentVariable("SYSTEMROOT", SYSTEMROOT, EnvironmentVariableTarget.Process);
                Environment.SetEnvironmentVariable("SYSTEMDRIVE", SYSTEMDRIVE, EnvironmentVariableTarget.Process);
            }
        }
    }
}

Setup setup = new Setup();その後、他のクラスから呼び出すことができます。以上です。:-)

于 2013-03-29T06:18:22.000 に答える
2

これでうまくいくはずです:

Environment.GetEnvironmentVariable("variable", EnvironmentVariableTarget.Machine);

私は小さなテストを行いましたが、動作しています:

        //has the value
        string a = Environment.GetEnvironmentVariable("TMP");

        Environment.SetEnvironmentVariable("TMP", null);

        //does not have has the value
        a = Environment.GetEnvironmentVariable("TMP");

        //has the value
        a = Environment.GetEnvironmentVariable("TMP", EnvironmentVariableTarget.Machine);
于 2013-03-29T04:17:54.513 に答える
1
Environment.GetEnvironmentVariable

こちらのリファレンスを参照してください

例えば

Environment.CurrentDirectory = Environment.GetEnvironmentVariable("windir");        
DirectoryInfo info = new DirectoryInfo(".");
lock(info)
{      
    Console.WriteLine("Directory Info:   "+info.FullName);
}
于 2013-03-29T03:30:59.160 に答える
0

変数はシステム全体で設定されていますか?

そうでない場合は、それが必要なことです。それ以外の場合は、COM が実行されているユーザーのユーザー変数を作成します。

于 2013-03-29T03:27:31.140 に答える