@@ -16,25 +16,16 @@ private RestartManager(uint sessionHandle, string sessionKey)
1616 SessionKey = sessionKey ;
1717 }
1818
19- public unsafe static RestartManager CreateSession ( )
19+ public static RestartManager CreateSession ( )
2020 {
21- var sessionKey = Guid . NewGuid ( ) . ToString ( ) ;
22-
23- uint sessionHandle ;
24- WIN32_ERROR result ;
25- fixed ( char * pKey = sessionKey )
26- {
27- result = PInvoke . RmStartSession (
28- & sessionHandle ,
29- 0 ,
30- ( PWSTR ) pKey
31- ) ;
32- }
33-
34- if ( result != Windows . Win32 . Foundation . WIN32_ERROR . ERROR_SUCCESS )
21+ Span < char > sessionKeyBuffer = stackalloc char [ ( int ) PInvoke . CCH_RM_SESSION_KEY + 1 ] ;
22+ var result = StartSession ( out var handle , sessionKeyBuffer ) ;
23+ if ( result != WIN32_ERROR . ERROR_SUCCESS )
3524 throw new Win32Exception ( ( int ) result , $ "RmStartSession failed ({ result } )") ;
3625
37- return new RestartManager ( sessionHandle , sessionKey ) ;
26+ var sessionKeyLength = sessionKeyBuffer . IndexOf ( '\0 ' ) ;
27+ var sessionKey = sessionKeyLength >= 0 ? new string ( sessionKeyBuffer [ ..sessionKeyLength ] ) : new string ( sessionKeyBuffer ) ;
28+ return new RestartManager ( handle , sessionKey ) ;
3829 }
3930
4031 /// <summary>Joins an existing Restart Manager session using the specified session key.</summary>
@@ -54,21 +45,12 @@ public static RestartManager JoinSession(string sessionKey)
5445 /// <param name="path">The full path of the file to register.</param>
5546 /// <exception cref="ArgumentNullException">Thrown when <paramref name="path"/> is <see langword="null"/>.</exception>
5647 /// <exception cref="Win32Exception">Thrown when the registration fails.</exception>
57- public unsafe void RegisterFile ( string path )
48+ public void RegisterFile ( string path )
5849 {
5950 ArgumentNullException . ThrowIfNull ( path ) ;
6051
6152 string [ ] resources = [ path ] ;
62- WIN32_ERROR result ;
63- fixed ( char * p0 = resources [ 0 ] )
64- {
65- char * * pcwstr = stackalloc char * [ 1 ] ;
66- pcwstr [ 0 ] = p0 ;
67-
68- PCWSTR * pResources = ( PCWSTR * ) pcwstr ;
69- result = PInvoke . RmRegisterResources ( SessionHandle , ( uint ) resources . Length , pResources , 0 , rgApplications : null , 0 , rgsServiceNames : null ) ;
70- }
71-
53+ var result = RegisterResources ( SessionHandle , resources ) ;
7254 if ( result != WIN32_ERROR . ERROR_SUCCESS )
7355 throw new Win32Exception ( ( int ) result , $ "RmRegisterResources failed ({ result } )") ;
7456 }
@@ -77,22 +59,11 @@ public unsafe void RegisterFile(string path)
7759 /// <param name="paths">An array of full file paths to register.</param>
7860 /// <exception cref="ArgumentNullException">Thrown when <paramref name="paths"/> is <see langword="null"/>.</exception>
7961 /// <exception cref="Win32Exception">Thrown when the registration fails.</exception>
80- public unsafe void RegisterFiles ( string [ ] paths )
62+ public void RegisterFiles ( string [ ] paths )
8163 {
8264 ArgumentNullException . ThrowIfNull ( paths ) ;
8365
84-
85- WIN32_ERROR result ;
86- fixed ( char * p0 = paths [ 0 ] )
87- {
88- char * * pcwstr = stackalloc char * [ 1 ] ;
89- pcwstr [ 0 ] = p0 ;
90-
91- PCWSTR * pPaths = ( PCWSTR * ) pcwstr ;
92- result = PInvoke . RmRegisterResources ( SessionHandle , ( uint ) paths . LongLength , pPaths , 0 , rgApplications : null , 0 , rgsServiceNames : null ) ;
93- }
94-
95-
66+ var result = RegisterResources ( SessionHandle , paths ) ;
9667 if ( result != WIN32_ERROR . ERROR_SUCCESS )
9768 throw new Win32Exception ( ( int ) result , $ "RmRegisterResources failed ({ result } )") ;
9869 }
@@ -191,6 +162,46 @@ public unsafe void Restart(delegate* unmanaged[Stdcall]<uint, void> callback)
191162 throw new Win32Exception ( ( int ) result , $ "RmRestart failed ({ result } )") ;
192163 }
193164
165+ private static unsafe WIN32_ERROR StartSession ( out uint handle , Span < char > sessionKeyBuffer )
166+ {
167+ uint localHandle = 0 ;
168+ fixed ( char * sessionKeyBufferPtr = sessionKeyBuffer )
169+ {
170+ var result = PInvoke . RmStartSession ( & localHandle , 0 , new PWSTR ( sessionKeyBufferPtr ) ) ;
171+ handle = localHandle ;
172+ return result ;
173+ }
174+ }
175+
176+ private static unsafe WIN32_ERROR RegisterResources ( uint sessionHandle , string [ ] paths )
177+ {
178+ if ( paths . Length == 0 )
179+ return PInvoke . RmRegisterResources ( sessionHandle , 0 , ( PCWSTR * ) null , 0 , ( RM_UNIQUE_PROCESS * ) null , 0 , ( PCWSTR * ) null ) ;
180+
181+ var handles = new GCHandle [ paths . Length ] ;
182+ try
183+ {
184+ var pathPointers = stackalloc PCWSTR [ paths . Length ] ;
185+ for ( var i = 0 ; i < paths . Length ; i ++ )
186+ {
187+ handles [ i ] = GCHandle . Alloc ( paths [ i ] , GCHandleType . Pinned ) ;
188+ pathPointers [ i ] = new PCWSTR ( ( char * ) handles [ i ] . AddrOfPinnedObject ( ) ) ;
189+ }
190+
191+ return PInvoke . RmRegisterResources ( sessionHandle , ( uint ) paths . Length , pathPointers , 0 , ( RM_UNIQUE_PROCESS * ) null , 0 , ( PCWSTR * ) null ) ;
192+ }
193+ finally
194+ {
195+ foreach ( var handle in handles )
196+ {
197+ if ( handle . IsAllocated )
198+ {
199+ handle . Free ( ) ;
200+ }
201+ }
202+ }
203+ }
204+
194205 /// <summary>Ends the Restart Manager session and releases all resources.</summary>
195206 /// <exception cref="Win32Exception">Thrown when ending the session fails.</exception>
196207 [ SuppressMessage ( "Design" , "CA1065:Do not raise exceptions in unexpected locations" , Justification = "<Pending>" ) ]
0 commit comments