2009-08-10 6 views
4

.NETで書かれたいくつかのコンポーネントを使用するVisual Basic 6.0アプリケーションがあります。ウィンドウがシャットダウンされると、アプリケーションは正常にシャットダウンする必要があります。問題は、コードの.NET部分にウィンドウが表示されている場合、アプリケーションでメッセージ"Cannot Quit"が表示され、終了できないということです。 (OSによって終了します).NETフォームが開いていると、Visual Basic 6.0アプリケーションがシャットダウンしません。代わりに "Can not Quit"というメッセージが表示されます

私は単純化されたアプリケーションでこれを再現することができました。

.NETコードがWPFウィンドウを作成し、ShowDialogを()を使用して、それを表示します。あなたは.NETの呼び出しブロックを参照してください(とGUIスレッドである)ことができたよう

[Guid("5F3D0B23-2196-4082-B9DE-B208C61FE89F")] 
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] 
public interface IComShutdownTest 
{ 
    [DispId(1)] 
    void RunTest(); 
} 

[Guid("E6613EDD-D51B-42c0-AA5B-5961AB28D063")] 
[ClassInterface(ClassInterfaceType.None)] 
[ProgId("ShutdownTest")] 
public class ShutdownTest : IComShutdownTest 
{ 
    public ShutdownTest() 
    { } 

    public void RunTest() 
    { 
     TestWindow testWindow = new TestWindow(); 
     bool? dialogResult = testWindow.ShowDialog(); 
    } 
} 

を、私はこの月を疑います問題の根源にはなりますが、すべての呼び出しを非ブロックにすることはできません。私は、OSがシャットダウンすると、開いているアプリケーションウィンドウがすべて終了すると想定していました。

Visual Basic 6.0アプリケーションは、ボタンクリックから.NETフォームを読み込んで表示します。

Private Sub ButtonTest_Click() 

    LogEventToFile "Starting" 
    Dim dotNetTestObject As ShutdownTest 

    LogEventToFile "Creating" 
    Set dotNetTestObject = New ShutdownTest 

    LogEventToFile "Running" 
    dotNetTestObject.RunTest 

    LogEventToFile "Done" 

End Sub 

.NETフォームが画面上にあるときにPCをシャットダウンしようとすると、失敗します。 「Can not quit」メッセージボックスはlike thisのように見えます。

あなたは COM見える(ファイル assemblyinfo.cs中)としてアセンブリをマークする必要があり、これを再作成するには:

[assembly: ComVisible(true)] 

、あなたはプロジェクト - >プロパティ>

「COM相互運用機能に登録」するには、タブを作成し設定する必要があります

コンパイル済みアセンブリを登録しました:

regasm ShutdownTestLibrary.dll /tlb ShutdownTestLibrary.tlb 

この問題を解決するにはどうすればよいですか?

答えて

1

すべてのウィンドウでShowDialog()を呼び出すと、ウィンドウが閉じるまで(ユーザーまたはコードから)スレッドがブロックされます。

.NETでウィンドウを閉じるには、COMインターフェイスでメソッドを作成するか、Visual Basicで何らかの方法でウィンドウのハンドルを取得してウィンドウを閉じる必要があります。

+0

しかし、OSシャットダウンですべての開いているウィンドウを閉じるべきではありません。 (私はQuerySessionEndとSessionEndメッセージを開いているすべてのウィンドウに送信して、それらを閉じることになると思いました)。 2つのウィンドウを持つ純粋な.netアプリケーションを作成し、ShowDialog()を使用すると、OSがシャットダウンすると自動的に閉じられます。 –

+2

OSはすべてのトップレベルウィンドウにこのコマンドを送信し、次にそれらの子ウィンドウを閉じます。あなたのトップレベルのウィンドウはVBであるため、おそらくあなたの.Netウィンドウを閉じる方法はわかりません。それは主なスレッドがブロックされていることを知っているだけです。 – jonathanpeppers

0

次の一つは、あなたの問題を解決する必要があります。

  • あなた.NETウィンドウが設定され、テキスト/名前のプロパティを持っていることを確認してください。私はこれが時々このような問題を引き起こすことを知っている。
  • .NETウィンドウの所有者をVisual Basicウィンドウに設定します。 user32.dllにSetParent関数を使用します。
  • .NETライブラリのMicrosoft.Win32.SystemEvents.SessionEndingにフックしてウィンドウを閉じます。
0

.NETメソッドのパラメータとして親ウィンドウを取得しようとすると、親コンポーネントが閉じようとすると.NETコンポーネントに通知されます。

public void RunTest(IWin32Window owner) 
{ 
    TestWindow testWindow = new TestWindow(); 
    bool? dialogResult = testWindow.ShowDialog(owner); 
} 

Visual Basic 6では、0コード:

Call dotNetTestObject.RunTest(Me.hWnd) 
関連する問題