C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

二重起動時にアクティブ

[トピック内 7 記事 (1 - 7 表示)]  << 0 >>

■96785 / inTopicNo.1)  二重起動時にアクティブ
  
□投稿者/ naoki (3回)-(2021/02/04(Thu) 17:47:20)

分類:[VB.NET/VB2005 以降] 

WindowsFormアプリ(VB2019)です。
アプリケーションの二重起動を禁止して、既にに起動していたら、
最初に起動しているFormをアクティブにして画面の最前面に
表示させたいのですが、どのような方法があるでしょうか?
スタートアップオブジェクトは「Sub Main(≠Form)」での実装方法があれば、教えてください。

検索したら以下に「Mutexを使用する方法」が見つかって実装してみたのですが、
二重起動は防止できましたが、最初に起動しているFormがアクティブになりません。
https://dobon.net/vb/dotnet/process/checkprevinstance.html
引用返信 編集キー/
■96786 / inTopicNo.2)  Re[1]: 二重起動時にアクティブ
□投稿者/ 魔界の仮面弁士 (2961回)-(2021/02/04(Thu) 18:11:45)
No96785 (naoki さん) に返信
> 最初に起動しているFormをアクティブにして画面の最前面に
> 表示させたいのですが、どのような方法があるでしょうか?

お手軽な所では AppActivate を利用することができます。
https://dobon.net/vb/bbs/log3-14/8010.html

より確実に行いたい場合には、API 併用になりますが、
SetForegroundWindow や IsIconic + ShowWindowAsync を用います。
https://www.atmarkit.co.jp/fdotnet/dotnettips/151winshow/winshow.html


ただし、SetForegroundWindow での切替には、いくつかの制限事項があります。
これは、「キーボード入力中とかに勝手にフォーカスが切り替わったら困るだろう」といった
理由によるものです。下記の条件などをご覧ください。
http://chokuto.ifdef.jp/advanced/function/SetForegroundWindow.html


強制的に切り替える場合、SPI_GETFOREGROUNDLOCKTIMEOUT の値を一時的に
変更するといった手法が使われることがありますが、VS2010 や VS2012 の場合、
開発環境の不具合で、この設定値が破壊されることがあったりします。
http://bbs.wankuma.com/index.cgi?mode=al2&namber=63230&KLOG=107
https://support.microsoft.com/ja-jp/topic/0618099f-3b7e-7140-517e-d3b545250047


…といった話をまとめたてんこ盛りのコードが下記にあります。
https://dobon.net/vb/dotnet/process/appactivate.html
引用返信 編集キー/
■96787 / inTopicNo.3)  Re[2]: 二重起動時にアクティブ
□投稿者/ naoki (4回)-(2021/02/04(Thu) 19:23:37)
No96786 (魔界の仮面弁士 さん) に返信

ありがとうございます。
SetForegroundWindowで実装して、期待通り、最前面に表示されましたが....
以下の問題が発生しました。何か情報をお持ちの方があれば、教えてください。

開発環境でReleaseビルドして「bin\Release」フォルダ内に作成された実行ファイル(.exe)
では期待通り、二重起動時、最前面に表示されます。

しかし、これを配布を考えて同じPCの新規フォルダに「bin\Release」内のファイル一式を
コピーしたものを実行すると最前面になりません。
アプリは普通に起動して動作するのでdllが不足しているとか、そういう問題ではないようです。
引用返信 編集キー/
■96788 / inTopicNo.4)  Re[3]: 二重起動時にアクティブ
□投稿者/ Azulean (1179回)-(2021/02/04(Thu) 20:08:15)
それだけでは第三者にはコメントが難しいと思います。

「うまくいく環境」と「うまくいかない環境」の差はほかにないですか?
たとえば、起動方法が違うとか。


なお、先にも書かれていますが、SetForegroundWindow が通じるのは、それを呼ぶプロセスがフォーカスを得ている or 得ようとしている場合のみです。
それ以外では、タスクバーで点滅するだけですね。
引用返信 編集キー/
■96789 / inTopicNo.5)  Re[4]: 二重起動時にアクティブ
□投稿者/ naoki (5回)-(2021/02/04(Thu) 20:47:14)
No96788 (Azulean さん) に返信
ありがとうございます。
原因がわかりました。多分、権限の問題かと。。コピーするフォルダを変えたら期待動作となりました。
実行方法は同じで、単純に「bin\Release」フォルダ内のファイル一式をコピー。
コピー先のEXEをダブルクリックで起動しただけです。

NG:「C:\Program Files\hoge\hoge」配下に「bin\Release」フォルダ内のファイル一式をコピー
OK:「"C:\Users\xxxx\Desktop\hoge"」配下に「bin\Release」フォルダ内のファイル一式をコピー

只、マニフェストファイル(app.manifest)で<requestedExecutionLevel>要素を「asInvoker」から「requireAdministrator」に変えたものでも、「C:\Program Files\hoge\hoge」はNGでした。

引用返信 編集キー/
■96790 / inTopicNo.6)  Re[5]: 二重起動時にアクティブ
□投稿者/ Azulean (1180回)-(2021/02/04(Thu) 21:17:41)
No96789 (naoki さん) に返信
> 原因がわかりました。多分、権限の問題かと。。コピーするフォルダを変えたら期待動作となりました。
(略)
> NG:「C:\Program Files\hoge\hoge」配下に「bin\Release」フォルダ内のファイル一式をコピー
> OK:「"C:\Users\xxxx\Desktop\hoge"」配下に「bin\Release」フォルダ内のファイル一式をコピー
>
> 只、マニフェストファイル(app.manifest)で<requestedExecutionLevel>要素を「asInvoker」から「requireAdministrator」に変えたものでも、「C:\Program Files\hoge\hoge」はNGでした。

マニフェスト書いてもダメなら権限ではなく、Program Files の半角スペースの影響とか、そういったパスの処理に関わる何かがあるのではないですかね?
引用返信 編集キー/
■96791 / inTopicNo.7)  Re[6]: 二重起動時にアクティブ
□投稿者/ naoki (6回)-(2021/02/04(Thu) 22:55:34)
2021/02/04(Thu) 23:03:48 編集(投稿者)

No96790 (Azulean さん) に返信

原因がわかりました。申し訳ありません。初歩的なミスでした。

EnumWindowsでTopWindowを列挙して、ウインドウのキャプションからウインドウを特定していたのですが、
explorerで同じ名前のキャプションを持つウインドウがあった為、そちらを先に拾っていたようです。
ウィンドウハンドルが違うものをSetForegroundWindowしていた為、NGだったみたいです。
ProcessNameからウインドウを特定したら、希望通りの結果が得られました。

以下の件は、EnumWindowsで、たまたま希望のウインドウの方が先に列挙された為、と思います。
> NG:「C:\Program Files\hoge\hoge」配下に「bin\Release」フォルダ内のファイル一式をコピー
> OK:「"C:\Users\xxxx\Desktop\hoge"」配下に「bin\Release」フォルダ内のファイル一式をコピー

どうも、ありがとうございました。


解決済み
引用返信 編集キー/

このトピックをツリーで一括表示


トピック内ページ移動 / << 0 >>

このトピックに書きこむ