スキップしてメイン コンテンツへ

 none
AcrobatReaderを最大化で表示 RRS feed

  • 質問

  • AcrobatReaderを最大化で表示

    OS:Windows10 Pro(x64)
    開発環境:VB.NET2015
    Adobe Acrobat Reader DC(2019.012.20040)

    以下ソースにてAcrobatReaderを最大化で起動し、PDFファイルを表示したいのですが、うまくいきません。

    ※前回終了時の状態(サイズ、表示位置)で表示されます。

            Using p As New System.Diagnostics.Process
                p.StartInfo.UseShellExecute = True
                p.StartInfo.Arguments = "@PDFファイルパス"
                p.StartInfo.CreateNoWindow = False
                p.StartInfo.WindowStyle = ProcessWindowStyle.Maximized
                p.StartInfo.FileName = "C:\Program Files ~~~\AcroRd32.exe"  '実行ファイルのパス
                p.Start()
                p.WaitForExit()
            End Using
    

    今わかっているのは、

    ・p.StartInfo.ArgumentsにPDFファイルを指定しない場合は、AcrobatReaderが最大化状態で表示

    ・p.StartInfo.FileNameが"notepad.exe"であれば、Argumentsにファイル名を指定しても最大化状態で表示

    ・APIのShowWindowを使ってみましたがうまくいかない

    AcrobatReaderの何らかの設定に引っ張られているような気もするのですが、設定を見回しましたが、どれが関係しているのかわかりませんでした。

    何かアドバイスを頂けないでしょうか?

    2019年9月9日 12:58

回答

  • 複数の環境で検証したわけではありませんが、とりあえず当方環境だと、こんな感じで最大化できているようです。

    Private ReadOnly Property IsWow64 As Boolean
        Get
            Return Environment.Is64BitOperatingSystem AndAlso Not Environment.Is64BitProcess
        End Get
    End Property
    
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim pdfPath As String = TextBox1.Text
        Dim acroRd32Path = "C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe"
        Dim arguments = String.Format("/n ""{0}""", pdfPath)
    
        If IsWow64 Then
            Dim root = Microsoft.Win32.RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.CurrentUser, Microsoft.Win32.RegistryView.Registry64)
            Dim reg = root.CreateSubKey("Software\Adobe\Acrobat Reader\DC\SDI")
            reg.SetValue("bNullDocMaximized", 1, Microsoft.Win32.RegistryValueKind.DWord)
            reg.SetValue("bMaximizeNextDocument", 1, Microsoft.Win32.RegistryValueKind.DWord)
            reg.Dispose()
            root.Dispose()
        Else
            Dim reg = Microsoft.Win32.Registry.CurrentUser.CreateSubKey("Software\Adobe\Acrobat Reader\DC\SDI")
            reg.SetValue("bNullDocMaximized", 1, Microsoft.Win32.RegistryValueKind.DWord)
            reg.SetValue("bMaximizeNextDocument", 1, Microsoft.Win32.RegistryValueKind.DWord)
            reg.Dispose()
        End If
        Process.Start(acroRd32Path, arguments)
    End Sub

    • 回答としてマーク onionsword 2019年9月11日 3:55
    2019年9月11日 3:12

