├── 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 | }
--------------------------------------------------------------------------------