5

タイトルが示すように、Java(そしてjavaのみ)で書かれたプログラムが管理者権限で自分自身(できれば.jar)を再起動し、ネイティブのWindows UACを(作成するために)表示することは可能かどうか疑問に思っていますユーザーにとってより信頼できる)、私は宿題をして、c ++とjavaの間のブリッジを使用してこれを達成できることを発見しましたが、純粋なjavaプロジェクトとしてこれを実行したいと思います。

PS:この結果が不可能であるという遠隔の場合、誰かが別の言語を使用してこれを行うための「簡単な」方法を教えてもらえますか(つまり、チュートリアルを見つけましたが、それはすべきではないと思う何かのために複雑ですそんなに複雑になります)。

P.S2:これを達成できる場合、他のプラットフォーム(OS X、Linux)で機能しますか?

4

5 に答える 5

9

純粋なJavaでは実行できません。

最善の策は、これをファイルに書き込むことです。

@echo Set objShell = CreateObject("Shell.Application") > %temp%\sudo.tmp.vbs
@echo args = Right("%*", (Len("%*") - Len("%1"))) >> %temp%\sudo.tmp.vbs
@echo objShell.ShellExecute "%1", args, "", "runas" >> %temp%\sudo.tmp.vbs
@cscript %temp%\sudo.tmp.vbs

something.batそして、それをWindowsの一時ディレクトリに保存します(これにアクセスできるため)。

Runtime次に、またはを使用してアプリケーションからこれを実行し、アプリケーションをProcessBuilder終了します(System.exit(0);)。

プログラムに昇格があるかどうかをチェックする即時起動チェックをアプリケーションに追加する必要があります。昇格した場合は、バッチを再実行して終了します。

これが私が作成した例です(これはJarとしてコンパイルされたときに実行する必要があります。そうしないと機能しません):

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import javax.swing.JOptionPane;

/**
 *
 * @author David
 */
public class UacTest {

    public static String jarName = "UacTest.jar", batName = "elevate.bat";

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        if (checkForUac()) {//uac is on
            JOptionPane.showMessageDialog(null, "I am not elevated");
            //attempt elevation
            new UacTest().elevate();
            System.exit(0);
        } else {//uac is not on
            //if we get here we are elevated
            JOptionPane.showMessageDialog(null, "I am elevated");
        }

    }

    private static boolean checkForUac() {
        File dummyFile = new File("c:/aaa.txt");
        dummyFile.deleteOnExit();

        try {
            //attempt to craete file in c:/
            try (FileWriter fw = new FileWriter(dummyFile, true)) {
            }
        } catch (IOException ex) {//we cannot UAC muts be on
            //ex.printStackTrace();
            return true;
        }
        return false;
    }

    private void elevate() {
        //create batch file in temporary directory as we have access to it regardless of UAC on or off
        File file = new File(System.getProperty("java.io.tmpdir") + "/" + batName);
        file.deleteOnExit();

        createBatchFile(file);

        runBatchFile();

    }

    private String getJarLocation() {
        return getClass().getProtectionDomain().getCodeSource().getLocation().getPath().substring(1);
    }

    private void runBatchFile() {
        //JOptionPane.showMessageDialog(null, getJarLocation());

        Runtime runtime = Runtime.getRuntime();
        String[] cmd = new String[]{"cmd.exe", "/C",
            System.getProperty("java.io.tmpdir") + "/" + batName + " java -jar " + getJarLocation()};
        try {
            Process proc = runtime.exec(cmd);
            //proc.waitFor();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    private void createBatchFile(File file) {
        try {
            try (FileWriter fw = new FileWriter(file, true)) {
                fw.write(
                        "@echo Set objShell = CreateObject(\"Shell.Application\") > %temp%\\sudo.tmp.vbs\r\n"
                        + "@echo args = Right(\"%*\", (Len(\"%*\") - Len(\"%1\"))) >> %temp%\\sudo.tmp.vbs\r\n"
                        + "@echo objShell.ShellExecute \"%1\", args, \"\", \"runas\" >> %temp%\\sudo.tmp.vbs\r\n"
                        + "@cscript %temp%\\sudo.tmp.vbs\r\n"
                        + "del /f %temp%\\sudo.tmp.vbs\r\n");
            }
        } catch (IOException ex) {
            //ex.printStackTrace();
        }
    }
}
于 2012-11-08T13:47:54.337 に答える
1

バッチファイルとrunasコマンドを使用します。

于 2012-11-08T13:45:06.633 に答える
0

「Javaだけ」とは思えません。せいぜい、MSFTモジュールの周りにJNIラッパーが必要です。を使用してexeを呼び出すProcessBuilderだけで「Javaのみ」としてカウントされない限り、ユーザーコンソールを起動するコードはJavaのみであり、呼び出すコードではありません。IOW、WinにはJavaAPIが付属していません

于 2012-11-08T13:48:03.590 に答える
0

昇格したアプリケーションを再起動するには、Windows APIから呼び出すShellExecuteか関数を実行し、動詞を使用する必要があります。ShellExecuteExrunas

これらのAPIは、JNAライブラリを使用する純粋なJavaで使用できます。

java.exe自分で再起動するには、またはへjavaw.exeのフルパス、コマンドラインパラメータ(クラスパス(存在する場合)、およびjarへのパス)を知っている必要があります。明らかに、WindowsAPIを使用してこの情報を取得できます。


リモートケースとはどういう意味ですか?
この方法でリモート昇格プロセスを開始することはできません。

ネットワーク共有から昇格したアプリケーションを再起動できます。ただし、マップされたドライブでは機能しません。昇格後、ユーザーのマップされたドライブにアクセスできなくなります。


いいえ、これは他のプラットフォームでは機能しません。UACはWindowsの機能です。Linuxの場合といくつかの点で似てsudoいるため、Linuxの場合はを使用できますsudo $pathtojava/java.exe <yourparameters>。ただし、アプリケーションがコンソールから起動されていない場合、これはうまく機能しません。ウィンドウマネージャーには通常、GUIダイアログでパスワードの入力を求めるラッパーがあります。

于 2012-11-11T10:05:57.637 に答える
0

Hackaprofaw(v29)でこれを行うだけです。また、2002年にリリースされ、1997年に開発が開始されました。2021年にはバージョン29.10.7でしたが-

if raw ram = 0
 disable "featureII" program = "JAVA(math = any)"
run on "Hackaprofaw (math = v29(x))
when "featureII" disabled
 end
于 2021-09-01T19:44:48.773 に答える