すべての返信

  • p.StartInfo.UseShellExecute = True
    p.StartInfo.CreateNoWindow = False
    p.StartInfo.WindowStyle = ProcessWindowStyle.Maximized

    WindowStyle = Maximized を指定するには、UseShellExecute を True に指定する必要があります。この場合、SHELLEXECUTEINFO 構造体の nShow フィールドに対して SW_SHOWMAXIMIZED が指定された状態で ShellExecuteEx API が呼び出されるようになっています。

    CreateNoWindow プロパティはコンソールウィンドウの表示有無を指定するものであり、コンソールアプリでのみ有効なオプションです。CreateNoWindow プロパティの指定は UseShellExecute プロパティが True だと無視されますが、もしも UseShellExcecute が False に設定されている場合には、CreateProcessWithLogonW API の第7引数 dwCreationFlags もしくは CreateProcess APIの第 6 引数に対して CREATE_NO_WINDOW フラグを指定するかどうかが左右されます。

    追記:CreateProcess(WithLogon)W API で呼び出されたアプリケーションは、最初に呼び出す ShowWindow API において、STARTUPINFO 構造体の情報が引き継がれることが期待されています。しかし https://referencesource.microsoft.com/ で確認した限りでは、Process クラスからの起動の場合、STARTUPINFO.wShowWindow フィールドには 0 (SW_HIDE) が設定されているように見えます。


    設定を見回しましたが、どれが関係しているのかわかりませんでした。

    自分も見つけられませんでした。残念ながら、設定変更で対処できるものではないのかもしれません。
    前回「最大化した状態」で終了されている分には、最大化で表示されるようですけれども。

    ウィンドウサイズを指定できる引数があれば良いのですけれどね…。

    SendKeys を使う方法で無理矢理最大化させることはできましたが、タイミング依存性が高いのが難点。

    AppActivate(pdfTitle)
    SendKeys.SendWait("% X")

    実験的に pdf ファイルへのショートカットを作成し、ショートカット プロパティの
     実行時の大きさ(U): [最大化]
    を指定してみたところ、一瞬だけ最大化された空白ウィンドウが表示されて
    直ちに消えた後、代わりに「前回終了時のサイズ」で AcroRd32.exe が起動しました。

    また pdf ファイルではなく、AcroRd32.exe 本体へのショートカットに
    同じことをした場合も、一瞬だけ最大化された空白ウィンドウが表示されて
    直ちに消えた後、代わりに「最大化状態」の AcroRd32.exe が起動しました。

    いずれの場合も、Adobe Acrobat Reader が起動すると、別のプロセスを起動しつつ、自身は非表示で実行されるようになっているようです。たとえばコマンドライン引数に "@PDFファイルパス" のみを指定して起動した場合、先に起動された AcroRd32.exe とは別に、もう一つ下記のプロセスが起動されています。

    "C:\Program Files~\AcroRd32.exe" --type=renderer /prefetch:1 "@PDFファイルパス"

    また、タスクマネージャーの[プロセス]タブで確認してみると、最初に起動された方は「バックグラウンド プロセス」の項目に分類され、後から自動起動された方は「アプリ」の項目に含まれていました。

    事後対処とはなりますが、EnumWindows API なり Process.GetProcessesByName("AcroRd32") メソッドなりで、追従起動された方のプロセスを拾って、対象ウィンドウに対して ShowWindow API で最大化の指定を行ってみては如何でしょうか。


    • 編集済み 魔界の仮面弁士MVP 2019年9月10日 5:29 誤字訂正:変わり→代わり、STARTUPINFO について言及
    2019年9月10日 2:22
  • 魔界の仮面弁士様

    動作検証とアドバイスありがとうございます。

    ※まさかあこがれの魔界様から回答がいただけるとは・・・。

    アドバイス頂いた

    GetProcessesByNameにてプロセス取得後、ShowWindow APIにて最大化指定してみましたが、やはりダメでした。

    こうなると、プログラム的な問題というより、AcrobatReaderの問題なのでしょうか・・・?

    もう少しほかの方法がないか検討してみます。

    2019年9月11日 2:11
  • 複数の環境で検証したわけではありませんが、とりあえず当方環境だと、こんな感じで最大化できているようです。

    Private ReadOnly Property IsWow64 As Boolean
        Get
            Return Environment.Is64BitOperatingSystem AndAlso Not Environment.Is64BitProcess
        End Get
    End Property
    
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim pdfPath As String = TextBox1.Text
        Dim acroRd32Path = "C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe"
        Dim arguments = String.Format("/n ""{0}""", pdfPath)
    
        If IsWow64 Then
            Dim root = Microsoft.Win32.RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.CurrentUser, Microsoft.Win32.RegistryView.Registry64)
            Dim reg = root.CreateSubKey("Software\Adobe\Acrobat Reader\DC\SDI")
            reg.SetValue("bNullDocMaximized", 1, Microsoft.Win32.RegistryValueKind.DWord)
            reg.SetValue("bMaximizeNextDocument", 1, Microsoft.Win32.RegistryValueKind.DWord)
            reg.Dispose()
            root.Dispose()
        Else
            Dim reg = Microsoft.Win32.Registry.CurrentUser.CreateSubKey("Software\Adobe\Acrobat Reader\DC\SDI")
            reg.SetValue("bNullDocMaximized", 1, Microsoft.Win32.RegistryValueKind.DWord)
            reg.SetValue("bMaximizeNextDocument", 1, Microsoft.Win32.RegistryValueKind.DWord)
            reg.Dispose()
        End If
        Process.Start(acroRd32Path, arguments)
    End Sub

    • 回答としてマーク onionsword 2019年9月11日 3:55
    2019年9月11日 3:12
  • 魔界の仮面弁士様

    ご提示いただいた方法で、当方でも実現できることを確認できました。

    「レジストリを操作するしかないのかな」とは思ってはいたのですが、どこに対して操作するのか見当もついていなかったので非常に助かりました。

    ご協力ありがとうございました。

    また機会がありましたらよろしくお願いいたします。

    2019年9月11日 3:54