none
コンソールコマンドライン引数の使用について RRS feed

  • 質問

  • 自作の別アプリをProcessメソッドで起動するとき、位置を指定するため次のようにしました。
            Dim p As Process = Process.Start(Application.StartupPath & "\○○.exe")
            '待機
            p.WaitForInputIdle()…①
            Dim lx As Integer = Left + Width…②
            Dim ly As Integer = Top
            MoveWindow(p.MainWindowHandle, lx, ly, 193, 255, False)
    しかし、呼び出し元のアプリの横に表示されず、WindowsDefaultLocationに表示されます。
    障害となっているのは何かと、いろいろと試したものの改善されませんでした。例えば、
    TopMost、非アクティヴにしていること、などなと…。
    また、①と②の間にMsgBoxを入れてプログラムを中断させると、MsgBox表示前はWindowsDefaultLocationに、MsgBoxを消すと目的の位置に表示されます。
    このことが改善されずに、気になっていたコンソールコマンド引数に別アプリを表示させる位置情報を呼び出し元から送ってはどうかと
            Dim l As Integer = Left + Width
            Dim t As Integer = Top
            Dim loc As String = CStr(l) & "," & CStr(t) '表示位置、このフォームの右
            Dim p As Diagnostics.Process = Process.Start(Application.StartupPath & "\○○.exe", loc)
    受け取り側(別アプリ)で
            'コマンドライン引数を配列で取得する
            Dim cmds As String() = System.Environment.GetCommandLineArgs()
            Dim myAppLocation As String() = cmds(1).Split(","c)
            Left = CInt(myAppLocation(0))
            Top = CInt(myAppLocation(1))
    として、目的は達せられたのですが、気持ちはすっきりしていません。
    というのも、そもそもコマンドライン引数は、このような使い方をしても良いものなのかと思っています。御法度なのかどうか。
    少し長くなりました。宜しくお願いします。
    2018年5月16日 22:39

回答

  • WaitForInputIdleではウィンドウができる前でも通ってしまうので、ウィンドウが作られて表示されるのを待ってみるとか

    Public Class Form1
        <System.Runtime.InteropServices.DllImport("user32.dll")> _
        Public Shared Function MoveWindow(ByVal hWnd As IntPtr, ByVal x As Integer, ByVal y As Integer, ByVal nWidth As Integer, ByVal nHeight As Integer, ByVal bRepaint As Boolean) As Boolean
        End Function
        <System.Runtime.InteropServices.DllImport("user32.dll")> _
        Private Shared Function IsWindowVisible(ByVal hWnd As IntPtr) As Boolean
        End Function
    
        Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Dim p As Process = Process.Start(Application.StartupPath & "\○○.exe")
    
            p.WaitForInputIdle()
    
            Do While (p.MainWindowHandle = IntPtr.Zero OrElse Not IsWindowVisible(p.MainWindowHandle))
                Await Task.Delay(0)
            Loop
    
            Dim lx As Integer = Left + Width
            Dim ly As Integer = Top
            MoveWindow(p.MainWindowHandle, lx, ly, 193, 255, False)
        End Sub
    End Class



    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 回答としてマーク nebokken 2018年5月19日 0:43
    2018年5月17日 4:18

すべての返信

  • p.MainWindowHandleは正しく取得できているのでしょうか? (取得できているかを確認できているでしょうか?) この値が不正であればMoveWindowが意図通りに動作しないのも当然です。
    2018年5月16日 23:07
  • p.MainWindowHandleは正しく取得できているのでしょうか? (取得できているかを確認できているでしょうか?)

    どうやって確認するのでしょうか。もしも、①の前に、Console.WriteLine(p.MainWindowHandle)でよいのでしたら、Trueになっています。

    2018年5月17日 0:21
  • WaitForInputIdleではウィンドウができる前でも通ってしまうので、ウィンドウが作られて表示されるのを待ってみるとか

    Public Class Form1
        <System.Runtime.InteropServices.DllImport("user32.dll")> _
        Public Shared Function MoveWindow(ByVal hWnd As IntPtr, ByVal x As Integer, ByVal y As Integer, ByVal nWidth As Integer, ByVal nHeight As Integer, ByVal bRepaint As Boolean) As Boolean
        End Function
        <System.Runtime.InteropServices.DllImport("user32.dll")> _
        Private Shared Function IsWindowVisible(ByVal hWnd As IntPtr) As Boolean
        End Function
    
        Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Dim p As Process = Process.Start(Application.StartupPath & "\○○.exe")
    
            p.WaitForInputIdle()
    
            Do While (p.MainWindowHandle = IntPtr.Zero OrElse Not IsWindowVisible(p.MainWindowHandle))
                Await Task.Delay(0)
            Loop
    
            Dim lx As Integer = Left + Width
            Dim ly As Integer = Top
            MoveWindow(p.MainWindowHandle, lx, ly, 193, 255, False)
        End Sub
    End Class



    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 回答としてマーク nebokken 2018年5月19日 0:43
    2018年5月17日 4:18
  • できました。…が、初心者なので、課題盛りだくさんです。Declare Function で MoveWindow等を定義していたのですが、<System.Runtime.InterServices.DllImport…>という書き方や、Private Sub ~Clickh は Private Async Sub ~としなければいけないこと等わからないにことばかりです。納得するには時間がかかりそうです。でも、ありがとうございました。

    あと、後半の部分コンソールライン引数の取り扱いはどうなりますか。申し訳ありません、課題が解決したのに…。

    2018年5月17日 8:23