Skip to content

Commit 358a3d0

Browse files
committed
fix: Prevent NamedPipeServerStream conflict when relaunching as admin
Closes #414
1 parent f5533c2 commit 358a3d0

File tree

2 files changed

+53
-33
lines changed

2 files changed

+53
-33
lines changed

CompactGUI/Application.xaml.vb

Lines changed: 40 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ Class Application
77

88
Public Shared ReadOnly mutex As New Mutex(False, "Global\CompactGUI")
99

10+
Private pipeServerCancellation As New CancellationTokenSource()
11+
Private pipeServerTask As Task
12+
1013
Private mainWindow As MainWindow
1114

1215
Private Async Sub Application_Startup(sender As Object, e As StartupEventArgs)
@@ -33,7 +36,7 @@ Class Application
3336

3437
End If
3538

36-
Using client = New NamedPipeClientStream("CompactGUI")
39+
Using client = New NamedPipeClientStream(".", "CompactGUI", PipeDirection.Out)
3740
client.Connect()
3841
Using writer = New StreamWriter(client)
3942
writer.WriteLine(e.Args(0))
@@ -42,8 +45,7 @@ Class Application
4245

4346
Application.Current.Shutdown()
4447
ElseIf Not SettingsHandler.AppSettings.AllowMultiInstance Then
45-
46-
ProcessNextInstanceMessage()
48+
pipeServerTask = ProcessNextInstanceMessage()
4749
End If
4850

4951

@@ -67,31 +69,40 @@ Class Application
6769
' can be handled in this file.
6870

6971

70-
Private Async Sub ProcessNextInstanceMessage()
71-
72-
Await Task.Run(Sub()
73-
While True
74-
75-
Using server = New NamedPipeServerStream("CompactGUI")
76-
server.WaitForConnection()
77-
Using reader = New StreamReader(server)
78-
Dim message = reader.ReadLine()
79-
mainWindow.Dispatcher.Invoke(Sub()
80-
mainWindow.Show()
81-
mainWindow.WindowState = WindowState.Normal
82-
mainWindow.Topmost = True
83-
mainWindow.Activate()
84-
mainWindow.Topmost = False
85-
If message IsNot Nothing Then
86-
mainWindow.ViewModel.SelectFolder(message)
87-
88-
End If
89-
End Sub)
90-
91-
End Using
92-
End Using
93-
End While
94-
End Sub)
95-
End Sub
72+
Private Async Function ProcessNextInstanceMessage() As Task
73+
Using server = New NamedPipeServerStream("CompactGUI",
74+
PipeDirection.In,
75+
1,
76+
PipeTransmissionMode.Byte,
77+
PipeOptions.Asynchronous)
78+
While Not pipeServerCancellation.IsCancellationRequested
79+
Try
80+
Await server.WaitForConnectionAsync(pipeServerCancellation.Token)
81+
Catch ex As OperationCanceledException
82+
Return
83+
End Try
84+
Using reader = New StreamReader(server)
85+
Dim message = Await reader.ReadLineAsync()
86+
mainWindow.Dispatcher.Invoke(Sub()
87+
mainWindow.Show()
88+
mainWindow.WindowState = WindowState.Normal
89+
mainWindow.Topmost = True
90+
mainWindow.Activate()
91+
mainWindow.Topmost = False
92+
If message IsNot Nothing Then
93+
mainWindow.ViewModel.SelectFolder(message)
94+
End If
95+
End Sub)
96+
End Using
97+
End While
98+
End Using
99+
End Function
100+
101+
Public Async Function ShutdownPipeServer() As Task
102+
If pipeServerTask IsNot Nothing Then
103+
pipeServerCancellation.Cancel()
104+
Await pipeServerTask
105+
End If
106+
End Function
96107

97108
End Class

CompactGUI/ViewModels/MainViewModel.vb

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -258,10 +258,19 @@ Public Class MainViewModel : Inherits ObservableObject
258258
.Arguments = $"""{ActiveFolder.FolderName}""",
259259
.Verb = "runas"}
260260
}
261-
Application.mutex.Dispose()
262-
myproc.Start()
263-
Application.Current.Shutdown()
264-
261+
Dim app As Application = Application.Current
262+
app.ShutdownPipeServer().ContinueWith(
263+
Sub()
264+
app.Dispatcher.Invoke(
265+
Sub()
266+
Application.mutex.ReleaseMutex()
267+
Application.mutex.Dispose()
268+
End Sub
269+
)
270+
myproc.Start()
271+
app.Dispatcher.Invoke(Sub() app.Shutdown())
272+
End Sub
273+
)
265274
End Sub
266275

267276

0 commit comments

Comments
 (0)