4
4
using System . ComponentModel ;
5
5
using System . IO ;
6
6
using System . Runtime . InteropServices ;
7
+ using System . Security ;
7
8
8
9
namespace Microsoft . Win32 . TaskScheduler
9
10
{
@@ -96,6 +97,7 @@ public sealed partial class TaskService : Component, ISupportInitialize, System.
96
97
private string userName ;
97
98
private bool userNameSet ;
98
99
private string userPassword ;
100
+ private SecureString userSecurePassword ;
99
101
private bool userPasswordSet ;
100
102
private WindowsImpersonatedIdentity v1Impersonation ;
101
103
@@ -130,6 +132,30 @@ public TaskService(string targetServer, string userName = null, string accountDo
130
132
EndInit ( ) ;
131
133
}
132
134
135
+ /// <summary>Initializes a new instance of the <see cref="TaskService"/> class.</summary>
136
+ /// <param name="targetServer">
137
+ /// The name of the computer that you want to connect to. If the this parameter is empty, then this will connect to the local computer.
138
+ /// </param>
139
+ /// <param name="userName">
140
+ /// The user name that is used during the connection to the computer. If the user is not specified, then the current token is used.
141
+ /// </param>
142
+ /// <param name="accountDomain">The domain of the user specified in the <paramref name="userName"/> parameter.</param>
143
+ /// <param name="userSecurePassword">
144
+ /// The password that is used to connect to the computer as a SecureString. If the user name and securePassword are not specified, then the current token is used.
145
+ /// </param>
146
+ /// <param name="forceV1">If set to <c>true</c> force Task Scheduler 1.0 compatibility.</param>
147
+ public TaskService ( string targetServer , string userName , string accountDomain , SecureString userSecurePassword , bool forceV1 = false )
148
+ {
149
+ BeginInit ( ) ;
150
+ TargetServer = targetServer ;
151
+ UserName = userName ;
152
+ UserAccountDomain = accountDomain ;
153
+ SetUserSecurePassword ( userSecurePassword ) ;
154
+ this . forceV1 = forceV1 ;
155
+ ResetHighestSupportedVersion ( ) ;
156
+ EndInit ( ) ;
157
+ }
158
+
133
159
private TaskService ( [ NotNull ] System . Runtime . Serialization . SerializationInfo info , System . Runtime . Serialization . StreamingContext context )
134
160
{
135
161
BeginInit ( ) ;
@@ -369,13 +395,38 @@ public string UserPassword
369
395
if ( value == null || value . Trim ( ) == string . Empty ) value = null ;
370
396
if ( string . CompareOrdinal ( value , userPassword ) != 0 )
371
397
{
398
+ userSecurePassword = null ;
372
399
userPasswordSet = true ;
373
400
userPassword = value ;
374
401
Connect ( ) ;
375
402
}
376
403
}
377
404
}
378
405
406
+ /// <summary>Gets the user password in plain text from either userPassword or userSecurePassword.</summary>
407
+ internal string UserPasswordPlainText
408
+ {
409
+ get
410
+ {
411
+ if ( ! string . IsNullOrEmpty ( userPassword ) )
412
+ return userPassword ;
413
+
414
+ if ( userSecurePassword == null )
415
+ return string . Empty ;
416
+
417
+ IntPtr valuePtr = IntPtr . Zero ;
418
+ try
419
+ {
420
+ valuePtr = Marshal . SecureStringToGlobalAllocUnicode ( userSecurePassword ) ;
421
+ return Marshal . PtrToStringUni ( valuePtr ) ;
422
+ }
423
+ finally
424
+ {
425
+ Marshal . ZeroFreeGlobalAllocUnicode ( valuePtr ) ;
426
+ }
427
+ }
428
+ }
429
+
379
430
/// <summary>Gets a <see cref="IEnumerator{T}"/> which enumerates all the tasks in all folders.</summary>
380
431
/// <value>A <see cref="IEnumerator{T}"/> for all <see cref="Task"/> instances.</value>
381
432
[ Browsable ( false ) ]
@@ -575,7 +626,7 @@ public void EndInit()
575
626
public override bool Equals ( object obj )
576
627
{
577
628
if ( obj is TaskService tsobj )
578
- return tsobj . TargetServer == TargetServer && tsobj . UserAccountDomain == UserAccountDomain && tsobj . UserName == UserName && tsobj . UserPassword == UserPassword && tsobj . forceV1 == forceV1 ;
629
+ return tsobj . TargetServer == TargetServer && tsobj . UserAccountDomain == UserAccountDomain && tsobj . UserName == UserName && tsobj . UserPasswordPlainText == UserPasswordPlainText && tsobj . forceV1 == forceV1 ;
579
630
return base . Equals ( obj ) ;
580
631
}
581
632
@@ -611,7 +662,7 @@ public Task FindTask([NotNull] string name, bool searchAllFolders = true)
611
662
/// <summary>Gets the event log for this <see cref="TaskService"/> instance.</summary>
612
663
/// <param name="taskPath">(Optional) The task path if only the events for a single task are desired.</param>
613
664
/// <returns>A <see cref="TaskEventLog"/> instance.</returns>
614
- public TaskEventLog GetEventLog ( string taskPath = null ) => new ( TargetServer , taskPath , UserAccountDomain , UserName , UserPassword ) ;
665
+ public TaskEventLog GetEventLog ( string taskPath = null ) => new ( TargetServer , taskPath , UserAccountDomain , UserName , UserPasswordPlainText ) ;
615
666
616
667
/// <summary>Gets the path to a folder of registered tasks.</summary>
617
668
/// <param name="folderName">
@@ -647,7 +698,7 @@ public TaskFolder GetFolder(string folderName)
647
698
648
699
/// <summary>Returns a hash code for this instance.</summary>
649
700
/// <returns>A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.</returns>
650
- public override int GetHashCode ( ) => new { A = TargetServer , B = UserAccountDomain , C = UserName , D = UserPassword , E = forceV1 } . GetHashCode ( ) ;
701
+ public override int GetHashCode ( ) => new { A = TargetServer , B = UserAccountDomain , C = UserName , D = UserPasswordPlainText , E = forceV1 } . GetHashCode ( ) ;
651
702
652
703
/// <summary>Gets a collection of running tasks.</summary>
653
704
/// <param name="includeHidden">True to include hidden tasks.</param>
@@ -711,6 +762,16 @@ public TaskDefinition NewTaskFromFile([NotNull] string xmlFile)
711
762
return td ;
712
763
}
713
764
765
+ /// <summary>Sets the user password as a secure string to be used when connecting to the <see cref="TargetServer"/>.</summary>
766
+ /// <param name="value">A secure string containing the user password to set.</param>
767
+ public void SetUserSecurePassword ( SecureString value )
768
+ {
769
+ userPasswordSet = true ;
770
+ userPassword = null ;
771
+ userSecurePassword = value ;
772
+ Connect ( ) ;
773
+ }
774
+
714
775
/// <summary>Starts the Task Scheduler UI for the OS hosting the assembly if the session is running in interactive mode.</summary>
715
776
public void StartSystemTaskSchedulerManager ( )
716
777
{
@@ -846,7 +907,7 @@ private void Connect()
846
907
847
908
if ( ! initializing && ! DesignMode )
848
909
{
849
- if ( ! string . IsNullOrEmpty ( userDomain ) && ! string . IsNullOrEmpty ( userName ) && ! string . IsNullOrEmpty ( userPassword ) || string . IsNullOrEmpty ( userDomain ) && string . IsNullOrEmpty ( userName ) && string . IsNullOrEmpty ( userPassword ) )
910
+ if ( ! string . IsNullOrEmpty ( userDomain ) && ! string . IsNullOrEmpty ( userName ) && ! string . IsNullOrEmpty ( UserPasswordPlainText ) || string . IsNullOrEmpty ( userDomain ) && string . IsNullOrEmpty ( userName ) && string . IsNullOrEmpty ( UserPasswordPlainText ) )
850
911
{
851
912
// Clear stuff if already connected
852
913
connecting = true ;
@@ -866,15 +927,15 @@ private void Connect()
866
927
}
867
928
else
868
929
targetServer = null ;
869
- v2TaskService . Connect ( targetServer , userName , userDomain , userPassword ) ;
930
+ v2TaskService . Connect ( targetServer , userName , userDomain , UserPasswordPlainText ) ;
870
931
targetServer = v2TaskService . TargetServer ;
871
932
userName = v2TaskService . ConnectedUser ;
872
933
userDomain = v2TaskService . ConnectedDomain ;
873
934
maxVer = GetV2Version ( ) ;
874
935
}
875
936
else
876
937
{
877
- v1Impersonation = new WindowsImpersonatedIdentity ( userName , userDomain , userPassword ) ;
938
+ v1Impersonation = new WindowsImpersonatedIdentity ( userName , userDomain , UserPasswordPlainText ) ;
878
939
v1TaskScheduler = new V1Interop . ITaskScheduler ( ) ;
879
940
if ( ! string . IsNullOrEmpty ( targetServer ) )
880
941
{
@@ -929,7 +990,11 @@ private void ResetUnsetProperties()
929
990
if ( ! targetServerSet ) targetServer = null ;
930
991
if ( ! userDomainSet ) userDomain = null ;
931
992
if ( ! userNameSet ) userName = null ;
932
- if ( ! userPasswordSet ) userPassword = null ;
993
+ if ( ! userPasswordSet )
994
+ {
995
+ userPassword = null ;
996
+ userSecurePassword = null ;
997
+ }
933
998
}
934
999
935
1000
private bool ShouldSerializeHighestSupportedVersion ( ) => LibraryIsV2 && maxVer <= TaskServiceVersion . V1_1 ;
0 commit comments