web-dev-qa-db-ja.com

起動時にWindows 7で管理者としてプログラムを自動的に実行する方法は?

子供のアクティビティを監視するために、自分のペアレンタルコントロールアプリを作成しました。アプリの唯一のGUIはタスクバーアイコンです。プログラムは管理者としてインストールされます。このプログラムをWindowsの起動時に管理ユーザーとして自動的に起動して、標準ユーザーがタスクマネージャーからこのプログラムを強制終了できないようにしたいと思います。

次の場所でレジストリキーを作成できます。

HKLM\Software\Microsoft\Windows\CurrentVersion\Run

windowsの起動時に自動的に実行されるようにします。問題は、プログラムがログイン(標準)ユーザーとして起動されることです。

昇格モードで実行するにはどうすればよいですか?これはWin7ではまったく可能ですか?

82
newman

システムの管理アクセス権を持つユーザーアカウントを使用して、ユーザーのログイン後に起動されるように、タスクスケジューラにプラグインする必要があります。そのアカウントによって起動されるプロセスに与えられる最高の特権があります。

これは、一般ユーザーとしてログインするときに管理者権限でプロセスを自動開始するために使用される実装です。

私はそれを使用して「OpenVPN GUI」ヘルパープロセスを起動しましたが、これは昇格した権限が正しく機能する必要があるため、レジストリキーから適切に起動しませんでした。

コマンドラインから、達成したいことのXML記述からタスクを作成できます。たとえば、これはシステムからエクスポートされており、ログインすると最高の権限でメモ帳が起動します。

<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="http://schemas.Microsoft.com/windows/2004/02/mit/task">
  <RegistrationInfo>
    <Date>2015-01-27T18:30:34</Date>
    <Author>Pete</Author>
  </RegistrationInfo>
  <Triggers>
    <LogonTrigger>
      <StartBoundary>2015-01-27T18:30:00</StartBoundary>
      <Enabled>true</Enabled>
    </LogonTrigger>
  </Triggers>
  <Principals>
    <Principal id="Author">
      <UserId>CHUMBAWUMBA\Pete</UserId>
      <LogonType>InteractiveToken</LogonType>
      <RunLevel>HighestAvailable</RunLevel>
    </Principal>
  </Principals>
  <Settings>
    <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
    <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
    <StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
    <AllowHardTerminate>true</AllowHardTerminate>
    <StartWhenAvailable>false</StartWhenAvailable>
    <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
    <IdleSettings>
      <StopOnIdleEnd>true</StopOnIdleEnd>
      <RestartOnIdle>false</RestartOnIdle>
    </IdleSettings>
    <AllowStartOnDemand>true</AllowStartOnDemand>
    <Enabled>true</Enabled>
    <Hidden>false</Hidden>
    <RunOnlyIfIdle>false</RunOnlyIfIdle>
    <WakeToRun>false</WakeToRun>
    <ExecutionTimeLimit>PT0S</ExecutionTimeLimit>
    <Priority>7</Priority>
  </Settings>
  <Actions Context="Author">
    <Exec>
      <Command>"c:\windows\system32\notepad.exe"</Command>
    </Exec>
  </Actions>
</Task>

そして、それは管理者コマンドプロンプトによって以下を使用して登録されます:

schtasks /create /tn "start notepad on login" /xml startnotepad.xml

この答えは、実際にはプログラミングの質問そのものではないため、他のスタック交換サイトのいずれかに実際に移動する必要があります。

59
Petesh
schtasks /create /sc onlogon /tn MyProgram /rl highest /tr "exeFullPath"
40
msPark

これは不可能です。
ただし、管理ユーザーの下で実行されるサービスを作成できます。

サービスは起動時に自動的に実行され、既存のアプリケーションと通信できます。
アプリケーションが管理者として何かをする必要がある場合、サービスにそれを行うように依頼できます。

複数のユーザーが一度にログオンできることに注意してください。

15
SLaks

タスクスケジューラを使用してプログラムを自動起動することはあまりユーザーフレンドリーではないと思いますし、副作用がある場合もあります(たとえば、プログラムのトレイアイコンは追加されません)。

これを改善するために、管理者特権で最初に再起動し、次にディレクトリ内のすべてのファイルを起動するElevated Startupというプログラムを作成しました。 Elevated Startupが昇格されたため、その後起動するすべてのプログラムには管理者権限も付与されます。このディレクトリは、クラシックスタートアップディレクトリの隣のスタートメニューにあり、ほとんど同じように機能します。

UAC設定によっては、プログラムが再起動するときに1つのUACダイアログが表示される場合があります。

ここからプログラムを入手できます: https://stefansundin.github.io/elevatedstartup/

5
stefansundin

管理者へのアプリケーションの互換性の設定(Run theprogram as an administrator)

task schedulerに接続し、UACをオフにします。

3
Wawan

