1

私はすでに長い間検索してきましたが、まだ有効な解決策を見つけることができませんでした:-(

CreateProcessAsUser ( http://www.pinvoke.net/default.aspx/advapi32/createprocessasuser.html )、WTSEnumerateSessions などを使用して、マシンにログオンしているすべてのユーザーでクライアントを起動するウィンドウ サービスを作成しました...

これはすでに正常に動作します。クライアントはユーザーのセッションで起動し、タスクバー アイコンを表示し、サービスとの通信は正常に機能しています。

私が抱えている問題は、そのクライアントがユーザーのプロファイルに一時ファイルを保存する必要があることです。ユーザーが最終的に経験する可能性のあるエラーを追跡できるように、小さなログ ファイルから始めてみました。残念ながら、WindowsIdentity は正しいユーザーを示していますが、クライアントが LocalSystem のコンテキストで実行されているように見えるため、ユーザーの一時フォルダーに保存できません。 System.IO.Path.GetTempPath() は常に 'C:\Windows\Temp' を返しますが、私のユーザーの管理者権限がないため、そこに書き込むことができません...さらに、現在のユーザーのレジストリに設定を保存する予定でしたが、これも機能していません。これは、何らかの方法で間違った一時パスに関連していると思います。

CreateEnvironmentBlock ( http://www.pinvoke.net/default.aspx/userenv/CreateEnvironmentBlock.html ) も試しましたが、動作させることができず、Vista またはより高いので、私はそれについての研究をやめました。

テストのために、これを行うだけの小さなテストフォームを作成しました:

        MessageBox.Show("Temp: " + System.IO.Path.GetTempPath() + Environment.NewLine + "User: " + WindowsIdentity.GetCurrent().Name, "Before impersonation");

        WindowsIdentity currentUserId = WindowsIdentity.GetCurrent();
        WindowsImpersonationContext impersonatedUser = currentUserId.Impersonate();

        MessageBox.Show("Temp: " + System.IO.Path.GetTempPath() + Environment.NewLine + "User: " + WindowsIdentity.GetCurrent().Name, "After impersonation");

これは、偽装の前後で常に同じ結果を示します: "Temp: C:\Windows\Temp User:testdomain\testuser" :-(

これがプロセスを開始するための私の関数です(ユーザートークンはWTSEnumerateSessionsによって配信されます)-もちろん、これはLocalSystemのコンテキストでのみ機能します:

    public static Process StartProcessAsUser(IntPtr UserToken, string App, string AppPath, string AppParameters)
    {
        Process ResultProcess = null;

        IntPtr hDupedToken = IntPtr.Zero;
        NativeProcessAPI.PROCESS_INFORMATION oProcessInformation = new NativeProcessAPI.PROCESS_INFORMATION();

        try
        {
            NativeProcessAPI.SECURITY_ATTRIBUTES oSecurityAttributes = new NativeProcessAPI.SECURITY_ATTRIBUTES();
            oSecurityAttributes.Length = Marshal.SizeOf(oSecurityAttributes);

            bool result = NativeProcessAPI.DuplicateTokenEx(
                  UserToken,
                  NativeProcessAPI.GENERIC_ALL_ACCESS,
                  ref oSecurityAttributes,
                  (int)NativeProcessAPI.SECURITY_IMPERSONATION_LEVEL.SecurityIdentification,
                  (int)NativeProcessAPI.TOKEN_TYPE.TokenPrimary,
                  ref hDupedToken
               );

            if (!result)
            {
                return null;
            }

            NativeProcessAPI.STARTUPINFO oStartupInfo = new NativeProcessAPI.STARTUPINFO();
            oStartupInfo.cb = Marshal.SizeOf(oStartupInfo);
            oStartupInfo.lpDesktop = String.Empty;

            result = NativeProcessAPI.CreateProcessAsUser(
                                 hDupedToken,
                                 null,
                                 App + " " + AppParameters,
                                 ref oSecurityAttributes, ref oSecurityAttributes,
                                 false, 0, IntPtr.Zero,
                                 AppPath, ref oStartupInfo, ref oProcessInformation
                           );

            if (result)
            {
                try
                {
                    int ProcessID = oProcessInformation.dwProcessID;

                    try
                    {
                        ResultProcess = System.Diagnostics.Process.GetProcessById(ProcessID);
                    }
                    catch
                    {
                        ResultProcess = null;
                    }
                }
                catch (Exception ex)
                {
                    ResultProcess = null;
                }
            }
        }
        catch
        {
            ResultProcess = null;
        }
        finally
        {
            if (oProcessInformation.hProcess != IntPtr.Zero)
                NativeProcessAPI.CloseHandle(oProcessInformation.hProcess);
            if (oProcessInformation.hThread != IntPtr.Zero)
                NativeProcessAPI.CloseHandle(oProcessInformation.hThread);
            if (hDupedToken != IntPtr.Zero)
                NativeProcessAPI.CloseHandle(hDupedToken);
        }

        return ResultProcess;
    }

LocalSystem のコンテキストではなく、ユーザーのコンテキストでプロセスを開始する方法はありますか?

どうもありがとう!

4

2 に答える 2