├── MygodWifiShare ├── Main.ico ├── Mygod.cer ├── Logger.cs ├── [References] │ └── [TaskScheduler] │ │ ├── CultureSwitcher.cs │ │ ├── Wildcard.cs │ │ ├── Native │ │ ├── ADVAPI32.cs │ │ └── WindowsImpersonatedIdentity.cs │ │ ├── EnumGlobalizer.cs │ │ ├── NotV1SupportedException.cs │ │ ├── NamedValueCollection.cs │ │ ├── TaskFolderCollection.cs │ │ ├── ActionCollection.cs │ │ ├── TriggerCollection.cs │ │ ├── XmlSerializationHelper.cs │ │ ├── TaskCollection.cs │ │ ├── V1 │ │ └── TaskSchedulerV1Schema.xsd │ │ ├── TaskFolder.cs │ │ └── TaskService.cs ├── AssemblyInfo.cs ├── app.manifest ├── DnsCache.cs ├── MygodWifiShare.csproj ├── WlanNativeMethods.cs ├── Resources.resx └── WlanManager.cs ├── readme.md ├── .gitattributes ├── MygodWifiShare.sln └── .gitignore /MygodWifiShare/Main.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mygod/MygodWifiShare/HEAD/MygodWifiShare/Main.ico -------------------------------------------------------------------------------- /MygodWifiShare/Mygod.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mygod/MygodWifiShare/HEAD/MygodWifiShare/Mygod.cer -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | Introduction 2 | ============ 3 | Mygod Wifi Share™! A light-weighted tool to share your Internet connection EVERYWHERE! 4 | 5 | Third Party Libraries 6 | --------------------- 7 | * Task Scheduler Managed Wrapper: http://taskscheduler.codeplex.com/ 8 | * Virtual Router: (modified) http://virtualrouter.codeplex.com/ -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /MygodWifiShare/Logger.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | 3 | namespace Mygod.WifiShare 4 | { 5 | internal static class Logger 6 | { 7 | public static readonly string LogPath = Path.Combine(Path.GetTempPath(), "MygodWifiShare.log"); 8 | public static StreamWriter Instance; 9 | public static bool Initialized; 10 | 11 | public static bool Initialize() 12 | { 13 | try 14 | { 15 | Instance = new StreamWriter(LogPath, true); 16 | return Initialized = true; 17 | } 18 | catch 19 | { 20 | return false; // another instance is already running 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /MygodWifiShare/[References]/[TaskScheduler]/CultureSwitcher.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Microsoft.Win32.TaskScheduler 4 | { 5 | internal class CultureSwitcher : IDisposable 6 | { 7 | System.Globalization.CultureInfo cur, curUI; 8 | 9 | public CultureSwitcher(System.Globalization.CultureInfo culture) 10 | { 11 | cur = System.Threading.Thread.CurrentThread.CurrentCulture; 12 | curUI = System.Threading.Thread.CurrentThread.CurrentUICulture; 13 | System.Threading.Thread.CurrentThread.CurrentCulture = System.Threading.Thread.CurrentThread.CurrentUICulture = culture; 14 | } 15 | 16 | public void Dispose() 17 | { 18 | System.Threading.Thread.CurrentThread.CurrentCulture = cur; 19 | System.Threading.Thread.CurrentThread.CurrentUICulture = curUI; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /MygodWifiShare/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // 有关程序集的常规信息通过以下 6 | // 特性集控制。更改这些特性值可修改 7 | // 与程序集关联的信息。 8 | [assembly: AssemblyTitle("Mygod无线网络共享")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Mygod")] 12 | [assembly: AssemblyProduct("Mygod无线网络共享")] 13 | [assembly: AssemblyCopyright("Copyright © Mygod 2011-2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // 将 ComVisible 设置为 false 使此程序集中的类型 18 | // 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型, 19 | // 则将该类型上的 ComVisible 特性设置为 true。 20 | [assembly: ComVisible(false)] 21 | 22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID 23 | [assembly: Guid("063a86ea-c99f-4611-8710-952813ac23ea")] 24 | 25 | // 程序集的版本信息由下面四个值组成: 26 | // 27 | // 主版本 28 | // 次版本 29 | // 内部版本号 30 | // 修订号 31 | // 32 | // 可以指定所有这些值,也可以使用“内部版本号”和“修订号”的默认值, 33 | // 方法是按如下所示使用“*”: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.7.33.361")] 36 | [assembly: AssemblyFileVersion("1.7.33.361")] 37 | -------------------------------------------------------------------------------- /MygodWifiShare.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.23107.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MygodWifiShare", "MygodWifiShare\MygodWifiShare.csproj", "{B0659576-2DC2-463A-8902-2986D886BAAD}" 7 | EndProject 8 | Global 9 | GlobalSection(Performance) = preSolution 10 | HasPerformanceSessions = true 11 | EndGlobalSection 12 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 13 | Debug|Any CPU = Debug|Any CPU 14 | Release|Any CPU = Release|Any CPU 15 | EndGlobalSection 16 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 17 | {B0659576-2DC2-463A-8902-2986D886BAAD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 18 | {B0659576-2DC2-463A-8902-2986D886BAAD}.Debug|Any CPU.Build.0 = Debug|Any CPU 19 | {B0659576-2DC2-463A-8902-2986D886BAAD}.Release|Any CPU.ActiveCfg = Release|Any CPU 20 | {B0659576-2DC2-463A-8902-2986D886BAAD}.Release|Any CPU.Build.0 = Release|Any CPU 21 | EndGlobalSection 22 | GlobalSection(SolutionProperties) = preSolution 23 | HideSolutionNode = FALSE 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /MygodWifiShare/[References]/[TaskScheduler]/Wildcard.cs: -------------------------------------------------------------------------------- 1 | using System.Text.RegularExpressions; 2 | 3 | namespace Microsoft.Win32.TaskScheduler 4 | { 5 | /// 6 | /// Represents a wildcard running on the 7 | /// engine. 8 | /// 9 | public class Wildcard : Regex 10 | { 11 | /// 12 | /// Initializes a wildcard with the given search pattern and options. 13 | /// 14 | /// The wildcard pattern to match. 15 | /// A combination of one or more . 16 | public Wildcard(string pattern, RegexOptions options = RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace) 17 | : base(WildcardToRegex(pattern), options) 18 | { 19 | } 20 | 21 | /// 22 | /// Converts a wildcard to a regex. 23 | /// 24 | /// The wildcard pattern to convert. 25 | /// A regex equivalent of the given wildcard. 26 | public static string WildcardToRegex(string pattern) 27 | { 28 | string s = "^" + Regex.Escape(pattern) + "$"; s = Regex.Replace(s, @"(? 2 | 3 | 4 | 使用这个工具可以让你通过无线网络共享自己的Internet。 5 | 6 | 7 | 8 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /MygodWifiShare/[References]/[TaskScheduler]/Native/WindowsImpersonatedIdentity.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.Runtime.InteropServices; 4 | using System.Security.Principal; 5 | 6 | namespace Microsoft.Win32 7 | { 8 | /// 9 | /// Impersonation of a user. Allows to execute code under another 10 | /// user context. 11 | /// Please note that the account that instantiates the Impersonator class 12 | /// needs to have the 'Act as part of operating system' privilege set. 13 | /// 14 | internal class WindowsImpersonatedIdentity : IDisposable, IIdentity 15 | { 16 | private WindowsImpersonationContext impersonationContext = null; 17 | private WindowsIdentity identity = null; 18 | 19 | /// 20 | /// Constructor. Starts the impersonation with the given credentials. 21 | /// Please note that the account that instantiates the Impersonator class 22 | /// needs to have the 'Act as part of operating system' privilege set. 23 | /// 24 | /// The name of the user to act as. 25 | /// The domain name of the user to act as. 26 | /// The password of the user to act as. 27 | public WindowsImpersonatedIdentity(string userName, string domainName, string password) 28 | { 29 | NativeMethods.SafeTokenHandle token; 30 | if (string.IsNullOrEmpty(userName) && string.IsNullOrEmpty(domainName) && string.IsNullOrEmpty(password)) 31 | { 32 | identity = WindowsIdentity.GetCurrent(); 33 | } 34 | else 35 | { 36 | if (NativeMethods.LogonUser(userName, domainName, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, out token) != 0) 37 | { 38 | using (token) 39 | { 40 | identity = new WindowsIdentity(token.DangerousGetHandle()); 41 | impersonationContext = identity.Impersonate(); 42 | } 43 | } 44 | else 45 | { 46 | throw new Win32Exception(Marshal.GetLastWin32Error()); 47 | } 48 | } 49 | } 50 | 51 | public void Dispose() 52 | { 53 | if (impersonationContext != null) 54 | impersonationContext.Undo(); 55 | if (identity != null) 56 | identity.Dispose(); 57 | } 58 | 59 | private const int LOGON32_LOGON_INTERACTIVE = 2; 60 | private const int LOGON32_PROVIDER_DEFAULT = 0; 61 | 62 | public string AuthenticationType 63 | { 64 | get { return identity == null ? null : identity.AuthenticationType; } 65 | } 66 | 67 | public bool IsAuthenticated 68 | { 69 | get { return identity == null ? false : identity.IsAuthenticated; } 70 | } 71 | 72 | public string Name 73 | { 74 | get { return identity == null ? null : identity.Name; } 75 | } 76 | } 77 | } -------------------------------------------------------------------------------- /MygodWifiShare/[References]/[TaskScheduler]/EnumGlobalizer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Globalization; 4 | using Mygod.WifiShare; 5 | 6 | namespace Microsoft.Win32.TaskScheduler 7 | { 8 | /// 9 | /// Functions to provide localized strings for enumerated types and values. 10 | /// 11 | public static class TaskEnumGlobalizer 12 | { 13 | /// 14 | /// Gets a string representing the localized value of the provided enum. 15 | /// 16 | /// The enum value. 17 | /// A localized string, if available. 18 | public static string GetString(object enumValue) 19 | { 20 | switch (enumValue.GetType().Name) 21 | { 22 | case "DaysOfTheWeek": 23 | return GetCultureEquivalentString((DaysOfTheWeek)enumValue); 24 | case "MonthsOfTheYear": 25 | return GetCultureEquivalentString((MonthsOfTheYear)enumValue); 26 | case "TaskTriggerType": 27 | return BuildEnumString("TriggerType", enumValue); 28 | case "WhichWeek": 29 | return BuildEnumString("WW", enumValue); 30 | case "TaskActionType": 31 | return BuildEnumString("ActionType", enumValue); 32 | case "TaskState": 33 | return BuildEnumString("TaskState", enumValue); 34 | default: 35 | break; 36 | } 37 | return enumValue.ToString(); 38 | } 39 | 40 | private static string GetCultureEquivalentString(DaysOfTheWeek val) 41 | { 42 | if (val == DaysOfTheWeek.AllDays) 43 | return Resources.DOWAllDays; 44 | 45 | List s = new List(7); 46 | Array vals = Enum.GetValues(val.GetType()); 47 | for (int i = 0; i < vals.Length - 1; i++) 48 | { 49 | if ((val & (DaysOfTheWeek)vals.GetValue(i)) > 0) 50 | s.Add(DateTimeFormatInfo.CurrentInfo.GetDayName((DayOfWeek)i)); 51 | } 52 | 53 | return string.Join(Resources.ListSeparator, s.ToArray()); 54 | } 55 | 56 | private static string GetCultureEquivalentString(MonthsOfTheYear val) 57 | { 58 | if (val == MonthsOfTheYear.AllMonths) 59 | return Resources.MOYAllMonths; 60 | 61 | List s = new List(12); 62 | Array vals = Enum.GetValues(val.GetType()); 63 | for (int i = 0; i < vals.Length - 1; i++) 64 | { 65 | if ((val & (MonthsOfTheYear)vals.GetValue(i)) > 0) 66 | s.Add(DateTimeFormatInfo.CurrentInfo.GetMonthName(i+1)); 67 | } 68 | 69 | return string.Join(Resources.ListSeparator, s.ToArray()); 70 | } 71 | 72 | private static string BuildEnumString(string preface, object enumValue) 73 | { 74 | string[] vals = enumValue.ToString().Split(new string[] { ", " }, StringSplitOptions.None); 75 | if (vals.Length == 0) 76 | return string.Empty; 77 | for (int i = 0; i < vals.Length; i++) 78 | vals[i] = Resources.ResourceManager.GetString(preface + vals[i]); 79 | return string.Join(Resources.ListSeparator, vals); 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /MygodWifiShare/[References]/[TaskScheduler]/NotV1SupportedException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.Reflection; 4 | 5 | namespace Microsoft.Win32.TaskScheduler 6 | { 7 | /// 8 | /// Abstract class for throwing a method specific exception. 9 | /// 10 | [System.Diagnostics.DebuggerStepThrough] 11 | public abstract class TSNotSupportedException : Exception 12 | { 13 | /// Defines the minimum supported version for the action not allowed by this exception. 14 | protected TaskCompatibility min; 15 | private string myMessage; 16 | 17 | internal TSNotSupportedException(TaskCompatibility minComp) 18 | { 19 | min = minComp; 20 | StackTrace stackTrace = new StackTrace(); 21 | StackFrame stackFrame = stackTrace.GetFrame(2); 22 | MethodBase methodBase = stackFrame.GetMethod(); 23 | myMessage = string.Format("{0}.{1} is not supported on {2}", methodBase.DeclaringType.Name, methodBase.Name, this.LibName); 24 | } 25 | 26 | internal TSNotSupportedException(string message, TaskCompatibility minComp) 27 | { 28 | myMessage = message; 29 | min = minComp; 30 | } 31 | 32 | /// 33 | /// Gets a message that describes the current exception. 34 | /// 35 | public override string Message 36 | { 37 | get { return myMessage; } 38 | } 39 | 40 | /// 41 | /// Gets the minimum supported TaskScheduler version required for this method or property. 42 | /// 43 | public TaskCompatibility MinimumSupportedVersion { get { return min; } } 44 | 45 | internal abstract string LibName { get; } 46 | } 47 | 48 | /// 49 | /// Thrown when the calling method is not supported by Task Scheduler 1.0. 50 | /// 51 | [System.Diagnostics.DebuggerStepThrough] 52 | public class NotV1SupportedException : TSNotSupportedException 53 | { 54 | internal NotV1SupportedException() : base(TaskCompatibility.V2) { } 55 | internal NotV1SupportedException(string message) : base(message, TaskCompatibility.V2) { } 56 | internal override string LibName { get { return "Task Scheduler 1.0"; } } 57 | } 58 | 59 | /// 60 | /// Thrown when the calling method is not supported by Task Scheduler 2.0. 61 | /// 62 | [System.Diagnostics.DebuggerStepThrough] 63 | public class NotV2SupportedException : TSNotSupportedException 64 | { 65 | internal NotV2SupportedException() : base(TaskCompatibility.V1) { } 66 | internal NotV2SupportedException(string message) : base(message, TaskCompatibility.V1) { } 67 | internal override string LibName { get { return "Task Scheduler 2.0 (1.2)"; } } 68 | } 69 | 70 | 71 | /// 72 | /// Thrown when the calling method is not supported by Task Scheduler versions prior to the one specified. 73 | /// 74 | [System.Diagnostics.DebuggerStepThrough] 75 | public class NotSupportedPriorToException : TSNotSupportedException 76 | { 77 | internal NotSupportedPriorToException(TaskCompatibility supportedVersion) : base(supportedVersion) { } 78 | internal override string LibName { get { return string.Format("Task Scheduler versions prior to 2.{0} (1.{1})", ((int)min) - 2, (int)min); } } 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *.tmp 11 | *.bak 12 | *.swp 13 | *~.nib 14 | local.properties 15 | .classpath 16 | .settings/ 17 | .loadpath 18 | 19 | # External tool builders 20 | .externalToolBuilders/ 21 | 22 | # Locally stored "Eclipse launch configurations" 23 | *.launch 24 | 25 | # CDT-specific 26 | .cproject 27 | 28 | # PDT-specific 29 | .buildpath 30 | 31 | 32 | ################# 33 | ## Visual Studio 34 | ################# 35 | 36 | ## Ignore Visual Studio temporary files, build results, and 37 | ## files generated by popular Visual Studio add-ons. 38 | 39 | # User-specific files 40 | *.suo 41 | *.user 42 | *.sln.docstates 43 | 44 | # Build results 45 | 46 | [Dd]ebug/ 47 | [Rr]elease/ 48 | x64/ 49 | build/ 50 | [Bb]in/ 51 | [Oo]bj/ 52 | 53 | # MSTest test Results 54 | [Tt]est[Rr]esult*/ 55 | [Bb]uild[Ll]og.* 56 | 57 | *_i.c 58 | *_p.c 59 | *.ilk 60 | *.meta 61 | *.obj 62 | *.pch 63 | *.pdb 64 | *.pgc 65 | *.pgd 66 | *.rsp 67 | *.sbr 68 | *.tlb 69 | *.tli 70 | *.tlh 71 | *.tmp 72 | *.tmp_proj 73 | *.log 74 | *.vspscc 75 | *.vssscc 76 | .builds 77 | *.pidb 78 | *.log 79 | *.scc 80 | 81 | # Visual C++ cache files 82 | ipch/ 83 | *.aps 84 | *.ncb 85 | *.opensdf 86 | *.sdf 87 | *.cachefile 88 | 89 | # Visual Studio profiler 90 | *.psess 91 | *.vsp 92 | *.vspx 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | 101 | # TeamCity is a build add-in 102 | _TeamCity* 103 | 104 | # DotCover is a Code Coverage Tool 105 | *.dotCover 106 | 107 | # NCrunch 108 | *.ncrunch* 109 | .*crunch*.local.xml 110 | 111 | # Installshield output folder 112 | [Ee]xpress/ 113 | 114 | # DocProject is a documentation generator add-in 115 | DocProject/buildhelp/ 116 | DocProject/Help/*.HxT 117 | DocProject/Help/*.HxC 118 | DocProject/Help/*.hhc 119 | DocProject/Help/*.hhk 120 | DocProject/Help/*.hhp 121 | DocProject/Help/Html2 122 | DocProject/Help/html 123 | 124 | # Click-Once directory 125 | publish/ 126 | 127 | # Publish Web Output 128 | *.Publish.xml 129 | *.pubxml 130 | 131 | # NuGet Packages Directory 132 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line 133 | #packages/ 134 | 135 | # Windows Azure Build Output 136 | csx 137 | *.build.csdef 138 | 139 | # Windows Store app package directory 140 | AppPackages/ 141 | 142 | # Others 143 | sql/ 144 | *.Cache 145 | ClientBin/ 146 | [Ss]tyle[Cc]op.* 147 | ~$* 148 | *~ 149 | *.dbmdl 150 | *.[Pp]ublish.xml 151 | *.pfx 152 | *.publishsettings 153 | 154 | # RIA/Silverlight projects 155 | Generated_Code/ 156 | 157 | # Backup & report files from converting an old project file to a newer 158 | # Visual Studio version. Backup files are not needed, because we have git ;-) 159 | _UpgradeReport_Files/ 160 | Backup*/ 161 | UpgradeLog*.XML 162 | UpgradeLog*.htm 163 | 164 | # SQL Server files 165 | App_Data/*.mdf 166 | App_Data/*.ldf 167 | 168 | ############# 169 | ## Windows detritus 170 | ############# 171 | 172 | # Windows image file caches 173 | Thumbs.db 174 | ehthumbs.db 175 | 176 | # Folder config file 177 | Desktop.ini 178 | 179 | # Recycle Bin used on file shares 180 | $RECYCLE.BIN/ 181 | 182 | # Mac crap 183 | .DS_Store 184 | 185 | 186 | ############# 187 | ## Python 188 | ############# 189 | 190 | *.py[co] 191 | 192 | # Packages 193 | *.egg 194 | *.egg-info 195 | dist/ 196 | build/ 197 | eggs/ 198 | parts/ 199 | var/ 200 | sdist/ 201 | develop-eggs/ 202 | .installed.cfg 203 | 204 | # Installer logs 205 | pip-log.txt 206 | 207 | # Unit test / coverage reports 208 | .coverage 209 | .tox 210 | 211 | #Translations 212 | *.mo 213 | 214 | #Mr Developer 215 | .mr.developer.cfg 216 | *.DotSettings 217 | -------------------------------------------------------------------------------- /MygodWifiShare/[References]/[TaskScheduler]/NamedValueCollection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.InteropServices; 4 | 5 | namespace Microsoft.Win32.TaskScheduler 6 | { 7 | /// 8 | /// Contains a collection of name-value pairs. 9 | /// 10 | public sealed class NamedValueCollection : IDisposable, System.Collections.IEnumerable 11 | { 12 | private V2Interop.ITaskNamedValueCollection v2Coll = null; 13 | private Dictionary unboundDict = null; 14 | 15 | internal NamedValueCollection(V2Interop.ITaskNamedValueCollection iColl) { v2Coll = iColl; } 16 | 17 | internal NamedValueCollection() 18 | { 19 | unboundDict = new Dictionary(5); 20 | } 21 | 22 | internal bool Bound 23 | { 24 | get { return v2Coll != null; } 25 | } 26 | 27 | internal void Bind(V2Interop.ITaskNamedValueCollection iTaskNamedValueCollection) 28 | { 29 | v2Coll = iTaskNamedValueCollection; 30 | v2Coll.Clear(); 31 | foreach (var item in unboundDict) 32 | v2Coll.Create(item.Key, item.Value); 33 | } 34 | 35 | /// 36 | /// Copies current to another. 37 | /// 38 | /// The destination collection. 39 | public void CopyTo(NamedValueCollection destCollection) 40 | { 41 | if (v2Coll != null) 42 | { 43 | for (int i = 1; i <= this.Count; i++) 44 | destCollection.Add(v2Coll[i].Name, v2Coll[i].Value); 45 | } 46 | else 47 | { 48 | foreach (var item in unboundDict) 49 | destCollection.Add(item.Key, item.Value); 50 | } 51 | } 52 | 53 | /// 54 | /// Releases all resources used by this class. 55 | /// 56 | public void Dispose() 57 | { 58 | if (v2Coll != null) Marshal.ReleaseComObject(v2Coll); 59 | } 60 | 61 | /// 62 | /// Gets the number of items in the collection. 63 | /// 64 | public int Count 65 | { 66 | get { return v2Coll != null ? v2Coll.Count : unboundDict.Count; } 67 | } 68 | 69 | /// 70 | /// Gets a collection of the names. 71 | /// 72 | /// 73 | /// The names. 74 | /// 75 | public IEnumerable Names 76 | { 77 | get 78 | { 79 | if (v2Coll == null) 80 | return unboundDict.Keys; 81 | List ret = new List(v2Coll.Count); 82 | foreach (V2Interop.ITaskNamedValuePair item in v2Coll) 83 | ret.Add(item.Name); 84 | return ret; 85 | } 86 | } 87 | 88 | /// 89 | /// Gets a collection of the values. 90 | /// 91 | /// 92 | /// The values. 93 | /// 94 | public IEnumerable Values 95 | { 96 | get 97 | { 98 | if (v2Coll == null) 99 | return unboundDict.Values; 100 | List ret = new List(v2Coll.Count); 101 | foreach (V2Interop.ITaskNamedValuePair item in v2Coll) 102 | ret.Add(item.Value); 103 | return ret; 104 | } 105 | } 106 | 107 | /// 108 | /// Gets the value of the item at the specified index. 109 | /// 110 | /// The index of the item being requested. 111 | /// The value of the name-value pair at the specified index. 112 | public string this[int index] 113 | { 114 | get 115 | { 116 | if (v2Coll != null) 117 | return v2Coll[++index].Value; 118 | string[] keys = new string[unboundDict.Count]; 119 | unboundDict.Keys.CopyTo(keys, 0); 120 | return unboundDict[keys[index]]; 121 | } 122 | } 123 | 124 | /// 125 | /// Gets the value of the item with the specified key. 126 | /// 127 | /// Key to get the value for. 128 | /// Value for the key, or null if not found. 129 | public string this[string key] 130 | { 131 | get 132 | { 133 | if (v2Coll != null) 134 | { 135 | foreach (V2Interop.ITaskNamedValuePair item in v2Coll) 136 | { 137 | if (string.Compare(item.Name, key, false) == 0) 138 | return item.Value; 139 | } 140 | return null; 141 | } 142 | 143 | string val = null; 144 | unboundDict.TryGetValue(key, out val); 145 | return val; 146 | } 147 | } 148 | 149 | /// 150 | /// Adds a name-value pair to the collection. 151 | /// 152 | /// The name associated with a value in a name-value pair. 153 | /// The value associated with a name in a name-value pair. 154 | public void Add(string Name, string Value) 155 | { 156 | if (v2Coll != null) 157 | v2Coll.Create(Name, Value); 158 | else 159 | unboundDict.Add(Name, Value); 160 | } 161 | 162 | /// 163 | /// Removes a selected name-value pair from the collection. 164 | /// 165 | /// Index of the pair to remove. 166 | public void RemoveAt(int index) 167 | { 168 | v2Coll.Remove(index); 169 | } 170 | 171 | /// 172 | /// Clears the entire collection of name-value pairs. 173 | /// 174 | public void Clear() 175 | { 176 | if (v2Coll != null) 177 | v2Coll.Clear(); 178 | else 179 | unboundDict.Clear(); 180 | } 181 | 182 | /// 183 | /// Gets the collection enumerator for the name-value collection. 184 | /// 185 | /// An for the collection. 186 | public System.Collections.IEnumerator GetEnumerator() 187 | { 188 | if (v2Coll != null) 189 | return v2Coll.GetEnumerator(); 190 | else 191 | return unboundDict.GetEnumerator(); 192 | } 193 | } 194 | } 195 | -------------------------------------------------------------------------------- /MygodWifiShare/DnsCache.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Collections.ObjectModel; 4 | using System.Linq; 5 | using System.Net; 6 | using System.Runtime.InteropServices; 7 | using System.Threading; 8 | 9 | namespace Mygod.WifiShare 10 | { 11 | // ReSharper disable MemberCanBePrivate.Global 12 | static class Arp 13 | { 14 | [DllImport("iphlpapi.dll")] 15 | private static extern int GetIpNetTable(IntPtr pIpNetTable, ref int pdwSize, bool bOrder); 16 | [DllImport("iphlpapi.dll", SetLastError = true, CharSet = CharSet.Auto)] 17 | private static extern int FreeMibTable(IntPtr pIpNetTable); 18 | 19 | [StructLayout(LayoutKind.Sequential)] 20 | public struct MibIpNetRow 21 | { 22 | /// 23 | /// The index of the adapter. 24 | /// 25 | public readonly int Index; 26 | /// 27 | /// The length, in bytes, of the physical address. 28 | /// 29 | public readonly int PhysAddrLen; 30 | /// 31 | /// The physical address. 32 | /// 33 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] 34 | public readonly byte[] PhysAddr; 35 | /// 36 | /// The IPv4 address. 37 | /// 38 | public readonly uint Addr; 39 | /// 40 | /// The type of ARP entry. This type can be one of the following values. 41 | /// 42 | public readonly IPNetRowType Type; 43 | 44 | public string MacAddress => string.Join(":", PhysAddr.Take(PhysAddrLen).Select(b => b.ToString("X2"))); 45 | public IPAddress IPAddress => new IPAddress(Addr); 46 | 47 | public override string ToString() 48 | { 49 | var type = string.Empty; 50 | switch (Type) 51 | { 52 | case IPNetRowType.Other: 53 | type = "其他"; 54 | break; 55 | case IPNetRowType.Invalid: 56 | type = "无效"; 57 | break; 58 | case IPNetRowType.Dynamic: 59 | type = "动态"; 60 | break; 61 | case IPNetRowType.Static: 62 | type = "静态"; 63 | break; 64 | } 65 | return string.IsNullOrWhiteSpace(type) ? IPAddress.ToString() : $"{IPAddress} ({type})"; 66 | } 67 | } 68 | 69 | public enum IPNetRowType 70 | { 71 | Other = 1, Invalid, Dynamic, Static 72 | } 73 | 74 | private static readonly int MibIpNetRowSize = Marshal.SizeOf(typeof(MibIpNetRow)); 75 | public static IEnumerable GetIpNetTable() 76 | { 77 | int bytesNeeded = 0, result = GetIpNetTable(IntPtr.Zero, ref bytesNeeded, false); 78 | if (result != 122) Helper.ThrowExceptionForHR(result); 79 | var buffer = IntPtr.Zero; 80 | try 81 | { 82 | buffer = Marshal.AllocCoTaskMem(bytesNeeded); 83 | Helper.ThrowExceptionForHR(GetIpNetTable(buffer, ref bytesNeeded, false)); 84 | var entries = Marshal.ReadInt32(buffer); 85 | var ptr = buffer + 4; 86 | for (var index = 0; index < entries; index++, ptr += MibIpNetRowSize) 87 | yield return Marshal.PtrToStructure(ptr); 88 | } 89 | finally 90 | { 91 | FreeMibTable(buffer); 92 | } 93 | } 94 | } 95 | // ReSharper restore MemberCanBePrivate.Global 96 | 97 | sealed class DnsCacheEntry 98 | { 99 | public DnsCacheEntry(IPAddress ip) 100 | { 101 | IPAddress = ip; 102 | } 103 | 104 | public void Update() 105 | { 106 | if (semaphore.Wait(0)) 107 | { 108 | try 109 | { 110 | var entry = Dns.GetHostEntry(IPAddress); 111 | Domains = string.Join(", ", new[] { entry.HostName }.Union(entry.Aliases)); 112 | } 113 | catch 114 | { 115 | Domains = null; 116 | } 117 | cacheTime = DateTime.Now; 118 | } 119 | else semaphore.Wait(); // wait for the already running thread 120 | semaphore.Release(); 121 | } 122 | public async void UpdateAsync() 123 | { 124 | if (!semaphore.Wait(0)) return; // already running 125 | try 126 | { 127 | var entry = await Dns.GetHostEntryAsync(IPAddress); 128 | Domains = string.Join(", ", new[] { entry.HostName }.Union(entry.Aliases)); 129 | } 130 | catch 131 | { 132 | Domains = null; 133 | } 134 | cacheTime = DateTime.Now; 135 | semaphore.Release(); 136 | } 137 | 138 | public readonly IPAddress IPAddress; 139 | public string Domains = "加载中"; 140 | private DateTime cacheTime = DateTime.MinValue; 141 | private readonly SemaphoreSlim semaphore = new SemaphoreSlim(1); 142 | 143 | public bool Decayed => (DateTime.Now - cacheTime).TotalSeconds >= Program.Ttl; 144 | } 145 | sealed class DnsCache : KeyedCollection 146 | { 147 | public string GetDomains(IPAddress ip, bool wait = false) 148 | { 149 | DnsCacheEntry entry; 150 | lock (this) 151 | if (Contains(ip)) entry = this[ip]; 152 | else Add(entry = new DnsCacheEntry(ip)); 153 | if (entry.Decayed) 154 | if (wait) entry.Update(); 155 | else entry.UpdateAsync(); 156 | return entry.Domains; 157 | } 158 | 159 | protected override IPAddress GetKeyForItem(DnsCacheEntry item) 160 | { 161 | return item.IPAddress; 162 | } 163 | } 164 | } 165 | -------------------------------------------------------------------------------- /MygodWifiShare/[References]/[TaskScheduler]/TaskFolderCollection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Microsoft.Win32.TaskScheduler 5 | { 6 | /// 7 | /// Provides information and control for a collection of folders that contain tasks. 8 | /// 9 | public sealed class TaskFolderCollection : IEnumerable 10 | { 11 | private TaskFolder parent; 12 | private TaskScheduler.V2Interop.ITaskFolderCollection v2FolderList = null; 13 | private TaskFolder[] v1FolderList = null; 14 | 15 | internal TaskFolderCollection() 16 | { 17 | v1FolderList = new TaskFolder[0]; 18 | } 19 | 20 | internal TaskFolderCollection(TaskFolder v1Folder) 21 | { 22 | parent = v1Folder; 23 | v1FolderList = new TaskFolder[] { v1Folder }; 24 | } 25 | 26 | internal TaskFolderCollection(TaskFolder folder, TaskScheduler.V2Interop.ITaskFolderCollection iCollection) 27 | { 28 | parent = folder; 29 | v2FolderList = iCollection; 30 | } 31 | 32 | /// 33 | /// Releases all resources used by this class. 34 | /// 35 | public void Dispose() 36 | { 37 | if (v1FolderList != null && v1FolderList.Length > 0) 38 | { 39 | v1FolderList[0].Dispose(); 40 | v1FolderList[0] = null; 41 | } 42 | if (v2FolderList != null) 43 | System.Runtime.InteropServices.Marshal.ReleaseComObject(v2FolderList); 44 | } 45 | 46 | /* 47 | /// 48 | /// Returns the index of the TaskFolder within the collection. 49 | /// 50 | /// TaskFolder to find. 51 | /// Index of the TaskFolder; -1 if not found. 52 | public int IndexOf(TaskFolder item) 53 | { 54 | return IndexOf(item.Path); 55 | } 56 | 57 | /// 58 | /// Returns the index of the TaskFolder within the collection. 59 | /// 60 | /// Path to find. 61 | /// Index of the TaskFolder; -1 if not found. 62 | public int IndexOf(string path) 63 | { 64 | if (v2FolderList != null) 65 | { 66 | for (int i = 0; i < v2FolderList.Count; i++) 67 | { 68 | if (v2FolderList[new System.Runtime.InteropServices.VariantWrapper(i)].Path == path) 69 | return i; 70 | } 71 | return -1; 72 | } 73 | else 74 | return (v1FolderList.Length > 0 && (path == string.Empty || path == "\\")) ? 0 : -1; 75 | } 76 | */ 77 | 78 | /// 79 | /// Gets the specified folder from the collection. 80 | /// 81 | /// The index of the folder to be retrieved. 82 | /// A TaskFolder instance that represents the requested folder. 83 | public TaskFolder this[int index] 84 | { 85 | get 86 | { 87 | if (v2FolderList != null) 88 | return new TaskFolder(parent.TaskService, v2FolderList[++index]); 89 | return v1FolderList[index]; 90 | } 91 | } 92 | 93 | /// 94 | /// Gets the specified folder from the collection. 95 | /// 96 | /// The path of the folder to be retrieved. 97 | /// A TaskFolder instance that represents the requested folder. 98 | public TaskFolder this[string path] 99 | { 100 | get 101 | { 102 | if (v2FolderList != null) 103 | return new TaskFolder(parent.TaskService, v2FolderList[path]); 104 | if (v1FolderList != null && v1FolderList.Length > 0 && (path == string.Empty || path == "\\")) 105 | return v1FolderList[0]; 106 | throw new ArgumentException("Path not found"); 107 | } 108 | } 109 | 110 | /// 111 | /// Determines whether the specified folder exists. 112 | /// 113 | /// The path of the folder. 114 | /// true if folder exists; otherwise, false. 115 | public bool Exists(string path) 116 | { 117 | try 118 | { 119 | if (parent.GetFolder(path) != null) 120 | return true; 121 | } 122 | catch { } 123 | return false; 124 | } 125 | 126 | /// 127 | /// Copies the elements of the ICollection to an Array, starting at a particular Array index. 128 | /// 129 | /// The one-dimensional Array that is the destination of the elements copied from . The Array must have zero-based indexing. 130 | /// The zero-based index in array at which copying begins. 131 | internal void CopyTo(TaskFolder[] array, int arrayIndex) 132 | { 133 | if (arrayIndex < 0) throw new ArgumentOutOfRangeException(); 134 | if (array == null) throw new ArgumentNullException(); 135 | if (v2FolderList != null) 136 | { 137 | if (arrayIndex + this.Count > array.Length) 138 | throw new ArgumentException(); 139 | foreach (TaskScheduler.V2Interop.ITaskFolder f in v2FolderList) 140 | array[arrayIndex++] = new TaskFolder(parent.TaskService, f); 141 | } 142 | else 143 | { 144 | if (arrayIndex + v1FolderList.Length > array.Length) 145 | throw new ArgumentException(); 146 | v1FolderList.CopyTo(array, arrayIndex); 147 | } 148 | } 149 | 150 | /// 151 | /// Gets the number of items in the collection. 152 | /// 153 | public int Count 154 | { 155 | get { return (v2FolderList != null) ? v2FolderList.Count : v1FolderList.Length; } 156 | } 157 | 158 | /// 159 | /// Gets a list of items in a collection. 160 | /// 161 | /// Enumerated list of items in the collection. 162 | public IEnumerator GetEnumerator() 163 | { 164 | TaskFolder[] eArray = new TaskFolder[this.Count]; 165 | this.CopyTo(eArray, 0); 166 | return new TaskFolderEnumerator(eArray); 167 | } 168 | 169 | System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 170 | { 171 | return this.GetEnumerator(); 172 | } 173 | 174 | private class TaskFolderEnumerator : IEnumerator 175 | { 176 | private TaskFolder[] folders = null; 177 | private System.Collections.IEnumerator iEnum = null; 178 | 179 | internal TaskFolderEnumerator(TaskFolder[] f) 180 | { 181 | folders = f; 182 | iEnum = f.GetEnumerator(); 183 | } 184 | 185 | /// 186 | /// Releases all resources used by this class. 187 | /// 188 | public void Dispose() 189 | { 190 | } 191 | 192 | public TaskFolder Current 193 | { 194 | get { return iEnum.Current as TaskFolder; } 195 | } 196 | 197 | object System.Collections.IEnumerator.Current 198 | { 199 | get { return this.Current; } 200 | } 201 | 202 | public bool MoveNext() 203 | { 204 | return iEnum.MoveNext(); 205 | } 206 | 207 | public void Reset() 208 | { 209 | iEnum.Reset(); 210 | } 211 | } 212 | } 213 | } 214 | -------------------------------------------------------------------------------- /MygodWifiShare/MygodWifiShare.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | x86 6 | 8.0.30703 7 | 2.0 8 | {B0659576-2DC2-463A-8902-2986D886BAAD} 9 | Exe 10 | Mygod.WifiShare 11 | Mygod无线网络共享 12 | v4.6.1 13 | 14 | 15 | 512 16 | true 17 | http://localhost/Software/SystemTool/MygodWifiShareForWin7/ 18 | true 19 | Web 20 | false 21 | Foreground 22 | 7 23 | Days 24 | false 25 | false 26 | true 27 | true 28 | publish.htm 29 | 0 30 | 1.0.0.%2a 31 | false 32 | true 33 | true 34 | 35 | 36 | x86 37 | true 38 | full 39 | false 40 | bin\Debug\ 41 | DEBUG;TRACE 42 | prompt 43 | 4 44 | false 45 | 46 | 47 | x86 48 | pdbonly 49 | true 50 | bin\Release\ 51 | TRACE 52 | prompt 53 | 4 54 | 55 | 56 | false 57 | 58 | 59 | Main.ico 60 | 61 | 62 | LocalIntranet 63 | 64 | 65 | false 66 | 67 | 68 | app.manifest 69 | 70 | 71 | 3A05ABFD90D9FE35EA3425A946B57F2AB4B00B81 72 | 73 | 74 | false 75 | 76 | 77 | Mygod.WifiShare.Program 78 | 79 | 80 | true 81 | bin\Debug\ 82 | DEBUG;TRACE 83 | full 84 | AnyCPU 85 | prompt 86 | MinimumRecommendedRules.ruleset 87 | false 88 | 89 | 90 | bin\Release\ 91 | TRACE 92 | true 93 | pdbonly 94 | AnyCPU 95 | prompt 96 | MinimumRecommendedRules.ruleset 97 | false 98 | 99 | 100 | true 101 | 102 | 103 | Mygod.pfx 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | [References]\WmiClass.cs 116 | 117 | 118 | [References]\WebsiteManager.cs 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | Resources.resx 134 | True 135 | True 136 | 137 | 138 | 139 | 140 | 141 | 142 | Component 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | ResXFileCodeGenerator 160 | Resources.Designer.cs 161 | Designer 162 | 163 | 164 | Designer 165 | 166 | 167 | 168 | 169 | 170 | 171 | False 172 | Microsoft .NET Framework 4 Client Profile %28x86 和 x64%29 173 | true 174 | 175 | 176 | False 177 | .NET Framework 3.5 SP1 Client Profile 178 | false 179 | 180 | 181 | False 182 | .NET Framework 3.5 SP1 183 | false 184 | 185 | 186 | False 187 | Windows Installer 3.1 188 | true 189 | 190 | 191 | 192 | 193 | "C:\Program Files (x86)\Windows Kits\8.1\bin\x86\signtool.exe" sign /v /f "$(ProjectDir)Mygod.pfx" "$(TargetDir)$(TargetFileName)" 194 | 195 | 202 | -------------------------------------------------------------------------------- /MygodWifiShare/[References]/[TaskScheduler]/ActionCollection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Xml.Serialization; 5 | using Mygod.WifiShare; 6 | 7 | namespace Microsoft.Win32.TaskScheduler 8 | { 9 | /// 10 | /// Collection that contains the actions that are performed by the task. 11 | /// 12 | /// A Task Scheduler 1.0 task can only contain a single . 13 | [XmlRoot("Actions", Namespace = TaskDefinition.tns, IsNullable = false)] 14 | public sealed class ActionCollection : IEnumerable, IDisposable, IXmlSerializable 15 | { 16 | private V1Interop.ITask v1Task; 17 | private V2Interop.ITaskDefinition v2Def; 18 | private V2Interop.IActionCollection v2Coll; 19 | 20 | internal ActionCollection(V1Interop.ITask task) 21 | { 22 | v1Task = task; 23 | } 24 | 25 | internal ActionCollection(V2Interop.ITaskDefinition iTaskDef) 26 | { 27 | v2Def = iTaskDef; 28 | v2Coll = iTaskDef.Actions; 29 | } 30 | 31 | /// 32 | /// Releases all resources used by this class. 33 | /// 34 | public void Dispose() 35 | { 36 | v1Task = null; 37 | v2Def = null; 38 | v2Coll = null; 39 | } 40 | 41 | /// 42 | /// Adds an action to the task. 43 | /// 44 | /// A derived class. 45 | /// The bound that was added to the collection. 46 | public Action Add(Action action) 47 | { 48 | if (v2Def != null) 49 | action.Bind(v2Def); 50 | else 51 | action.Bind(v1Task); 52 | return action; 53 | } 54 | 55 | /// 56 | /// Adds a new instance to the task. 57 | /// 58 | /// Type of task to be created 59 | /// Specialized instance. 60 | public Action AddNew(TaskActionType actionType) 61 | { 62 | if (v1Task != null) 63 | return new ExecAction(v1Task); 64 | 65 | return Action.CreateAction(v2Coll.Create(actionType)); 66 | } 67 | 68 | /// 69 | /// Clears all actions from the task. 70 | /// 71 | public void Clear() 72 | { 73 | if (v2Coll != null) 74 | v2Coll.Clear(); 75 | else 76 | Add(new ExecAction()); 77 | } 78 | 79 | /// 80 | /// Determines whether the specified action type is contained in this collection. 81 | /// 82 | /// Type of the action. 83 | /// 84 | /// true if the specified action type is contained in this collection; otherwise, false. 85 | /// 86 | public bool ContainsType(Type actionType) 87 | { 88 | foreach (Action a in this) 89 | if (a.GetType() == actionType) 90 | return true; 91 | return false; 92 | } 93 | 94 | /// 95 | /// Inserts an action at the specified index. 96 | /// 97 | /// The zero-based index at which action should be inserted. 98 | /// The action to insert into the list. 99 | public void Insert(int index, Action action) 100 | { 101 | if (v2Coll == null && this.Count > 0) 102 | throw new NotV1SupportedException("Only a single action is allowed."); 103 | 104 | Action[] pushItems = new Action[this.Count - index]; 105 | for (int i = index; i < this.Count; i++) 106 | pushItems[i - index] = (Action)this[i].Clone(); 107 | for (int j = this.Count - 1; j >= index; j--) 108 | RemoveAt(j); 109 | Add(action); 110 | for (int k = 0; k < pushItems.Length; k++) 111 | Add(pushItems[k]); 112 | } 113 | 114 | /// 115 | /// Removes the action at a specified index. 116 | /// 117 | /// Index of action to remove. 118 | /// Index out of range. 119 | public void RemoveAt(int index) 120 | { 121 | if (index >= this.Count) 122 | throw new ArgumentOutOfRangeException("index", index, "Failed to remove action. Index out of range."); 123 | if (v2Coll != null) 124 | v2Coll.Remove(++index); 125 | else if (index == 0) 126 | Add(new ExecAction()); 127 | else 128 | throw new NotV1SupportedException("There can be only a single action and it cannot be removed."); 129 | } 130 | 131 | /// 132 | /// Returns a that represents the actions in this collection. 133 | /// 134 | /// 135 | /// A that represents the actions in this collection. 136 | /// 137 | public override string ToString() 138 | { 139 | if (this.Count == 1) 140 | return this[0].ToString(); 141 | if (this.Count > 1) 142 | return Resources.MultipleActions; 143 | return string.Empty; 144 | } 145 | 146 | /// 147 | /// Gets or sets a an action at the specified index. 148 | /// 149 | /// The zero-based index of the action to get or set. 150 | public Action this[int index] 151 | { 152 | get 153 | { 154 | if (v2Coll != null) 155 | return Action.CreateAction(v2Coll[++index]); 156 | if (index == 0) 157 | return new ExecAction(v1Task.GetApplicationName(), v1Task.GetParameters(), v1Task.GetWorkingDirectory()); 158 | throw new ArgumentOutOfRangeException(); 159 | } 160 | set 161 | { 162 | if (this.Count <= index) 163 | throw new ArgumentOutOfRangeException("index", index, "Index is not a valid index in the ActionCollection"); 164 | RemoveAt(index); 165 | Insert(index, value); 166 | } 167 | } 168 | 169 | /// 170 | /// Gets or sets the identifier of the principal for the task. 171 | /// 172 | /// Not supported under Task Scheduler 1.0. 173 | [System.Xml.Serialization.XmlAttribute(AttributeName = "Context", DataType = "IDREF")] 174 | public string Context 175 | { 176 | get 177 | { 178 | if (v2Coll != null) 179 | return v2Coll.Context; 180 | return string.Empty; 181 | } 182 | set 183 | { 184 | if (v2Coll != null) 185 | v2Coll.Context = value; 186 | else 187 | throw new NotV1SupportedException(); 188 | } 189 | } 190 | 191 | /// 192 | /// Gets the number of actions in the collection. 193 | /// 194 | public int Count 195 | { 196 | get 197 | { 198 | if (v2Coll != null) 199 | return v2Coll.Count; 200 | return ((string)v1Task.GetApplicationName()).Length == 0 ? 0 : 1; 201 | } 202 | } 203 | 204 | /// 205 | /// Gets or sets an XML-formatted version of the collection. 206 | /// 207 | public string XmlText 208 | { 209 | get 210 | { 211 | if (v2Coll != null) 212 | return v2Coll.XmlText; 213 | return XmlSerializationHelper.WriteObjectToXmlText(this); 214 | } 215 | set 216 | { 217 | if (v2Coll != null) 218 | v2Coll.XmlText = value; 219 | else 220 | XmlSerializationHelper.ReadObjectFromXmlText(value, this); 221 | } 222 | } 223 | 224 | /// 225 | /// Retrieves an enumeration of each of the actions. 226 | /// 227 | /// Returns an object that implements the interface and that can iterate through the objects within the . 228 | public IEnumerator GetEnumerator() 229 | { 230 | if (v2Coll != null) 231 | return new Enumerator(this); 232 | return new Enumerator(this.v1Task); 233 | } 234 | 235 | System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 236 | { 237 | return this.GetEnumerator(); 238 | } 239 | 240 | internal class Enumerator : IEnumerator 241 | { 242 | private V1Interop.ITask v1Task; 243 | private int v1Pos = -1; 244 | private IEnumerator v2Enum; 245 | private ActionCollection parent; 246 | 247 | internal Enumerator(V1Interop.ITask task) 248 | { 249 | v1Task = task; 250 | } 251 | 252 | internal Enumerator(ActionCollection iColl) 253 | { 254 | parent = iColl; 255 | if (iColl.v2Coll != null) 256 | v2Enum = iColl.v2Coll.GetEnumerator(); 257 | } 258 | 259 | public Action Current 260 | { 261 | get 262 | { 263 | if (v2Enum != null) 264 | { 265 | V2Interop.IAction iAction = v2Enum.Current as V2Interop.IAction; 266 | if (iAction != null) 267 | return Action.CreateAction(iAction); 268 | } 269 | if (v1Pos == 0) 270 | return new ExecAction(v1Task.GetApplicationName(), v1Task.GetParameters(), v1Task.GetWorkingDirectory()); 271 | throw new InvalidOperationException(); 272 | } 273 | } 274 | 275 | /// 276 | /// Releases all resources used by this class. 277 | /// 278 | public void Dispose() 279 | { 280 | v1Task = null; 281 | v2Enum = null; 282 | } 283 | 284 | object System.Collections.IEnumerator.Current 285 | { 286 | get { return this.Current; } 287 | } 288 | 289 | public bool MoveNext() 290 | { 291 | if (v2Enum != null) 292 | return v2Enum.MoveNext(); 293 | return ++v1Pos == 0; 294 | } 295 | 296 | public void Reset() 297 | { 298 | if (v2Enum != null) 299 | v2Enum.Reset(); 300 | v1Pos = -1; 301 | } 302 | } 303 | 304 | System.Xml.Schema.XmlSchema IXmlSerializable.GetSchema() 305 | { 306 | throw new NotImplementedException(); 307 | } 308 | 309 | void IXmlSerializable.ReadXml(System.Xml.XmlReader reader) 310 | { 311 | reader.ReadStartElement("Actions", TaskDefinition.tns); 312 | while (reader.MoveToContent() == System.Xml.XmlNodeType.Element) 313 | { 314 | Action newAction = null; 315 | switch (reader.LocalName) 316 | { 317 | case "Exec": 318 | newAction = this.AddNew(TaskActionType.Execute); 319 | break; 320 | default: 321 | reader.Skip(); 322 | break; 323 | } 324 | if (newAction != null) 325 | XmlSerializationHelper.ReadObject(reader, newAction); 326 | } 327 | reader.ReadEndElement(); 328 | } 329 | 330 | void IXmlSerializable.WriteXml(System.Xml.XmlWriter writer) 331 | { 332 | if (this.Count > 0) 333 | { 334 | XmlSerializationHelper.WriteObject(writer, this[0] as ExecAction); 335 | } 336 | } 337 | } 338 | } 339 | -------------------------------------------------------------------------------- /MygodWifiShare/[References]/[TaskScheduler]/TriggerCollection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.InteropServices; 4 | using System.Xml.Serialization; 5 | using Mygod.WifiShare; 6 | 7 | namespace Microsoft.Win32.TaskScheduler 8 | { 9 | /// 10 | /// Provides the methods that are used to add to, remove from, and get the triggers of a task. 11 | /// 12 | [XmlRoot("Triggers", Namespace = TaskDefinition.tns, IsNullable = false)] 13 | public sealed class TriggerCollection : IEnumerable, IDisposable, IXmlSerializable 14 | { 15 | private V1Interop.ITask v1Task = null; 16 | private V2Interop.ITaskDefinition v2Def = null; 17 | private V2Interop.ITriggerCollection v2Coll = null; 18 | 19 | internal TriggerCollection(V1Interop.ITask iTask) 20 | { 21 | v1Task = iTask; 22 | } 23 | 24 | internal TriggerCollection(V2Interop.ITaskDefinition iTaskDef) 25 | { 26 | v2Def = iTaskDef; 27 | v2Coll = v2Def.Triggers; 28 | } 29 | 30 | /// 31 | /// Releases all resources used by this class. 32 | /// 33 | public void Dispose() 34 | { 35 | if (v2Coll != null) Marshal.ReleaseComObject(v2Coll); 36 | v2Def = null; 37 | v1Task = null; 38 | } 39 | 40 | /// 41 | /// Gets the collection enumerator for this collection. 42 | /// 43 | /// The for this collection. 44 | public IEnumerator GetEnumerator() 45 | { 46 | if (v1Task != null) 47 | return new V1TriggerEnumerator(v1Task); 48 | return new V2TriggerEnumerator(v2Coll, v2Def); 49 | } 50 | 51 | System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 52 | { 53 | return this.GetEnumerator(); 54 | } 55 | 56 | internal sealed class V1TriggerEnumerator : IEnumerator 57 | { 58 | private V1Interop.ITask iTask; 59 | private short curItem = -1; 60 | 61 | internal V1TriggerEnumerator(V1Interop.ITask task) 62 | { 63 | iTask = task; 64 | } 65 | 66 | public Trigger Current 67 | { 68 | get 69 | { 70 | return Trigger.CreateTrigger(iTask.GetTrigger((ushort)curItem)); 71 | } 72 | } 73 | 74 | /// 75 | /// Releases all resources used by this class. 76 | /// 77 | public void Dispose() 78 | { 79 | iTask = null; 80 | } 81 | 82 | object System.Collections.IEnumerator.Current 83 | { 84 | get { return this.Current; } 85 | } 86 | 87 | public bool MoveNext() 88 | { 89 | if (++curItem >= iTask.GetTriggerCount()) 90 | return false; 91 | return true; 92 | } 93 | 94 | public void Reset() 95 | { 96 | curItem = -1; 97 | } 98 | } 99 | 100 | internal sealed class V2TriggerEnumerator : IEnumerator 101 | { 102 | private System.Collections.IEnumerator iEnum; 103 | private V2Interop.ITaskDefinition v2Def = null; 104 | 105 | internal V2TriggerEnumerator(V2Interop.ITriggerCollection iColl, V2Interop.ITaskDefinition iDef) 106 | { 107 | iEnum = iColl.GetEnumerator(); 108 | v2Def = iDef; 109 | } 110 | 111 | #region IEnumerator Members 112 | 113 | public Trigger Current 114 | { 115 | get 116 | { 117 | return Trigger.CreateTrigger((V2Interop.ITrigger)iEnum.Current, v2Def); 118 | } 119 | } 120 | 121 | #endregion 122 | 123 | #region IDisposable Members 124 | 125 | /// 126 | /// Releases all resources used by this class. 127 | /// 128 | public void Dispose() 129 | { 130 | iEnum = null; 131 | } 132 | 133 | #endregion 134 | 135 | #region IEnumerator Members 136 | 137 | object System.Collections.IEnumerator.Current 138 | { 139 | get { return this.Current; } 140 | } 141 | 142 | public bool MoveNext() 143 | { 144 | return iEnum.MoveNext(); 145 | } 146 | 147 | public void Reset() 148 | { 149 | iEnum.Reset(); 150 | } 151 | 152 | #endregion 153 | } 154 | 155 | /// 156 | /// Gets the number of triggers in the collection. 157 | /// 158 | public int Count 159 | { 160 | get 161 | { 162 | if (v2Coll != null) 163 | return v2Coll.Count; 164 | return (int)v1Task.GetTriggerCount(); 165 | } 166 | } 167 | 168 | /// 169 | /// Add an unbound to the task. 170 | /// 171 | /// derivative to add to the task. 172 | /// Bound trigger. 173 | /// unboundTrigger is null. 174 | public Trigger Add(Trigger unboundTrigger) 175 | { 176 | if (unboundTrigger == null) 177 | throw new ArgumentNullException("unboundTrigger"); 178 | if (v2Def != null) 179 | unboundTrigger.Bind(v2Def); 180 | else 181 | unboundTrigger.Bind(v1Task); 182 | return unboundTrigger; 183 | } 184 | 185 | /// 186 | /// Add a new trigger to the collections of triggers for the task. 187 | /// 188 | /// The type of trigger to create. 189 | /// A instance of the specified type. 190 | public Trigger AddNew(TaskTriggerType taskTriggerType) 191 | { 192 | if (v1Task != null) 193 | { 194 | ushort idx; 195 | return Trigger.CreateTrigger(v1Task.CreateTrigger(out idx), Trigger.ConvertToV1TriggerType(taskTriggerType)); 196 | } 197 | 198 | return Trigger.CreateTrigger(v2Coll.Create(taskTriggerType)); 199 | } 200 | 201 | /// 202 | /// Adds a collection of unbound triggers to the end of the . 203 | /// 204 | /// The triggers to be added to the end of the . The collection itself cannot be null and cannot contain null elements. 205 | /// triggers is null. 206 | public void AddRange(IEnumerable triggers) 207 | { 208 | if (triggers == null) 209 | throw new ArgumentNullException("triggers"); 210 | foreach (var item in triggers) 211 | this.Add(item); 212 | } 213 | 214 | internal void Bind() 215 | { 216 | foreach (Trigger t in this) 217 | t.SetV1TriggerData(); 218 | } 219 | 220 | /// 221 | /// Clears all triggers from the task. 222 | /// 223 | public void Clear() 224 | { 225 | if (v2Coll != null) 226 | v2Coll.Clear(); 227 | else 228 | { 229 | for (int i = this.Count - 1; i >= 0; i--) 230 | RemoveAt(i); 231 | } 232 | } 233 | 234 | /// 235 | /// Determines whether the specified trigger type is contained in this collection. 236 | /// 237 | /// Type of the trigger. 238 | /// 239 | /// true if the specified trigger type is contained in this collection; otherwise, false. 240 | /// 241 | public bool ContainsType(Type triggerType) 242 | { 243 | foreach (Trigger t in this) 244 | if (t.GetType() == triggerType) 245 | return true; 246 | return false; 247 | } 248 | 249 | /// 250 | /// Gets a specified trigger from the collection. 251 | /// 252 | /// The index of the trigger to be retrieved. 253 | /// Specialized instance. 254 | public Trigger this[int index] 255 | { 256 | get 257 | { 258 | if (v2Coll != null) 259 | return Trigger.CreateTrigger(v2Coll[++index]); 260 | return Trigger.CreateTrigger(v1Task.GetTrigger((ushort)index)); 261 | } 262 | set 263 | { 264 | if (this.Count <= index) 265 | throw new ArgumentOutOfRangeException("index", index, "Index is not a valid index in the TriggerCollection"); 266 | RemoveAt(index); 267 | Insert(index, value); 268 | } 269 | } 270 | 271 | /// 272 | /// Inserts an trigger at the specified index. 273 | /// 274 | /// The zero-based index at which trigger should be inserted. 275 | /// The trigger to insert into the list. 276 | public void Insert(int index, Trigger trigger) 277 | { 278 | Trigger[] pushItems = new Trigger[this.Count - index]; 279 | for (int i = index; i < this.Count; i++) 280 | pushItems[i - index] = (Trigger)this[i].Clone(); 281 | for (int j = this.Count - 1; j >= index; j--) 282 | RemoveAt(j); 283 | Add(trigger); 284 | for (int k = 0; k < pushItems.Length; k++) 285 | Add(pushItems[k]); 286 | } 287 | 288 | /// 289 | /// Removes the trigger at a specified index. 290 | /// 291 | /// Index of trigger to remove. 292 | /// Index out of range. 293 | public void RemoveAt(int index) 294 | { 295 | if (index >= this.Count) 296 | throw new ArgumentOutOfRangeException("index", index, "Failed to remove Trigger. Index out of range."); 297 | if (v2Coll != null) 298 | v2Coll.Remove(++index); 299 | else 300 | v1Task.DeleteTrigger((ushort)index); //Remove the trigger from the Task Scheduler 301 | } 302 | 303 | /// 304 | /// Returns a that represents the triggers in this collection. 305 | /// 306 | /// 307 | /// A that represents the triggers in this collection. 308 | /// 309 | public override string ToString() 310 | { 311 | if (this.Count == 1) 312 | return this[0].ToString(); 313 | if (this.Count > 1) 314 | return Resources.MultipleTriggers; 315 | return string.Empty; 316 | } 317 | 318 | System.Xml.Schema.XmlSchema IXmlSerializable.GetSchema() 319 | { 320 | throw new NotImplementedException(); 321 | } 322 | 323 | void IXmlSerializable.ReadXml(System.Xml.XmlReader reader) 324 | { 325 | reader.ReadStartElement("Triggers", TaskDefinition.tns); 326 | while (reader.MoveToContent() == System.Xml.XmlNodeType.Element) 327 | { 328 | switch (reader.LocalName) 329 | { 330 | case "BootTrigger": 331 | XmlSerializationHelper.ReadObject(reader, this.AddNew(TaskTriggerType.Boot)); 332 | break; 333 | case "IdleTrigger": 334 | XmlSerializationHelper.ReadObject(reader, this.AddNew(TaskTriggerType.Idle)); 335 | break; 336 | case "TimeTrigger": 337 | XmlSerializationHelper.ReadObject(reader, this.AddNew(TaskTriggerType.Time)); 338 | break; 339 | case "LogonTrigger": 340 | XmlSerializationHelper.ReadObject(reader, this.AddNew(TaskTriggerType.Logon)); 341 | break; 342 | case "CalendarTrigger": 343 | this.Add(CalendarTrigger.GetTriggerFromXml(reader)); 344 | break; 345 | default: 346 | reader.Skip(); 347 | break; 348 | } 349 | } 350 | reader.ReadEndElement(); 351 | } 352 | 353 | void IXmlSerializable.WriteXml(System.Xml.XmlWriter writer) 354 | { 355 | foreach (var t in this) 356 | XmlSerializationHelper.WriteObject(writer, t); 357 | } 358 | } 359 | } 360 | -------------------------------------------------------------------------------- /MygodWifiShare/[References]/[TaskScheduler]/XmlSerializationHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Reflection; 5 | using System.Text; 6 | using System.Xml; 7 | using System.Xml.Serialization; 8 | 9 | namespace Microsoft.Win32.TaskScheduler 10 | { 11 | internal static class XmlSerializationHelper 12 | { 13 | public static object GetDefaultValue(PropertyInfo prop) 14 | { 15 | var attributes = prop.GetCustomAttributes(typeof(DefaultValueAttribute), true); 16 | if (attributes.Length > 0) 17 | { 18 | var defaultAttr = (DefaultValueAttribute)attributes[0]; 19 | return defaultAttr.Value; 20 | } 21 | 22 | // Attribute not found, fall back to default value for the type 23 | if (prop.PropertyType.IsValueType) 24 | return Activator.CreateInstance(prop.PropertyType); 25 | return null; 26 | } 27 | 28 | private static bool GetPropertyValue(object obj, string property, ref object outVal) 29 | { 30 | if (obj != null) 31 | { 32 | PropertyInfo pi = obj.GetType().GetProperty(property); 33 | if (pi != null) 34 | { 35 | outVal = pi.GetValue(obj, null); 36 | return true; 37 | } 38 | } 39 | return false; 40 | } 41 | 42 | private static bool GetAttributeValue(Type objType, Type attrType, string property, bool inherit, ref object outVal) 43 | { 44 | object[] attrs = objType.GetCustomAttributes(attrType, inherit); 45 | if (attrs.Length > 0) 46 | return GetPropertyValue(attrs[0], property, ref outVal); 47 | return false; 48 | } 49 | 50 | private static bool GetAttributeValue(PropertyInfo propInfo, Type attrType, string property, bool inherit, ref object outVal) 51 | { 52 | Attribute attr = Attribute.GetCustomAttribute(propInfo, attrType, inherit); 53 | return GetPropertyValue(attr, property, ref outVal); 54 | } 55 | 56 | private static bool IsStandardType(Type type) 57 | { 58 | return type.IsPrimitive || type == typeof(DateTime) || type == typeof(DateTimeOffset) || type == typeof(Decimal) || type == typeof(Guid) || type == typeof(TimeSpan) || type == typeof(string) || type.IsEnum; 59 | } 60 | 61 | private static bool HasMembers(object obj) 62 | { 63 | if (obj is IXmlSerializable) 64 | { 65 | using (System.IO.MemoryStream mem = new System.IO.MemoryStream()) 66 | { 67 | using (XmlTextWriter tw = new XmlTextWriter(mem, Encoding.UTF8)) 68 | { 69 | ((IXmlSerializable)obj).WriteXml(tw); 70 | tw.Flush(); 71 | return mem.Length > 0; 72 | } 73 | } 74 | } 75 | else 76 | { 77 | // Enumerate each public property 78 | PropertyInfo[] props = obj.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public); 79 | foreach (var pi in props) 80 | { 81 | if (!Attribute.IsDefined(pi, typeof(XmlIgnoreAttribute), false)) 82 | { 83 | object value = pi.GetValue(obj, null); 84 | if (!value.Equals(GetDefaultValue(pi))) 85 | { 86 | if (!IsStandardType(pi.PropertyType)) 87 | { 88 | if (HasMembers(value)) 89 | return true; 90 | } 91 | else 92 | return true; 93 | } 94 | } 95 | } 96 | } 97 | return false; 98 | } 99 | 100 | public static string GetPropertyElementName(PropertyInfo pi) 101 | { 102 | object oVal = null; 103 | string eName = pi.Name; 104 | if (GetAttributeValue(pi, typeof(XmlElementAttribute), "ElementName", false, ref oVal)) 105 | eName = oVal.ToString(); 106 | else if (GetAttributeValue(pi.PropertyType, typeof(XmlRootAttribute), "ElementName", true, ref oVal)) 107 | eName = oVal.ToString(); 108 | return eName; 109 | } 110 | 111 | public delegate bool PropertyConversionHandler(PropertyInfo pi, Object obj, ref Object value); 112 | 113 | public static bool WriteProperty(XmlWriter writer, PropertyInfo pi, Object obj, PropertyConversionHandler handler = null) 114 | { 115 | if (Attribute.IsDefined(pi, typeof(XmlIgnoreAttribute), false)) 116 | return false; 117 | 118 | object value = pi.GetValue(obj, null); 119 | object defValue = GetDefaultValue(pi); 120 | if ((value == null && defValue == null) || (value != null && value.Equals(defValue))) 121 | return false; 122 | 123 | Type propType = pi.PropertyType; 124 | if (handler != null && handler(pi, obj, ref value)) 125 | propType = value.GetType(); 126 | 127 | bool isStdType = IsStandardType(propType); 128 | bool rw = pi.CanRead && pi.CanWrite; 129 | bool ro = pi.CanRead && !pi.CanWrite; 130 | string eName = GetPropertyElementName(pi); 131 | if (isStdType && rw) 132 | { 133 | string output = null; 134 | if (propType.IsEnum) 135 | { 136 | if (Attribute.IsDefined(propType, typeof(FlagsAttribute), false)) 137 | output = Convert.ChangeType(value, Enum.GetUnderlyingType(propType)).ToString(); 138 | else 139 | output = value.ToString(); 140 | } 141 | else 142 | { 143 | switch (propType.FullName) 144 | { 145 | case "System.Boolean": 146 | output = XmlConvert.ToString((System.Boolean)value); 147 | break; 148 | case "System.Byte": 149 | output = XmlConvert.ToString((System.Byte)value); 150 | break; 151 | case "System.Char": 152 | output = XmlConvert.ToString((System.Char)value); 153 | break; 154 | case "System.DateTime": 155 | output = XmlConvert.ToString((System.DateTime)value, XmlDateTimeSerializationMode.RoundtripKind); 156 | break; 157 | case "System.DateTimeOffset": 158 | output = XmlConvert.ToString((System.DateTimeOffset)value); 159 | break; 160 | case "System.Decimal": 161 | output = XmlConvert.ToString((System.Decimal)value); 162 | break; 163 | case "System.Double": 164 | output = XmlConvert.ToString((System.Double)value); 165 | break; 166 | case "System.Single": 167 | output = XmlConvert.ToString((System.Single)value); 168 | break; 169 | case "System.Guid": 170 | output = XmlConvert.ToString((System.Guid)value); 171 | break; 172 | case "System.Int16": 173 | output = XmlConvert.ToString((System.Int16)value); 174 | break; 175 | case "System.Int32": 176 | output = XmlConvert.ToString((System.Int32)value); 177 | break; 178 | case "System.Int64": 179 | output = XmlConvert.ToString((System.Int64)value); 180 | break; 181 | case "System.SByte": 182 | output = XmlConvert.ToString((System.SByte)value); 183 | break; 184 | case "System.TimeSpan": 185 | output = XmlConvert.ToString((System.TimeSpan)value); 186 | break; 187 | case "System.UInt16": 188 | output = XmlConvert.ToString((System.UInt16)value); 189 | break; 190 | case "System.UInt32": 191 | output = XmlConvert.ToString((System.UInt32)value); 192 | break; 193 | case "System.UInt64": 194 | output = XmlConvert.ToString((System.UInt64)value); 195 | break; 196 | default: 197 | output = value == null ? string.Empty : value.ToString(); 198 | break; 199 | } 200 | if (output != null) 201 | writer.WriteElementString(eName, output); 202 | } 203 | } 204 | else if (!isStdType) 205 | { 206 | WriteObject(writer, value); 207 | } 208 | return false; 209 | } 210 | 211 | public static void WriteObjectProperties(XmlWriter writer, object obj, PropertyConversionHandler handler = null) 212 | { 213 | // Enumerate each public property 214 | foreach (var pi in obj.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public)) 215 | WriteProperty(writer, pi, obj, handler); 216 | } 217 | 218 | public static void WriteObject(XmlWriter writer, object obj, PropertyConversionHandler handler = null) 219 | { 220 | if (obj == null) 221 | return; 222 | 223 | // Get name of top level element 224 | object oVal = null; 225 | string oName = GetAttributeValue(obj.GetType(), typeof(XmlRootAttribute), "ElementName", true, ref oVal) ? oVal.ToString() : obj.GetType().Name; 226 | 227 | // Get namespace of top level element 228 | string ns = GetAttributeValue(obj.GetType(), typeof(XmlRootAttribute), "Namespace", true, ref oVal) ? oVal.ToString() : null; 229 | 230 | if (!HasMembers(obj)) 231 | return; 232 | 233 | writer.WriteStartElement(oName, ns); 234 | 235 | if (obj is IXmlSerializable) 236 | { 237 | ((IXmlSerializable)obj).WriteXml(writer); 238 | } 239 | else 240 | { 241 | WriteObjectProperties(writer, obj, handler); 242 | } 243 | 244 | writer.WriteEndElement(); 245 | } 246 | 247 | public static void ReadObjectProperties(XmlReader reader, object obj, PropertyConversionHandler handler = null) 248 | { 249 | // Build property lookup table 250 | PropertyInfo[] props = obj.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public); 251 | Dictionary propHash = new Dictionary(props.Length); 252 | foreach (var pi in props) 253 | if (!Attribute.IsDefined(pi, typeof(XmlIgnoreAttribute), false)) 254 | propHash.Add(GetPropertyElementName(pi), pi); 255 | 256 | while (reader.MoveToContent() == System.Xml.XmlNodeType.Element) 257 | { 258 | PropertyInfo pi; 259 | if (propHash.TryGetValue(reader.LocalName, out pi)) 260 | { 261 | if (IsStandardType(pi.PropertyType)) 262 | { 263 | object value = null; 264 | if (pi.PropertyType.IsEnum) 265 | value = Enum.Parse(pi.PropertyType, reader.ReadElementContentAsString()); 266 | else 267 | value = reader.ReadElementContentAs(pi.PropertyType, null); 268 | 269 | if (handler != null) 270 | handler(pi, obj, ref value); 271 | 272 | pi.SetValue(obj, value, null); 273 | } 274 | else 275 | { 276 | ReadObject(reader, pi.GetValue(obj, null)); 277 | } 278 | } 279 | else 280 | { 281 | reader.Skip(); 282 | reader.MoveToContent(); 283 | } 284 | } 285 | } 286 | 287 | public static void ReadObject(XmlReader reader, object obj, PropertyConversionHandler handler = null) 288 | { 289 | if (obj == null) 290 | throw new ArgumentNullException("obj"); 291 | 292 | reader.MoveToContent(); 293 | 294 | if (obj is IXmlSerializable) 295 | { 296 | ((IXmlSerializable)obj).ReadXml(reader); 297 | } 298 | else 299 | { 300 | object oVal = null; 301 | string oName = GetAttributeValue(obj.GetType(), typeof(XmlRootAttribute), "ElementName", true, ref oVal) ? oVal.ToString() : obj.GetType().Name; 302 | if (reader.LocalName != oName) 303 | throw new XmlException("XML element name does not match object."); 304 | 305 | if (!reader.IsEmptyElement) 306 | { 307 | reader.ReadStartElement(); 308 | reader.MoveToContent(); 309 | ReadObjectProperties(reader, obj, handler); 310 | reader.ReadEndElement(); 311 | } 312 | else 313 | reader.Skip(); 314 | } 315 | } 316 | 317 | public static void ReadObjectFromXmlText(string xml, object obj, PropertyConversionHandler handler = null) 318 | { 319 | using (System.IO.StringReader sr = new System.IO.StringReader(xml)) 320 | { 321 | using (XmlReader reader = XmlReader.Create(sr)) 322 | { 323 | reader.MoveToContent(); 324 | ReadObject(reader, obj, handler); 325 | } 326 | } 327 | } 328 | 329 | public static string WriteObjectToXmlText(object obj, PropertyConversionHandler handler = null) 330 | { 331 | StringBuilder sb = new StringBuilder(); 332 | using (XmlWriter writer = XmlWriter.Create(sb, new XmlWriterSettings() { Indent = true })) 333 | WriteObject(writer, obj, handler); 334 | return sb.ToString(); 335 | } 336 | } 337 | } 338 | -------------------------------------------------------------------------------- /MygodWifiShare/WlanNativeMethods.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | 4 | namespace Mygod.WifiShare 5 | { 6 | public static class WlanNativeMethods 7 | { 8 | public delegate void WlanNotificationCallback(ref WlanNotificationData notificationData, IntPtr context); 9 | 10 | /// 11 | /// 12 | /// 13 | /// Must pass in IntPtr.Zero 14 | /// 15 | [DllImport("Wlanapi.dll", EntryPoint = "WlanCloseHandle")] 16 | public static extern int WlanCloseHandle([In] IntPtr hClientHandle, IntPtr pReserved); 17 | 18 | [DllImport("Wlanapi.dll", EntryPoint = "WlanHostedNetworkForceStart")] 19 | public static extern int WlanHostedNetworkForceStart(IntPtr hClientHandle, 20 | [Out] out WlanHostedNetworkReason pFailReason, IntPtr pReserved); 21 | 22 | [DllImport("Wlanapi.dll", EntryPoint = "WlanHostedNetworkForceStop")] 23 | public static extern int WlanHostedNetworkForceStop(IntPtr hClientHandle, 24 | [Out] out WlanHostedNetworkReason pFailReason, IntPtr pReserved); 25 | 26 | [DllImport("Wlanapi.dll", EntryPoint = "WlanHostedNetworkInitSettings")] 27 | public static extern int WlanHostedNetworkInitSettings(IntPtr hClientHandle, 28 | [Out] out WlanHostedNetworkReason pFailReason, IntPtr pReserved); 29 | 30 | [DllImport("Wlanapi.dll", EntryPoint = "WlanHostedNetworkQueryProperty")] 31 | public static extern int WlanHostedNetworkQueryProperty(IntPtr hClientHandle, WlanHostedNetworkOpcode opCode, 32 | [Out] out uint pDataSize, [Out] out IntPtr ppvData, [Out] out WlanOpcodeValueType pWlanOpcodeValueType, 33 | IntPtr pReserved); 34 | 35 | [DllImport("Wlanapi.dll", EntryPoint = "WlanHostedNetworkQuerySecondaryKey")] 36 | public static extern int WlanHostedNetworkQuerySecondaryKey(IntPtr hClientHandle, [Out] out uint pKeyLength, 37 | [Out, MarshalAs(UnmanagedType.LPStr)] out string ppucKeyData, [Out] out bool pbIsPassPhrase, 38 | [Out] out bool pbPersistent, [Out] out WlanHostedNetworkReason pFailReason, IntPtr pReserved); 39 | 40 | [DllImport("Wlanapi.dll", EntryPoint = "WlanHostedNetworkQueryStatus")] 41 | public static extern int WlanHostedNetworkQueryStatus(IntPtr hClientHandle, 42 | [Out] out IntPtr ppWlanHostedNetworkStatus, IntPtr pReserved); 43 | 44 | [DllImport("Wlanapi.dll", EntryPoint = "WlanHostedNetworkRefreshSecuritySettings")] 45 | public static extern int WlanHostedNetworkRefreshSecuritySettings(IntPtr hClientHandle, 46 | [Out] out WlanHostedNetworkReason pFailReason, IntPtr pReserved); 47 | 48 | [DllImport("Wlanapi.dll", EntryPoint = "WlanHostedNetworkSetProperty")] 49 | public static extern int WlanHostedNetworkSetProperty(IntPtr hClientHandle, WlanHostedNetworkOpcode opCode, 50 | uint dwDataSize, IntPtr pvData, [Out] out WlanHostedNetworkReason pFailReason, IntPtr pReserved); 51 | 52 | [DllImport("Wlanapi.dll", EntryPoint = "WlanHostedNetworkSetSecondaryKey")] 53 | public static extern int WlanHostedNetworkSetSecondaryKey(IntPtr hClientHandle, uint dwKeyLength, 54 | byte[] pucKeyData, bool bIsPassPhrase, bool bPersistent, [Out] out WlanHostedNetworkReason pFailReason, 55 | IntPtr pReserved); 56 | 57 | [DllImport("Wlanapi.dll", EntryPoint = "WlanOpenHandle")] 58 | public static extern int WlanOpenHandle(uint dwClientVersion, IntPtr pReserved, 59 | [Out] out uint pdwNegotiatedVersion, [Out] out IntPtr clientHandle); 60 | 61 | [DllImport("Wlanapi.dll", EntryPoint = "WlanRegisterNotification")] 62 | public static extern int WlanRegisterNotification(IntPtr hClientHandle, WlanNotificationSource dwNotifSource, 63 | bool bIgnoreDuplicate, 64 | WlanNotificationCallback funcCallback, IntPtr pCallbackContext, IntPtr pReserved, 65 | [Out] out WlanNotificationSource pdwPrevNotifSource); 66 | } 67 | 68 | public enum Dot11AuthAlgorithm 69 | { 70 | /// DOT11_AUTH_ALGO_80211_OPEN -> 1 71 | Open = 1, 72 | 73 | /// DOT11_AUTH_ALGO_80211_SHARED_KEY -> 2 74 | SharedKey = 2, 75 | 76 | /// DOT11_AUTH_ALGO_WPA -> 3 77 | Wpa = 3, 78 | 79 | /// DOT11_AUTH_ALGO_WPA_PSK -> 4 80 | WpaPsk = 4, 81 | 82 | /// DOT11_AUTH_ALGO_WPA_NONE -> 5 83 | WpaNone = 5, 84 | 85 | /// DOT11_AUTH_ALGO_RSNA -> 6 86 | Rsna = 6, 87 | 88 | /// DOT11_AUTH_ALGO_RSNA_PSK -> 7 89 | RsnaPsk = 7, 90 | } 91 | 92 | public enum Dot11CipherAlgorithm 93 | { 94 | /// DOT11_CIPHER_ALGO_NONE -> 0x00 95 | None = 0, 96 | 97 | /// DOT11_CIPHER_ALGO_WEP40 -> 0x01 98 | Wep40 = 1, 99 | 100 | /// DOT11_CIPHER_ALGO_TKIP -> 0x02 101 | Tkip = 2, 102 | 103 | /// DOT11_CIPHER_ALGO_CCMP -> 0x04 104 | Ccmp = 4, 105 | 106 | /// DOT11_CIPHER_ALGO_WEP104 -> 0x05 107 | Wep104 = 5, 108 | 109 | /// DOT11_CIPHER_ALGO_WPA_USE_GROUP -> 0x100 110 | WpaUseGroup = 256, 111 | 112 | /// DOT11_CIPHER_ALGO_WEP -> 0x101 113 | Wep = 257, 114 | } 115 | 116 | [StructLayout(LayoutKind.Sequential, Pack = 1)] 117 | public struct Dot11MacAddress 118 | { 119 | private readonly byte one; 120 | private readonly byte two; 121 | private readonly byte three; 122 | private readonly byte four; 123 | private readonly byte five; 124 | private readonly byte six; 125 | 126 | public override string ToString() 127 | { 128 | return $"{one:X2}:{two:X2}:{three:X2}:{four:X2}:{five:X2}:{six:X2}"; 129 | } 130 | } 131 | 132 | public enum Dot11PhyType : uint 133 | { 134 | Fhss = 1, 135 | Dsss = 2, 136 | Irbaseband = 3, 137 | Ofdm = 4, 138 | Hrdsss = 5, 139 | Erp = 6, 140 | Ht = 7, 141 | Vht = 8 142 | } 143 | 144 | //http://msdn.microsoft.com/en-us/library/ms706027%28VS.85%29.aspx 145 | public enum Dot11RadioState 146 | { 147 | Unknown, 148 | On, 149 | Off 150 | } 151 | 152 | [StructLayout(LayoutKind.Sequential)] //, CharSet = CharSet.Ansi)] 153 | public struct Ssid 154 | { 155 | /// ULONG->unsigned int 156 | public int Length; //uint 157 | 158 | /// UCHAR[] 159 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] 160 | public string Content; 161 | 162 | //[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] 163 | //public byte[] ucSSID; 164 | } 165 | 166 | [StructLayout(LayoutKind.Sequential)] //, CharSet = CharSet.Unicode)] 167 | public struct WlanHostedNetworkConnectionSettings 168 | { 169 | public Ssid HostedNetworkSSID; 170 | public UInt32 MaxNumberOfPeers; // DWORD 171 | } 172 | 173 | //http://msdn.microsoft.com/en-us/library/dd439500%28VS.85%29.aspx 174 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 175 | public struct WlanHostedNetworkDataPeerStateChange 176 | { 177 | public WlanHostedNetworkPeerState OldState; 178 | public WlanHostedNetworkPeerState NewState; 179 | public readonly WlanHostedNetworkReason Reason; //NewState; 180 | } 181 | 182 | //http://msdn.microsoft.com/en-us/library/dd439501%28VS.85%29.aspx 183 | public enum WlanHostedNetworkNotificationCode 184 | { 185 | /// 186 | /// The Hosted Network state has changed. 187 | /// 188 | StateChange = 0x00001000, 189 | 190 | /// 191 | /// The Hosted Network peer state has changed. 192 | /// 193 | PeerStateChange, 194 | 195 | /// 196 | /// The Hosted Network radio state has changed. 197 | /// 198 | RadioStateChange 199 | } 200 | 201 | public enum WlanHostedNetworkOpcode 202 | { 203 | ConnectionSettings, 204 | SecuritySettings, 205 | StationProfile, 206 | Enable 207 | } 208 | 209 | //http://msdn.microsoft.com/en-us/library/dd439503%28VS.85%29.aspx 210 | public enum WlanHostedNetworkPeerAuthState 211 | { 212 | Invalid, 213 | Authenticated 214 | } 215 | 216 | [StructLayout(LayoutKind.Sequential)] 217 | public struct WlanHostedNetworkPeerState 218 | { 219 | public Dot11MacAddress PeerMacAddress; 220 | public readonly WlanHostedNetworkPeerAuthState PeerAuthState; 221 | } 222 | 223 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 224 | public struct WlanHostedNetworkRadioState 225 | { 226 | public readonly Dot11RadioState dot11SoftwareRadioState; 227 | public readonly Dot11RadioState dot11HardwareRadioState; 228 | } 229 | 230 | //http://msdn.microsoft.com/en-us/library/dd439506%28VS.85%29.aspx 231 | public enum WlanHostedNetworkReason 232 | { 233 | Success = 0, 234 | Unspecified, 235 | BadParameters, 236 | ServiceShuttingDown, 237 | InsufficientResources, 238 | ElevationRequired, 239 | ReadOnly, 240 | PersistenceFailed, 241 | CryptError, 242 | Impersonation, 243 | StopBeforeStart, 244 | InterfaceAvailable, 245 | InterfaceUnavailable, 246 | MiniportStopped, 247 | MiniportStarted, 248 | IncompatibleConnectionStarted, 249 | IncompatibleConnectionStopped, 250 | UserAction, 251 | ClientAbort, 252 | ApStartFailed, 253 | PeerArrived, 254 | PeerDeparted, 255 | PeerTimeout, 256 | GpDenied, 257 | ServiceUnavailable, 258 | DeviceChange, 259 | PropertiesChange, 260 | VirtualStationBlockingUse, 261 | ServiceAvailableOnVirtualStation 262 | } 263 | 264 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 265 | public struct WlanHostedNetworkSecuritySettings 266 | { 267 | public readonly Dot11AuthAlgorithm Dot11AuthAlgo; 268 | public readonly Dot11CipherAlgorithm Dot11CipherAlgo; 269 | } 270 | 271 | //http://msdn.microsoft.com/en-us/library/dd439508%28VS.85%29.aspx 272 | public enum WlanHostedNetworkState 273 | { 274 | Unavailable, 275 | Idle, 276 | Active 277 | } 278 | 279 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 280 | public struct WlanHostedNetworkStateChange 281 | { 282 | public readonly WlanHostedNetworkState OldState; 283 | public readonly WlanHostedNetworkState NewState; 284 | public readonly WlanHostedNetworkReason Reason; // NewState; 285 | } 286 | 287 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 288 | public struct WlanHostedNetworkStatus 289 | { 290 | public WlanHostedNetworkState HostedNetworkState; 291 | public Guid IPDeviceID; 292 | public Dot11MacAddress wlanHostedNetworkBSSID; 293 | public Dot11PhyType dot11PhyType; 294 | public uint ulChannelFrequency; // ULONG 295 | public uint dwNumberOfPeers; // DWORD 296 | public WlanHostedNetworkPeerState[] PeerList; 297 | } 298 | 299 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 300 | internal struct WlanHostedNetworkStatusTemp 301 | { 302 | public readonly WlanHostedNetworkState HostedNetworkState; 303 | public Guid IPDeviceID; 304 | public Dot11MacAddress wlanHostedNetworkBSSID; 305 | public readonly Dot11PhyType dot11PhyType; 306 | public readonly uint ChannelFrequency; // ULONG 307 | public readonly uint NumberOfPeers; // DWORD 308 | } 309 | 310 | /// 311 | /// Contains information provided when registering for notifications. 312 | /// 313 | /// 314 | /// Corresponds to the native WLAN_NOTIFICATION_DATA type. 315 | /// 316 | [StructLayout(LayoutKind.Sequential)] 317 | public struct WlanNotificationData 318 | { 319 | /// 320 | /// Specifies where the notification comes from. 321 | /// 322 | public readonly WlanNotificationSource notificationSource; 323 | 324 | /// 325 | /// Indicates the type of notification. The value of this field indicates what type of associated data will 326 | /// be present in . 327 | /// 328 | public readonly int notificationCode; 329 | 330 | /// 331 | /// Indicates which interface the notification is for. 332 | /// 333 | private readonly Guid interfaceGuid; 334 | 335 | /// 336 | /// Specifies the size of , in bytes. 337 | /// 338 | public readonly int dataSize; 339 | 340 | /// 341 | /// Pointer to additional data needed for the notification, as indicated by 342 | /// . 343 | /// 344 | public IntPtr dataPtr; 345 | } 346 | 347 | /// 348 | /// Specifies where the notification comes from. 349 | /// 350 | [Flags] 351 | public enum WlanNotificationSource : uint 352 | { 353 | /// 354 | /// All notifications, including those generated by the 802.1X module. 355 | /// 356 | All = 0X0000FFFF, 357 | 358 | /// 359 | /// Notifications generated by the wireless Hosted Network. 360 | /// 361 | Hnwk = 0X00000080, 362 | } 363 | 364 | public enum WlanOpcodeValueType 365 | { 366 | QueryOnly = 0, 367 | SetByGroupPolicy, 368 | SetByUser, 369 | Invalid 370 | } 371 | } -------------------------------------------------------------------------------- /MygodWifiShare/Resources.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | Call a COM object 122 | 123 | 124 | Start a program 125 | 126 | 127 | Send an e-mail 128 | 129 | 130 | Display a message 131 | 132 | 133 | {0} 134 | 0 = Class GUID; 1 = Data; 2 = Id 135 | 136 | 137 | every day 138 | 139 | 140 | {1} {0} 141 | 0 = Subject; 1 = To; 2 = Cc, 3 = Bcc, 4 = From, 5 = ReplyTo, 6 = Body, 7 = Server, 8 = Id 142 | 143 | 144 | . 145 | 146 | 147 | {0} {1} 148 | 0 = Executable Path; 1 = Arguments; 2 = WorkingDirectory; 3 = Id 149 | 150 | 151 | - 152 | 153 | 154 | , 155 | 156 | 157 | every month 158 | 159 | 160 | Multiple actions defined 161 | 162 | 163 | Multiple triggers defined 164 | 165 | 166 | {0} 167 | 0 = Title; 1 = MessageBody; 2 = Id 168 | 169 | 170 | Author 171 | 172 | 173 | Disabled 174 | 175 | 176 | Queued 177 | 178 | 179 | Ready 180 | 181 | 182 | Running 183 | 184 | 185 | Unknown 186 | 187 | 188 | any user 189 | 190 | 191 | At system startup 192 | 193 | 194 | Custom Trigger 195 | 196 | 197 | At {0:t} every day 198 | 199 | 200 | At {0:t} every {1} days 201 | 202 | 203 | indefinitely 204 | 205 | 206 | for a duration of {0} 207 | 0 = Duration 208 | 209 | 210 | Trigger expires at {0:G}. 211 | 0 = EndBoundary 212 | 213 | 214 | Custom event filter 215 | 216 | 217 | On event - Log: {0} 218 | 0 = Log name 219 | 220 | 221 | , Source: {0} 222 | 0 = Source name (appended after log) 223 | 224 | 225 | , EventID: {0} 226 | 0 = Event ID (appended after log or source) 227 | 228 | 229 | When computer is idle 230 | 231 | 232 | At log on of {0} 233 | 234 | 235 | At {0:t} on day {1} of {2}, starting {0:d} 236 | 0 = StartBoundary; 1 = list of Days; 2 = list of Months 237 | 238 | 239 | At {0:t} on the {1} {2:f} each {3}, starting {0:d} 240 | 0 = StartBoundary; 1 = list of weeks of Month; 2 = list of Week Days; 3 = list of Months 241 | 242 | 243 | When the task is created or modified 244 | 245 | 246 | After triggered, repeat every {0}{1}. 247 | 0 = Interval; 1= Duration string 248 | 249 | 250 | On local connection to {0}. 251 | 0 = UserId 252 | 253 | 254 | On local disconnect from {0}. 255 | 0 = UserId 256 | 257 | 258 | On remote connection to {0}. 259 | 0 = UserId 260 | 261 | 262 | On remote disconnect from {0}. 263 | 0 = UserId 264 | 265 | 266 | On workstation lock of {0}. 267 | 0 = UserId 268 | 269 | 270 | On workstation unlock of {0}. 271 | 0 = UserId 272 | 273 | 274 | user session of {0} 275 | 0 = UserId 276 | 277 | 278 | At {0:t} on {0:d} 279 | 0 = StartBoundary 280 | 281 | 282 | At startup 283 | 284 | 285 | Custom Trigger 286 | 287 | 288 | Daily 289 | 290 | 291 | On an event 292 | 293 | 294 | On idle 295 | 296 | 297 | At log on 298 | 299 | 300 | Monthly 301 | 302 | 303 | Monthly 304 | 305 | 306 | At task creation/modification 307 | 308 | 309 | On state change 310 | 311 | 312 | One time 313 | 314 | 315 | Weekly 316 | 317 | 318 | At {0:t} every {1} of every week, starting {0:d} 319 | 0 = StartBoundary; 1 = list of Week Days 320 | 321 | 322 | At {0:t} every {1} of every {2} weeks, starting {0:d} 323 | 0 = StartBoundary; 1 = list of Week Days; 2 = WeekInterval 324 | 325 | 326 | every 327 | 328 | 329 | fifth 330 | 331 | 332 | first 333 | 334 | 335 | fourth 336 | 337 | 338 | last 339 | 340 | 341 | second 342 | 343 | 344 | third 345 | 346 | -------------------------------------------------------------------------------- /MygodWifiShare/[References]/[TaskScheduler]/TaskCollection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.InteropServices; 4 | using System.Text.RegularExpressions; 5 | 6 | namespace Microsoft.Win32.TaskScheduler 7 | { 8 | /// 9 | /// Contains all the tasks that are registered. 10 | /// 11 | /// Potentially breaking change in 1.6.2 and later where under V1 the list previously included the '.job' extension on the task name. This has been removed so that it is consistent with V2. 12 | public sealed class TaskCollection : IEnumerable, IDisposable 13 | { 14 | private TaskService svc; 15 | private Regex filter; 16 | private TaskFolder fld; 17 | private V1Interop.ITaskScheduler v1TS = null; 18 | private V2Interop.IRegisteredTaskCollection v2Coll = null; 19 | 20 | internal TaskCollection(TaskService svc, Regex filter = null) 21 | { 22 | this.svc = svc; 23 | this.Filter = filter; 24 | v1TS = svc.v1TaskScheduler; 25 | } 26 | 27 | internal TaskCollection(TaskFolder folder, V2Interop.IRegisteredTaskCollection iTaskColl, Regex filter = null) 28 | { 29 | this.svc = folder.TaskService; 30 | this.Filter = filter; 31 | fld = folder; 32 | v2Coll = iTaskColl; 33 | } 34 | 35 | /// 36 | /// Releases all resources used by this class. 37 | /// 38 | public void Dispose() 39 | { 40 | v1TS = null; 41 | if (v2Coll != null) 42 | Marshal.ReleaseComObject(v2Coll); 43 | } 44 | 45 | /// 46 | /// Gets the collection enumerator for the register task collection. 47 | /// 48 | /// An for this collection. 49 | public IEnumerator GetEnumerator() 50 | { 51 | if (v1TS != null) 52 | return new V1TaskEnumerator(svc, filter); 53 | return new V2TaskEnumerator(fld, v2Coll, filter); 54 | } 55 | 56 | System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 57 | { 58 | return this.GetEnumerator(); 59 | } 60 | 61 | internal class V1TaskEnumerator : IEnumerator, IDisposable 62 | { 63 | private TaskService svc; 64 | private V1Interop.IEnumWorkItems wienum = null; 65 | private V1Interop.ITaskScheduler m_ts = null; 66 | private Guid ITaskGuid = Marshal.GenerateGuidForType(typeof(V1Interop.ITask)); 67 | private string curItem = null; 68 | private Regex filter; 69 | 70 | /// 71 | /// Internal constructor 72 | /// 73 | /// TaskService instance 74 | /// The filter. 75 | internal V1TaskEnumerator(TaskService svc, Regex filter = null) 76 | { 77 | this.svc = svc; 78 | this.filter = filter; 79 | m_ts = svc.v1TaskScheduler; 80 | wienum = m_ts.Enum(); 81 | Reset(); 82 | } 83 | 84 | /// 85 | /// Retrieves the current task. See for more information. 86 | /// 87 | public Microsoft.Win32.TaskScheduler.Task Current 88 | { 89 | get { return new Task(svc, this.ICurrent); } 90 | } 91 | 92 | internal V1Interop.ITask ICurrent 93 | { 94 | get { return m_ts.Activate(curItem, ref ITaskGuid); } 95 | } 96 | 97 | /// 98 | /// Releases all resources used by this class. 99 | /// 100 | public void Dispose() 101 | { 102 | if (wienum != null) Marshal.ReleaseComObject(wienum); 103 | m_ts = null; 104 | } 105 | 106 | object System.Collections.IEnumerator.Current 107 | { 108 | get { return this.Current; } 109 | } 110 | 111 | /// 112 | /// Moves to the next task. See MoveNext for more information. 113 | /// 114 | /// true if next task found, false if no more tasks. 115 | public bool MoveNext() 116 | { 117 | IntPtr names = IntPtr.Zero; 118 | bool valid = false; 119 | do 120 | { 121 | curItem = null; 122 | uint uFetched = 0; 123 | try 124 | { 125 | wienum.Next(1, out names, out uFetched); 126 | if (uFetched != 1) 127 | break; 128 | using (V1Interop.CoTaskMemString name = new V1Interop.CoTaskMemString(Marshal.ReadIntPtr(names))) 129 | curItem = name.ToString(); 130 | if (curItem.EndsWith(".job", StringComparison.InvariantCultureIgnoreCase)) 131 | curItem = curItem.Remove(curItem.Length - 4); 132 | } 133 | catch { } 134 | finally { Marshal.FreeCoTaskMem(names); names = IntPtr.Zero; } 135 | 136 | // If name doesn't match filter, look for next item 137 | if (filter != null) 138 | { 139 | if (!filter.IsMatch(curItem)) 140 | continue; 141 | } 142 | 143 | V1Interop.ITask itask = null; 144 | try { itask = this.ICurrent; valid = true; } 145 | catch { valid = false; } 146 | finally { itask = null; } 147 | } while (!valid); 148 | 149 | return (curItem != null); 150 | } 151 | 152 | /// 153 | /// Reset task enumeration. See Reset for more information. 154 | /// 155 | public void Reset() 156 | { 157 | curItem = null; 158 | wienum.Reset(); 159 | } 160 | 161 | internal int Count 162 | { 163 | get 164 | { 165 | int i = 0; 166 | Reset(); 167 | while (this.MoveNext()) 168 | i++; 169 | Reset(); 170 | return i; 171 | } 172 | } 173 | } 174 | 175 | internal class V2TaskEnumerator : IEnumerator, IDisposable 176 | { 177 | private System.Collections.IEnumerator iEnum; 178 | private TaskFolder fld; 179 | private Regex filter; 180 | 181 | internal V2TaskEnumerator(TaskFolder folder, TaskScheduler.V2Interop.IRegisteredTaskCollection iTaskColl, Regex filter = null) 182 | { 183 | this.fld = folder; 184 | this.iEnum = iTaskColl.GetEnumerator(); 185 | this.filter = filter; 186 | } 187 | 188 | public Task Current 189 | { 190 | get { return Task.CreateTask(fld.TaskService, (TaskScheduler.V2Interop.IRegisteredTask)iEnum.Current); } 191 | } 192 | 193 | /// 194 | /// Releases all resources used by this class. 195 | /// 196 | public void Dispose() 197 | { 198 | iEnum = null; 199 | } 200 | 201 | object System.Collections.IEnumerator.Current 202 | { 203 | get { return this.Current; } 204 | } 205 | 206 | public bool MoveNext() 207 | { 208 | bool hasNext = iEnum.MoveNext(); 209 | if (!hasNext) 210 | return false; 211 | 212 | while (hasNext && filter != null) 213 | { 214 | if (filter.IsMatch(this.Current.Name)) 215 | break; 216 | hasNext = iEnum.MoveNext(); 217 | } 218 | 219 | return hasNext; 220 | } 221 | 222 | public void Reset() 223 | { 224 | iEnum.Reset(); 225 | } 226 | } 227 | 228 | /// 229 | /// Gets the number of registered tasks in the collection. 230 | /// 231 | public int Count 232 | { 233 | get 234 | { 235 | int i = 0; 236 | if (v2Coll != null) 237 | { 238 | if (filter == null) 239 | return v2Coll.Count; 240 | else 241 | { 242 | V2TaskEnumerator v2te = new V2TaskEnumerator(this.fld, this.v2Coll, this.filter); 243 | while (v2te.MoveNext()) 244 | i++; 245 | } 246 | } 247 | else 248 | { 249 | V1TaskEnumerator v1te = new V1TaskEnumerator(this.svc, this.filter); 250 | return v1te.Count; 251 | } 252 | return i; 253 | } 254 | } 255 | 256 | /// 257 | /// Gets or sets the regular expression filter for task names. 258 | /// 259 | /// The regular expression filter. 260 | private Regex Filter 261 | { 262 | get 263 | { 264 | return filter; 265 | } 266 | set 267 | { 268 | string sfilter = value == null ? string.Empty : value.ToString().TrimStart('^').TrimEnd('$'); 269 | if (sfilter == string.Empty || sfilter == "*") 270 | filter = null; 271 | else 272 | { 273 | if (value.ToString().TrimEnd('$').EndsWith("\\.job", StringComparison.InvariantCultureIgnoreCase)) 274 | filter = new Regex(value.ToString().Replace("\\.job", "")); 275 | else 276 | filter = value; 277 | } 278 | } 279 | } 280 | 281 | /// 282 | /// Gets the specified registered task from the collection. 283 | /// 284 | /// The index of the registered task to be retrieved. 285 | /// A instance that contains the requested context. 286 | public Task this[int index] 287 | { 288 | get 289 | { 290 | int i = 0; 291 | if (v2Coll != null) 292 | { 293 | if (filter == null) 294 | return Task.CreateTask(svc, v2Coll[++index]); 295 | else 296 | { 297 | V2TaskEnumerator v2te = new V2TaskEnumerator(this.fld, this.v2Coll, this.filter); 298 | while (v2te.MoveNext()) 299 | if (i++ == index) 300 | return v2te.Current; 301 | } 302 | } 303 | else 304 | { 305 | V1TaskEnumerator v1te = new V1TaskEnumerator(this.svc, this.filter); 306 | while (v1te.MoveNext()) 307 | if (i++ == index) 308 | return v1te.Current; 309 | } 310 | throw new ArgumentOutOfRangeException(); 311 | } 312 | } 313 | 314 | /// 315 | /// Gets the named registered task from the collection. 316 | /// 317 | /// The name of the registered task to be retrieved. 318 | /// A instance that contains the requested context. 319 | public Task this[string name] 320 | { 321 | get 322 | { 323 | if (v2Coll != null) 324 | return Task.CreateTask(svc, v2Coll[name]); 325 | 326 | Task v1Task = svc.GetTask(name); 327 | if (v1Task != null) 328 | return v1Task; 329 | 330 | throw new ArgumentOutOfRangeException(); 331 | } 332 | } 333 | 334 | /// 335 | /// Determines whether the specified task exists. 336 | /// 337 | /// The name of the task. 338 | /// true if task exists; otherwise, false. 339 | public bool Exists(string taskName) 340 | { 341 | try 342 | { 343 | if (v2Coll != null) 344 | return v2Coll[taskName] != null; 345 | 346 | return svc.GetTask(taskName) != null; 347 | } 348 | catch { } 349 | return false; 350 | } 351 | } 352 | 353 | /// 354 | /// Collection of running tasks. 355 | /// 356 | public sealed class RunningTaskCollection : IEnumerable, IDisposable 357 | { 358 | private TaskService svc; 359 | private V1Interop.ITaskScheduler v1TS = null; 360 | private V2Interop.ITaskService v2Svc = null; 361 | private V2Interop.IRunningTaskCollection v2Coll = null; 362 | 363 | internal RunningTaskCollection(TaskService svc) 364 | { 365 | this.svc = svc; 366 | v1TS = svc.v1TaskScheduler; 367 | } 368 | 369 | internal RunningTaskCollection(TaskService svc, V2Interop.IRunningTaskCollection iTaskColl) 370 | { 371 | this.svc = svc; 372 | v2Svc = svc.v2TaskService; 373 | v2Coll = iTaskColl; 374 | } 375 | 376 | /// 377 | /// Releases all resources used by this class. 378 | /// 379 | public void Dispose() 380 | { 381 | v1TS = null; 382 | v2Svc = null; 383 | if (v2Coll != null) 384 | Marshal.ReleaseComObject(v2Coll); 385 | } 386 | 387 | /// 388 | /// Gets an IEnumerator instance for this collection. 389 | /// 390 | /// An enumerator. 391 | public IEnumerator GetEnumerator() 392 | { 393 | if (v2Coll != null) 394 | return new RunningTaskEnumerator(svc, v2Coll); 395 | return new V1RunningTaskEnumerator(svc); 396 | } 397 | 398 | System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 399 | { 400 | return this.GetEnumerator(); 401 | } 402 | 403 | internal class V1RunningTaskEnumerator : IEnumerator 404 | { 405 | private TaskService svc; 406 | private TaskCollection.V1TaskEnumerator tEnum; 407 | 408 | internal V1RunningTaskEnumerator(TaskService svc) 409 | { 410 | this.svc = svc; 411 | tEnum = new TaskCollection.V1TaskEnumerator(svc); 412 | } 413 | 414 | public bool MoveNext() 415 | { 416 | if (tEnum.MoveNext()) 417 | { 418 | if (tEnum.Current.State == TaskState.Running) 419 | return true; 420 | return this.MoveNext(); 421 | } 422 | return false; 423 | } 424 | 425 | public RunningTask Current 426 | { 427 | get { return new RunningTask(svc, tEnum.ICurrent); } 428 | } 429 | 430 | /// 431 | /// Releases all resources used by this class. 432 | /// 433 | public void Dispose() 434 | { 435 | tEnum.Dispose(); 436 | } 437 | 438 | object System.Collections.IEnumerator.Current 439 | { 440 | get { return this.Current; } 441 | } 442 | 443 | public void Reset() 444 | { 445 | tEnum.Reset(); 446 | } 447 | } 448 | 449 | internal class RunningTaskEnumerator : IEnumerator, IDisposable 450 | { 451 | private TaskService svc; 452 | private V2Interop.ITaskService v2Svc = null; 453 | private System.Collections.IEnumerator iEnum; 454 | 455 | internal RunningTaskEnumerator(TaskService svc, V2Interop.IRunningTaskCollection iTaskColl) 456 | { 457 | this.svc = svc; 458 | v2Svc = svc.v2TaskService; 459 | iEnum = iTaskColl.GetEnumerator(); 460 | } 461 | 462 | public RunningTask Current 463 | { 464 | get 465 | { 466 | V2Interop.IRunningTask irt = (V2Interop.IRunningTask)iEnum.Current; 467 | V2Interop.IRegisteredTask task = null; 468 | try { task = TaskService.GetTask(v2Svc, irt.Path); } catch { } 469 | if (task == null) return null; 470 | return new RunningTask(svc, task, irt); 471 | } 472 | } 473 | 474 | /// 475 | /// Releases all resources used by this class. 476 | /// 477 | public void Dispose() 478 | { 479 | v2Svc = null; 480 | iEnum = null; 481 | } 482 | 483 | object System.Collections.IEnumerator.Current 484 | { 485 | get { return this.Current; } 486 | } 487 | 488 | public bool MoveNext() 489 | { 490 | return iEnum.MoveNext(); 491 | } 492 | 493 | public void Reset() 494 | { 495 | iEnum.Reset(); 496 | } 497 | } 498 | 499 | /// 500 | /// Gets the number of registered tasks in the collection. 501 | /// 502 | public int Count 503 | { 504 | get 505 | { 506 | if (v2Coll != null) 507 | return v2Coll.Count; 508 | int i = 0; 509 | V1RunningTaskEnumerator v1te = new V1RunningTaskEnumerator(svc); 510 | while (v1te.MoveNext()) 511 | i++; 512 | return i; 513 | } 514 | } 515 | 516 | /// 517 | /// Gets the specified running task from the collection. 518 | /// 519 | /// The index of the running task to be retrieved. 520 | /// A instance. 521 | public RunningTask this[int index] 522 | { 523 | get 524 | { 525 | if (v2Coll != null) 526 | { 527 | V2Interop.IRunningTask irt = v2Coll[++index]; 528 | return new RunningTask(svc, TaskService.GetTask(svc.v2TaskService, irt.Path), irt); 529 | } 530 | 531 | int i = 0; 532 | V1RunningTaskEnumerator v1te = new V1RunningTaskEnumerator(svc); 533 | while (v1te.MoveNext()) 534 | if (i++ == index) 535 | return v1te.Current; 536 | throw new ArgumentOutOfRangeException(); 537 | } 538 | } 539 | } 540 | 541 | } 542 | -------------------------------------------------------------------------------- /MygodWifiShare/[References]/[TaskScheduler]/V1/TaskSchedulerV1Schema.xsd: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | -------------------------------------------------------------------------------- /MygodWifiShare/[References]/[TaskScheduler]/TaskFolder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Microsoft.Win32.TaskScheduler 4 | { 5 | /// 6 | /// Provides the methods that are used to register (create) tasks in the folder, remove tasks from the folder, and create or remove subfolders from the folder. 7 | /// 8 | public sealed class TaskFolder : IDisposable 9 | { 10 | V1Interop.ITaskScheduler v1List = null; 11 | V2Interop.ITaskFolder v2Folder = null; 12 | 13 | internal TaskFolder(TaskService svc) 14 | { 15 | this.TaskService = svc; 16 | v1List = svc.v1TaskScheduler; 17 | } 18 | 19 | internal TaskFolder(TaskService svc, V2Interop.ITaskFolder iFldr) 20 | { 21 | this.TaskService = svc; 22 | v2Folder = iFldr; 23 | } 24 | 25 | /// 26 | /// Releases all resources used by this class. 27 | /// 28 | public void Dispose() 29 | { 30 | if (v2Folder != null) 31 | System.Runtime.InteropServices.Marshal.ReleaseComObject(v2Folder); 32 | v1List = null; 33 | } 34 | 35 | /// 36 | /// Gets the name that is used to identify the folder that contains a task. 37 | /// 38 | public string Name 39 | { 40 | get { return (v2Folder == null) ? @"\" : v2Folder.Name; } 41 | } 42 | 43 | /// 44 | /// Gets the path to where the folder is stored. 45 | /// 46 | public string Path 47 | { 48 | get { return (v2Folder == null) ? @"\" : v2Folder.Path; } 49 | } 50 | 51 | internal TaskFolder GetFolder(string Path) 52 | { 53 | if (v2Folder != null) 54 | return new TaskFolder(this.TaskService, v2Folder.GetFolder(Path)); 55 | throw new NotV1SupportedException(); 56 | } 57 | 58 | /// 59 | /// Gets or sets the security descriptor of the task. 60 | /// 61 | /// The security descriptor. 62 | public System.Security.AccessControl.GenericSecurityDescriptor SecurityDescriptor 63 | { 64 | get 65 | { 66 | return GetSecurityDescriptor(System.Security.AccessControl.AccessControlSections.All); 67 | } 68 | set 69 | { 70 | SetSecurityDescriptor(value, System.Security.AccessControl.AccessControlSections.All); 71 | } 72 | } 73 | 74 | /// 75 | /// Gets all the subfolders in the folder. 76 | /// 77 | public TaskFolderCollection SubFolders 78 | { 79 | get 80 | { 81 | if (v2Folder != null) 82 | return new TaskFolderCollection(this, v2Folder.GetFolders(0)); 83 | return new TaskFolderCollection(); 84 | } 85 | } 86 | 87 | /// 88 | /// Gets a collection of all the tasks in the folder. 89 | /// 90 | public TaskCollection Tasks 91 | { 92 | get { return GetTasks(); } 93 | } 94 | 95 | /// 96 | /// Gets or sets the that manages this task. 97 | /// 98 | /// The task service. 99 | public TaskService TaskService { get; private set; } 100 | 101 | /// 102 | /// Creates a folder for related tasks. Not available to Task Scheduler 1.0. 103 | /// 104 | /// The name used to identify the folder. If "FolderName\SubFolder1\SubFolder2" is specified, the entire folder tree will be created if the folders do not exist. This parameter can be a relative path to the current instance. The root task folder is specified with a backslash (\). An example of a task folder path, under the root task folder, is \MyTaskFolder. The '.' character cannot be used to specify the current task folder and the '..' characters cannot be used to specify the parent task folder in the path. 105 | /// The security descriptor associated with the folder. 106 | /// A instance that represents the new subfolder. 107 | public TaskFolder CreateFolder(string subFolderName, System.Security.AccessControl.GenericSecurityDescriptor sd) 108 | { 109 | return this.CreateFolder(subFolderName, sd.GetSddlForm(System.Security.AccessControl.AccessControlSections.All)); 110 | } 111 | 112 | /// 113 | /// Creates a folder for related tasks. Not available to Task Scheduler 1.0. 114 | /// 115 | /// The name used to identify the folder. If "FolderName\SubFolder1\SubFolder2" is specified, the entire folder tree will be created if the folders do not exist. This parameter can be a relative path to the current instance. The root task folder is specified with a backslash (\). An example of a task folder path, under the root task folder, is \MyTaskFolder. The '.' character cannot be used to specify the current task folder and the '..' characters cannot be used to specify the parent task folder in the path. 116 | /// The security descriptor associated with the folder. 117 | /// A instance that represents the new subfolder. 118 | /// Not supported under Task Scheduler 1.0. 119 | public TaskFolder CreateFolder(string subFolderName, string sddlForm = null) 120 | { 121 | if (v2Folder != null) 122 | return new TaskFolder(this.TaskService, v2Folder.CreateFolder(subFolderName, sddlForm)); 123 | throw new NotV1SupportedException(); 124 | } 125 | 126 | /// 127 | /// Deletes a subfolder from the parent folder. Not available to Task Scheduler 1.0. 128 | /// 129 | /// The name of the subfolder to be removed. The root task folder is specified with a backslash (\). This parameter can be a relative path to the folder you want to delete. An example of a task folder path, under the root task folder, is \MyTaskFolder. The '.' character cannot be used to specify the current task folder and the '..' characters cannot be used to specify the parent task folder in the path. 130 | /// Set this value to false to avoid having an exception called if the folder does not exist. 131 | /// Not supported under Task Scheduler 1.0. 132 | public void DeleteFolder(string subFolderName, bool exceptionOnNotExists = true) 133 | { 134 | if (v2Folder != null) 135 | { 136 | try 137 | { 138 | v2Folder.DeleteFolder(subFolderName, 0); 139 | } 140 | catch (System.IO.FileNotFoundException) 141 | { 142 | if (exceptionOnNotExists) 143 | throw; 144 | } 145 | } 146 | else 147 | throw new NotV1SupportedException(); 148 | } 149 | 150 | /// 151 | /// Deletes a task from the folder. 152 | /// 153 | /// The name of the task that is specified when the task was registered. The '.' character cannot be used to specify the current task folder and the '..' characters cannot be used to specify the parent task folder in the path. 154 | /// Set this value to false to avoid having an exception called if the task does not exist. 155 | public void DeleteTask(string Name, bool exceptionOnNotExists = true) 156 | { 157 | try 158 | { 159 | if (v2Folder != null) 160 | v2Folder.DeleteTask(Name, 0); 161 | else 162 | { 163 | if (!Name.EndsWith(".job", StringComparison.CurrentCultureIgnoreCase)) 164 | Name += ".job"; 165 | v1List.Delete(Name); 166 | } 167 | } 168 | catch (System.IO.FileNotFoundException) 169 | { 170 | if (exceptionOnNotExists) 171 | throw; 172 | } 173 | } 174 | 175 | /// 176 | /// Gets the security descriptor for the folder. Not available to Task Scheduler 1.0. 177 | /// 178 | /// Section(s) of the security descriptor to return. 179 | /// The security descriptor for the folder. 180 | public System.Security.AccessControl.GenericSecurityDescriptor GetSecurityDescriptor(System.Security.AccessControl.AccessControlSections includeSections) 181 | { 182 | return new System.Security.AccessControl.RawSecurityDescriptor(GetSecurityDescriptorSddlForm(includeSections)); 183 | } 184 | 185 | /// 186 | /// Gets the security descriptor for the folder. Not available to Task Scheduler 1.0. 187 | /// 188 | /// Section(s) of the security descriptor to return. 189 | /// The security descriptor for the folder. 190 | /// Not supported under Task Scheduler 1.0. 191 | public string GetSecurityDescriptorSddlForm(System.Security.AccessControl.AccessControlSections includeSections) 192 | { 193 | if (v2Folder != null) 194 | return v2Folder.GetSecurityDescriptor((int)includeSections); 195 | throw new NotV1SupportedException(); 196 | } 197 | 198 | /// 199 | /// Gets a collection of all the tasks in the folder whose name matches the optional . 200 | /// 201 | /// The optional name filter expression. 202 | /// Collection of all matching tasks. 203 | public TaskCollection GetTasks(System.Text.RegularExpressions.Regex filter = null) 204 | { 205 | if (v2Folder != null) 206 | return new TaskCollection(this, v2Folder.GetTasks(1), filter); 207 | return new TaskCollection(this.TaskService, filter); 208 | } 209 | 210 | /// 211 | /// Imports a from an XML file. 212 | /// 213 | /// The task name. If this value is NULL, the task will be registered in the root task folder and the task name will be a GUID value that is created by the Task Scheduler service. A task name cannot begin or end with a space character. The '.' character cannot be used to specify the current task folder and the '..' characters cannot be used to specify the parent task folder in the path. 214 | /// The file containing the XML-formatted definition of the task. 215 | /// A instance that represents the new task. 216 | /// Importing from an XML file is only supported under Task Scheduler 2.0. 217 | public Task ImportTask(string Path, string xmlFile) 218 | { 219 | return RegisterTask(Path, System.IO.File.ReadAllText(xmlFile)); 220 | } 221 | 222 | /// 223 | /// Registers (creates) a new task in the folder using XML to define the task. 224 | /// 225 | /// The task name. If this value is NULL, the task will be registered in the root task folder and the task name will be a GUID value that is created by the Task Scheduler service. A task name cannot begin or end with a space character. The '.' character cannot be used to specify the current task folder and the '..' characters cannot be used to specify the parent task folder in the path. 226 | /// An XML-formatted definition of the task. 227 | /// A union of flags. 228 | /// The user credentials used to register the task. 229 | /// The password for the userId used to register the task. 230 | /// A value that defines what logon technique is used to run the registered task. 231 | /// The security descriptor associated with the registered task. You can specify the access control list (ACL) in the security descriptor for a task in order to allow or deny certain users and groups access to a task. 232 | /// A instance that represents the new task. 233 | public Task RegisterTask(string Path, string XmlText, TaskCreation createType = TaskCreation.CreateOrUpdate, string UserId = null, string password = null, TaskLogonType LogonType = TaskLogonType.S4U, string sddl = null) 234 | { 235 | if (v2Folder != null) 236 | return new Task(this.TaskService, v2Folder.RegisterTask(Path, XmlText, (int)createType, UserId, password, LogonType, sddl)); 237 | 238 | try 239 | { 240 | TaskDefinition td = this.TaskService.NewTask(); 241 | XmlSerializationHelper.ReadObjectFromXmlText(XmlText, td); 242 | return this.RegisterTaskDefinition(Path, td, createType, UserId == null ? td.Principal.ToString() : UserId, 243 | password, LogonType == TaskLogonType.S4U ? td.Principal.LogonType : LogonType, sddl); 244 | } 245 | catch 246 | { 247 | throw; // new NotV1SupportedException(); 248 | } 249 | } 250 | 251 | /// 252 | /// Registers (creates) a task in a specified location using a instance to define a task. 253 | /// 254 | /// The task name. If this value is NULL, the task will be registered in the root task folder and the task name will be a GUID value that is created by the Task Scheduler service. A task name cannot begin or end with a space character. The '.' character cannot be used to specify the current task folder and the '..' characters cannot be used to specify the parent task folder in the path. 255 | /// The of the registered task. 256 | /// A instance that represents the new task. 257 | public Task RegisterTaskDefinition(string Path, TaskDefinition definition) 258 | { 259 | return RegisterTaskDefinition(Path, definition, TaskCreation.CreateOrUpdate, 260 | definition.Principal.LogonType == TaskLogonType.Group ? definition.Principal.GroupId : definition.Principal.UserId, 261 | null, definition.Principal.LogonType, null); 262 | } 263 | 264 | /// 265 | /// Registers (creates) a task in a specified location using a instance to define a task. 266 | /// 267 | /// The task name. If this value is NULL, the task will be registered in the root task folder and the task name will be a GUID value that is created by the Task Scheduler service. A task name cannot begin or end with a space character. The '.' character cannot be used to specify the current task folder and the '..' characters cannot be used to specify the parent task folder in the path. 268 | /// The of the registered task. 269 | /// A union of flags. 270 | /// The user credentials used to register the task. 271 | /// The password for the userId used to register the task. 272 | /// A value that defines what logon technique is used to run the registered task. 273 | /// The security descriptor associated with the registered task. You can specify the access control list (ACL) in the security descriptor for a task in order to allow or deny certain users and groups access to a task. 274 | /// 275 | /// A instance that represents the new task. 276 | /// 277 | /// 278 | /// This LogonType is not supported on Task Scheduler 1.0. 279 | /// or 280 | /// Security settings are not available on Task Scheduler 1.0. 281 | /// or 282 | /// Registration triggers are not available on Task Scheduler 1.0. 283 | /// or 284 | /// Xml validation not available on Task Scheduler 1.0. 285 | /// 286 | public Task RegisterTaskDefinition(string Path, TaskDefinition definition, TaskCreation createType, string UserId, string password = null, TaskLogonType LogonType = TaskLogonType.S4U, string sddl = null) 287 | { 288 | if (v2Folder != null) 289 | return new Task(this.TaskService, v2Folder.RegisterTaskDefinition(Path, definition.v2Def, (int)createType, UserId, password, LogonType, sddl)); 290 | 291 | // Adds ability to set a password for a V1 task. Provided by Arcao. 292 | V1Interop.TaskFlags flags = definition.v1Task.GetFlags(); 293 | if (LogonType == TaskLogonType.InteractiveTokenOrPassword && string.IsNullOrEmpty(password)) 294 | LogonType = TaskLogonType.InteractiveToken; 295 | if (string.IsNullOrEmpty(UserId)) 296 | UserId = System.Security.Principal.WindowsIdentity.GetCurrent().Name; 297 | switch (LogonType) 298 | { 299 | case TaskLogonType.Group: 300 | case TaskLogonType.S4U: 301 | case TaskLogonType.None: 302 | throw new NotV1SupportedException("This LogonType is not supported on Task Scheduler 1.0."); 303 | case TaskLogonType.InteractiveToken: 304 | flags |= (V1Interop.TaskFlags.RunOnlyIfLoggedOn | V1Interop.TaskFlags.Interactive); 305 | if (String.IsNullOrEmpty(UserId)) 306 | UserId = System.Security.Principal.WindowsIdentity.GetCurrent().Name; 307 | definition.v1Task.SetAccountInformation(UserId, IntPtr.Zero); 308 | break; 309 | case TaskLogonType.ServiceAccount: 310 | flags &= ~(V1Interop.TaskFlags.Interactive | V1Interop.TaskFlags.RunOnlyIfLoggedOn); 311 | definition.v1Task.SetAccountInformation((String.IsNullOrEmpty(UserId) || UserId.Equals("SYSTEM", StringComparison.CurrentCultureIgnoreCase)) ? String.Empty : UserId, IntPtr.Zero); 312 | break; 313 | case TaskLogonType.InteractiveTokenOrPassword: 314 | flags |= V1Interop.TaskFlags.Interactive; 315 | using (V1Interop.CoTaskMemString cpwd = new V1Interop.CoTaskMemString(password)) 316 | definition.v1Task.SetAccountInformation(UserId, cpwd.DangerousGetHandle()); 317 | break; 318 | case TaskLogonType.Password: 319 | using (V1Interop.CoTaskMemString cpwd = new V1Interop.CoTaskMemString(password)) 320 | definition.v1Task.SetAccountInformation(UserId, cpwd.DangerousGetHandle()); 321 | break; 322 | default: 323 | break; 324 | } 325 | definition.v1Task.SetFlags(flags); 326 | 327 | switch (createType) 328 | { 329 | case TaskCreation.Create: 330 | case TaskCreation.CreateOrUpdate: 331 | case TaskCreation.Disable: 332 | case TaskCreation.Update: 333 | if (createType == TaskCreation.Disable) 334 | definition.Settings.Enabled = false; 335 | definition.V1Save(Path); 336 | break; 337 | case TaskCreation.DontAddPrincipalAce: 338 | throw new NotV1SupportedException("Security settings are not available on Task Scheduler 1.0."); 339 | case TaskCreation.IgnoreRegistrationTriggers: 340 | throw new NotV1SupportedException("Registration triggers are not available on Task Scheduler 1.0."); 341 | case TaskCreation.ValidateOnly: 342 | throw new NotV1SupportedException("Xml validation not available on Task Scheduler 1.0."); 343 | default: 344 | break; 345 | } 346 | return new Task(this.TaskService, definition.v1Task); 347 | } 348 | 349 | /// 350 | /// Sets the security descriptor for the folder. Not available to Task Scheduler 1.0. 351 | /// 352 | /// The security descriptor for the folder. 353 | /// Section(s) of the security descriptor to set. 354 | public void SetSecurityDescriptor(System.Security.AccessControl.GenericSecurityDescriptor sd, System.Security.AccessControl.AccessControlSections includeSections) 355 | { 356 | this.SetSecurityDescriptorSddlForm(sd.GetSddlForm(includeSections), includeSections); 357 | } 358 | 359 | /// 360 | /// Sets the security descriptor for the folder. Not available to Task Scheduler 1.0. 361 | /// 362 | /// The security descriptor for the folder. 363 | /// Section(s) of the security descriptor to set. 364 | /// Not supported under Task Scheduler 1.0. 365 | public void SetSecurityDescriptorSddlForm(string sddlForm, System.Security.AccessControl.AccessControlSections includeSections) 366 | { 367 | if (v2Folder != null) 368 | v2Folder.SetSecurityDescriptor(sddlForm, (int)includeSections); 369 | else 370 | throw new NotV1SupportedException(); 371 | } 372 | 373 | /// 374 | /// Returns a that represents this instance. 375 | /// 376 | /// 377 | /// A that represents this instance. 378 | /// 379 | public override string ToString() 380 | { 381 | return this.Path; 382 | } 383 | } 384 | } 385 | -------------------------------------------------------------------------------- /MygodWifiShare/WlanManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.Runtime.InteropServices; 4 | using System.Text; 5 | 6 | namespace Mygod.WifiShare 7 | { 8 | public static class Helper 9 | { 10 | public static void ThrowExceptionForHR(int code) 11 | { 12 | Marshal.ThrowExceptionForHR(code); 13 | if (code != 0) throw new COMException("COM failed: " + code, code); 14 | } 15 | } 16 | 17 | public static class WlanManager 18 | { 19 | private static IntPtr wlanHandle; 20 | private static readonly WlanNativeMethods.WlanNotificationCallback Callback = OnNotification; 21 | 22 | static WlanManager() 23 | { 24 | Restart(); 25 | } 26 | 27 | public static void Restart() 28 | { 29 | lock (Callback) 30 | { 31 | try 32 | { 33 | if (wlanHandle != IntPtr.Zero) WlanNativeMethods.WlanCloseHandle(wlanHandle, IntPtr.Zero); 34 | } 35 | catch { } // who cares 36 | var failed = true; 37 | try 38 | { 39 | uint serverVersion; 40 | Helper.ThrowExceptionForHR(WlanNativeMethods.WlanOpenHandle(2, IntPtr.Zero, out serverVersion, 41 | out wlanHandle)); 42 | // WLAN_CLIENT_VERSION_VISTA: Client version for Windows Vista and Windows Server 2008 43 | WlanNotificationSource notifSource; 44 | Helper.ThrowExceptionForHR(WlanNativeMethods.WlanRegisterNotification(wlanHandle, 45 | WlanNotificationSource.All, true, Callback, IntPtr.Zero, IntPtr.Zero, out notifSource)); 46 | var failReason = InitSettings(); 47 | if (failReason != WlanHostedNetworkReason.Success) 48 | throw new Exception("Init Error WlanHostedNetworkInitSettings: " + failReason); 49 | AppDomain.CurrentDomain.DomainUnload += (sender, e) => 50 | { 51 | if (wlanHandle != IntPtr.Zero) 52 | Helper.ThrowExceptionForHR(WlanNativeMethods.WlanCloseHandle(wlanHandle, IntPtr.Zero)); 53 | }; 54 | failed = false; 55 | } 56 | finally 57 | { 58 | if (failed) WlanNativeMethods.WlanCloseHandle(wlanHandle, IntPtr.Zero); 59 | } 60 | } 61 | } 62 | 63 | private static Ssid ToDOT11_SSID(string ssid) 64 | { 65 | var length = Encoding.Default.GetByteCount(ssid); 66 | if (length > 32) throw new ArgumentException("SSID 过长。"); 67 | return new Ssid { Content = ssid, Length = length }; 68 | } 69 | public static string ToString(WlanHostedNetworkReason reason) 70 | { 71 | switch (reason) 72 | { 73 | case WlanHostedNetworkReason.Success: return "操作成功。"; 74 | case WlanHostedNetworkReason.Unspecified: return "未知错误。"; 75 | case WlanHostedNetworkReason.BadParameters: return "参数错误。"; 76 | case WlanHostedNetworkReason.ServiceShuttingDown: return "服务正在关闭。"; 77 | case WlanHostedNetworkReason.InsufficientResources: return "服务资源不足。"; 78 | case WlanHostedNetworkReason.ElevationRequired: return "当前操作需要提升权限。"; 79 | case WlanHostedNetworkReason.ReadOnly: return "尝试修改只读数据。"; 80 | case WlanHostedNetworkReason.PersistenceFailed: return "数据持久化失败。"; 81 | case WlanHostedNetworkReason.CryptError: return "加密时出现错误。"; 82 | case WlanHostedNetworkReason.Impersonation: return "用户模拟失败。"; 83 | case WlanHostedNetworkReason.StopBeforeStart: return "函数调用顺序错误。"; 84 | case WlanHostedNetworkReason.InterfaceAvailable: return "无线接口可用。"; 85 | case WlanHostedNetworkReason.InterfaceUnavailable: return "无线接口不可用。"; 86 | case WlanHostedNetworkReason.MiniportStopped: return "无线微型端口驱动程序终止了托管网络。"; 87 | case WlanHostedNetworkReason.MiniportStarted: return "无线微型端口驱动程序状态已改变。"; 88 | case WlanHostedNetworkReason.IncompatibleConnectionStarted: return "开始了一个不兼容的连接。"; 89 | case WlanHostedNetworkReason.IncompatibleConnectionStopped: return "一个不兼容的连接已停止。"; 90 | case WlanHostedNetworkReason.UserAction: return "由于用户操作,状态已改变。"; 91 | case WlanHostedNetworkReason.ClientAbort: return "由于客户端终止,状态已改变。"; 92 | case WlanHostedNetworkReason.ApStartFailed: return "无线托管网络驱动启动失败。"; 93 | case WlanHostedNetworkReason.PeerArrived: return "一个客户端已连接到无线托管网络。"; 94 | case WlanHostedNetworkReason.PeerDeparted: return "一个客户端已从无线托管网络断开连接。"; 95 | case WlanHostedNetworkReason.PeerTimeout: return "一个客户端连接超时。"; 96 | case WlanHostedNetworkReason.GpDenied: return "操作被组策略禁止。"; 97 | case WlanHostedNetworkReason.ServiceUnavailable: return "无线局域网服务未运行。"; 98 | case WlanHostedNetworkReason.DeviceChange: return "无线托管网络所使用的无线适配器已改变。"; 99 | case WlanHostedNetworkReason.PropertiesChange: return "无线托管网络所使用的属性已改变。"; 100 | case WlanHostedNetworkReason.VirtualStationBlockingUse: return "一个活动的虚拟站阻止了操作。"; 101 | case WlanHostedNetworkReason.ServiceAvailableOnVirtualStation: return "在虚拟站上一个相同的服务已可用。"; 102 | default: return "未知的 WLAN_HOSTED_NETWORK_REASON。"; 103 | } 104 | } 105 | public static string ToString(WlanHostedNetworkState state) 106 | { 107 | switch (state) 108 | { 109 | case WlanHostedNetworkState.Unavailable: return "不可用"; 110 | case WlanHostedNetworkState.Idle: return "未启用"; 111 | case WlanHostedNetworkState.Active: return "已启用"; 112 | default: return "未知的 WLAN_HOSTED_NETWORK_STATE"; 113 | } 114 | } 115 | public static string ToString(Dot11PhyType type) 116 | { 117 | switch (type) 118 | { 119 | case Dot11PhyType.Fhss: return "FHSS"; 120 | case Dot11PhyType.Dsss: return "DSSS"; 121 | case Dot11PhyType.Irbaseband: return "红外基带"; 122 | case Dot11PhyType.Ofdm: return "OFDM"; 123 | case Dot11PhyType.Hrdsss: return "HRDSSS"; 124 | case Dot11PhyType.Erp: return "ERP"; 125 | case Dot11PhyType.Ht: return "802.11n"; 126 | case Dot11PhyType.Vht: return "802.11ac"; 127 | default: return (int)type < 0 ? "IHV" : "未知的 DOT11_PHY_TYPE"; 128 | } 129 | } 130 | public static string ToString(WlanHostedNetworkPeerAuthState state) 131 | { 132 | switch (state) 133 | { 134 | case WlanHostedNetworkPeerAuthState.Invalid: return "无效"; 135 | case WlanHostedNetworkPeerAuthState.Authenticated: return "已认证"; 136 | default: return "未知的 WLAN_HOSTED_NETWORK_PEER_AUTH_STATE"; 137 | } 138 | } 139 | private static string ToString(Dot11RadioState state) 140 | { 141 | switch (state) 142 | { 143 | case Dot11RadioState.On: return "开"; 144 | case Dot11RadioState.Off: return "关"; 145 | case Dot11RadioState.Unknown: return "未知"; 146 | default: return "未知的 DOT11_RADIO_STATE"; 147 | } 148 | } 149 | public static string ToString(WlanOpcodeValueType opCode) 150 | { 151 | switch (opCode) 152 | { 153 | case WlanOpcodeValueType.QueryOnly: return "未知"; 154 | case WlanOpcodeValueType.SetByGroupPolicy: return "组策略设置"; 155 | case WlanOpcodeValueType.SetByUser: return "用户自定义"; 156 | case WlanOpcodeValueType.Invalid: return "无效"; 157 | default: return "未知的 WLAN_OPCODE_VALUE_TYPE"; 158 | } 159 | } 160 | public static string ToString(Dot11AuthAlgorithm algorithm) 161 | { 162 | switch (algorithm) 163 | { 164 | case Dot11AuthAlgorithm.Open: return "IEEE 802.11 开放式系统"; 165 | case Dot11AuthAlgorithm.SharedKey: return "802.11 共享密钥认证算法"; 166 | case Dot11AuthAlgorithm.Wpa: return "WPA"; 167 | case Dot11AuthAlgorithm.WpaPsk: return "使用 PSK 的 WPA"; 168 | case Dot11AuthAlgorithm.WpaNone: return "无 WPA"; 169 | case Dot11AuthAlgorithm.Rsna: return "802.11i RSNA"; 170 | case Dot11AuthAlgorithm.RsnaPsk: return "使用 PSK 的 802.11i RSNA"; 171 | default: return algorithm < 0 ? "IHV" : "未知的 WLAN_OPCODE_VALUE_TYPE"; 172 | } 173 | } 174 | public static string ToString(Dot11CipherAlgorithm algorithm) 175 | { 176 | switch (algorithm) 177 | { 178 | case Dot11CipherAlgorithm.None: return "无"; 179 | case Dot11CipherAlgorithm.Wep40: return "WEP (40 位密钥)"; 180 | case Dot11CipherAlgorithm.Tkip: return "TKIP"; 181 | case Dot11CipherAlgorithm.Ccmp: return "AES-CCMP"; 182 | case Dot11CipherAlgorithm.Wep104: return "WEP (104 位密钥)"; 183 | case Dot11CipherAlgorithm.WpaUseGroup: return "WPA/RSN (使用组密钥)"; 184 | case Dot11CipherAlgorithm.Wep: return "WEP"; 185 | default: return algorithm < 0 ? "IHV" : "未知的 DOT11_CIPHER_ALGORITHM"; 186 | } 187 | } 188 | 189 | private static void OnNotification(ref WlanNotificationData notifData, IntPtr context) 190 | { 191 | if (notifData.dataSize <= 0 || notifData.dataPtr == IntPtr.Zero 192 | || notifData.notificationSource != WlanNotificationSource.Hnwk) return; 193 | lock (Logger.Instance) 194 | { 195 | Logger.Instance.Write("[{0}]\t", DateTime.Now.ToString("yyyy.M.d H:mm:ss")); 196 | switch ((WlanHostedNetworkNotificationCode)notifData.notificationCode) 197 | { 198 | case WlanHostedNetworkNotificationCode.StateChange: 199 | var pStateChange = Marshal.PtrToStructure(notifData.dataPtr); 200 | Logger.Instance.Write("托管网络状态已改变:" + ToString(pStateChange.OldState)); 201 | if (pStateChange.OldState != pStateChange.NewState) 202 | Logger.Instance.Write(" => " + ToString(pStateChange.NewState)); 203 | Logger.Instance.WriteLine(";原因:" + ToString(pStateChange.Reason)); 204 | break; 205 | case WlanHostedNetworkNotificationCode.PeerStateChange: 206 | var pPeerStateChange = Marshal.PtrToStructure 207 | (notifData.dataPtr); 208 | var lookup = Program.Lookup; 209 | Logger.Instance.WriteLine("客户端已改变。原因:{0}{3}{1}=>{3}{2}", 210 | ToString(pPeerStateChange.Reason), 211 | Program.GetDeviceDetails(pPeerStateChange.OldState, true, lookup), 212 | Program.GetDeviceDetails(pPeerStateChange.NewState, true, lookup), 213 | Environment.NewLine); 214 | break; 215 | case WlanHostedNetworkNotificationCode.RadioStateChange: 216 | var pRadioState = Marshal.PtrToStructure(notifData.dataPtr); 217 | Logger.Instance.WriteLine("无线状态已改变。软件开关:{0};硬件开关:{1}。", 218 | ToString(pRadioState.dot11SoftwareRadioState), 219 | ToString(pRadioState.dot11HardwareRadioState)); 220 | break; 221 | default: 222 | Logger.Instance.WriteLine("具体事件未知。"); 223 | break; 224 | } 225 | Logger.Instance.WriteLine(); 226 | Logger.Instance.Flush(); 227 | } 228 | } 229 | 230 | public static WlanHostedNetworkReason ForceStart() 231 | { 232 | WlanHostedNetworkReason failReason; 233 | Helper.ThrowExceptionForHR 234 | (WlanNativeMethods.WlanHostedNetworkForceStart(wlanHandle, out failReason, IntPtr.Zero)); 235 | return failReason; 236 | } 237 | 238 | public static WlanHostedNetworkReason ForceStop() 239 | { 240 | WlanHostedNetworkReason failReason; 241 | Helper.ThrowExceptionForHR 242 | (WlanNativeMethods.WlanHostedNetworkForceStop(wlanHandle, out failReason, IntPtr.Zero)); 243 | return failReason; 244 | } 245 | 246 | private static WlanHostedNetworkReason InitSettings() 247 | { 248 | WlanHostedNetworkReason failReason; 249 | Helper.ThrowExceptionForHR 250 | (WlanNativeMethods.WlanHostedNetworkInitSettings(wlanHandle, out failReason, IntPtr.Zero)); 251 | return failReason; 252 | } 253 | 254 | public static WlanHostedNetworkReason QuerySecondaryKey(out string passKey, out bool isPassPhrase, 255 | out bool isPersistent) 256 | { 257 | WlanHostedNetworkReason failReason; 258 | uint keyLen; 259 | Helper.ThrowExceptionForHR(WlanNativeMethods.WlanHostedNetworkQuerySecondaryKey(wlanHandle, out keyLen, 260 | out passKey, out isPassPhrase, out isPersistent, out failReason, IntPtr.Zero)); 261 | return failReason; 262 | } 263 | 264 | public static WlanHostedNetworkReason SetSecondaryKey(string passKey, bool isPersistent = true) 265 | { 266 | WlanHostedNetworkReason failReason; 267 | Helper.ThrowExceptionForHR(WlanNativeMethods.WlanHostedNetworkSetSecondaryKey(wlanHandle, 268 | (uint)(passKey.Length + 1), Encoding.Default.GetBytes(passKey), true, isPersistent, out failReason, 269 | IntPtr.Zero)); 270 | return failReason; 271 | } 272 | public static WlanHostedNetworkReason SetSecondaryKey(byte[] passKey, bool isPersistent = true) 273 | { 274 | WlanHostedNetworkReason failReason; 275 | Helper.ThrowExceptionForHR(WlanNativeMethods.WlanHostedNetworkSetSecondaryKey(wlanHandle, 276 | 32, passKey, false, isPersistent, out failReason, IntPtr.Zero)); 277 | return failReason; 278 | } 279 | 280 | public static WlanHostedNetworkStatus QueryStatus() 281 | { 282 | IntPtr ptr; 283 | Helper.ThrowExceptionForHR(WlanNativeMethods.WlanHostedNetworkQueryStatus 284 | (wlanHandle, out ptr, IntPtr.Zero)); 285 | var netStat = Marshal.PtrToStructure(ptr); 286 | var stat = new WlanHostedNetworkStatus(); 287 | if ((stat.HostedNetworkState = netStat.HostedNetworkState) != WlanHostedNetworkState.Unavailable) 288 | { 289 | stat.IPDeviceID = netStat.IPDeviceID; 290 | stat.wlanHostedNetworkBSSID = netStat.wlanHostedNetworkBSSID; 291 | if (netStat.HostedNetworkState == WlanHostedNetworkState.Active) 292 | { 293 | stat.dot11PhyType = netStat.dot11PhyType; 294 | stat.ulChannelFrequency = netStat.ChannelFrequency; 295 | stat.dwNumberOfPeers = netStat.NumberOfPeers; 296 | stat.PeerList = new WlanHostedNetworkPeerState[stat.dwNumberOfPeers]; 297 | var offset = Marshal.SizeOf(typeof(WlanHostedNetworkStatusTemp)); 298 | for (var i = 0; i < netStat.NumberOfPeers; i++) offset += Marshal.SizeOf(stat.PeerList[i] = 299 | Marshal.PtrToStructure(new IntPtr(ptr.ToInt64() + offset))); 300 | } 301 | } 302 | return stat; 303 | } 304 | 305 | public static WlanHostedNetworkReason SetConnectionSettings(string hostedNetworkSsid, int maxNumberOfPeers) 306 | { 307 | WlanHostedNetworkReason failReason; 308 | var settings = new WlanHostedNetworkConnectionSettings 309 | { HostedNetworkSSID = ToDOT11_SSID(hostedNetworkSsid), MaxNumberOfPeers = (uint)maxNumberOfPeers }; 310 | var settingsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(settings)); 311 | Marshal.StructureToPtr(settings, settingsPtr, false); 312 | Helper.ThrowExceptionForHR(WlanNativeMethods.WlanHostedNetworkSetProperty(wlanHandle, 313 | WlanHostedNetworkOpcode.ConnectionSettings, 314 | (uint)Marshal.SizeOf(settings), settingsPtr, out failReason, IntPtr.Zero)); 315 | return failReason; 316 | } 317 | 318 | public static WlanHostedNetworkReason SetEnabled(bool enabled) 319 | { 320 | WlanHostedNetworkReason failReason; 321 | var settingsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(enabled)); 322 | Marshal.StructureToPtr(enabled, settingsPtr, false); 323 | Helper.ThrowExceptionForHR(WlanNativeMethods.WlanHostedNetworkSetProperty(wlanHandle, 324 | WlanHostedNetworkOpcode.Enable, 325 | (uint)Marshal.SizeOf(enabled), settingsPtr, out failReason, IntPtr.Zero)); 326 | return failReason; 327 | } 328 | 329 | public static WlanHostedNetworkReason RefreshSecuritySettings() 330 | { 331 | WlanHostedNetworkReason failReason; 332 | Helper.ThrowExceptionForHR 333 | (WlanNativeMethods.WlanHostedNetworkRefreshSecuritySettings(wlanHandle, out failReason, IntPtr.Zero)); 334 | return failReason; 335 | } 336 | 337 | public static WlanOpcodeValueType QueryConnectionSettings(out WlanHostedNetworkConnectionSettings settings) 338 | { 339 | uint dataSize; 340 | IntPtr dataPtr; 341 | WlanOpcodeValueType opcode; 342 | var hr = WlanNativeMethods.WlanHostedNetworkQueryProperty(wlanHandle, 343 | WlanHostedNetworkOpcode.ConnectionSettings, 344 | out dataSize, out dataPtr, out opcode, IntPtr.Zero); 345 | if (hr == 1610) throw new BadConfigurationException(); 346 | Helper.ThrowExceptionForHR(hr); 347 | settings = Marshal.PtrToStructure(dataPtr); 348 | return opcode; 349 | } 350 | 351 | public static WlanOpcodeValueType QuerySecuritySettings(out WlanHostedNetworkSecuritySettings settings) 352 | { 353 | uint dataSize; 354 | IntPtr dataPtr; 355 | WlanOpcodeValueType opcode; 356 | Helper.ThrowExceptionForHR(WlanNativeMethods.WlanHostedNetworkQueryProperty(wlanHandle, 357 | WlanHostedNetworkOpcode.SecuritySettings, 358 | out dataSize, out dataPtr, out opcode, IntPtr.Zero)); 359 | settings = Marshal.PtrToStructure(dataPtr); 360 | return opcode; 361 | } 362 | 363 | public static WlanOpcodeValueType QueryStationProfile(out string profile) 364 | { 365 | uint dataSize; 366 | IntPtr dataPtr; 367 | WlanOpcodeValueType opcode; 368 | var hr = WlanNativeMethods.WlanHostedNetworkQueryProperty(wlanHandle, 369 | WlanHostedNetworkOpcode.StationProfile, 370 | out dataSize, out dataPtr, out opcode, IntPtr.Zero); 371 | if (hr == 1610) throw new BadConfigurationException(); 372 | Helper.ThrowExceptionForHR(hr); 373 | profile = Marshal.PtrToStringUni(dataPtr, (int)(dataSize >> 1)); 374 | return opcode; 375 | } 376 | 377 | public static WlanOpcodeValueType QueryEnabled(out bool enabled) 378 | { 379 | uint dataSize; 380 | IntPtr dataPtr; 381 | WlanOpcodeValueType opcode; 382 | Helper.ThrowExceptionForHR(WlanNativeMethods.WlanHostedNetworkQueryProperty(wlanHandle, 383 | WlanHostedNetworkOpcode.Enable, 384 | out dataSize, out dataPtr, out opcode, IntPtr.Zero)); 385 | enabled = Marshal.PtrToStructure(dataPtr); 386 | return opcode; 387 | } 388 | } 389 | 390 | public sealed class BadConfigurationException : Win32Exception 391 | { 392 | public BadConfigurationException() 393 | : base(1610) 394 | { 395 | } 396 | } 397 | } -------------------------------------------------------------------------------- /MygodWifiShare/[References]/[TaskScheduler]/TaskService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.Runtime.InteropServices; 4 | 5 | namespace Microsoft.Win32.TaskScheduler 6 | { 7 | /// 8 | /// Provides access to the Task Scheduler service for managing registered tasks. 9 | /// 10 | [Description("Provides access to the Task Scheduler service.")] 11 | [ToolboxItem(true), DefaultProperty("TargetServer")] 12 | public sealed partial class TaskService : Component, IDisposable, ISupportInitialize 13 | { 14 | internal static readonly bool hasV2 = (Environment.OSVersion.Version >= new Version(6, 0)); 15 | internal static readonly Version v1Ver = new Version(1, 1); 16 | 17 | internal V1Interop.ITaskScheduler v1TaskScheduler = null; 18 | internal V2Interop.TaskSchedulerClass v2TaskService = null; 19 | 20 | private bool forceV1 = false; 21 | private bool initializing = false; 22 | private Version maxVer; 23 | private bool maxVerSet = false; 24 | private string targetServer = null; 25 | private bool targetServerSet = false; 26 | private string userDomain = null; 27 | private bool userDomainSet = false; 28 | private string userName = null; 29 | private bool userNameSet = false; 30 | private string userPassword = null; 31 | private bool userPasswordSet = false; 32 | private WindowsImpersonatedIdentity v1Impersonation = null; 33 | 34 | /// 35 | /// Creates a new instance of a TaskService connecting to the local machine as the current user. 36 | /// 37 | public TaskService() 38 | { 39 | ResetHighestSupportedVersion(); 40 | Connect(); 41 | } 42 | 43 | /// 44 | /// Initializes a new instance of the class. 45 | /// 46 | /// 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. 47 | /// The user name that is used during the connection to the computer. If the user is not specified, then the current token is used. 48 | /// The domain of the user specified in the parameter. 49 | /// The password that is used to connect to the computer. If the user name and password are not specified, then the current token is used. 50 | /// If set to true force Task Scheduler 1.0 compatibility. 51 | public TaskService(string targetServer, string userName = null, string accountDomain = null, string password = null, bool forceV1 = false) 52 | { 53 | this.BeginInit(); 54 | this.TargetServer = targetServer; 55 | this.UserName = userName; 56 | this.UserAccountDomain = accountDomain; 57 | this.UserPassword = password; 58 | this.forceV1 = forceV1; 59 | ResetHighestSupportedVersion(); 60 | this.EndInit(); 61 | } 62 | 63 | /// 64 | /// Gets a Boolean value that indicates if you are connected to the Task Scheduler service. 65 | /// 66 | [Browsable(false)] 67 | public bool Connected 68 | { 69 | get { return (v2TaskService != null && v2TaskService.Connected) || v1TaskScheduler != null; } 70 | } 71 | 72 | /// 73 | /// Gets the name of the domain to which the computer is connected. 74 | /// 75 | [Browsable(false)] 76 | [DefaultValue((string)null)] 77 | [Obsolete("This property has been superceded by the UserAccountDomin property and may not be available in future releases.")] 78 | public string ConnectedDomain 79 | { 80 | get 81 | { 82 | if (v2TaskService != null) 83 | return v2TaskService.ConnectedDomain; 84 | string[] parts = v1Impersonation.Name.Split('\\'); 85 | if (parts.Length == 2) 86 | return parts[0]; 87 | return string.Empty; 88 | } 89 | } 90 | 91 | /// 92 | /// Gets the name of the user that is connected to the Task Scheduler service. 93 | /// 94 | [Browsable(false)] 95 | [DefaultValue((string)null)] 96 | [Obsolete("This property has been superceded by the UserName property and may not be available in future releases.")] 97 | public string ConnectedUser 98 | { 99 | get 100 | { 101 | if (v2TaskService != null) 102 | return v2TaskService.ConnectedUser; 103 | string[] parts = v1Impersonation.Name.Split('\\'); 104 | if (parts.Length == 2) 105 | return parts[1]; 106 | return parts[0]; 107 | } 108 | } 109 | 110 | /// 111 | /// Gets the highest version of Task Scheduler that a computer supports. 112 | /// 113 | [Category("Data"), TypeConverter(typeof(VersionConverter)), Description("Highest version of library that should be used.")] 114 | public Version HighestSupportedVersion 115 | { 116 | get { return maxVer; } 117 | set 118 | { 119 | this.maxVer = value; 120 | this.maxVerSet = true; 121 | bool forceV1 = (value <= v1Ver); 122 | if (forceV1 != this.forceV1) 123 | { 124 | this.forceV1 = forceV1; 125 | Connect(); 126 | } 127 | } 128 | } 129 | 130 | /// 131 | /// Gets the root ("\") folder. For Task Scheduler 1.0, this is the only folder. 132 | /// 133 | [Browsable(false)] 134 | public TaskFolder RootFolder 135 | { 136 | get { return GetFolder(@"\"); } 137 | } 138 | 139 | /// 140 | /// Gets or sets the name of the computer that is running the Task Scheduler service that the user is connected to. 141 | /// 142 | [Category("Data"), DefaultValue((string)null), Description("The name of the computer to connect to.")] 143 | public string TargetServer 144 | { 145 | get { return ShouldSerializeTargetServer() ? targetServer : null; } 146 | set 147 | { 148 | if (value == null || value.Trim() == string.Empty) value = null; 149 | if (string.Compare(value, targetServer, true) != 0) 150 | { 151 | this.targetServerSet = true; 152 | targetServer = value; 153 | Connect(); 154 | } 155 | } 156 | } 157 | 158 | /// 159 | /// Gets or sets the user account domain to be used when connecting to the . 160 | /// 161 | /// The user account domain. 162 | [Category("Data"), DefaultValue((string)null), Description("The user account domain to be used when connecting.")] 163 | public string UserAccountDomain 164 | { 165 | get { return ShouldSerializeUserAccountDomain() ? userDomain : null; } 166 | set 167 | { 168 | if (value == null || value.Trim() == string.Empty) value = null; 169 | if (string.Compare(value, userDomain, true) != 0) 170 | { 171 | this.userDomainSet = true; 172 | userDomain = value; 173 | Connect(); 174 | } 175 | } 176 | } 177 | 178 | /// 179 | /// Gets or sets the user name to be used when connecting to the . 180 | /// 181 | /// The user name. 182 | [Category("Data"), DefaultValue((string)null), Description("The user name to be used when connecting.")] 183 | public string UserName 184 | { 185 | get { return ShouldSerializeUserName() ? userName : null; } 186 | set 187 | { 188 | if (value == null || value.Trim() == string.Empty) value = null; 189 | if (string.Compare(value, userName, true) != 0) 190 | { 191 | this.userNameSet = true; 192 | userName = value; 193 | Connect(); 194 | } 195 | } 196 | } 197 | 198 | /// 199 | /// Gets or sets the user password to be used when connecting to the . 200 | /// 201 | /// The user password. 202 | [Category("Data"), DefaultValue((string)null), Description("The user password to be used when connecting.")] 203 | public string UserPassword 204 | { 205 | get { return userPassword; } 206 | set 207 | { 208 | if (value == null || value.Trim() == string.Empty) value = null; 209 | if (string.Compare(value, userPassword, true) != 0) 210 | { 211 | this.userPasswordSet = true; 212 | userPassword = value; 213 | Connect(); 214 | } 215 | } 216 | } 217 | 218 | /// 219 | /// Gets a value indicating whether the component can raise an event. 220 | /// 221 | /// 222 | /// true if the component can raise events; otherwise, false. The default is true. 223 | /// 224 | protected override bool CanRaiseEvents 225 | { 226 | get { return false; } 227 | } 228 | 229 | /// 230 | /// Creates a new task, registers the taks, and returns the instance. 231 | /// 232 | /// The task name. If this value is NULL, the task will be registered in the root task folder and the task name will be a GUID value that is created by the Task Scheduler service. A task name cannot begin or end with a space character. The '.' character cannot be used to specify the current task folder and the '..' characters cannot be used to specify the parent task folder in the path. 233 | /// The to determine when to run the task. 234 | /// The to determine what happens when the task is triggered. 235 | /// The user credentials used to register the task. 236 | /// The password for the userId used to register the task. 237 | /// A value that defines what logon technique is used to run the registered task. 238 | /// 239 | /// A instance of the registered task. 240 | /// 241 | public Task AddTask(string path, Trigger trigger, Action action, string UserId = null, string Password = null, TaskLogonType LogonType = TaskLogonType.InteractiveToken) 242 | { 243 | TaskDefinition td = NewTask(); 244 | 245 | // Create a trigger that will fire the task at a specific date and time 246 | td.Triggers.Add(trigger); 247 | 248 | // Create an action that will launch Notepad whenever the trigger fires 249 | td.Actions.Add(action); 250 | 251 | // Register the task in the root folder 252 | return RootFolder.RegisterTaskDefinition(path, td, TaskCreation.CreateOrUpdate, UserId, Password, LogonType); 253 | } 254 | 255 | /// 256 | /// Finds all tasks matching a name or standard wildcards. 257 | /// 258 | /// Name of the task in regular expression form. 259 | /// if set to true search all sub folders. 260 | /// An array of containing all tasks matching . 261 | public Task[] FindAllTasks(System.Text.RegularExpressions.Regex name, bool searchAllFolders = true) 262 | { 263 | System.Collections.Generic.List results = new System.Collections.Generic.List(); 264 | FindTaskInFolder(this.RootFolder, name, ref results, searchAllFolders); 265 | return results.ToArray(); 266 | } 267 | 268 | /// 269 | /// Finds a task given a name and standard wildcards. 270 | /// 271 | /// The task name. This can include the wildcards * or ?. 272 | /// if set to true search all sub folders. 273 | /// A if one matches , otherwise NULL. 274 | public Task FindTask(string name, bool searchAllFolders = true) 275 | { 276 | Task[] results = FindAllTasks(new Wildcard(name), searchAllFolders); 277 | if (results.Length > 0) 278 | return results[0]; 279 | return null; 280 | } 281 | 282 | /// 283 | /// Gets the path to a folder of registered tasks. 284 | /// 285 | /// The path to the folder to retrieve. Do not use a backslash following the last folder name in the path. The root task folder is specified with a backslash (\). An example of a task folder path, under the root task folder, is \MyTaskFolder. The '.' character cannot be used to specify the current task folder and the '..' characters cannot be used to specify the parent task folder in the path. 286 | /// instance for the requested folder. 287 | /// Requested folder was not found. 288 | /// Folder other than the root (\) was requested on a system not supporting Task Scheduler 2.0. 289 | public TaskFolder GetFolder(string folderName) 290 | { 291 | return v2TaskService != null ? new TaskFolder(this, v2TaskService.GetFolder(folderName)) : new TaskFolder(this); 292 | } 293 | 294 | /// 295 | /// Gets a collection of running tasks. 296 | /// 297 | /// True to include hidden tasks. 298 | /// instance with the list of running tasks. 299 | public RunningTaskCollection GetRunningTasks(bool includeHidden = true) 300 | { 301 | return v2TaskService != null ? new RunningTaskCollection(this, v2TaskService.GetRunningTasks(includeHidden ? 1 : 0)) : new RunningTaskCollection(this); 302 | } 303 | 304 | /// 305 | /// Gets the task with the specified path. 306 | /// 307 | /// The task path. 308 | /// The task. 309 | public Task GetTask(string taskPath) 310 | { 311 | Task t = null; 312 | if (v2TaskService != null) 313 | { 314 | V2Interop.IRegisteredTask iTask = GetTask(this.v2TaskService, taskPath); 315 | if (iTask != null) 316 | t = Task.CreateTask(this, iTask); 317 | } 318 | else 319 | { 320 | V1Interop.ITask iTask = GetTask(this.v1TaskScheduler, taskPath); 321 | if (iTask != null) 322 | t = new Task(this, iTask); 323 | } 324 | return t; 325 | } 326 | 327 | /// 328 | /// Signals the object that initialization is starting. 329 | /// 330 | public void BeginInit() 331 | { 332 | initializing = true; 333 | } 334 | 335 | /// 336 | /// Signals the object that initialization is complete. 337 | /// 338 | public void EndInit() 339 | { 340 | initializing = false; 341 | Connect(); 342 | } 343 | 344 | /// 345 | /// Returns an empty task definition object to be filled in with settings and properties and then registered using the method. 346 | /// 347 | /// A instance for setting properties. 348 | public TaskDefinition NewTask() 349 | { 350 | if (v2TaskService != null) 351 | return new TaskDefinition(v2TaskService.NewTask(0)); 352 | Guid ITaskGuid = Marshal.GenerateGuidForType(typeof(V1Interop.ITask)); 353 | Guid CTaskGuid = Marshal.GenerateGuidForType(typeof(V1Interop.CTask)); 354 | string v1Name = "Temp" + Guid.NewGuid().ToString("B"); 355 | return new TaskDefinition(v1TaskScheduler.NewWorkItem(v1Name, ref CTaskGuid, ref ITaskGuid), v1Name); 356 | } 357 | 358 | /// 359 | /// Returns a populated with the properties defined in an XML file. 360 | /// 361 | /// The XML file to use as input. 362 | /// A instance. 363 | /// Importing from an XML file is only supported under Task Scheduler 2.0. 364 | public TaskDefinition NewTaskFromFile(string xmlFile) 365 | { 366 | if (v2TaskService != null) 367 | { 368 | TaskDefinition td = new TaskDefinition(v2TaskService.NewTask(0)); 369 | td.XmlText = System.IO.File.ReadAllText(xmlFile); 370 | return td; 371 | } 372 | throw new NotV1SupportedException(); 373 | } 374 | 375 | /// 376 | /// Starts the Task Scheduler UI for the OS hosting the assembly if the session is running in interactive mode. 377 | /// 378 | public void StartSystemTaskSchedulerManager() 379 | { 380 | if (System.Environment.UserInteractive) 381 | System.Diagnostics.Process.Start("control.exe", "schedtasks"); 382 | } 383 | 384 | internal static V2Interop.IRegisteredTask GetTask(V2Interop.ITaskService iSvc, string name) 385 | { 386 | V2Interop.ITaskFolder fld = null; 387 | try 388 | { 389 | fld = iSvc.GetFolder("\\"); 390 | return fld.GetTask(name); 391 | } 392 | catch 393 | { 394 | return null; 395 | } 396 | finally 397 | { 398 | if (fld != null) Marshal.ReleaseComObject(fld); 399 | } 400 | } 401 | 402 | internal static V1Interop.ITask GetTask(V1Interop.ITaskScheduler iSvc, string name) 403 | { 404 | Guid ITaskGuid = Marshal.GenerateGuidForType(typeof(V1Interop.ITask)); 405 | try { return iSvc.Activate(name, ref ITaskGuid); } catch {} 406 | return null; 407 | } 408 | 409 | /// 410 | /// Releases the unmanaged resources used by the and optionally releases the managed resources. 411 | /// 412 | /// true to release both managed and unmanaged resources; false to release only unmanaged resources. 413 | protected override void Dispose(bool disposing) 414 | { 415 | if (v2TaskService != null) 416 | { 417 | Marshal.ReleaseComObject(v2TaskService); 418 | v2TaskService = null; 419 | } 420 | if (v1TaskScheduler != null) 421 | { 422 | Marshal.ReleaseComObject(v1TaskScheduler); 423 | v1TaskScheduler = null; 424 | } 425 | if (v1Impersonation != null) 426 | { 427 | v1Impersonation.Dispose(); 428 | v1Impersonation = null; 429 | } 430 | base.Dispose(disposing); 431 | } 432 | 433 | /// 434 | /// Connects this instance of the class to a running Task Scheduler. 435 | /// 436 | private void Connect() 437 | { 438 | ResetUnsetProperties(); 439 | 440 | if (!initializing && !DesignMode) 441 | { 442 | if (((!string.IsNullOrEmpty(userDomain) && !string.IsNullOrEmpty(userName) && !string.IsNullOrEmpty(userPassword)) || 443 | (string.IsNullOrEmpty(userDomain) && string.IsNullOrEmpty(userName) && string.IsNullOrEmpty(userPassword)))) 444 | { 445 | // Clear stuff if already connected 446 | if (this.v2TaskService != null || this.v1TaskScheduler != null) 447 | this.Dispose(true); 448 | 449 | if (hasV2 && !forceV1) 450 | { 451 | v2TaskService = new V2Interop.TaskSchedulerClass(); 452 | if (!string.IsNullOrEmpty(targetServer)) 453 | { 454 | // Check to ensure character only server name. (Suggested by bigsan) 455 | if (targetServer.StartsWith(@"\")) 456 | targetServer = targetServer.TrimStart('\\'); 457 | // Make sure null is provided for local machine to compensate for a native library oddity (Found by ctrollen) 458 | if (targetServer.Equals(Environment.MachineName, StringComparison.CurrentCultureIgnoreCase)) 459 | targetServer = null; 460 | } 461 | v2TaskService.Connect(targetServer, userName, userDomain, userPassword); 462 | targetServer = v2TaskService.TargetServer; 463 | userName = v2TaskService.ConnectedUser; 464 | userDomain = v2TaskService.ConnectedDomain; 465 | maxVer = GetV2Version(); 466 | } 467 | else 468 | { 469 | v1Impersonation = new WindowsImpersonatedIdentity(userName, userDomain, userPassword); 470 | V1Interop.CTaskScheduler csched = new V1Interop.CTaskScheduler(); 471 | v1TaskScheduler = (V1Interop.ITaskScheduler)csched; 472 | if (!string.IsNullOrEmpty(targetServer)) 473 | { 474 | // Check to ensure UNC format for server name. (Suggested by bigsan) 475 | if (!targetServer.StartsWith(@"\\")) 476 | targetServer = @"\\" + targetServer; 477 | } 478 | else 479 | targetServer = null; 480 | v1TaskScheduler.SetTargetComputer(targetServer); 481 | targetServer = v1TaskScheduler.GetTargetComputer(); 482 | maxVer = v1Ver; 483 | } 484 | } 485 | else 486 | { 487 | throw new ArgumentException("A username, password, and domain must be provided."); 488 | } 489 | } 490 | } 491 | 492 | /// 493 | /// Finds the task in folder. 494 | /// 495 | /// The folder. 496 | /// The wildcard expression to compare task names with. 497 | /// The results. 498 | /// if set to true recurse folders. 499 | /// True if any tasks are found, False if not. 500 | private bool FindTaskInFolder(TaskFolder fld, System.Text.RegularExpressions.Regex taskName, ref System.Collections.Generic.List results, bool recurse = true) 501 | { 502 | results.AddRange(fld.GetTasks(taskName)); 503 | 504 | if (recurse) 505 | { 506 | foreach (var f in fld.SubFolders) 507 | { 508 | if (FindTaskInFolder(f, taskName, ref results, recurse)) 509 | return true; 510 | } 511 | } 512 | return false; 513 | } 514 | 515 | private Version GetV2Version() 516 | { 517 | uint v = v2TaskService.HighestVersion; 518 | return new Version((int)(v >> 16), (int)(v & 0x0000FFFF)); 519 | } 520 | 521 | private void ResetUnsetProperties() 522 | { 523 | if (!maxVerSet) ResetHighestSupportedVersion(); 524 | if (!targetServerSet) targetServer = null; 525 | if (!userDomainSet) userDomain = null; 526 | if (!userNameSet) userName = null; 527 | if (!userPasswordSet) userPassword = null; 528 | } 529 | 530 | private void ResetHighestSupportedVersion() 531 | { 532 | if (this.Connected) 533 | this.maxVer = v2TaskService != null ? GetV2Version() : v1Ver; 534 | else 535 | this.maxVer = hasV2 ? (Environment.OSVersion.Version.Minor > 0 ? new Version(1, 3) : new Version(1, 2)) : v1Ver; 536 | } 537 | 538 | private bool ShouldSerializeHighestSupportedVersion() 539 | { 540 | return (hasV2 && maxVer <= v1Ver); 541 | } 542 | 543 | private bool ShouldSerializeTargetServer() 544 | { 545 | return targetServer != null && !targetServer.Trim('\\').Equals(System.Environment.MachineName.Trim('\\'), StringComparison.InvariantCultureIgnoreCase); 546 | } 547 | 548 | private bool ShouldSerializeUserAccountDomain() 549 | { 550 | return userDomain != null && !userDomain.Equals(System.Environment.UserDomainName, StringComparison.InvariantCultureIgnoreCase); 551 | } 552 | 553 | private bool ShouldSerializeUserName() 554 | { 555 | return userName != null && !userName.Equals(System.Environment.UserName, StringComparison.InvariantCultureIgnoreCase); 556 | } 557 | 558 | private class VersionConverter : TypeConverter 559 | { 560 | public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) 561 | { 562 | if (sourceType == typeof(string)) 563 | return true; 564 | return base.CanConvertFrom(context, sourceType); 565 | } 566 | 567 | public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) 568 | { 569 | if (value is string) 570 | return new Version(value as string); 571 | return base.ConvertFrom(context, culture, value); 572 | } 573 | } 574 | } 575 | } --------------------------------------------------------------------------------