TaskSchedler library を介して管理者として実行中にタスクをインストールすることにより、これを行うことができます。ここでは、関連する質問を考えると、.NET/C#が適切なプラットフォーム/言語であると仮定しています。

このライブラリを使用すると、タスクスケジューラAPIにきめ細かくアクセスできるため、起動の優先度など、schtasksを呼び出してコマンドラインで設定できない設定を調整できます。ペアレンタルコントロールアプリケーションであるため、スタートアップの優先度を0(最大)にする必要があります。schtasksはデフォルトで優先度7を作成します。

以下は、適切に構成された起動タスクをインストールして、ログオン時に無期限に目的のアプリケーションを管理者として実行するコード例です。このコードは、実行元のプロセスのタスクをインストールします。

/*
Copyright © 2017 Jesse Nicholson  
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

/// <summary>
/// Used for synchronization when creating run at startup task.
/// </summary>
private ReaderWriterLockSlim m_runAtStartupLock = new ReaderWriterLockSlim();

public void EnsureStarupTaskExists()
{
    try
    {
        m_runAtStartupLock.EnterWriteLock();


        using(var ts = new Microsoft.Win32.TaskScheduler.TaskService())
        {
            // Start off by deleting existing tasks always. Ensure we have a clean/current install of the task.
            ts.RootFolder.DeleteTask(Process.GetCurrentProcess().ProcessName, false);

            // Create a new task definition and assign properties
            using(var td = ts.NewTask())
            {
                td.Principal.RunLevel = Microsoft.Win32.TaskScheduler.TaskRunLevel.Highest;
                // This is not normally necessary. RealTime is the highest priority that
                // there is.
                td.Settings.Priority = ProcessPriorityClass.RealTime;
                td.Settings.DisallowStartIfOnBatteries = false;
                td.Settings.StopIfGoingOnBatteries = false;
                td.Settings.WakeToRun = false;
                td.Settings.AllowDemandStart = false;
                td.Settings.IdleSettings.RestartOnIdle = false;                    
                td.Settings.IdleSettings.StopOnIdleEnd = false;
                td.Settings.RestartCount = 0;                    
                td.Settings.AllowHardTerminate = false;
                td.Settings.Hidden = true;
                td.Settings.Volatile = false;
                td.Settings.Enabled = true;
                td.Settings.Compatibility = Microsoft.Win32.TaskScheduler.TaskCompatibility.V2;
                td.Settings.ExecutionTimeLimit = TimeSpan.Zero;

                td.RegistrationInfo.Description = "Runs the content filter at startup.";

                // Create a trigger that will fire the task at this time every other day
                var logonTrigger = new Microsoft.Win32.TaskScheduler.LogonTrigger();
                logonTrigger.Enabled = true;                    
                logonTrigger.Repetition.StopAtDurationEnd = false;
                logonTrigger.ExecutionTimeLimit = TimeSpan.Zero;
                td.Triggers.Add(logonTrigger);

                // Create an action that will launch Notepad whenever the trigger fires
                td.Actions.Add(new Microsoft.Win32.TaskScheduler.ExecAction(Process.GetCurrentProcess().MainModule.FileName, "/StartMinimized", null));

                // Register the task in the root folder
                ts.RootFolder.RegisterTaskDefinition(Process.GetCurrentProcess().ProcessName, td);
            }
        }                
    }
    finally
    {
        m_runAtStartupLock.ExitWriteLock();
    }
}
3
user7000146

また、管理者レベルのユーザーまたはサービスとしてプロセスを実行することのセキュリティへの影響を考慮する必要があります。ネットワークインターフェイスでリッスンしている場合など、入力が適切に検証されていない場合。この入力のパーサーが適切に検証されない場合、パーサーが悪用され、昇格したユーザーとしてコードを実行する可能性のある悪用につながる可能性があります。 abatishchevの例では、それほど問題にはなりませんが、エンタープライズ環境に展開する場合は、大規模な展開の前にセキュリティ評価を行ってください。

2
Curtis

私が書いたプログラム、farmCommはこれを解決するかもしれません。オープンソースおよびパブリックドメインとしてリリースしました。

基準を満たしていない場合は、簡単に変更して基準を満たすことができる場合があります。

farmComm:

  • サービスの下で起動時に実行され、ユーザーがログインまたはログアウトしても継続します。
    • セッション0
    • ユーザー「NT AUTHORITY\SYSTEM」の下。
  • 任意のプロセスを生成します(選択);
    • セッション0でも
    • 「目に見えない」、またはユーザーインターフェイス/ GUIを表示せずに
    • グラフィックハードウェア(GPUなど)へのアクセス。
    • Secure Desktopを含め、アクティブセッションが変更された場合でも、アクティブセッションに応答します。これがその方法です:
    • ユーザーが8.5分間アイドル状態になった後にのみプロセスを生成します
    • ユーザーがアイドルから再開したときにスポーンを終了します

ソーススクリプトは次の場所にあります。

https://github.com/r-alex-hall/farmComm

2
Alex Hall