質問
以下を使用して、プロセスから管理者権限でプロセスを起動する方法を知っています。
proc.StartInfo.UseShellExecute = true;
proc.StartInfo.Verb = "runas";
ここで、proc は System.Diagnostics.Process です。しかし、どうやってその逆を行うのでしょうか?
現在のプロセスがすでに昇格されている場合、管理者権限なしで新しいプロセスを起動するにはどうすればよいでしょうか?より正確には、Windows エクスプローラーと同じアクセス許可レベルで新しいプロセスを起動する必要があるため、UAC が無効になっている場合は変更ありませんが、UAC が有効であってもプロセスが昇格して実行されている場合は、特定の操作を昇格せずに実行する必要があります。なぜなら、仮想ドライブを作成しているのですが、それが昇格されたアクセス許可で作成され、Windows エクスプローラーが昇格されていない状態で実行されている場合、表示されないからです。
適切な説明が思いつきませんでしたので、タイトルをより良いものに変更してください。
解決 2
私たちは、このコードプロジェクトの記事からのサンプルを使用して終了:高い標高が可能お使いのアプリケーションに悪い:インストールするの最後に非上昇プロセスを開始する方法
これは、これまでに動作しているようですが、私はそれをします。rundll32.exeに注入集め、私のC ++ / Win32のは、私はちょうどそれは使用ですが、実際の実装にはあまり見ていないかなり弱いです。それはVistaとWin7の中で両方のx86およびx64を(少なくとも私たちのために、x86およびx64のインストール時にチェックされ、適切なものが使用されている別のDLLのを必要とする)動作することを確認しました。
他のヒント
解決策は、EXPLORER.exe プロセスを使用することです。
このアイデアは、Windows のファイル エクスプローラー プロセスを使用して、UN-ELEVATE モードでプロセスを実行することです。 explorer.exe
(情報)。起動したいプロセスが実行されているとします。 $TEMP\MyUnElevatedProcess.exe
.
したがって、NSIS コードの場合は、次のように書きます。(ただし、どの言語でも実行できます)
Exec '"$WINDIR\explorer.exe" "$TEMP\MyUnElevatedProcess.exe"'
コード例 (NSISインストーラーを使用する)
Exec '"$WINDIR\explorer.exe" "$TEMP\MyUnElevatedProcess.exe"'
***から取得したコード http://mdb-blog.blogspot.com/2013/01/nsis-lunch-program-as-user-from-uac.html
あなたはシェルプロセスのアクセストークンをコピーし、新しいプロセスを開始するためにそれを使用することができます。
public static class UnelevatedProcessStarter
{
public static void Start(string cmdArgs)
{
// 1. Get the shell
var shell = NativeMethods.GetShellWindow();
if (shell == IntPtr.Zero)
{
throw new Exception("Could not find shell window");
}
// 2. Copy the access token of the process
NativeMethods.GetWindowThreadProcessId(shell, out uint shellProcessId);
var hShellProcess = NativeMethods.OpenProcess(0x00000400 /* QueryInformation */, false, (int)shellProcessId);
if (!NativeMethods.OpenProcessToken(hShellProcess, 2 /* TOKEN_DUPLICATE */, out IntPtr hShellToken))
{
throw new Win32Exception();
}
// 3. Dublicate the acess token
uint tokenAccess = 8 /*TOKEN_QUERY*/ | 1 /*TOKEN_ASSIGN_PRIMARY*/ | 2 /*TOKEN_DUPLICATE*/ | 0x80 /*TOKEN_ADJUST_DEFAULT*/ | 0x100 /*TOKEN_ADJUST_SESSIONID*/;
var securityAttributes = new SecurityAttributes();
NativeMethods.DuplicateTokenEx(
hShellToken,
tokenAccess,
ref securityAttributes,
2 /* SecurityImpersonation */,
1 /* TokenPrimary */,
out IntPtr hToken);
// 4. Create a new process with the copied token
var si = new Startupinfo();
si.cb = Marshal.SizeOf(si);
if (!NativeMethods.CreateProcessWithTokenW(
hToken,
0x00000002 /* LogonNetcredentialsOnly */,
null,
cmdArgs,
0x00000010 /* CreateNewConsole */,
IntPtr.Zero,
null,
ref si,
out ProcessInformation _))
{
throw new Win32Exception();
}
}
public class NativeMethods
{
[DllImport("user32.dll")]
public static extern IntPtr GetShellWindow();
[DllImport("user32.dll", SetLastError = true)]
public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr OpenProcess(int processAccess, bool bInheritHandle, int processId);
[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool OpenProcessToken(IntPtr processHandle, UInt32 desiredAccess, out IntPtr tokenHandle);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool DuplicateTokenEx(IntPtr hExistingToken, uint dwDesiredAccess,
ref SecurityAttributes lpTokenAttributes,
int impersonationLevel,
int tokenType,
out IntPtr phNewToken);
[DllImport("advapi32", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool CreateProcessWithTokenW(
IntPtr hToken, int dwLogonFlags,
string lpApplicationName, string lpCommandLine,
int dwCreationFlags, IntPtr lpEnvironment,
string lpCurrentDirectory, [In] ref Startupinfo lpStartupInfo, out ProcessInformation lpProcessInformation);
}
[StructLayout(LayoutKind.Sequential)]
public struct ProcessInformation
{
public IntPtr hProcess;
public IntPtr hThread;
public int dwProcessId;
public int dwThreadId;
}
[StructLayout(LayoutKind.Sequential)]
public struct SecurityAttributes
{
public int nLength;
public IntPtr lpSecurityDescriptor;
public int bInheritHandle;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct Startupinfo
{
public Int32 cb;
public string lpReserved;
public string lpDesktop;
public string lpTitle;
public Int32 dwX;
public Int32 dwY;
public Int32 dwXSize;
public Int32 dwYSize;
public Int32 dwXCountChars;
public Int32 dwYCountChars;
public Int32 dwFillAttribute;
public Int32 dwFlags;
public Int16 wShowWindow;
public Int16 cbReserved2;
public IntPtr lpReserved2;
public IntPtr hStdInput;
public IntPtr hStdOutput;
public IntPtr hStdError;
}
}
あなたは ProcessStartInfo.UserName と ProcessStartInfo.Password を指定しますあなたは、プロセスの下で実行するアカウントます。
class Program
{
static void Main(string[] args)
{
var psi = new ProcessStartInfo(@"c:\windows\system32\whoami.exe");
var password = new SecureString();
password.AppendChar('s');
password.AppendChar('e');
password.AppendChar('c');
password.AppendChar('r');
password.AppendChar('e');
password.AppendChar('t');
psi.Password = password;
psi.UserName = "username";
psi.UseShellExecute = false;
psi.RedirectStandardOutput = true;
var p = new Process();
p.StartInfo = psi;
p.Start();
p.WaitForExit();
Console.WriteLine(p.StandardOutput.ReadToEnd());
}
}