winpeasv1

This commit is contained in:
carlospolop 2020-08-06 00:12:41 +01:00
parent 3d0f4749bf
commit e47619321d
224 changed files with 127663 additions and 88863 deletions

View File

@ -0,0 +1,343 @@
<?xml version="1.0" encoding="utf-8"?>
<RuleSet Name="New Rule Set" Description=" " ToolsVersion="16.0">
<Rules AnalyzerId="Microsoft.Analyzers.ManagedCodeAnalysis" RuleNamespace="Microsoft.Rules.Managed">
<Rule Id="CA1801" Action="Warning" />
<Rule Id="CA1804" Action="Warning" />
<Rule Id="CA1811" Action="Warning" />
<Rule Id="CA1812" Action="Warning" />
<Rule Id="CA1823" Action="Warning" />
</Rules>
<Rules AnalyzerId="Microsoft.CodeAnalysis.CSharp" RuleNamespace="Microsoft.CodeAnalysis.CSharp">
<Rule Id="AD0001" Action="None" />
<Rule Id="CS0078" Action="None" />
<Rule Id="CS0105" Action="None" />
<Rule Id="CS0108" Action="None" />
<Rule Id="CS0109" Action="None" />
<Rule Id="CS0114" Action="None" />
<Rule Id="CS0162" Action="None" />
<Rule Id="CS0164" Action="None" />
<Rule Id="CS0168" Action="None" />
<Rule Id="CS0183" Action="None" />
<Rule Id="CS0184" Action="None" />
<Rule Id="CS0197" Action="None" />
<Rule Id="CS0219" Action="None" />
<Rule Id="CS0251" Action="None" />
<Rule Id="CS0252" Action="None" />
<Rule Id="CS0253" Action="None" />
<Rule Id="CS0278" Action="None" />
<Rule Id="CS0279" Action="None" />
<Rule Id="CS0280" Action="None" />
<Rule Id="CS0282" Action="None" />
<Rule Id="CS0419" Action="None" />
<Rule Id="CS0420" Action="None" />
<Rule Id="CS0435" Action="None" />
<Rule Id="CS0436" Action="None" />
<Rule Id="CS0437" Action="None" />
<Rule Id="CS0440" Action="None" />
<Rule Id="CS0458" Action="None" />
<Rule Id="CS0464" Action="None" />
<Rule Id="CS0465" Action="None" />
<Rule Id="CS0469" Action="None" />
<Rule Id="CS0472" Action="None" />
<Rule Id="CS0473" Action="None" />
<Rule Id="CS0612" Action="None" />
<Rule Id="CS0618" Action="None" />
<Rule Id="CS0626" Action="None" />
<Rule Id="CS0628" Action="None" />
<Rule Id="CS0642" Action="None" />
<Rule Id="CS0652" Action="None" />
<Rule Id="CS0657" Action="None" />
<Rule Id="CS0658" Action="None" />
<Rule Id="CS0659" Action="None" />
<Rule Id="CS0660" Action="None" />
<Rule Id="CS0661" Action="None" />
<Rule Id="CS0665" Action="None" />
<Rule Id="CS0672" Action="None" />
<Rule Id="CS0675" Action="None" />
<Rule Id="CS0684" Action="None" />
<Rule Id="CS0693" Action="None" />
<Rule Id="CS0728" Action="None" />
<Rule Id="CS0809" Action="None" />
<Rule Id="CS0811" Action="None" />
<Rule Id="CS0824" Action="None" />
<Rule Id="CS1030" Action="None" />
<Rule Id="CS1058" Action="None" />
<Rule Id="CS1062" Action="None" />
<Rule Id="CS1064" Action="None" />
<Rule Id="CS1066" Action="None" />
<Rule Id="CS1072" Action="None" />
<Rule Id="CS1522" Action="None" />
<Rule Id="CS1570" Action="None" />
<Rule Id="CS1571" Action="None" />
<Rule Id="CS1572" Action="None" />
<Rule Id="CS1573" Action="None" />
<Rule Id="CS1574" Action="None" />
<Rule Id="CS1580" Action="None" />
<Rule Id="CS1581" Action="None" />
<Rule Id="CS1584" Action="None" />
<Rule Id="CS1587" Action="None" />
<Rule Id="CS1589" Action="None" />
<Rule Id="CS1590" Action="None" />
<Rule Id="CS1591" Action="None" />
<Rule Id="CS1592" Action="None" />
<Rule Id="CS1616" Action="None" />
<Rule Id="CS1633" Action="None" />
<Rule Id="CS1634" Action="None" />
<Rule Id="CS1635" Action="None" />
<Rule Id="CS1645" Action="None" />
<Rule Id="CS1658" Action="None" />
<Rule Id="CS1668" Action="None" />
<Rule Id="CS1685" Action="None" />
<Rule Id="CS1687" Action="None" />
<Rule Id="CS1690" Action="None" />
<Rule Id="CS1692" Action="None" />
<Rule Id="CS1695" Action="None" />
<Rule Id="CS1696" Action="None" />
<Rule Id="CS1697" Action="None" />
<Rule Id="CS1700" Action="None" />
<Rule Id="CS1701" Action="None" />
<Rule Id="CS1702" Action="None" />
<Rule Id="CS1710" Action="None" />
<Rule Id="CS1711" Action="None" />
<Rule Id="CS1712" Action="None" />
<Rule Id="CS1717" Action="None" />
<Rule Id="CS1718" Action="None" />
<Rule Id="CS1720" Action="None" />
<Rule Id="CS1723" Action="None" />
<Rule Id="CS1734" Action="None" />
<Rule Id="CS1735" Action="None" />
<Rule Id="CS1762" Action="None" />
<Rule Id="CS1927" Action="None" />
<Rule Id="CS1956" Action="None" />
<Rule Id="CS1957" Action="None" />
<Rule Id="CS1974" Action="None" />
<Rule Id="CS1981" Action="None" />
<Rule Id="CS1998" Action="None" />
<Rule Id="CS2002" Action="None" />
<Rule Id="CS2008" Action="None" />
<Rule Id="CS2023" Action="None" />
<Rule Id="CS2029" Action="None" />
<Rule Id="CS2038" Action="None" />
<Rule Id="CS3000" Action="None" />
<Rule Id="CS3001" Action="None" />
<Rule Id="CS3002" Action="None" />
<Rule Id="CS3003" Action="None" />
<Rule Id="CS3005" Action="None" />
<Rule Id="CS3006" Action="None" />
<Rule Id="CS3007" Action="None" />
<Rule Id="CS3008" Action="None" />
<Rule Id="CS3009" Action="None" />
<Rule Id="CS3010" Action="None" />
<Rule Id="CS3011" Action="None" />
<Rule Id="CS3012" Action="None" />
<Rule Id="CS3013" Action="None" />
<Rule Id="CS3014" Action="None" />
<Rule Id="CS3015" Action="None" />
<Rule Id="CS3016" Action="None" />
<Rule Id="CS3017" Action="None" />
<Rule Id="CS3018" Action="None" />
<Rule Id="CS3019" Action="None" />
<Rule Id="CS3021" Action="None" />
<Rule Id="CS3022" Action="None" />
<Rule Id="CS3023" Action="None" />
<Rule Id="CS3024" Action="None" />
<Rule Id="CS3026" Action="None" />
<Rule Id="CS3027" Action="None" />
<Rule Id="CS4014" Action="None" />
<Rule Id="CS4024" Action="None" />
<Rule Id="CS4025" Action="None" />
<Rule Id="CS4026" Action="None" />
<Rule Id="CS7033" Action="None" />
<Rule Id="CS7035" Action="None" />
<Rule Id="CS7080" Action="None" />
<Rule Id="CS7081" Action="None" />
<Rule Id="CS7082" Action="None" />
<Rule Id="CS7090" Action="None" />
<Rule Id="CS7095" Action="None" />
<Rule Id="CS8001" Action="None" />
<Rule Id="CS8002" Action="None" />
<Rule Id="CS8009" Action="None" />
<Rule Id="CS8012" Action="None" />
<Rule Id="CS8018" Action="None" />
<Rule Id="CS8019" Action="None" />
<Rule Id="CS8021" Action="None" />
<Rule Id="CS8029" Action="None" />
<Rule Id="CS8032" Action="None" />
<Rule Id="CS8033" Action="None" />
<Rule Id="CS8034" Action="None" />
<Rule Id="CS8040" Action="None" />
<Rule Id="CS8073" Action="None" />
<Rule Id="CS8094" Action="None" />
<Rule Id="CS8105" Action="None" />
<Rule Id="CS8123" Action="None" />
<Rule Id="CS8305" Action="None" />
<Rule Id="CS8321" Action="None" />
<Rule Id="CS8359" Action="None" />
<Rule Id="CS8360" Action="None" />
<Rule Id="CS8371" Action="None" />
<Rule Id="CS8383" Action="None" />
<Rule Id="CS8387" Action="None" />
<Rule Id="CS8424" Action="None" />
<Rule Id="CS8425" Action="None" />
<Rule Id="CS8509" Action="None" />
<Rule Id="CS8512" Action="None" />
<Rule Id="CS8513" Action="None" />
<Rule Id="CS8519" Action="None" />
<Rule Id="CS8520" Action="None" />
<Rule Id="CS8597" Action="None" />
<Rule Id="CS8600" Action="None" />
<Rule Id="CS8601" Action="None" />
<Rule Id="CS8602" Action="None" />
<Rule Id="CS8603" Action="None" />
<Rule Id="CS8604" Action="None" />
<Rule Id="CS8605" Action="None" />
<Rule Id="CS8606" Action="None" />
<Rule Id="CS8607" Action="None" />
<Rule Id="CS8608" Action="None" />
<Rule Id="CS8609" Action="None" />
<Rule Id="CS8610" Action="None" />
<Rule Id="CS8611" Action="None" />
<Rule Id="CS8612" Action="None" />
<Rule Id="CS8613" Action="None" />
<Rule Id="CS8614" Action="None" />
<Rule Id="CS8615" Action="None" />
<Rule Id="CS8616" Action="None" />
<Rule Id="CS8617" Action="None" />
<Rule Id="CS8618" Action="None" />
<Rule Id="CS8619" Action="None" />
<Rule Id="CS8620" Action="None" />
<Rule Id="CS8621" Action="None" />
<Rule Id="CS8622" Action="None" />
<Rule Id="CS8624" Action="None" />
<Rule Id="CS8625" Action="None" />
<Rule Id="CS8626" Action="None" />
<Rule Id="CS8629" Action="None" />
<Rule Id="CS8631" Action="None" />
<Rule Id="CS8632" Action="None" />
<Rule Id="CS8633" Action="None" />
<Rule Id="CS8634" Action="None" />
<Rule Id="CS8638" Action="None" />
<Rule Id="CS8643" Action="None" />
<Rule Id="CS8644" Action="None" />
<Rule Id="CS8645" Action="None" />
<Rule Id="CS8653" Action="None" />
<Rule Id="CS8654" Action="None" />
<Rule Id="CS8655" Action="None" />
<Rule Id="CS8656" Action="None" />
<Rule Id="CS8667" Action="None" />
<Rule Id="CS8714" Action="None" />
</Rules>
<Rules AnalyzerId="Microsoft.CodeAnalysis.CSharp.Features" RuleNamespace="Microsoft.CodeAnalysis.CSharp.Features">
<Rule Id="IDE0001" Action="None" />
<Rule Id="IDE0002" Action="None" />
<Rule Id="IDE0003" Action="None" />
<Rule Id="IDE0003WithoutSuggestion" Action="None" />
<Rule Id="IDE0004" Action="None" />
<Rule Id="IDE0004WithoutSuggestion" Action="None" />
<Rule Id="IDE0005" Action="None" />
<Rule Id="IDE0007" Action="None" />
<Rule Id="IDE0007WithoutSuggestion" Action="None" />
<Rule Id="IDE0008" Action="None" />
<Rule Id="IDE0008WithoutSuggestion" Action="None" />
<Rule Id="IDE0009" Action="None" />
<Rule Id="IDE0009WithoutSuggestion" Action="None" />
<Rule Id="IDE0011" Action="None" />
<Rule Id="IDE0011WithoutSuggestion" Action="None" />
<Rule Id="IDE0016" Action="None" />
<Rule Id="IDE0016WithoutSuggestion" Action="None" />
<Rule Id="IDE0017" Action="None" />
<Rule Id="IDE0017WithoutSuggestion" Action="None" />
<Rule Id="IDE0018" Action="None" />
<Rule Id="IDE0018WithoutSuggestion" Action="None" />
<Rule Id="IDE0019" Action="None" />
<Rule Id="IDE0019WithoutSuggestion" Action="None" />
<Rule Id="IDE0020" Action="None" />
<Rule Id="IDE0020WithoutSuggestion" Action="None" />
<Rule Id="IDE0021" Action="None" />
<Rule Id="IDE0022" Action="None" />
<Rule Id="IDE0023" Action="None" />
<Rule Id="IDE0024" Action="None" />
<Rule Id="IDE0025" Action="None" />
<Rule Id="IDE0026" Action="None" />
<Rule Id="IDE0027" Action="None" />
<Rule Id="IDE0028" Action="None" />
<Rule Id="IDE0028WithoutSuggestion" Action="None" />
<Rule Id="IDE0029" Action="None" />
<Rule Id="IDE0029WithoutSuggestion" Action="None" />
<Rule Id="IDE0030" Action="None" />
<Rule Id="IDE0030WithoutSuggestion" Action="None" />
<Rule Id="IDE0031" Action="None" />
<Rule Id="IDE0031WithoutSuggestion" Action="None" />
<Rule Id="IDE0032" Action="None" />
<Rule Id="IDE0032WithoutSuggestion" Action="None" />
<Rule Id="IDE0034" Action="None" />
<Rule Id="IDE0034WithoutSuggestion" Action="None" />
<Rule Id="IDE0035" Action="None" />
<Rule Id="IDE0035WithoutSuggestion" Action="None" />
<Rule Id="IDE0036" Action="None" />
<Rule Id="IDE0036WithoutSuggestion" Action="None" />
<Rule Id="IDE0037" Action="None" />
<Rule Id="IDE0037WithoutSuggestion" Action="None" />
<Rule Id="IDE0039" Action="None" />
<Rule Id="IDE0039WithoutSuggestion" Action="None" />
<Rule Id="IDE0040" Action="None" />
<Rule Id="IDE0040WithoutSuggestion" Action="None" />
<Rule Id="IDE0041" Action="None" />
<Rule Id="IDE0041WithoutSuggestion" Action="None" />
<Rule Id="IDE0042" Action="None" />
<Rule Id="IDE0042WithoutSuggestion" Action="None" />
<Rule Id="IDE0043" Action="None" />
<Rule Id="IDE0045" Action="None" />
<Rule Id="IDE0045WithoutSuggestion" Action="None" />
<Rule Id="IDE0046" Action="None" />
<Rule Id="IDE0046WithoutSuggestion" Action="None" />
<Rule Id="IDE0047" Action="None" />
<Rule Id="IDE0048" Action="None" />
<Rule Id="IDE0048WithoutSuggestion" Action="None" />
<Rule Id="IDE0049" Action="None" />
<Rule Id="IDE0049WithoutSuggestion" Action="None" />
<Rule Id="IDE0050" Action="None" />
<Rule Id="IDE0050WithoutSuggestion" Action="None" />
<Rule Id="IDE0051" Action="None" />
<Rule Id="IDE0052" Action="None" />
<Rule Id="IDE0053" Action="None" />
<Rule Id="IDE0053WithoutSuggestion" Action="None" />
<Rule Id="IDE0054" Action="None" />
<Rule Id="IDE0054WithoutSuggestion" Action="None" />
<Rule Id="IDE0056" Action="None" />
<Rule Id="IDE0056WithoutSuggestion" Action="None" />
<Rule Id="IDE0057" Action="None" />
<Rule Id="IDE0057WithoutSuggestion" Action="None" />
<Rule Id="IDE0058" Action="None" />
<Rule Id="IDE0059" Action="None" />
<Rule Id="IDE0060" Action="None" />
<Rule Id="IDE0061" Action="None" />
<Rule Id="IDE0062" Action="None" />
<Rule Id="IDE0062WithoutSuggestion" Action="None" />
<Rule Id="IDE0063" Action="None" />
<Rule Id="IDE0063WithoutSuggestion" Action="None" />
<Rule Id="IDE0064" Action="None" />
<Rule Id="IDE0065" Action="None" />
<Rule Id="IDE0066" Action="None" />
<Rule Id="IDE0066WithoutSuggestion" Action="None" />
<Rule Id="IDE1005" Action="None" />
<Rule Id="IDE1005WithoutSuggestion" Action="None" />
<Rule Id="IDE1006" Action="None" />
<Rule Id="IDE1006WithoutSuggestion" Action="None" />
<Rule Id="RE0001" Action="None" />
<Rule Id="RE0001WithoutSuggestion" Action="None" />
</Rules>
<Rules AnalyzerId="Microsoft.CodeAnalysis.Features" RuleNamespace="Microsoft.CodeAnalysis.Features">
<Rule Id="IDE0010" Action="None" />
<Rule Id="IDE0010WithoutSuggestion" Action="None" />
<Rule Id="IDE0033" Action="None" />
<Rule Id="IDE0033WithoutSuggestion" Action="None" />
<Rule Id="IDE0044" Action="None" />
<Rule Id="IDE0044WithoutSuggestion" Action="None" />
<Rule Id="IDE0055" Action="None" />
<Rule Id="IDE0055WithoutSuggestion" Action="None" />
<Rule Id="IDE0067" Action="None" />
<Rule Id="IDE0068" Action="None" />
<Rule Id="IDE0069" Action="None" />
</Rules>
</RuleSet>

View File

@ -12,8 +12,8 @@ Check also the **Local Windows Privilege Escalation checklist** from **[book.hac
Download the **[latest obfuscated version from here](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/winPEAS/winPEASexe/winPEAS/bin/Obfuscated%20Releases)** or **compile it yourself** (read instructions for compilation).
```bash
winpeas.exe cmd searchall searchfast #cmd commands, search all filenames and avoid sleepig (noisy - CTFs)
winpeas.exe #Will execute all checks except the ones that use a CMD
winpeas.exe cmd searchall #cmd commands, search all filenames and avoid sleepig (noisy - CTFs)
winpeas.exe #Will execute all checks except the ones that use external Windows binaries
winpeas.exe cmd #All checks
winpeas.exe systeminfo userinfo #Only systeminfo and userinfo checks executed
winpeas.exe notcolor #Do not color the output
@ -52,11 +52,11 @@ To use **dotfuscator** you will need to **create an account** *(they will send y
Once you have installed and activated it you need to:
1. **Compile** winpeas in VisualStudio
2. **Open dotfuscator** app
3. **Open** in dotfuscator **winPEAS.exe compiled** before and **Microsoft.Win32.TaskScheduler.dll** (is in the same folder as winPEAS.exe)
3. **Open** in dotfuscator **winPEAS.exe compiled**
4. Click on **Build**
5. The **single, minimized and obfuscated binary** will appear in a **folder called Dotfuscator inside the folder were winPEAS.exe** and the DLL were (this location will be saved by dotfuscator and by default all the following builds will appear in this folder).
**I'm sorry that all of this is necessary but is worth it. Dotfuscator minimizes the size of the executable and obfuscates the code** (F\*\*k you Defender).
**I'm sorry that all of this is necessary but is worth it. Dotfuscator minimizes a bit the size of the executable and obfuscates the code**.
![](https://raw.githubusercontent.com/carlospolop/privilege-escalation-awesome-scripts-suite/master/winPEAS/winPEASexe/images/dotfuscator.PNG)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 64 KiB

View File

@ -2,5 +2,5 @@
<configuration>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/></startup>
</configuration>

View File

@ -2,8 +2,10 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Management;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using Microsoft.Win32;
using Microsoft.Win32.TaskScheduler;
@ -31,7 +33,7 @@ namespace winPEAS
return null;
}
public static List<string> GetAppsRegistry()
/*public static List<string> GetAppsRegistry()
{
List<string> retList = new List<string>();
try
@ -47,7 +49,7 @@ namespace winPEAS
Beaprint.GrayPrint("Error: "+ex);
}
return retList;
}
}*/
public static SortedDictionary<string, Dictionary<string, string>> GetInstalledAppsPermsPath(string fpath)
{
@ -145,6 +147,224 @@ namespace winPEAS
return results;
}
//////////////////////////////////////
/////// Get Autorun Registry ////////
//////////////////////////////////////
/// Find Autorun registry where you have write or equivalent access
public static List<Dictionary<string, string>> GetRegistryAutoRuns(Dictionary<string, string> NtAccountNames)
{
List<Dictionary<string, string>> results = new List<Dictionary<string, string>>();
try
{
List<List<String>> autorunLocations = new List<List<string>>()
{
//Common Autoruns
new List<String> {"HKLM","SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run"},
new List<String> {"HKLM","SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce"},
new List<String> {"HKLM","SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Run"},
new List<String> {"HKLM","SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\RunOnce"},
new List<String> {"HKCU","SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run"},
new List<String> {"HKCU","SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce"},
new List<String> {"HKCU","SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Run"},
new List<String> {"HKCU","SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\RunOnce"},
new List<String> {"HKLM",@"Software\Microsoft\Windows NT\CurrentVersion\Terminal Server\Install\Software\Microsoft\Windows\CurrentVersion\Run"},
new List<String> {"HKLM",@"Software\Microsoft\Windows NT\CurrentVersion\Terminal Server\Install\Software\Microsoft\Windows\CurrentVersion\Runonce"},
new List<String> {"HKLM",@"Software\Microsoft\Windows NT\CurrentVersion\Terminal Server\Install\Software\Microsoft\Windows\CurrentVersion\RunEx"},
//Service Autoruns
new List<String> {"HKLM","SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunService"},
new List<String> {"HKLM","SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnceService"},
new List<String> {"HKLM","SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\RunService"},
new List<String> {"HKLM","SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\RunOnceService"},
new List<String> {"HKCU", "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunService"},
new List<String> {"HKCU", "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnceService"},
new List<String> {"HKCU", "SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\RunService"},
new List<String> {"HKCU", "SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\RunOnceService"},
//Special Autorun
new List<String> {"HKLM","Software\\Microsoft\\Windows\\CurrentVersion\\RunOnceEx"},
new List<String> {"HKLM","Software\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\RunOnceEx"},
new List<String> {"HKCU","Software\\Microsoft\\Windows\\CurrentVersion\\RunOnceEx"},
new List<String> {"HKCU","Software\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\RunOnceEx"},
//Startup Path
new List<String> {"HKCU", @"Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders", "Common Startup"},
new List<String> {"HKCU", @"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders", "Common Startup"},
new List<String> {"HKLM", @"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders", "Common Startup"},
new List<String> {"HKLM", @"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders", "Common Startup"},
//Winlogon
new List<String> {"HKLM", @"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon", "Userinit"},
new List<String> {"HKLM", @"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon", "Shell"},
//Policy Settings
new List<String> {"HKLM", @"Software\Microsoft\Windows\CurrentVersion\Policies\Explorer", "Run"},
new List<String> {"HKCU", @"Software\Microsoft\Windows\CurrentVersion\Policies\Explorer", "Run"},
//AlternateShell in SafeBoot
new List<String> {"HKLM","SYSTEM\\CurrentControlSet\\Control\\SafeBoot", "AlternateShell"},
//Font Drivers
new List<String> {"HKLM", @"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Font Drivers"},
new List<String> {"HKLM", @"SOFTWARE\WOW6432Node\Microsoft\Windows NT\CurrentVersion\Font Drivers"},
//Open Command
new List<String> {"HKLM", @"SOFTWARE\Classes\htmlfile\shell\open\command", ""}, //Get (Default) value with empty string
new List<String> {"HKLM", @"SOFTWARE\Wow6432Node\Classes\htmlfile\shell\open\command", ""}, //Get (Default) value with empty string
};
List<List<String>> autorunLocationsKeys = new List<List<String>>
{
//Installed Components
new List<String> { "HKLM","SOFTWARE\\Microsoft\\Active Setup\\Installed Components", "StubPath"},
new List<String> { "HKLM","SOFTWARE\\Wow6432Node\\Microsoft\\Active Setup\\Installed Components", "StubPath"},
new List<String> { "HKCU","SOFTWARE\\Microsoft\\Active Setup\\Installed Components", "StubPath"},
new List<String> { "HKCU","SOFTWARE\\Wow6432Node\\Microsoft\\Active Setup\\Installed Components", "StubPath"},
};
//This registry expect subkeys with the CLSID name
List<List<String>> autorunLocationsKeysCLSIDs = new List<List<String>>
{
//Browser Helper Objects
new List<String> { "HKLM", @"Software\Microsoft\Windows\CurrentVersion\Explorer\Browser Helper Objects" },
new List<String> { "HKLM", @"Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Explorer\Browser Helper Objects" },
//Internet Explorer Extensions
new List<String> { "HKLM", @"Software\Microsoft\Internet Explorer\Extensions" },
new List<String> { "HKLM", @"Software\Wow6432Node\Microsoft\Internet Explorer\Extensions" },
};
//Add the keyvalues inside autorunLocationsKeys to autorunLocations
foreach (List<String> autorunLocationKey in autorunLocationsKeys)
{
List<String> subkeys = MyUtils.GetRegSubkeys(autorunLocationKey[0], autorunLocationKey[1]).ToList();
foreach (String keyname in subkeys)
{
string clsid_name = keyname;
Match clsid = Regex.Match(keyname, @"^\W*(\{[\w\-]+\})\W*");
if (clsid.Groups.Count > 1) //Sometime the CLSID is bad writting and this kind of fix common mistakes
clsid_name = clsid.Groups[1].ToString();
if (autorunLocationKey.Count > 2)
autorunLocations.Add(new List<string> { autorunLocationKey[0], autorunLocationKey[1] + "\\" + clsid_name, autorunLocationKey[2] });
else
autorunLocations.Add(new List<string> { autorunLocationKey[0], autorunLocationKey[1] + "\\" + clsid_name });
}
}
//Read registry and get values
foreach (List<String> autorunLocation in autorunLocations)
{
Dictionary<string, object> settings = MyUtils.GetRegValues(autorunLocation[0], autorunLocation[1]);
if ((settings != null) && (settings.Count != 0))
{
foreach (KeyValuePair<string, object> kvp in settings)
{
RegistryKey key = null;
if ("HKLM" == autorunLocation[0])
key = Registry.LocalMachine.OpenSubKey(autorunLocation[1]);
else
key = Registry.CurrentUser.OpenSubKey(autorunLocation[1]);
if (autorunLocation.Count > 2 && kvp.Key != autorunLocation[2])
continue; //If only interested on 1 key of the registry and it's that one, continue
string orig_filepath = Environment.ExpandEnvironmentVariables(String.Format("{0}", kvp.Value));
string filepath = orig_filepath;
if (MyUtils.GetExecutableFromPath(Environment.ExpandEnvironmentVariables(String.Format("{0}", kvp.Value))).Length > 0)
filepath = MyUtils.GetExecutableFromPath(filepath);
string filepath_cleaned = filepath.Replace("'", "").Replace("\"", "");
string folder = System.IO.Path.GetDirectoryName(filepath_cleaned);
try
{ //If the path doesn't exist, pass
if (File.GetAttributes(filepath_cleaned).HasFlag(FileAttributes.Directory))
{ //If the path is already a folder, change the values of the params
orig_filepath = "";
folder = filepath_cleaned;
}
}
catch
{
}
results.Add(new Dictionary<string, string>()
{
{"Reg", autorunLocation[0] + "\\" + autorunLocation[1]},
{"RegKey", kvp.Key},
{"Folder", folder},
{"File", orig_filepath},
{
"RegPermissions",
string.Join(", ", MyUtils.GetMyPermissionsR(key, Program.currentUserSIDs))
},
{
"interestingFolderRights",
String.Join(", ", MyUtils.GetPermissionsFolder(folder, Program.currentUserSIDs))
},
{
"interestingFileRights",
orig_filepath.Length > 1 ? String.Join(", ", MyUtils.GetPermissionsFile(orig_filepath, Program.currentUserSIDs)) : ""
},
{"isUnquotedSpaced", MyUtils.CheckQuoteAndSpace(filepath).ToString()}
});
}
}
}
//Check the autoruns that depends on CLSIDs
foreach (List<String> autorunLocation in autorunLocationsKeysCLSIDs)
{
List<String> CLSIDs = MyUtils.GetRegSubkeys(autorunLocation[0], autorunLocation[1]).ToList();
foreach (String clsid in CLSIDs)
{
string reg = autorunLocation[1] + "\\" + clsid;
RegistryKey key = null;
if ("HKLM" == autorunLocation[0])
key = Registry.LocalMachine.OpenSubKey(reg);
else
key = Registry.CurrentUser.OpenSubKey(reg);
string orig_filepath = MyUtils.GetCLSIDBinPath(clsid);
if (String.IsNullOrEmpty(orig_filepath))
continue;
orig_filepath = Environment.ExpandEnvironmentVariables(orig_filepath).Replace("'", "").Replace("\"", "");
string folder = System.IO.Path.GetDirectoryName(orig_filepath);
results.Add(new Dictionary<string, string>()
{
{"Reg", autorunLocation[0] + "\\" + reg},
{"RegKey", ""},
{"Folder", folder},
{"File", orig_filepath},
{
"RegPermissions",
string.Join(", ", MyUtils.GetMyPermissionsR(key , Program.currentUserSIDs))
},
{
"interestingFolderRights",
String.Join(", ", MyUtils.GetPermissionsFolder(folder, Program.currentUserSIDs))
},
{
"interestingFileRights",
orig_filepath.Length > 1 ? String.Join(", ", MyUtils.GetPermissionsFile(orig_filepath, Program.currentUserSIDs)) : ""
},
{"isUnquotedSpaced", MyUtils.CheckQuoteAndSpace(orig_filepath).ToString()}
});
}
}
}
catch (Exception ex)
{
Beaprint.GrayPrint(String.Format(" [X] Exception: {0}", ex.Message));
}
return results;
}
public static List<Dictionary<string, string>> GetAutoRunsFolder()
{
List<Dictionary<string, string>> results = new List<Dictionary<string, string>>();
@ -159,6 +379,8 @@ namespace winPEAS
string folder = Path.GetDirectoryName(filepath);
results.Add(new Dictionary<string, string>() {
{ "Reg", "" },
{ "RegKey", "" },
{ "RegPermissions", "" },
{ "Folder", folder },
{ "File", filepath },
{ "isWritableReg", ""},
@ -171,11 +393,55 @@ namespace winPEAS
return results;
}
public static List<Dictionary<string, string>> GetAutoRunsWMIC()
{
List<Dictionary<string, string>> results = new List<Dictionary<string, string>>();
try
{
SelectQuery query = new SelectQuery("Win32_StartupCommand");
ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
ManagementObjectCollection win32_startup = searcher.Get();
foreach (ManagementObject startup in win32_startup)
{
string command = startup["command"].ToString();
command = Environment.ExpandEnvironmentVariables(String.Format("{0}", command));
string filepath = MyUtils.GetExecutableFromPath(command);
string filepath_cleaned = filepath.Replace("'", "").Replace("\"", "");
string folder = System.IO.Path.GetDirectoryName(filepath_cleaned);
results.Add(new Dictionary<string, string>()
{
{"Reg", ""},
{"RegKey", "From WMIC"},
{"RegPermissions", ""},
{"Folder", folder},
{"File", command},
{"isWritableReg", ""},
{
"interestingFolderRights",
String.Join(", ", MyUtils.GetPermissionsFolder(folder, Program.currentUserSIDs))
},
{
"interestingFileRights",
String.Join(", ", MyUtils.GetPermissionsFile(filepath, Program.currentUserSIDs))
},
{"isUnquotedSpaced", MyUtils.CheckQuoteAndSpace(command).ToString()}
});
}
}
catch (Exception e)
{
Beaprint.GrayPrint("Error getting autoruns from WMIC: " + e);
}
return results;
}
public static List<Dictionary<string, string>> GetAutoRuns(Dictionary<string,string> NtAccountNames)
{
List<Dictionary<string, string>> reg_autorus = ServicesInfo.GetRegistryAutoRuns(NtAccountNames);
List<Dictionary<string, string>> reg_autorus = GetRegistryAutoRuns(NtAccountNames);
List<Dictionary<string, string>> file_autorus = GetAutoRunsFolder();
List<Dictionary<string, string>> wmic_autorus = GetAutoRunsWMIC();
reg_autorus.AddRange(file_autorus);
reg_autorus.AddRange(wmic_autorus);
return reg_autorus;
}

View File

@ -71,6 +71,8 @@ namespace winPEAS
Thread.Sleep(700);
}
private Beaprint(){}
public static void PrintInit()
{
if (Program.banner)
@ -99,10 +101,10 @@ namespace winPEAS
{
System.Console.WriteLine(YELLOW + " [*] " + GREEN + "WinPEAS is a binary to enumerate possible paths to escalate privileges locally" + NOCOLOR);
System.Console.WriteLine(LBLUE + " quiet" + GRAY + " Do not print banner" + NOCOLOR);
System.Console.WriteLine(LBLUE + " searchfast" + GRAY + " Avoid sleeping while searching files (notable amount of resources)" + NOCOLOR);
System.Console.WriteLine(LBLUE + " searchall" + GRAY + " Search all known filenames whith possible credentials (coul take some mins)" + NOCOLOR);
System.Console.WriteLine(LBLUE + " searchslow" + GRAY + " Sleep while searching files to not consume a notable amount of resources" + NOCOLOR);
System.Console.WriteLine(LBLUE + " searchall" + GRAY + " Search all known filenames whith possible credentials (could take some mins)" + NOCOLOR);
System.Console.WriteLine(LBLUE + " cmd" + GRAY + " Obtain wifi, cred manager and clipboard information executing CMD commands" + NOCOLOR);
System.Console.WriteLine(LBLUE + " notcolor" + GRAY + " Don't use ansi colors (all white)" + NOCOLOR);
System.Console.WriteLine(LBLUE + " notcolor" + GRAY + " Don't use ansi colors (all white)" + NOCOLOR);
System.Console.WriteLine(LBLUE + " systeminfo" + GRAY + " Search system information" + NOCOLOR);
System.Console.WriteLine(LBLUE + " userinfo" + GRAY + " Search user information" + NOCOLOR);
System.Console.WriteLine(LBLUE + " procesinfo" + GRAY + " Search processes information" + NOCOLOR);
@ -112,6 +114,7 @@ namespace winPEAS
System.Console.WriteLine(LBLUE + " windowscreds" + GRAY + " Search windows credentials" + NOCOLOR);
System.Console.WriteLine(LBLUE + " browserinfo" + GRAY + " Search browser information" + NOCOLOR);
System.Console.WriteLine(LBLUE + " filesinfo" + GRAY + " Search files that can contains credentials" + NOCOLOR);
System.Console.WriteLine(LBLUE + " wait" + GRAY + " Wait for user input between checks" + NOCOLOR);
System.Console.WriteLine(YELLOW + " [+] " + LYELLOW + "By default all checks (except CMD checks) are executed" + NOCOLOR);
}
@ -128,10 +131,10 @@ namespace winPEAS
System.Console.WriteLine(LCYAN + " " + new String('=', halfTotal - toPrint.Length) + "(" + NOCOLOR + YELLOW + toPrint + LCYAN + ")" + new String('=', halfTotal - toPrint.Length) + NOCOLOR);
}
public static void MainPrint(string toPrint, string attackid)
public static void MainPrint(string toPrint)
{
System.Console.WriteLine();
System.Console.WriteLine(YELLOW + " [+] " + GREEN + toPrint + YELLOW + "(" + DGRAY + attackid + YELLOW + ")" + NOCOLOR);
System.Console.WriteLine(YELLOW + " [+] " + GREEN + toPrint + NOCOLOR);
}
public static void LinkPrint(string link, string comment = "")

View File

@ -11,6 +11,7 @@ namespace winPEAS
{
class InterestingFiles
{
private InterestingFiles() {}
public static List<string> GetUnattendedInstallFiles()
{ //From SharpUP
List<string> results = new List<string>();

View File

@ -15,6 +15,8 @@ namespace winPEAS
{
class KnownFileCredsInfo
{
private KnownFileCredsInfo() { }
public static List<string> GetFirefoxDbs()
{
List<string> results = new List<string>();
@ -79,7 +81,7 @@ namespace winPEAS
}
public static List<string> ParseFirefoxHistory(string path, string user)
public static List<string> ParseFirefoxHistory(string path)
{
List<string> results = new List<string>();
// parses a Firefox history file via regex
@ -129,19 +131,17 @@ namespace winPEAS
foreach (string dir in dirs)
{
string[] parts = dir.Split('\\');
string userName = parts[parts.Length - 1];
if (!(dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("All Users")))
{
string userFirefoxBasePath = String.Format("{0}\\AppData\\Roaming\\Mozilla\\Firefox\\Profiles\\", dir);
results = ParseFirefoxHistory(userFirefoxBasePath, userName);
results = ParseFirefoxHistory(userFirefoxBasePath);
}
}
}
else
{
string userName = Environment.GetEnvironmentVariable("USERNAME");
string userFirefoxBasePath = String.Format("{0}\\AppData\\Roaming\\Mozilla\\Firefox\\Profiles\\", System.Environment.GetEnvironmentVariable("USERPROFILE"));
results = ParseFirefoxHistory(userFirefoxBasePath, userName);
results = ParseFirefoxHistory(userFirefoxBasePath);
}
}
catch (Exception ex)
@ -197,7 +197,7 @@ namespace winPEAS
public static List<string> ParseChromeHistory(string path, string user)
public static List<string> ParseChromeHistory(string path)
{
List<string> results = new List<string>();
@ -234,7 +234,7 @@ namespace winPEAS
}
public static List<string> ParseChromeBookmarks(string path, string user)
public static List<string> ParseChromeBookmarks(string path)
{
List<string> results = new List<string>();
// parses a Chrome bookmarks
@ -289,25 +289,24 @@ namespace winPEAS
foreach (string dir in dirs)
{
string[] parts = dir.Split('\\');
string userName = parts[parts.Length - 1];
if (!(dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("All Users")))
{
string userChromeHistoryPath = String.Format("{0}\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\History", dir);
results["history"] = ParseChromeHistory(userChromeHistoryPath, userName);
results["history"] = ParseChromeHistory(userChromeHistoryPath);
string userChromeBookmarkPath = String.Format("{0}\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Bookmarks", dir);
results["bookmarks"] = ParseChromeBookmarks(userChromeBookmarkPath, userName);
results["bookmarks"] = ParseChromeBookmarks(userChromeBookmarkPath);
}
}
}
else
{
string userChromeHistoryPath = String.Format("{0}\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\History", System.Environment.GetEnvironmentVariable("USERPROFILE"));
results["history"] = ParseChromeHistory(userChromeHistoryPath, System.Environment.GetEnvironmentVariable("USERNAME"));
results["history"] = ParseChromeHistory(userChromeHistoryPath);
string userChromeBookmarkPath = String.Format("{0}\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Bookmarks", System.Environment.GetEnvironmentVariable("USERPROFILE"));
results["bookmarks"] = ParseChromeBookmarks(userChromeBookmarkPath, System.Environment.GetEnvironmentVariable("USERNAME"));
results["bookmarks"] = ParseChromeBookmarks(userChromeBookmarkPath);
}
}
catch (Exception ex)
@ -583,12 +582,6 @@ namespace winPEAS
[DllImport("vaultcli.dll")]
public extern static Int32 VaultOpenVault(ref Guid vaultGuid, UInt32 offset, ref IntPtr vaultHandle);
[DllImport("vaultcli.dll")]
public extern static Int32 VaultCloseVault(ref IntPtr vaultHandle);
[DllImport("vaultcli.dll")]
public extern static Int32 VaultFree(ref IntPtr vaultHandle);
[DllImport("vaultcli.dll")]
public extern static Int32 VaultEnumerateVaults(Int32 offset, ref Int32 vaultCount, ref IntPtr vaultGuid);

View File

@ -5,6 +5,7 @@ using System.IO;
using Microsoft.Win32;
using System.Security.Principal;
using System.Diagnostics;
using System.Net;
using System.Text.RegularExpressions;
using System.Reflection;
using System.Security.AccessControl;
@ -241,6 +242,11 @@ namespace winPEAS
}
}
public static string GetCLSIDBinPath(string CLSID)
{
return GetRegValue("HKLM", @"SOFTWARE\Classes\CLSID\" + CLSID + @"\InprocServer32", ""); //To get the default object you need to use an empty string
}
///////////////////////////////////
//////// Check Permissions ////////
@ -522,9 +528,17 @@ namespace winPEAS
public static string GetExecutableFromPath(string path)
{
string binaryPath = "";
Match match_path = Regex.Match(path, @"^\W*([a-z]:\\.+?(\.exe|\.dll|\.sys))\W*", RegexOptions.IgnoreCase);
Match match_path = Regex.Match(path, @"^\W*([a-z]:\\.+?(\.exe|\.dll|\.sys))\W*", RegexOptions.RightToLeft | RegexOptions.IgnoreCase);
if (match_path.Groups.Count > 1)
binaryPath = match_path.Groups[1].ToString();
//Check if rundll32
string[] binaryPathdll32 = binaryPath.Split(new string[] {"Rundll32.exe"}, StringSplitOptions.None);
if (binaryPathdll32.Length > 1)
{
binaryPath = binaryPathdll32[1].Trim();
}
return binaryPath;
}

View File

@ -9,10 +9,10 @@ namespace winPEAS
{
class Program
{
public static string version = "vBETA VERSION, Please if you find any issue let me know in https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/issues";
public static string version = "v1";
public static string advisory = "winpeas should be used for authorized penetration testing and/or educational purposes only.Any misuse of this software will not be the responsibility of the author or of any other collaborator. Use it at your own networks and/or with the network owner's permission.";
public static bool banner = true;
public static bool search_fast = false;
public static bool search_fast = true;
public static int search_time = 50;
static bool exec_cmd = false;
public static bool notcolor = false;
@ -23,7 +23,7 @@ namespace winPEAS
static string badgroups = "docker|Remote |DNSAdmins|AD Recycle Bin|Azure Admins|Admins";//The space in Remote is important to not mix with SeShutdownRemotePrivilege
static string badpasswd = "NotChange|NotExpi";
static string badPrivileges = "SeImpersonatePrivilege|SeAssignPrimaryPrivilege|SeTcbPrivilege|SeBackupPrivilege|SeRestorePrivilege|SeCreateTokenPrivilege|SeLoadDriverPrivilege|SeTakeOwnershipPrivilege|SeDebugPrivilege";
static string goodSoft = "Windows Phone Kits|Windows Kits|Windows Defender|Windows Mail|Windows Media Player|Windows Multimedia Platform|windows nt|Windows Photo Viewer|Windows Portable Devices|Windows Security|Windows Sidebar|WindowsApps|WindowsPowerShell| Windows$|Microsoft|WOW6432Node|internet explorer|Internet Explorer|Common Files";
//static string goodSoft = "Windows Phone Kits|Windows Kits|Windows Defender|Windows Mail|Windows Media Player|Windows Multimedia Platform|windows nt|Windows Photo Viewer|Windows Portable Devices|Windows Security|Windows Sidebar|WindowsApps|WindowsPowerShell| Windows$|Microsoft|WOW6432Node|internet explorer|Internet Explorer|Common Files";
static string commonShares = "[a-zA-Z]+[$]";
static string badIps = "127.0.0.1";
static string badUAC = "No prompting|PromptForNonWindowsBinaries";
@ -153,6 +153,11 @@ namespace winPEAS
}
}
public static void waitInput()
{
Console.Write("\n -- Press a key to continue... ");
Console.ReadLine();
}
/////////////////////////////////////////////////
@ -164,7 +169,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Basic System Information", "T1082&T1124&T1012&T1497&T1212");
Beaprint.MainPrint("Basic System Information");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#kernel-exploits", "Check if the Windows versions is vulnerable to some known exploit");
Dictionary<string, string> basicDictSystem = SystemInfo.GetBasicOSInfo();
basicDictSystem["Hotfixes"] = Beaprint.ansi_color_good + basicDictSystem["Hotfixes"] + Beaprint.NOCOLOR;
@ -193,7 +198,7 @@ namespace winPEAS
{ "PS history file: .+", Beaprint.ansi_color_bad },
{ "PS history size: .+", Beaprint.ansi_color_bad }
};
Beaprint.MainPrint("PowerShell Settings", "");
Beaprint.MainPrint("PowerShell Settings");
Dictionary<string, string> PSs = SystemInfo.GetPowerShellSettings();
Beaprint.DictPrint(PSs, colorsPSI, false);
}
@ -207,7 +212,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Audit Settings", "T1012");
Beaprint.MainPrint("Audit Settings");
Beaprint.LinkPrint("", "Check what is being logged");
Dictionary<string, string> auditDict = SystemInfo.GetAuditSettings();
Beaprint.DictPrint(auditDict, false);
@ -222,7 +227,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("WEF Settings", "T1012");
Beaprint.MainPrint("WEF Settings");
Beaprint.LinkPrint("", "Windows Event Forwarding, is interesting to know were are sent the logs");
Dictionary<string, string> weftDict = SystemInfo.GetWEFSettings();
Beaprint.DictPrint(weftDict, false);
@ -237,7 +242,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("LAPS Settings", "T1012");
Beaprint.MainPrint("LAPS Settings");
Beaprint.LinkPrint("", "If installed, local administrator password is changed frequently and is restricted by ACL");
Dictionary<string, string> lapsDict = SystemInfo.GetLapsSettings();
Dictionary<string, string> colorsSI = new Dictionary<string, string>()
@ -254,7 +259,7 @@ namespace winPEAS
void PrintWdigest()
{
Beaprint.MainPrint("Wdigest", "");
Beaprint.MainPrint("Wdigest");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/stealing-credentials/credentials-protections#wdigest", "If enabled, plain-text crds could be stored in LSASS");
string useLogonCredential = MyUtils.GetRegValue("HKLM", @"SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest", "UseLogonCredential");
if (useLogonCredential == "1")
@ -265,7 +270,7 @@ namespace winPEAS
void PrintLSAProtection()
{
Beaprint.MainPrint("LSA Protection", "");
Beaprint.MainPrint("LSA Protection");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/stealing-credentials/credentials-protections#lsa-protection", "If enabled, a driver is needed to read LSASS memory (If Secure Boot or UEFI, RunAsPPL cannot be disabled by deleting the registry key)");
string useLogonCredential = MyUtils.GetRegValue("HKLM", @"SYSTEM\CurrentControlSet\Control\LSA", "RunAsPPL");
if (useLogonCredential == "1")
@ -276,7 +281,7 @@ namespace winPEAS
void PrintCredentialGuard()
{
Beaprint.MainPrint("Credentials Guard", "");
Beaprint.MainPrint("Credentials Guard");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/stealing-credentials/credentials-protections#credential-guard", "If enabled, a driver is needed to read LSASS memory");
string lsaCfgFlags = MyUtils.GetRegValue("HKLM", @"System\CurrentControlSet\Control\LSA", "LsaCfgFlags");
if (lsaCfgFlags == "1")
@ -295,7 +300,7 @@ namespace winPEAS
void PrintCachedCreds()
{
Beaprint.MainPrint("Cached Creds", "");
Beaprint.MainPrint("Cached Creds");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/stealing-credentials/credentials-protections#cached-credentials", "If > 0, credentials will be cached in the registry and accessible by SYSTEM user");
string cachedlogonscount = MyUtils.GetRegValue("HKLM", @"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon", "CACHEDLOGONSCOUNT");
if (!String.IsNullOrEmpty(cachedlogonscount))
@ -312,7 +317,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("User Environment Variables", "");
Beaprint.MainPrint("User Environment Variables");
Beaprint.LinkPrint("", "Check for some passwords or keys in the env variables");
Dictionary<string, string> userEnvDict = SystemInfo.GetUserEnvVariables();
Dictionary<string, string> colorsSI = new Dictionary<string, string>()
@ -331,7 +336,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("System Environment Variables", "");
Beaprint.MainPrint("System Environment Variables");
Beaprint.LinkPrint("", "Check for some passwords or keys in the env variables");
Dictionary<string, string> sysEnvDict = SystemInfo.GetSystemEnvVariables();
Dictionary<string, string> colorsSI = new Dictionary<string, string>()
@ -355,11 +360,11 @@ namespace winPEAS
{ "ProxyServer.*", Beaprint.ansi_color_bad }
};
Beaprint.MainPrint("HKCU Internet Settings", "T1012");
Beaprint.MainPrint("HKCU Internet Settings");
Dictionary<string, string> HKCUDict = SystemInfo.GetInternetSettings("HKCU");
Beaprint.DictPrint(HKCUDict, colorsSI, true);
Beaprint.MainPrint("HKLM Internet Settings", "T1012");
Beaprint.MainPrint("HKLM Internet Settings");
Dictionary<string, string> HKMLDict = SystemInfo.GetInternetSettings("HKLM");
Beaprint.DictPrint(HKMLDict, colorsSI, true);
}
@ -373,7 +378,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Drives Information", "T1120");
Beaprint.MainPrint("Drives Information");
Beaprint.LinkPrint("", "Remember that you should search more info inside the other drives");
Dictionary<string, string> colorsSI = new Dictionary<string, string>()
{
@ -409,7 +414,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("AV Information", "T1063");
Beaprint.MainPrint("AV Information");
Dictionary<string, string> AVInfo = SystemInfo.GetAVInfo();
if (AVInfo.ContainsKey("Name") && AVInfo["Name"].Length > 0)
Beaprint.GoodPrint(" Some AV was detected, search for bypasses");
@ -428,7 +433,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("UAC Status", "T1012");
Beaprint.MainPrint("UAC Status");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#basic-uac-bypass-full-file-system-access", "If you are in the Administrators group check how to bypass the UAC");
Dictionary<string, string> uacDict = SystemInfo.GetUACSystemPolicies();
@ -514,7 +519,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Users", "T1087&T1069&T1033");
Beaprint.MainPrint("Users");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#users-and-groups", "Check if you have some admin equivalent privileges");
List<string> users_grps = UserInfo.GetMachineUsers(false, false, false, false, true);
@ -543,7 +548,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Current Token privileges", "T1134");
Beaprint.MainPrint("Current Token privileges");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#token-manipulation", "Check if you can escalate privilege using some enabled token");
Dictionary<string, string> token_privs = UserInfo.GetTokenGroupPrivs();
Beaprint.DictPrint(token_privs, colorsU(), false);
@ -558,7 +563,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Clipboard text", "T1134");
Beaprint.MainPrint("Clipboard text");
string clipb = UserInfo.GetClipboardText();
if (String.IsNullOrEmpty(clipb))
Beaprint.BadPrint(clipb);
@ -584,7 +589,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Logged users", "T1087&T1033");
Beaprint.MainPrint("Logged users");
List<string> loggedusers = UserInfo.GetLoggedUsers();
Beaprint.ListPrint(loggedusers, colorsU());
@ -599,7 +604,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("RDP Sessions", "T1087&T1033");
Beaprint.MainPrint("RDP Sessions");
List<Dictionary<string, string>> rdp_sessions = UserInfo.GetRDPSessions();
if (rdp_sessions.Count > 0)
{
@ -622,7 +627,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Ever logged users", "T1087&T1033");
Beaprint.MainPrint("Ever logged users");
List<string> everlogged = UserInfo.GetEverLoggedUsers();
Beaprint.ListPrint(everlogged, colorsU());
}
@ -636,7 +641,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Looking for AutoLogon credentials", "T1012");
Beaprint.MainPrint("Looking for AutoLogon credentials");
bool ban = false;
Dictionary<string, string> autologon = UserInfo.GetAutoLogon();
if (autologon.Count > 0)
@ -669,7 +674,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Home folders found", "T1087&T1083&T1033");
Beaprint.MainPrint("Home folders found");
List<string> user_folders = UserInfo.GetUsersFolders();
foreach (string ufold in user_folders)
{
@ -690,7 +695,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Password Policies", "T1201");
Beaprint.MainPrint("Password Policies");
Beaprint.LinkPrint("", "Check for a possible brute-force");
List<Dictionary<string, string>> PPy = UserInfo.GetPasswordPolicy();
Beaprint.DictPrint(PPy, colorsU(), false);
@ -725,7 +730,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Interesting Processes -non Microsoft-", "T1010&T1057&T1007");
Beaprint.MainPrint("Interesting Processes -non Microsoft-");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#running-processes", "Check if any interesting proccesses for memmory dump or if you could overwrite some binary running");
List<Dictionary<string, string>> processes_info = ProcessesInfo.GetProcInfo();
foreach (Dictionary<string, string> proc_info in processes_info)
@ -809,7 +814,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Interesting Services -non Microsoft-", "T1007");
Beaprint.MainPrint("Interesting Services -non Microsoft-");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#services", "Check if you can overwrite some service binary or perform a DLL hijacking, also check for unquoted paths");
List<Dictionary<string, string>> services_info = ServicesInfo.GetNonstandardServices();
@ -884,7 +889,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Modifiable Services", "T1007");
Beaprint.MainPrint("Modifiable Services");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#services", "Check if you can modify any service");
if (mod_services.Count > 0)
{
@ -909,7 +914,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Looking if you can modify any service registry", "");
Beaprint.MainPrint("Looking if you can modify any service registry");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#services-registry-permissions", "Check if you can modify the registry of a service");
List<Dictionary<string, string>> regPerms = ServicesInfo.GetWriteServiceRegs(currentUserSIDs);
@ -937,7 +942,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Checking write permissions in PATH folders (DLL Hijacking)", "");
Beaprint.MainPrint("Checking write permissions in PATH folders (DLL Hijacking)");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#dll-hijacking", "Check for DLL Hijacking in PATH folders");
Dictionary<string, string> path_dllhijacking = ServicesInfo.GetPathDLLHijacking();
foreach (KeyValuePair<string, string> entry in path_dllhijacking)
@ -974,7 +979,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Current Active Window Application", "T1010&T1518");
Beaprint.MainPrint("Current Active Window Application");
string title = ApplicationInfo.GetActiveWindowTitle();
List<string> permsFile = MyUtils.GetPermissionsFile(title, currentUserSIDs);
List<string> permsFolder = MyUtils.GetPermissionsFolder(title, currentUserSIDs);
@ -1002,7 +1007,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Installed Applications --Via Program Files/Uninstall registry--", "T1083&T1012&T1010&T1518");
Beaprint.MainPrint("Installed Applications --Via Program Files/Uninstall registry--");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#software", "Check if you can modify installed software");
SortedDictionary<string, Dictionary<string, string>> InstalledAppsPerms = ApplicationInfo.GetInstalledAppsPerms();
string format = " ==> {0} ({1})";
@ -1033,7 +1038,7 @@ namespace winPEAS
}
System.Console.WriteLine();
/*Beaprint.MainPrint("Installed Applications --Via Registry--", "T1083&T1012&T1010");
/*Beaprint.MainPrint("Installed Applications --Via Registry--"");
Dictionary<string, string> colorsA = new Dictionary<string, string>()
{
@ -1051,8 +1056,8 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Autorun Applications", "T1010");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#run-at-startup", "Check if you can modify other users AutoRuns binaries");
Beaprint.MainPrint("Autorun Applications");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation/privilege-escalation-with-autorun-binaries", "Check if you can modify other users AutoRuns binaries (Note that is normal that you can modify HKCU registry and binaries indicated there)");
List<Dictionary<string, string>> apps = ApplicationInfo.GetAutoRuns(currentUserSIDs);
foreach (Dictionary<string, string> app in apps)
@ -1062,6 +1067,7 @@ namespace winPEAS
{ "FolderPerms:.*", Beaprint.ansi_color_bad },
{ "FilePerms:.*", Beaprint.ansi_color_bad },
{ "(Unquoted and Space detected)", Beaprint.ansi_color_bad },
{ "(PATH Injection)", Beaprint.ansi_color_bad },
{ "RegPerms: .*", Beaprint.ansi_color_bad },
{ (app["Folder"].Length > 0) ? app["Folder"].Replace("\\", "\\\\").Replace("(", "\\(").Replace(")", "\\)").Replace("]", "\\]").Replace("[", "\\[").Replace("?", "\\?").Replace("+","\\+") : "ouigyevb2uivydi2u3id2ddf3", !String.IsNullOrEmpty(app["interestingFolderRights"]) ? Beaprint.ansi_color_bad : Beaprint.ansi_color_good },
{ (app["File"].Length > 0) ? app["File"].Replace("\\", "\\\\").Replace("(", "\\(").Replace(")", "\\)").Replace("]", "\\]").Replace("[", "\\[").Replace("?", "\\?").Replace("+","\\+") : "adu8v298hfubibuidiy2422r", !String.IsNullOrEmpty(app["interestingFileRights"]) ? Beaprint.ansi_color_bad : Beaprint.ansi_color_good },
@ -1069,8 +1075,22 @@ namespace winPEAS
};
string line = "";
if (!String.IsNullOrEmpty(app["Reg"]))
line += "\n RegPath: " + app["Reg"];
if (app["RegPermissions"].Length > 0)
line += "\n RegPerms: " + app["RegPermissions"];
if (!String.IsNullOrEmpty(app["RegKey"]))
line += "\n Key: " + app["RegKey"];
if (!String.IsNullOrEmpty(app["Folder"]))
line += " Folder: " + app["Folder"];
line += "\n Folder: " + app["Folder"];
else
{
if (!String.IsNullOrEmpty(app["Reg"]))
line += "\n Folder: None (PATH Injection)";
}
if (!String.IsNullOrEmpty(app["interestingFolderRights"]))
{
@ -1087,12 +1107,6 @@ namespace winPEAS
if (!String.IsNullOrEmpty(app["interestingFileRights"]))
line += "\n FilePerms: " + app["interestingFileRights"];
if (!String.IsNullOrEmpty(app["Reg"]))
line += "\n RegPath: " + app["Reg"];
if (app["RegPermissions"].Length > 0)
line += "\n RegPerms: "+ app["RegPermissions"];
Beaprint.AnsiPrint(line, colorsA);
Beaprint.PrintLineSeparator();
}
@ -1107,8 +1121,8 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Scheduled Applications --Non Microsoft--", "T1010");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#run-at-startup", "Check if you can modify other users scheduled binaries");
Beaprint.MainPrint("Scheduled Applications --Non Microsoft--");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation/privilege-escalation-with-autorun-binaries", "Check if you can modify other users scheduled binaries");
List<Dictionary<string, string>> scheduled_apps = ApplicationInfo.GetScheduledAppsNoMicrosoft();
foreach (Dictionary<string, string> sapp in scheduled_apps)
@ -1143,7 +1157,7 @@ namespace winPEAS
Beaprint.GreatPrint("Applications Information");
PrintActiveWindow();
PrintInstalledApps();
//PrintInstalledApps();
PrintAutoRuns();
PrintScheduled();
}
@ -1159,7 +1173,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Network Shares", "T1135");
Beaprint.MainPrint("Network Shares");
Dictionary<string, string> colorsN = new Dictionary<string, string>()
{
{ commonShares, Beaprint.ansi_color_good },
@ -1184,7 +1198,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Host File", "T1016");
Beaprint.MainPrint("Host File");
string[] lines = File.ReadAllLines(@Path.GetPathRoot(Environment.SystemDirectory) + @"\windows\system32\drivers\etc\hosts");
foreach (string line in lines)
{
@ -1202,7 +1216,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Network Ifaces and known hosts", "T1016");
Beaprint.MainPrint("Network Ifaces and known hosts");
Beaprint.LinkPrint("", "The masks are only for the IPv4 addresses");
foreach (Dictionary<string, string> card in NetworkInfo.GetNetCardInfo())
{
@ -1227,7 +1241,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Current Listening Ports", "T1049&T1049");
Beaprint.MainPrint("Current Listening Ports");
Beaprint.LinkPrint("", "Check for services restricted from the outside");
List<List<string>> conns = NetworkInfo.GetNetConnections();
@ -1257,7 +1271,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Firewall Rules", "T1016");
Beaprint.MainPrint("Firewall Rules");
Beaprint.LinkPrint("", "Showing only DENY rules (too many ALLOW rules always)");
Dictionary<string, string> colorsN = new Dictionary<string, string>()
{
@ -1301,7 +1315,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("DNS cached --limit 70--", "T1016");
Beaprint.MainPrint("DNS cached --limit 70--");
Beaprint.GrayPrint(String.Format(" {0,-38}{1,-38}{2}", "Entry", "Name", "Data"));
List<Dictionary<string, string>> DNScache = NetworkInfo.GetDNSCache();
foreach (Dictionary<string, string> entry in DNScache.GetRange(0, DNScache.Count <= 70 ? DNScache.Count : 70))
@ -1334,7 +1348,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Checking Windows Vault", "");
Beaprint.MainPrint("Checking Windows Vault");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#credentials-manager-windows-vault");
List<Dictionary<string, string>> vault_creds = KnownFileCredsInfo.DumpVault();
@ -1354,7 +1368,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Checking Credential manager", "");
Beaprint.MainPrint("Checking Credential manager");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#credentials-manager-windows-vault");
if (exec_cmd)
{
@ -1382,7 +1396,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Saved RDP connections", "");
Beaprint.MainPrint("Saved RDP connections");
List<Dictionary<string, string>> rdps_info = KnownFileCredsInfo.GetSavedRDPConnections();
if (rdps_info.Count > 0)
@ -1403,7 +1417,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Recently run commands", "");
Beaprint.MainPrint("Recently run commands");
Dictionary<string, object> recentCommands = KnownFileCredsInfo.GetRecentRunCommands();
Beaprint.DictPrint(recentCommands, false);
}
@ -1417,7 +1431,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("PS default transcripts history", "");
Beaprint.MainPrint("PS default transcripts history");
Beaprint.InfoPrint("Read the PS histpry inside these files (if any)");
string drive = Path.GetPathRoot(Environment.SystemDirectory);
string path = drive + @"transcripts\";
@ -1447,7 +1461,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Checking for DPAPI Master Keys", "");
Beaprint.MainPrint("Checking for DPAPI Master Keys");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#dpapi");
List<Dictionary<string, string>> master_keys = KnownFileCredsInfo.ListMasterKeys();
if (master_keys.Count != 0)
@ -1470,7 +1484,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Checking for Credential Files", "");
Beaprint.MainPrint("Checking for Credential Files");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#dpapi");
List<Dictionary<string, string>> cred_files = KnownFileCredsInfo.GetCredFiles();
Beaprint.DictPrint(cred_files, false);
@ -1487,7 +1501,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Checking for RDCMan Settings Files", "");
Beaprint.MainPrint("Checking for RDCMan Settings Files");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#remote-desktop-credential-manager", "Dump credentials from Remote Desktop Connection Manager");
List<Dictionary<string, string>> rdc_files = KnownFileCredsInfo.GetRDCManFiles();
Beaprint.DictPrint(rdc_files, false);
@ -1504,7 +1518,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Looking for kerberos tickets", "");
Beaprint.MainPrint("Looking for kerberos tickets");
Beaprint.LinkPrint("https://book.hacktricks.xyz/pentesting/pentesting-kerberos-88");
List<Dictionary<string, string>> kerberos_tckts = KnownFileCredsInfo.ListKerberosTickets();
Beaprint.DictPrint(kerberos_tckts, false);
@ -1519,7 +1533,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Looking for kerberos TGT tickets", "");
Beaprint.MainPrint("Looking for kerberos TGT tickets");
List<Dictionary<string, string>> kerberos_tgts = KnownFileCredsInfo.GetKerberosTGTData();
Beaprint.DictPrint(kerberos_tgts, false);
}
@ -1533,7 +1547,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Looking saved Wifis", "");
Beaprint.MainPrint("Looking saved Wifis");
if (exec_cmd)
{
Dictionary<string, string> colorsC = new Dictionary<string, string>()
@ -1559,7 +1573,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Looking AppCmd.exe", "");
Beaprint.MainPrint("Looking AppCmd.exe");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#appcmd-exe");
if (File.Exists(Environment.ExpandEnvironmentVariables(@"%systemroot%\system32\inetsrv\appcmd.exe")))
Beaprint.BadPrint(" AppCmd.exe was found in " + Environment.ExpandEnvironmentVariables(@"%systemroot%\system32\inetsrv\appcmd.exe You should try to search for credentials"));
@ -1576,7 +1590,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Looking SSClient.exe", "");
Beaprint.MainPrint("Looking SSClient.exe");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#scclient-sccm");
if (File.Exists(Environment.ExpandEnvironmentVariables(@"%systemroot%\Windows\CCM\SCClient.exe")))
Beaprint.BadPrint(" SCClient.exe was found in " + Environment.ExpandEnvironmentVariables(@"%systemroot%\Windows\CCM\SCClient.exe DLL Side loading?"));
@ -1593,7 +1607,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Checking AlwaysInstallElevated", "T1012");
Beaprint.MainPrint("Checking AlwaysInstallElevated");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#alwaysinstallelevated");
string path = "Software\\Policies\\Microsoft\\Windows\\Installer";
string HKLM_AIE = MyUtils.GetRegValue("HKLM", path, "AlwaysInstallElevated");
@ -1615,7 +1629,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Checking WSUS", "T1012");
Beaprint.MainPrint("Checking WSUS");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#wsus");
string path = "Software\\Policies\\Microsoft\\Windows\\WindowsUpdate";
string path2 = "Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU";
@ -1675,7 +1689,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Looking for Firefox DBs", "T1503");
Beaprint.MainPrint("Looking for Firefox DBs");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#browsers-history");
List<string> firefoxDBs = KnownFileCredsInfo.GetFirefoxDbs();
if (firefoxDBs.Count > 0)
@ -1700,7 +1714,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Looking for GET credentials in Firefox history", "T1503");
Beaprint.MainPrint("Looking for GET credentials in Firefox history");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#browsers-history");
List<string> firefoxHist = KnownFileCredsInfo.GetFirefoxHistory();
if (firefoxHist.Count > 0)
@ -1730,7 +1744,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Looking for Chrome DBs", "T1503");
Beaprint.MainPrint("Looking for Chrome DBs");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#browsers-history");
Dictionary<string, string> chromeDBs = KnownFileCredsInfo.GetChromeDbs();
if (chromeDBs.ContainsKey("userChromeCookiesPath"))
@ -1758,7 +1772,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Looking for GET credentials in Chrome history", "T1503");
Beaprint.MainPrint("Looking for GET credentials in Chrome history");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#browsers-history");
Dictionary<string, List<string>> chromeHistBook = KnownFileCredsInfo.GetChromeHistBook();
List<string> history = chromeHistBook["history"];
@ -1782,7 +1796,7 @@ namespace winPEAS
Beaprint.NotFoundPrint();
}
Beaprint.MainPrint("Chrome bookmarks", "T1217");
Beaprint.MainPrint("Chrome bookmarks");
Beaprint.ListPrint(bookmarks);
}
catch (Exception ex)
@ -1795,7 +1809,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Current IE tabs", "T1503");
Beaprint.MainPrint("Current IE tabs");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#browsers-history");
List<string> urls = KnownFileCredsInfo.GetCurrentIETabs();
@ -1815,7 +1829,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Looking for GET credentials in IE history", "T1503");
Beaprint.MainPrint("Looking for GET credentials in IE history");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#browsers-history");
Dictionary<string, List<string>> chromeHistBook = KnownFileCredsInfo.GetIEHistFav();
List<string> history = chromeHistBook["history"];
@ -1835,7 +1849,7 @@ namespace winPEAS
System.Console.WriteLine();
}
Beaprint.MainPrint("IE favorites", "T1217");
Beaprint.MainPrint("IE favorites");
Beaprint.ListPrint(favorites);
}
catch (Exception ex)
@ -1864,7 +1878,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Putty Sessions", "");
Beaprint.MainPrint("Putty Sessions");
List<Dictionary<string, string>> putty_sess = KnownFileCredsInfo.GetPuttySessions();
Dictionary<string, string> colorF = new Dictionary<string, string>()
@ -1883,7 +1897,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Putty SSH Host keys", "");
Beaprint.MainPrint("Putty SSH Host keys");
List<Dictionary<string, string>> putty_sess = KnownFileCredsInfo.ListPuttySSHHostKeys();
Dictionary<string, string> colorF = new Dictionary<string, string>()
{
@ -1901,7 +1915,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("SSH keys in registry", "");
Beaprint.MainPrint("SSH keys in registry");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#ssh-keys-in-registry", "If you find anything here, follow the link to learn how to decrypt the SSH keys");
string[] ssh_reg = MyUtils.GetRegSubkeys("HKCU", @"OpenSSH\Agent\Keys");
@ -1923,7 +1937,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Cloud Credentials", "T1538&T1083&T1081");
Beaprint.MainPrint("Cloud Credentials");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#credentials-inside-files");
List<Dictionary<string, string>> could_creds = KnownFileCredsInfo.ListCloudCreds();
if (could_creds.Count != 0)
@ -1948,7 +1962,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Unnattend Files", "");
Beaprint.MainPrint("Unnattend Files");
//Beaprint.LinkPrint("");
List<string> unattended_files = InterestingFiles.GetUnattendedInstallFiles();
foreach (string path in unattended_files)
@ -1968,7 +1982,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Powershell History", "");
Beaprint.MainPrint("Powershell History");
string console_host_history = InterestingFiles.GetConsoleHostHistory();
if (console_host_history != "")
{
@ -1993,7 +2007,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Looking for common SAM & SYSTEM backups", "");
Beaprint.MainPrint("Looking for common SAM & SYSTEM backups");
List<string> sam_files = InterestingFiles.GetSAMBackups();
foreach (string path in sam_files)
Beaprint.BadPrint(" " + path);
@ -2009,7 +2023,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Looking for McAfee Sitelist.xml Files", "");
Beaprint.MainPrint("Looking for McAfee Sitelist.xml Files");
List<string> sam_files = InterestingFiles.GetMcAfeeSitelistFiles();
foreach (string path in sam_files)
Beaprint.BadPrint(" " + path);
@ -2025,7 +2039,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Cached GPP Passwords", "");
Beaprint.MainPrint("Cached GPP Passwords");
Dictionary<string, Dictionary<string, string>> gpp_passwords = InterestingFiles.GetCachedGPPPassword();
Dictionary<string, string> gppColors = new Dictionary<string, string>()
@ -2053,7 +2067,7 @@ namespace winPEAS
string[] pass_reg_hkcu = new string[] { @"Software\ORL\WinVNC3\Password", @"Software\TightVNC\Server", @"Software\SimonTatham\PuTTY\Sessions" };
string[] pass_reg_hklm = new string[] { @"SYSTEM\CurrentControlSet\Services\SNMP" };
Beaprint.MainPrint("Looking for possible regs with creds", "T1012&T1214");
Beaprint.MainPrint("Looking for possible regs with creds");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#inside-the-registry");
string winVNC4 = MyUtils.GetRegValue("HKLM", @"SOFTWARE\RealVNC\WinVNC4", "passwword");
@ -2083,7 +2097,7 @@ namespace winPEAS
{ pattern_color, Beaprint.ansi_color_bad },
};
Beaprint.MainPrint("Looking for possible password files in users homes", "T1083&T1081");
Beaprint.MainPrint("Looking for possible password files in users homes");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#credentials-inside-files");
string searchPath = String.Format("{0}\\", Environment.GetEnvironmentVariable("SystemDrive") + "\\Users");
List<string> files_paths = MyUtils.FindFiles(searchPath, patterns);
@ -2121,7 +2135,7 @@ namespace winPEAS
{ patterns_file_creds_color + "|.*password.*|.*credential.*", Beaprint.ansi_color_bad },
};
Beaprint.MainPrint("Looking inside the Recycle Bin for creds files", "T1083&T1081&T1145");
Beaprint.MainPrint("Looking inside the Recycle Bin for creds files");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#credentials-inside-files");
List<Dictionary<string, string>> recy_files = InterestingFiles.GetRecycleBin();
foreach (Dictionary<string, string> rec_file in recy_files)
@ -2153,7 +2167,7 @@ namespace winPEAS
{ patterns_file_creds_color, Beaprint.ansi_color_bad },
};
Beaprint.MainPrint("Searching known files that can contain creds in home", "T1083&T1081");
Beaprint.MainPrint("Searching known files that can contain creds in home");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#credentials-inside-files");
string searchPath = Environment.GetEnvironmentVariable("USERPROFILE");
MyUtils.FindFiles(searchPath, patterns_file_creds, colorF);
@ -2168,7 +2182,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Looking for documents --limit 100--", "T1083");
Beaprint.MainPrint("Looking for documents --limit 100--");
List<string> doc_files = InterestingFiles.ListUsersDocs();
Beaprint.ListPrint(doc_files.GetRange(0, doc_files.Count <= 100 ? doc_files.Count : 100));
}
@ -2182,7 +2196,7 @@ namespace winPEAS
{
try
{
Beaprint.MainPrint("Recent files --limit 70--", "T1083&T1081");
Beaprint.MainPrint("Recent files --limit 70--");
List<Dictionary<string, string>> rec_files = KnownFileCredsInfo.GetRecentFiles();
Dictionary<string, string> colorF = new Dictionary<string, string>()
@ -2243,6 +2257,7 @@ namespace winPEAS
bool check_wc = false;
bool check_bi = false;
bool check_if = false;
bool wait = false;
foreach (string arg in args)
{
if (string.Equals(arg, "cmd", StringComparison.CurrentCultureIgnoreCase))
@ -2257,7 +2272,7 @@ namespace winPEAS
if (string.Equals(arg, "searchall", StringComparison.CurrentCultureIgnoreCase))
patterns_file_creds = patterns_file_creds + complete_patterns_file_creds;
if (string.Equals(arg, "searchfast", StringComparison.CurrentCultureIgnoreCase))
if (string.Equals(arg, "searchslow", StringComparison.CurrentCultureIgnoreCase))
search_fast = false;
if (string.Equals(arg, "help", StringComparison.CurrentCultureIgnoreCase))
@ -2337,6 +2352,11 @@ namespace winPEAS
check_if = true;
check_all = false;
}
else if (string.Equals(arg, "wait", StringComparison.CurrentCultureIgnoreCase))
{
wait = true;
}
}
//Start execution
@ -2349,28 +2369,60 @@ namespace winPEAS
Beaprint.PrintInit();
if (check_si || check_all)
{
PrintSystemInfo();
if (wait) waitInput();
}
if (check_iu || check_all)
{
PrintInfoUsers();
if (wait) waitInput();
}
if (check_ip || check_all)
{
PrintInfoProcesses();
if (wait) waitInput();
}
if (check_is || check_all)
{
PrintInfoServices();
if (wait) waitInput();
}
if (check_ia || check_all)
{
PrintInfoApplications();
if (wait) waitInput();
}
if (check_in || check_all)
{
PrintInfoNetwork();
if (wait) waitInput();
}
if (check_wc || check_all)
{
PrintWindowsCreds();
if (wait) waitInput();
}
if (check_bi || check_all)
{
PrintBrowserInfo();
if (wait) waitInput();
}
if (check_if || check_all)
PrintInterestingFiles();
/*
* Wifi (passwords?)
* Keylogger?
* Check if you can modify a task
* Input prompt ==> Better in PS
* List Drivers ==> but how do I know if a driver is malicious?
*/

View File

@ -0,0 +1,702 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace winPEAS.Properties {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("winPEAS.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized string similar to Call a COM object.
/// </summary>
internal static string ActionTypeComHandler {
get {
return ResourceManager.GetString("ActionTypeComHandler", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Start a program.
/// </summary>
internal static string ActionTypeExecute {
get {
return ResourceManager.GetString("ActionTypeExecute", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Send an e-mail.
/// </summary>
internal static string ActionTypeSendEmail {
get {
return ResourceManager.GetString("ActionTypeSendEmail", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Display a message.
/// </summary>
internal static string ActionTypeShowMessage {
get {
return ResourceManager.GetString("ActionTypeShowMessage", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to {3} {0:P}.
/// </summary>
internal static string ComHandlerAction {
get {
return ResourceManager.GetString("ComHandlerAction", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to every day.
/// </summary>
internal static string DOWAllDays {
get {
return ResourceManager.GetString("DOWAllDays", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to {1} {0}.
/// </summary>
internal static string EmailAction {
get {
return ResourceManager.GetString("EmailAction", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to ..
/// </summary>
internal static string EndSentence {
get {
return ResourceManager.GetString("EndSentence", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The date and time a trigger expires must be later than the time time it starts or is activated..
/// </summary>
internal static string Error_TriggerEndBeforeStart {
get {
return ResourceManager.GetString("Error_TriggerEndBeforeStart", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to {0} {1}.
/// </summary>
internal static string ExecAction {
get {
return ResourceManager.GetString("ExecAction", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to -.
/// </summary>
internal static string HyphenSeparator {
get {
return ResourceManager.GetString("HyphenSeparator", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to ,.
/// </summary>
internal static string ListSeparator {
get {
return ResourceManager.GetString("ListSeparator", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to every month.
/// </summary>
internal static string MOYAllMonths {
get {
return ResourceManager.GetString("MOYAllMonths", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Multiple actions defined.
/// </summary>
internal static string MultipleActions {
get {
return ResourceManager.GetString("MultipleActions", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Multiple triggers defined.
/// </summary>
internal static string MultipleTriggers {
get {
return ResourceManager.GetString("MultipleTriggers", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to {0}.
/// </summary>
internal static string ShowMessageAction {
get {
return ResourceManager.GetString("ShowMessageAction", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Author.
/// </summary>
internal static string TaskDefaultPrincipal {
get {
return ResourceManager.GetString("TaskDefaultPrincipal", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Disabled.
/// </summary>
internal static string TaskStateDisabled {
get {
return ResourceManager.GetString("TaskStateDisabled", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Queued.
/// </summary>
internal static string TaskStateQueued {
get {
return ResourceManager.GetString("TaskStateQueued", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Ready.
/// </summary>
internal static string TaskStateReady {
get {
return ResourceManager.GetString("TaskStateReady", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Running.
/// </summary>
internal static string TaskStateRunning {
get {
return ResourceManager.GetString("TaskStateRunning", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Unknown.
/// </summary>
internal static string TaskStateUnknown {
get {
return ResourceManager.GetString("TaskStateUnknown", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to any user.
/// </summary>
internal static string TriggerAnyUser {
get {
return ResourceManager.GetString("TriggerAnyUser", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to At system startup.
/// </summary>
internal static string TriggerBoot1 {
get {
return ResourceManager.GetString("TriggerBoot1", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Custom Trigger.
/// </summary>
internal static string TriggerCustom1 {
get {
return ResourceManager.GetString("TriggerCustom1", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to At {0:t} every day.
/// </summary>
internal static string TriggerDaily1 {
get {
return ResourceManager.GetString("TriggerDaily1", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to At {0:t} every {1} days.
/// </summary>
internal static string TriggerDaily2 {
get {
return ResourceManager.GetString("TriggerDaily2", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to indefinitely.
/// </summary>
internal static string TriggerDuration0 {
get {
return ResourceManager.GetString("TriggerDuration0", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to for a duration of {0}.
/// </summary>
internal static string TriggerDurationNot0 {
get {
return ResourceManager.GetString("TriggerDurationNot0", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to for {0}.
/// </summary>
internal static string TriggerDurationNot0Short {
get {
return ResourceManager.GetString("TriggerDurationNot0Short", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Trigger expires at {0:G}..
/// </summary>
internal static string TriggerEndBoundary {
get {
return ResourceManager.GetString("TriggerEndBoundary", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Custom event filter.
/// </summary>
internal static string TriggerEvent1 {
get {
return ResourceManager.GetString("TriggerEvent1", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to On event - Log: {0}.
/// </summary>
internal static string TriggerEventBasic1 {
get {
return ResourceManager.GetString("TriggerEventBasic1", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to , Source: {0}.
/// </summary>
internal static string TriggerEventBasic2 {
get {
return ResourceManager.GetString("TriggerEventBasic2", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to , EventID: {0}.
/// </summary>
internal static string TriggerEventBasic3 {
get {
return ResourceManager.GetString("TriggerEventBasic3", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to When computer is idle.
/// </summary>
internal static string TriggerIdle1 {
get {
return ResourceManager.GetString("TriggerIdle1", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to At log on of {0}.
/// </summary>
internal static string TriggerLogon1 {
get {
return ResourceManager.GetString("TriggerLogon1", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to At {0:t} on day {1} of {2}, starting {0:d}.
/// </summary>
internal static string TriggerMonthly1 {
get {
return ResourceManager.GetString("TriggerMonthly1", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to At {0:t} on {1} {2:f} each {3}, starting {0:d}.
/// </summary>
internal static string TriggerMonthlyDOW1 {
get {
return ResourceManager.GetString("TriggerMonthlyDOW1", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to When the task is created or modified.
/// </summary>
internal static string TriggerRegistration1 {
get {
return ResourceManager.GetString("TriggerRegistration1", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to After triggered, repeat every {0} {1}..
/// </summary>
internal static string TriggerRepetition {
get {
return ResourceManager.GetString("TriggerRepetition", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Every {0} {1}..
/// </summary>
internal static string TriggerRepetitionShort {
get {
return ResourceManager.GetString("TriggerRepetitionShort", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to On local connection to {0}..
/// </summary>
internal static string TriggerSessionConsoleConnect {
get {
return ResourceManager.GetString("TriggerSessionConsoleConnect", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to On local disconnect from {0}..
/// </summary>
internal static string TriggerSessionConsoleDisconnect {
get {
return ResourceManager.GetString("TriggerSessionConsoleDisconnect", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to On remote connection to {0}..
/// </summary>
internal static string TriggerSessionRemoteConnect {
get {
return ResourceManager.GetString("TriggerSessionRemoteConnect", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to On remote disconnect from {0}..
/// </summary>
internal static string TriggerSessionRemoteDisconnect {
get {
return ResourceManager.GetString("TriggerSessionRemoteDisconnect", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to On workstation lock of {0}..
/// </summary>
internal static string TriggerSessionSessionLock {
get {
return ResourceManager.GetString("TriggerSessionSessionLock", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to On workstation unlock of {0}..
/// </summary>
internal static string TriggerSessionSessionUnlock {
get {
return ResourceManager.GetString("TriggerSessionSessionUnlock", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to user session of {0}.
/// </summary>
internal static string TriggerSessionUserSession {
get {
return ResourceManager.GetString("TriggerSessionUserSession", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to At {0:t} on {0:d}.
/// </summary>
internal static string TriggerTime1 {
get {
return ResourceManager.GetString("TriggerTime1", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to At startup.
/// </summary>
internal static string TriggerTypeBoot {
get {
return ResourceManager.GetString("TriggerTypeBoot", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Custom Trigger.
/// </summary>
internal static string TriggerTypeCustom {
get {
return ResourceManager.GetString("TriggerTypeCustom", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Daily.
/// </summary>
internal static string TriggerTypeDaily {
get {
return ResourceManager.GetString("TriggerTypeDaily", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to On an event.
/// </summary>
internal static string TriggerTypeEvent {
get {
return ResourceManager.GetString("TriggerTypeEvent", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to On idle.
/// </summary>
internal static string TriggerTypeIdle {
get {
return ResourceManager.GetString("TriggerTypeIdle", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to At log on.
/// </summary>
internal static string TriggerTypeLogon {
get {
return ResourceManager.GetString("TriggerTypeLogon", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Monthly.
/// </summary>
internal static string TriggerTypeMonthly {
get {
return ResourceManager.GetString("TriggerTypeMonthly", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Monthly.
/// </summary>
internal static string TriggerTypeMonthlyDOW {
get {
return ResourceManager.GetString("TriggerTypeMonthlyDOW", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to At task creation/modification.
/// </summary>
internal static string TriggerTypeRegistration {
get {
return ResourceManager.GetString("TriggerTypeRegistration", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to On state change.
/// </summary>
internal static string TriggerTypeSessionStateChange {
get {
return ResourceManager.GetString("TriggerTypeSessionStateChange", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to One time.
/// </summary>
internal static string TriggerTypeTime {
get {
return ResourceManager.GetString("TriggerTypeTime", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Weekly.
/// </summary>
internal static string TriggerTypeWeekly {
get {
return ResourceManager.GetString("TriggerTypeWeekly", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to At {0:t} every {1} of every week, starting {0:d}.
/// </summary>
internal static string TriggerWeekly1Week {
get {
return ResourceManager.GetString("TriggerWeekly1Week", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to At {0:t} every {1} of every {2} weeks, starting {0:d}.
/// </summary>
internal static string TriggerWeeklyMultWeeks {
get {
return ResourceManager.GetString("TriggerWeeklyMultWeeks", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to every.
/// </summary>
internal static string WWAllWeeks {
get {
return ResourceManager.GetString("WWAllWeeks", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to fifth.
/// </summary>
internal static string WWFifthWeek {
get {
return ResourceManager.GetString("WWFifthWeek", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to first.
/// </summary>
internal static string WWFirstWeek {
get {
return ResourceManager.GetString("WWFirstWeek", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to fourth.
/// </summary>
internal static string WWFourthWeek {
get {
return ResourceManager.GetString("WWFourthWeek", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to last.
/// </summary>
internal static string WWLastWeek {
get {
return ResourceManager.GetString("WWLastWeek", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to second.
/// </summary>
internal static string WWSecondWeek {
get {
return ResourceManager.GetString("WWSecondWeek", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to third.
/// </summary>
internal static string WWThirdWeek {
get {
return ResourceManager.GetString("WWThirdWeek", resourceCulture);
}
}
}
}

View File

@ -0,0 +1,355 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="ActionTypeComHandler" xml:space="preserve">
<value>COM-Objekt aufrufen</value>
</data>
<data name="ActionTypeExecute" xml:space="preserve">
<value>Programm starten</value>
</data>
<data name="ActionTypeSendEmail" xml:space="preserve">
<value>E-Mail senden</value>
</data>
<data name="ActionTypeShowMessage" xml:space="preserve">
<value>Meldung anzeigen</value>
</data>
<data name="ComHandlerAction" xml:space="preserve">
<value>{3} {0:P}</value>
<comment>0 = Class GUID; 1 = Data; 2 = Id</comment>
</data>
<data name="DOWAllDays" xml:space="preserve">
<value>jeden Tag</value>
</data>
<data name="EmailAction" xml:space="preserve">
<value>{1} {0}</value>
<comment>0 = Subject; 1 = To; 2 = Cc, 3 = Bcc, 4 = From, 5 = ReplyTo, 6 = Body, 7 = Server, 8 = Id</comment>
</data>
<data name="EndSentence" xml:space="preserve">
<value>.</value>
</data>
<data name="ExecAction" xml:space="preserve">
<value>{0} {1}</value>
<comment>0 = Executable Path; 1 = Arguments; 2 = WorkingDirectory; 3 = Id</comment>
</data>
<data name="HyphenSeparator" xml:space="preserve">
<value>-</value>
</data>
<data name="ListSeparator" xml:space="preserve">
<value>,</value>
</data>
<data name="MOYAllMonths" xml:space="preserve">
<value>jeden Monat</value>
</data>
<data name="MultipleActions" xml:space="preserve">
<value>Mehrere Aktionen definiert</value>
</data>
<data name="MultipleTriggers" xml:space="preserve">
<value>Mehrere Trigger definiert</value>
</data>
<data name="ShowMessageAction" xml:space="preserve">
<value>{0}</value>
<comment>0 = Title; 1 = MessageBody; 2 = Id</comment>
</data>
<data name="TaskDefaultPrincipal" xml:space="preserve">
<value>Autor</value>
</data>
<data name="TaskStateDisabled" xml:space="preserve">
<value>Deaktiviert</value>
</data>
<data name="TaskStateQueued" xml:space="preserve">
<value>Eingereiht</value>
</data>
<data name="TaskStateReady" xml:space="preserve">
<value>Bereit</value>
</data>
<data name="TaskStateRunning" xml:space="preserve">
<value>Wird ausgeführt</value>
</data>
<data name="TaskStateUnknown" xml:space="preserve">
<value>Unbekannt</value>
</data>
<data name="TriggerAnyUser" xml:space="preserve">
<value>eines Benutzers</value>
</data>
<data name="TriggerBoot1" xml:space="preserve">
<value>Beim Systemstart</value>
</data>
<data name="TriggerCustom1" xml:space="preserve">
<value>Benutzerdefinierter Trigger</value>
</data>
<data name="TriggerDaily1" xml:space="preserve">
<value>Um {0:t} jeden Tag</value>
</data>
<data name="TriggerDaily2" xml:space="preserve">
<value>Um {0:t} alle {1} Tage</value>
</data>
<data name="TriggerDuration0" xml:space="preserve">
<value>Sofort</value>
</data>
<data name="TriggerDurationNot0" xml:space="preserve">
<value>für eine Dauer von {0}</value>
<comment>0 = Duration</comment>
</data>
<data name="TriggerEndBoundary" xml:space="preserve">
<value>Trigger läuft um {0:G} ab.</value>
<comment>0 = EndBoundary</comment>
</data>
<data name="TriggerEvent1" xml:space="preserve">
<value>Benutzerdefinierter Ereignisfilter</value>
</data>
<data name="TriggerEventBasic1" xml:space="preserve">
<value>Bei Ereignis - Protokoll: {0}</value>
<comment>0 = Log name</comment>
</data>
<data name="TriggerEventBasic2" xml:space="preserve">
<value>, Quelle: {0}</value>
<comment>0 = Source name (appended after log)</comment>
</data>
<data name="TriggerEventBasic3" xml:space="preserve">
<value>, EreignisID: {0}</value>
<comment>0 = Event ID (appended after log or source)</comment>
</data>
<data name="TriggerIdle1" xml:space="preserve">
<value>Wenn der Computer inaktiv ist</value>
</data>
<data name="TriggerLogon1" xml:space="preserve">
<value>Bei Anmeldung von {0}</value>
</data>
<data name="TriggerMonthly1" xml:space="preserve">
<value>Um {0:t} am {1} {2}, beginnend mit dem {0:d}</value>
<comment>0 = StartBoundary; 1 = list of Days; 2 = list of Months</comment>
</data>
<data name="TriggerMonthlyDOW1" xml:space="preserve">
<value>Um {0:t} am {1} {2:f} jeden {3}, beginnend mit dem {0:d}</value>
<comment>0 = StartBoundary; 1 = list of weeks of Month; 2 = list of Week Days; 3 = list of Months</comment>
</data>
<data name="TriggerRegistration1" xml:space="preserve">
<value>Bei Aufgabenerstellung oder -modifizierung</value>
</data>
<data name="TriggerRepetition" xml:space="preserve">
<value>Nach Auslösung, alle {0} {1} wiederholen</value>
<comment>0 = Interval; 1= Duration string</comment>
</data>
<data name="TriggerSessionConsoleConnect" xml:space="preserve">
<value>Bei lokaler Verbingung mit {0}.</value>
<comment>0 = UserId</comment>
</data>
<data name="TriggerSessionConsoleDisconnect" xml:space="preserve">
<value>Bei lokaler Trennung von {0}.</value>
<comment>0 = UserId</comment>
</data>
<data name="TriggerSessionRemoteConnect" xml:space="preserve">
<value>Bei Remotverbindung mit {0}.</value>
<comment>0 = UserId</comment>
</data>
<data name="TriggerSessionRemoteDisconnect" xml:space="preserve">
<value>Bei Remottrennung der {0}.</value>
<comment>0 = UserId</comment>
</data>
<data name="TriggerSessionSessionLock" xml:space="preserve">
<value>Beim Sperren der Arbeiststation von {0}.</value>
<comment>0 = UserId</comment>
</data>
<data name="TriggerSessionSessionUnlock" xml:space="preserve">
<value>Beim Entsperren der Arbeiststation von {0}.</value>
<comment>0 = UserId</comment>
</data>
<data name="TriggerSessionUserSession" xml:space="preserve">
<value>Benutzersitzung von {0}</value>
<comment>0 = UserId</comment>
</data>
<data name="TriggerTime1" xml:space="preserve">
<value>Um {0:t} am {0:d}</value>
<comment>0 = StartBoundary</comment>
</data>
<data name="TriggerTypeBoot" xml:space="preserve">
<value>Beim Start</value>
</data>
<data name="TriggerTypeCustom" xml:space="preserve">
<value>Nach einem Zeitplan</value>
</data>
<data name="TriggerTypeDaily" xml:space="preserve">
<value>Täglich</value>
</data>
<data name="TriggerTypeEvent" xml:space="preserve">
<value>Bei einem Ereignis</value>
</data>
<data name="TriggerTypeIdle" xml:space="preserve">
<value>Im Leerlauf</value>
</data>
<data name="TriggerTypeLogon" xml:space="preserve">
<value>Bei Anmeldung</value>
</data>
<data name="TriggerTypeMonthly" xml:space="preserve">
<value>Monatlich</value>
</data>
<data name="TriggerTypeMonthlyDOW" xml:space="preserve">
<value>Monatlich</value>
</data>
<data name="TriggerTypeRegistration" xml:space="preserve">
<value>Bei Aufgabenerstellung/-änderung</value>
</data>
<data name="TriggerTypeSessionStateChange" xml:space="preserve">
<value>Bei Zustandänderung</value>
</data>
<data name="TriggerTypeTime" xml:space="preserve">
<value>Einmal</value>
</data>
<data name="TriggerTypeWeekly" xml:space="preserve">
<value>Wöchentlich</value>
</data>
<data name="TriggerWeekly1Week" xml:space="preserve">
<value>Um {0:t} jeden {1}, beginnend mit dem {0:d}</value>
<comment>0 = StartBoundary; 1 = list of Week Days</comment>
</data>
<data name="TriggerWeeklyMultWeeks" xml:space="preserve">
<value>Um {0:t} jeden {1} alle {2} Wochen, beginnend mit dem {0:d}</value>
<comment>0 = StartBoundary; 1 = list of Week Days; 2 = WeekInterval</comment>
</data>
<data name="WWAllWeeks" xml:space="preserve">
<value>Jede</value>
</data>
<data name="WWFifthWeek" xml:space="preserve">
<value>Fünfte</value>
</data>
<data name="WWFirstWeek" xml:space="preserve">
<value>Erste</value>
</data>
<data name="WWFourthWeek" xml:space="preserve">
<value>Vierte</value>
</data>
<data name="WWLastWeek" xml:space="preserve">
<value>Letzte</value>
</data>
<data name="WWSecondWeek" xml:space="preserve">
<value>Zweite</value>
</data>
<data name="WWThirdWeek" xml:space="preserve">
<value>Dritte</value>
</data>
<data name="TriggerDurationNot0Short" xml:space="preserve">
<value>für {0}</value>
</data>
<data name="TriggerRepetitionShort" xml:space="preserve">
<value>Alle {0} {1}.</value>
</data>
<data name="Error_TriggerEndBeforeStart" xml:space="preserve">
<value>Das Datum und die Uhrzeit, zu der ein Trigger abläuft, müssen nach der Uhrzeit liegen, zu der er gestartet oder aktiviert wird.</value>
</data>
</root>

View File

@ -0,0 +1,333 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="ActionTypeComHandler" xml:space="preserve">
<value>Llamar a un objeto COM</value>
</data>
<data name="ActionTypeExecute" xml:space="preserve">
<value>Iniciar un programa</value>
</data>
<data name="ActionTypeSendEmail" xml:space="preserve">
<value>Enviar un correo electrónico</value>
</data>
<data name="ActionTypeShowMessage" xml:space="preserve">
<value>Mostrar un mensaje</value>
</data>
<data name="ComHandlerAction" xml:space="preserve">
<value>{3} {0:P}</value>
</data>
<data name="DOWAllDays" xml:space="preserve">
<value>todos los días</value>
</data>
<data name="EmailAction" xml:space="preserve">
<value>{1} {0}</value>
</data>
<data name="EndSentence" xml:space="preserve">
<value>.</value>
</data>
<data name="ExecAction" xml:space="preserve">
<value>{0} {1}</value>
</data>
<data name="HyphenSeparator" xml:space="preserve">
<value>-</value>
</data>
<data name="ListSeparator" xml:space="preserve">
<value>,</value>
</data>
<data name="MOYAllMonths" xml:space="preserve">
<value>mensualmente</value>
</data>
<data name="MultipleActions" xml:space="preserve">
<value>Varias acciones definidas.</value>
</data>
<data name="MultipleTriggers" xml:space="preserve">
<value>Se definieron varios desencadenadores</value>
</data>
<data name="ShowMessageAction" xml:space="preserve">
<value>{0}</value>
</data>
<data name="TaskDefaultPrincipal" xml:space="preserve">
<value>Autor</value>
</data>
<data name="TaskStateDisabled" xml:space="preserve">
<value>Deshabilitado</value>
</data>
<data name="TaskStateQueued" xml:space="preserve">
<value>En cola</value>
</data>
<data name="TaskStateReady" xml:space="preserve">
<value>Listo</value>
</data>
<data name="TaskStateRunning" xml:space="preserve">
<value>En ejecución</value>
</data>
<data name="TaskStateUnknown" xml:space="preserve">
<value>Desconocido</value>
</data>
<data name="TriggerAnyUser" xml:space="preserve">
<value>Cualquier usuario</value>
</data>
<data name="TriggerBoot1" xml:space="preserve">
<value>Al iniciar el sistema</value>
</data>
<data name="TriggerCustom1" xml:space="preserve">
<value>Desencadenador personalizado</value>
</data>
<data name="TriggerDaily1" xml:space="preserve">
<value>A las {0:t} cada día</value>
</data>
<data name="TriggerDaily2" xml:space="preserve">
<value>A las {0:t} cada {1} días </value>
</data>
<data name="TriggerDuration0" xml:space="preserve">
<value>indefinidamente</value>
</data>
<data name="TriggerDurationNot0" xml:space="preserve">
<value>para una duración de {0}</value>
</data>
<data name="TriggerEndBoundary" xml:space="preserve">
<value>El desencadenador expira en {0:G}.</value>
</data>
<data name="TriggerEvent1" xml:space="preserve">
<value>Filtro de eventos personalizado</value>
</data>
<data name="TriggerEventBasic1" xml:space="preserve">
<value>Al producirse un evento: {0}</value>
</data>
<data name="TriggerEventBasic2" xml:space="preserve">
<value>, Origen: {0}</value>
</data>
<data name="TriggerEventBasic3" xml:space="preserve">
<value>, Identificador del evento: {0}</value>
</data>
<data name="TriggerIdle1" xml:space="preserve">
<value>Cuando el equipo está inactivo</value>
</data>
<data name="TriggerLogon1" xml:space="preserve">
<value>Cuando {0} inicie sesión</value>
</data>
<data name="TriggerMonthly1" xml:space="preserve">
<value>A las {0:t} el día {1} de {2}, a partir del {0:d}</value>
</data>
<data name="TriggerMonthlyDOW1" xml:space="preserve">
<value>A las {0:t} el {1} {2:f} cada {3}, a partir del {0:d}</value>
</data>
<data name="TriggerRegistration1" xml:space="preserve">
<value>Al crear o modificar la tarea</value>
</data>
<data name="TriggerRepetition" xml:space="preserve">
<value>Después de desencadenarse, repetir cada {0} {1}.</value>
</data>
<data name="TriggerSessionConsoleConnect" xml:space="preserve">
<value>En la conexión local a {0}.</value>
</data>
<data name="TriggerSessionConsoleDisconnect" xml:space="preserve">
<value>En la desconexión local de {0}.</value>
</data>
<data name="TriggerSessionRemoteConnect" xml:space="preserve">
<value>En la conexión remota a {0}.</value>
</data>
<data name="TriggerSessionRemoteDisconnect" xml:space="preserve">
<value>En la desconexión remota desde {0}.</value>
</data>
<data name="TriggerSessionSessionLock" xml:space="preserve">
<value>Cuando {0} bloquee la estación de trabajo</value>
</data>
<data name="TriggerSessionSessionUnlock" xml:space="preserve">
<value>Cuando {0} desbloquee la estación de trabajo</value>
</data>
<data name="TriggerSessionUserSession" xml:space="preserve">
<value>sesión de usuario de {0}</value>
</data>
<data name="TriggerTime1" xml:space="preserve">
<value>A las {0:t} el {0:d}</value>
</data>
<data name="TriggerTypeBoot" xml:space="preserve">
<value>Al inicio</value>
</data>
<data name="TriggerTypeCustom" xml:space="preserve">
<value>Desencadenador personalizado</value>
</data>
<data name="TriggerTypeDaily" xml:space="preserve">
<value>Diariamente</value>
</data>
<data name="TriggerTypeEvent" xml:space="preserve">
<value>Al producirse un evento</value>
</data>
<data name="TriggerTypeIdle" xml:space="preserve">
<value>Al estar inactivo</value>
</data>
<data name="TriggerTypeLogon" xml:space="preserve">
<value>Al iniciar la sesión</value>
</data>
<data name="TriggerTypeMonthly" xml:space="preserve">
<value>Mensual</value>
</data>
<data name="TriggerTypeMonthlyDOW" xml:space="preserve">
<value>Mensual</value>
</data>
<data name="TriggerTypeRegistration" xml:space="preserve">
<value>Al crear o modificar tarea</value>
</data>
<data name="TriggerTypeSessionStateChange" xml:space="preserve">
<value>Al producirse un cambio de estado</value>
</data>
<data name="TriggerTypeTime" xml:space="preserve">
<value>Una vez</value>
</data>
<data name="TriggerTypeWeekly" xml:space="preserve">
<value>Semanalmente</value>
</data>
<data name="TriggerWeekly1Week" xml:space="preserve">
<value>A las {0:t} cada {1} de todas las semanas, a partir del {0:d}</value>
</data>
<data name="TriggerWeeklyMultWeeks" xml:space="preserve">
<value>A las {0:t} cada {1} cada {2} semanas, a partir del {0:d}</value>
</data>
<data name="WWAllWeeks" xml:space="preserve">
<value>cada</value>
</data>
<data name="WWFifthWeek" xml:space="preserve">
<value>quinto</value>
</data>
<data name="WWFirstWeek" xml:space="preserve">
<value>primero</value>
</data>
<data name="WWFourthWeek" xml:space="preserve">
<value>cuarto</value>
</data>
<data name="WWLastWeek" xml:space="preserve">
<value>último</value>
</data>
<data name="WWSecondWeek" xml:space="preserve">
<value>segundo</value>
</data>
<data name="WWThirdWeek" xml:space="preserve">
<value>tercer</value>
</data>
<data name="TriggerRepetitionShort" xml:space="preserve">
<value>Cada {0} {1}.</value>
</data>
<data name="TriggerDurationNot0Short" xml:space="preserve">
<value>para {0}</value>
</data>
<data name="Error_TriggerEndBeforeStart" xml:space="preserve">
<value>La fecha y hora en que expira el activador deben ser posteriores a la hora en que se inicia o se activa.</value>
</data>
</root>

View File

@ -0,0 +1,333 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="ActionTypeExecute" xml:space="preserve">
<value>Démarrer un programme</value>
</data>
<data name="ActionTypeSendEmail" xml:space="preserve">
<value>Envoyer un courrier électronique</value>
</data>
<data name="ActionTypeShowMessage" xml:space="preserve">
<value>Afficher un message</value>
</data>
<data name="ComHandlerAction" xml:space="preserve">
<value>{3} {0:P}</value>
</data>
<data name="DOWAllDays" xml:space="preserve">
<value>tous les jours</value>
</data>
<data name="EmailAction" xml:space="preserve">
<value>{1} {0}</value>
</data>
<data name="EndSentence" xml:space="preserve">
<value>.</value>
</data>
<data name="ExecAction" xml:space="preserve">
<value>{0} {1}</value>
</data>
<data name="HyphenSeparator" xml:space="preserve">
<value>-</value>
</data>
<data name="ListSeparator" xml:space="preserve">
<value>,</value>
</data>
<data name="MOYAllMonths" xml:space="preserve">
<value>chaque mois</value>
</data>
<data name="MultipleActions" xml:space="preserve">
<value>Plusieurs actions définies.</value>
</data>
<data name="MultipleTriggers" xml:space="preserve">
<value>Plusieurs déclencheurs sont définis.</value>
</data>
<data name="ShowMessageAction" xml:space="preserve">
<value>{0}</value>
</data>
<data name="TaskDefaultPrincipal" xml:space="preserve">
<value>Auteur</value>
</data>
<data name="TaskStateDisabled" xml:space="preserve">
<value>Désactivé</value>
</data>
<data name="TaskStateQueued" xml:space="preserve">
<value>En attente</value>
</data>
<data name="TaskStateReady" xml:space="preserve">
<value>Prêt</value>
</data>
<data name="TaskStateRunning" xml:space="preserve">
<value>En cours d'exécution</value>
</data>
<data name="TaskStateUnknown" xml:space="preserve">
<value>Inconnu</value>
</data>
<data name="TriggerAnyUser" xml:space="preserve">
<value>Tout utilisateur</value>
</data>
<data name="TriggerBoot1" xml:space="preserve">
<value>Au démarrage du système</value>
</data>
<data name="TriggerCustom1" xml:space="preserve">
<value>Personnaliser le déclencheur</value>
</data>
<data name="TriggerDuration0" xml:space="preserve">
<value>Indéfiniment</value>
</data>
<data name="TriggerEvent1" xml:space="preserve">
<value>Filtre dévénement personnalisé</value>
</data>
<data name="TriggerEventBasic2" xml:space="preserve">
<value>, Source : {0}</value>
</data>
<data name="TriggerIdle1" xml:space="preserve">
<value>Lorsque lordinateur est inactif</value>
</data>
<data name="TriggerLogon1" xml:space="preserve">
<value>À louverture de session de {0}</value>
</data>
<data name="TriggerRegistration1" xml:space="preserve">
<value>Lors de la création ou de la modification de la tâche</value>
</data>
<data name="TriggerSessionSessionLock" xml:space="preserve">
<value>Lors du verrouillage de la station de travail de {0}.</value>
</data>
<data name="TriggerSessionSessionUnlock" xml:space="preserve">
<value>Lors du déverrouillage de la station de travail de {0}.</value>
</data>
<data name="TriggerSessionUserSession" xml:space="preserve">
<value>session utilisateur de {0}</value>
</data>
<data name="TriggerTypeBoot" xml:space="preserve">
<value>Au démarrage</value>
</data>
<data name="TriggerTypeCustom" xml:space="preserve">
<value>Personnaliser le déclencheur</value>
</data>
<data name="TriggerTypeDaily" xml:space="preserve">
<value>Tous les jours</value>
</data>
<data name="TriggerTypeEvent" xml:space="preserve">
<value>Sur un événement</value>
</data>
<data name="TriggerTypeIdle" xml:space="preserve">
<value>Après une période d'inactivité</value>
</data>
<data name="TriggerTypeLogon" xml:space="preserve">
<value>À louverture de session</value>
</data>
<data name="TriggerTypeMonthly" xml:space="preserve">
<value>Tous les mois</value>
</data>
<data name="TriggerTypeMonthlyDOW" xml:space="preserve">
<value>Tous les mois</value>
</data>
<data name="TriggerTypeRegistration" xml:space="preserve">
<value>Lors de la création/modification de la tâche</value>
</data>
<data name="TriggerTypeSessionStateChange" xml:space="preserve">
<value>Au changement de statut</value>
</data>
<data name="TriggerTypeTime" xml:space="preserve">
<value>Une fois</value>
</data>
<data name="TriggerTypeWeekly" xml:space="preserve">
<value>Hebdomadaire</value>
</data>
<data name="TriggerWeekly1Week" xml:space="preserve">
<value>À {0:t} chaque {1} de chaque semaine, à partir du {0:d}</value>
</data>
<data name="TriggerWeeklyMultWeeks" xml:space="preserve">
<value>À {0:t} chaque {1} de chaque {2} semaines, à partir du {0:d}</value>
</data>
<data name="WWAllWeeks" xml:space="preserve">
<value>toutes les</value>
</data>
<data name="WWFifthWeek" xml:space="preserve">
<value>cinquième</value>
</data>
<data name="WWFirstWeek" xml:space="preserve">
<value>premier</value>
</data>
<data name="WWFourthWeek" xml:space="preserve">
<value>quatrième</value>
</data>
<data name="WWLastWeek" xml:space="preserve">
<value>dernier</value>
</data>
<data name="WWSecondWeek" xml:space="preserve">
<value>deuxième</value>
</data>
<data name="WWThirdWeek" xml:space="preserve">
<value>troisième</value>
</data>
<data name="TriggerDurationNot0Short" xml:space="preserve">
<value>pour {0}</value>
</data>
<data name="TriggerRepetitionShort" xml:space="preserve">
<value>Chaque {0} {1}.</value>
</data>
<data name="TriggerRepetition" xml:space="preserve">
<value>Après déclenché, répéter chaque les {0} {1}.</value>
</data>
<data name="TriggerDurationNot0" xml:space="preserve">
<value>pour une durée de {0}</value>
</data>
<data name="ActionTypeComHandler" xml:space="preserve">
<value>Appeler un objet COM</value>
</data>
<data name="TriggerDaily1" xml:space="preserve">
<value>À {0} tous les jours</value>
</data>
<data name="TriggerDaily2" xml:space="preserve">
<value>À {0} tous les {1} jours</value>
</data>
<data name="TriggerEndBoundary" xml:space="preserve">
<value>Déclencheur expire à {0:G}.</value>
</data>
<data name="TriggerMonthly1" xml:space="preserve">
<value>À {0:t} le jour {1} de {2}, à compter du {0:d}.</value>
</data>
<data name="TriggerMonthlyDOW1" xml:space="preserve">
<value>À {0:t} sur {1} {2} de chaque {3}, à partir du {0:d}.</value>
</data>
<data name="TriggerTime1" xml:space="preserve">
<value>À {0:t} le {0:d}</value>
</data>
<data name="TriggerEventBasic1" xml:space="preserve">
<value>Lors de l'événement - Journal: {0}</value>
</data>
<data name="TriggerEventBasic3" xml:space="preserve">
<value>, ID d'événement: {0}</value>
</data>
<data name="TriggerSessionConsoleConnect" xml:space="preserve">
<value>Lors de la connexion locale à {0}.</value>
</data>
<data name="TriggerSessionRemoteConnect" xml:space="preserve">
<value>Lors de la connexion à distance à {0}.</value>
</data>
<data name="TriggerSessionConsoleDisconnect" xml:space="preserve">
<value>Sur lordinateur local, se déconnecter de {0}.</value>
</data>
<data name="TriggerSessionRemoteDisconnect" xml:space="preserve">
<value>Sur lordinateur distant, se déconnecter de {0}.</value>
</data>
<data name="Error_TriggerEndBeforeStart" xml:space="preserve">
<value>La date et l&amp;#39;heure d&amp;#39;expiration d&amp;#39;un déclencheur doivent être postérieures à son heure de démarrage ou d&amp;#39;activation.!</value>
</data>
</root>

View File

@ -0,0 +1,352 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="ActionTypeComHandler" xml:space="preserve">
<value>Chiamare un oggetto COM</value>
</data>
<data name="ActionTypeExecute" xml:space="preserve">
<value>Avviare un programma</value>
</data>
<data name="ActionTypeSendEmail" xml:space="preserve">
<value>Invia una email</value>
</data>
<data name="ActionTypeShowMessage" xml:space="preserve">
<value>Mostra un messaggio</value>
</data>
<data name="ComHandlerAction" xml:space="preserve">
<value>{3} {0:P}</value>
<comment>0 = Class GUID; 1 = Data; 2 = Id</comment>
</data>
<data name="DOWAllDays" xml:space="preserve">
<value>tutti i giorni</value>
</data>
<data name="EmailAction" xml:space="preserve">
<value>{1} {0}</value>
<comment>0 = Subject; 1 = To; 2 = Cc, 3 = Bcc, 4 = From, 5 = ReplyTo, 6 = Body, 7 = Server, 8 = Id</comment>
</data>
<data name="EndSentence" xml:space="preserve">
<value>.</value>
</data>
<data name="ExecAction" xml:space="preserve">
<value>{0} {1}</value>
<comment>0 = Executable Path; 1 = Arguments; 2 = WorkingDirectory; 3 = Id</comment>
</data>
<data name="ListSeparator" xml:space="preserve">
<value>,</value>
</data>
<data name="MOYAllMonths" xml:space="preserve">
<value>tutti i mesi</value>
</data>
<data name="MultipleActions" xml:space="preserve">
<value>Azioni multiple definite</value>
</data>
<data name="MultipleTriggers" xml:space="preserve">
<value>Attivazione multiple definite</value>
</data>
<data name="ShowMessageAction" xml:space="preserve">
<value>{0}</value>
<comment>0 = Title; 1 = MessageBody; 2 = Id</comment>
</data>
<data name="TaskDefaultPrincipal" xml:space="preserve">
<value>Autore</value>
</data>
<data name="TaskStateDisabled" xml:space="preserve">
<value>Disabile</value>
</data>
<data name="TaskStateQueued" xml:space="preserve">
<value>In coda</value>
</data>
<data name="TaskStateReady" xml:space="preserve">
<value>Pronto</value>
</data>
<data name="TaskStateRunning" xml:space="preserve">
<value>Corsa</value>
</data>
<data name="TaskStateUnknown" xml:space="preserve">
<value>Sconosciuto</value>
</data>
<data name="TriggerAnyUser" xml:space="preserve">
<value>Qualsiasi utente</value>
</data>
<data name="TriggerBoot1" xml:space="preserve">
<value>All'avvio del sistema</value>
</data>
<data name="TriggerDaily1" xml:space="preserve">
<value>A {0:t} ogni giorno</value>
</data>
<data name="TriggerDaily2" xml:space="preserve">
<value>A {0:t} ogni {1} giorni</value>
</data>
<data name="TriggerEvent1" xml:space="preserve">
<value>Evento personalizzato filtro</value>
</data>
<data name="TriggerEventBasic1" xml:space="preserve">
<value>Su evento - Log: {0}</value>
<comment>0 = Log name</comment>
</data>
<data name="TriggerEventBasic2" xml:space="preserve">
<value>, Fonte: {0}</value>
<comment>0 = Source name (appended after log)</comment>
</data>
<data name="TriggerEventBasic3" xml:space="preserve">
<value>, EventID: {0}</value>
<comment>0 = Event ID (appended after log or source)</comment>
</data>
<data name="TriggerIdle1" xml:space="preserve">
<value>Quando il computer è inattivo</value>
</data>
<data name="TriggerLogon1" xml:space="preserve">
<value>A collegarsi di {0}</value>
</data>
<data name="TriggerMonthly1" xml:space="preserve">
<value>A {0:t} sul giorno {1} di {2}, a partire dal {0:d}</value>
<comment>0 = StartBoundary; 1 = list of Days; 2 = list of Months</comment>
</data>
<data name="TriggerMonthlyDOW1" xml:space="preserve">
<value>A {0:t} sul {1} {2:f} ogni {3}, a partire dal {0:d}</value>
<comment>0 = StartBoundary; 1 = list of weeks of Month; 2 = list of Week Days; 3 = list of Months</comment>
</data>
<data name="TriggerRegistration1" xml:space="preserve">
<value>Quando l'attività viene creato o modificato</value>
</data>
<data name="TriggerSessionConsoleConnect" xml:space="preserve">
<value>Sulla connessione locale a {0}.</value>
<comment>0 = UserId</comment>
</data>
<data name="TriggerSessionConsoleDisconnect" xml:space="preserve">
<value>Il locale disconnettersi da {0}.</value>
<comment>0 = UserId</comment>
</data>
<data name="TriggerSessionRemoteConnect" xml:space="preserve">
<value>Sulla connessione remota a {0}.</value>
<comment>0 = UserId</comment>
</data>
<data name="TriggerSessionRemoteDisconnect" xml:space="preserve">
<value>Sul telecomando disconnettersi da {0}.</value>
<comment>0 = UserId</comment>
</data>
<data name="TriggerSessionSessionLock" xml:space="preserve">
<value>Sul blocco della workstation di {0}.</value>
<comment>0 = UserId</comment>
</data>
<data name="TriggerSessionSessionUnlock" xml:space="preserve">
<value>Su sblocco della workstation di {0}.</value>
<comment>0 = UserId</comment>
</data>
<data name="TriggerSessionUserSession" xml:space="preserve">
<value>sessione utente di {0}</value>
<comment>0 = UserId</comment>
</data>
<data name="TriggerTime1" xml:space="preserve">
<value>A {0:t} su {0:d}</value>
<comment>0 = StartBoundary</comment>
</data>
<data name="TriggerTypeBoot" xml:space="preserve">
<value>All'avvio</value>
</data>
<data name="TriggerTypeDaily" xml:space="preserve">
<value>Quotidiano</value>
</data>
<data name="TriggerTypeEvent" xml:space="preserve">
<value>Su un evento</value>
</data>
<data name="TriggerTypeIdle" xml:space="preserve">
<value>Su di inattività</value>
</data>
<data name="TriggerTypeLogon" xml:space="preserve">
<value>A effettuare l'accesso</value>
</data>
<data name="TriggerTypeMonthly" xml:space="preserve">
<value>Mensile</value>
</data>
<data name="TriggerTypeMonthlyDOW" xml:space="preserve">
<value>Mensile</value>
</data>
<data name="TriggerTypeRegistration" xml:space="preserve">
<value>Alla creazione / modifica di attività</value>
</data>
<data name="TriggerTypeTime" xml:space="preserve">
<value>Una volta</value>
</data>
<data name="TriggerTypeWeekly" xml:space="preserve">
<value>Settimanale</value>
</data>
<data name="TriggerWeekly1Week" xml:space="preserve">
<value>A {0:t} ogni {1} di ogni settimana, a partire {0: d}</value>
<comment>0 = StartBoundary; 1 = list of Week Days</comment>
</data>
<data name="TriggerWeeklyMultWeeks" xml:space="preserve">
<value>A {0:t} ogni {1} di {2} ogni settimana, a partire {0:d}</value>
<comment>0 = StartBoundary; 1 = list of Week Days; 2 = WeekInterval</comment>
</data>
<data name="WWAllWeeks" xml:space="preserve">
<value>tutte</value>
</data>
<data name="WWFifthWeek" xml:space="preserve">
<value>quinta</value>
</data>
<data name="WWFirstWeek" xml:space="preserve">
<value>prima</value>
</data>
<data name="WWFourthWeek" xml:space="preserve">
<value>quarta</value>
</data>
<data name="WWLastWeek" xml:space="preserve">
<value>scorsa</value>
</data>
<data name="WWSecondWeek" xml:space="preserve">
<value>seconda</value>
</data>
<data name="WWThirdWeek" xml:space="preserve">
<value>terza</value>
</data>
<data name="HyphenSeparator">
<value>-</value>
</data>
<data name="TriggerDuration0">
<value>indefinitamente</value>
</data>
<data name="TriggerDurationNot0">
<value>per una durata di {0}</value>
</data>
<data name="TriggerEndBoundary">
<value>Attivazione scade {0:G}.</value>
</data>
<data name="TriggerRepetition">
<value>Dopo aver attivato, ripetere ogni {0} {1}.</value>
</data>
<data name="TriggerCustom1" xml:space="preserve">
<value>Attivazione personalizata</value>
</data>
<data name="TriggerTypeCustom" xml:space="preserve">
<value>Attivazione personalizata</value>
</data>
<data name="TriggerRepetitionShort" xml:space="preserve">
<value>Ogni {0} {1}.</value>
</data>
<data name="TriggerDurationNot0Short" xml:space="preserve">
<value>per {0}</value>
</data>
<data name="TriggerTypeSessionStateChange" xml:space="preserve">
<value>Sul cambiamento di stato</value>
</data>
<data name="Error_TriggerEndBeforeStart" xml:space="preserve">
<value>La data e l&amp;#39;ora in cui un trigger scade deve essere successiva al tempo in cui inizia o viene attivato.</value>
</data>
</root>

View File

@ -0,0 +1,333 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="ActionTypeComHandler" xml:space="preserve">
<value>Wywołaj obiekt COM.</value>
</data>
<data name="ActionTypeExecute" xml:space="preserve">
<value>Uruchom program</value>
</data>
<data name="ActionTypeSendEmail" xml:space="preserve">
<value>Wyślij wiadomość e-mail</value>
</data>
<data name="ActionTypeShowMessage" xml:space="preserve">
<value>Wyświetl komunikat</value>
</data>
<data name="ComHandlerAction" xml:space="preserve">
<value>{3} {0:P}</value>
</data>
<data name="DOWAllDays" xml:space="preserve">
<value>Codziennie</value>
</data>
<data name="EmailAction" xml:space="preserve">
<value>{0} z {1}</value>
</data>
<data name="EndSentence" xml:space="preserve">
<value>.</value>
</data>
<data name="ExecAction" xml:space="preserve">
<value>{0} {1}</value>
</data>
<data name="HyphenSeparator" xml:space="preserve">
<value>-</value>
</data>
<data name="ListSeparator" xml:space="preserve">
<value>,</value>
</data>
<data name="MOYAllMonths" xml:space="preserve">
<value>comiesięcznie</value>
</data>
<data name="MultipleActions" xml:space="preserve">
<value>Zdefiniowano wiele akcji</value>
</data>
<data name="MultipleTriggers" xml:space="preserve">
<value>Zdefiniowano wiele wyzwalaczy</value>
</data>
<data name="ShowMessageAction" xml:space="preserve">
<value>{0}</value>
</data>
<data name="TaskDefaultPrincipal" xml:space="preserve">
<value>Autor</value>
</data>
<data name="TaskStateDisabled" xml:space="preserve">
<value>Wyłączony</value>
</data>
<data name="TaskStateQueued" xml:space="preserve">
<value>W kolejce</value>
</data>
<data name="TaskStateReady" xml:space="preserve">
<value>Gotowy</value>
</data>
<data name="TaskStateRunning" xml:space="preserve">
<value>Działa</value>
</data>
<data name="TaskStateUnknown" xml:space="preserve">
<value>Nieznany</value>
</data>
<data name="TriggerAnyUser" xml:space="preserve">
<value>dowolny użytkownik</value>
</data>
<data name="TriggerBoot1" xml:space="preserve">
<value>Przy uruchamienia systemu</value>
</data>
<data name="TriggerCustom1" xml:space="preserve">
<value>Wyzwalacz niestandardowy</value>
</data>
<data name="TriggerDaily1" xml:space="preserve">
<value>Każdego dnia o godzinie {0:t}</value>
</data>
<data name="TriggerDaily2" xml:space="preserve">
<value>O godzinie {0:t} co {1} dni</value>
</data>
<data name="TriggerDuration0" xml:space="preserve">
<value>przez nieokreślony czas</value>
</data>
<data name="TriggerDurationNot0" xml:space="preserve">
<value>przez okres {0}</value>
</data>
<data name="TriggerDurationNot0Short" xml:space="preserve">
<value>przez {0}</value>
</data>
<data name="TriggerEndBoundary" xml:space="preserve">
<value>Wyzwalacz wygasa o {0:G}.</value>
</data>
<data name="TriggerEvent1" xml:space="preserve">
<value>Niestandardowy filtr zdarzeń</value>
</data>
<data name="TriggerEventBasic1" xml:space="preserve">
<value>Przy zdarzeniu - Dziennik: {0}</value>
</data>
<data name="TriggerEventBasic2" xml:space="preserve">
<value>, Źródło: {0}</value>
</data>
<data name="TriggerEventBasic3" xml:space="preserve">
<value>, Identyfikator zdarzenia: {0}</value>
</data>
<data name="TriggerIdle1" xml:space="preserve">
<value>Przy bezczynności</value>
</data>
<data name="TriggerLogon1" xml:space="preserve">
<value>Przy logowaniu {0}</value>
</data>
<data name="TriggerMonthly1" xml:space="preserve">
<value>O godzinie {0:t}, dzień: {1}, miesiąc: {2}, data początkowa: {0:d}</value>
</data>
<data name="TriggerMonthlyDOW1" xml:space="preserve">
<value>Uruchamiane w tygodniu {1}, dzień: {2}, miesiąc: {3}, data początkowa: {0:d}</value>
</data>
<data name="TriggerRegistration1" xml:space="preserve">
<value>Przy tworzeniu/modyfikowaniu zadania</value>
</data>
<data name="TriggerRepetition" xml:space="preserve">
<value>Po wyzwoleniu powtarzaj co {0} przez okres {1}.</value>
</data>
<data name="TriggerRepetitionShort" xml:space="preserve">
<value>Co {0} przez {1}.</value>
</data>
<data name="TriggerSessionConsoleConnect" xml:space="preserve">
<value>Przy połączeniu lokalnym z sesją użytkownika {0}.</value>
</data>
<data name="TriggerSessionConsoleDisconnect" xml:space="preserve">
<value>Przy rozłączeniu lokalnym z sesją użytkownika {0}.</value>
</data>
<data name="TriggerSessionRemoteConnect" xml:space="preserve">
<value>Przy połączeniu zdalnym z sesją użytkownika {0}.</value>
</data>
<data name="TriggerSessionRemoteDisconnect" xml:space="preserve">
<value>Przy rozłączeniu zdalnym z sesją użytkownika {0}.</value>
</data>
<data name="TriggerSessionSessionLock" xml:space="preserve">
<value>Przy zablokowaniu stacji roboczej przez użytkownika {0}.</value>
</data>
<data name="TriggerSessionSessionUnlock" xml:space="preserve">
<value>Przy odblokowaniu stacji roboczej przez użytkownika {0}.</value>
</data>
<data name="TriggerSessionUserSession" xml:space="preserve">
<value>sesja użytkownika {0}</value>
</data>
<data name="TriggerTime1" xml:space="preserve">
<value>O godzinie {0:t} w dniu {0:d}</value>
</data>
<data name="TriggerTypeBoot" xml:space="preserve">
<value>Przy uruchamianiu</value>
</data>
<data name="TriggerTypeCustom" xml:space="preserve">
<value>Wyzwalacz niestandardowy</value>
</data>
<data name="TriggerTypeDaily" xml:space="preserve">
<value>Codziennie</value>
</data>
<data name="TriggerTypeEvent" xml:space="preserve">
<value>Przy zdarzeniu</value>
</data>
<data name="TriggerTypeIdle" xml:space="preserve">
<value>Przy bezczynności</value>
</data>
<data name="TriggerTypeLogon" xml:space="preserve">
<value>Przy logowaniu</value>
</data>
<data name="TriggerTypeMonthly" xml:space="preserve">
<value>Comiesięcznie</value>
</data>
<data name="TriggerTypeMonthlyDOW" xml:space="preserve">
<value>Comiesięcznie</value>
</data>
<data name="TriggerTypeRegistration" xml:space="preserve">
<value>Przy tworzeniu/modyfikowaniu zadania</value>
</data>
<data name="TriggerTypeSessionStateChange" xml:space="preserve">
<value>Przy zmianie stanu sesji</value>
</data>
<data name="TriggerTypeTime" xml:space="preserve">
<value>Jeden raz</value>
</data>
<data name="TriggerTypeWeekly" xml:space="preserve">
<value>Cotygodniowo</value>
</data>
<data name="TriggerWeekly1Week" xml:space="preserve">
<value>O godzinie {0:t}, dzień: {1}, data początkowa: {0:d}</value>
</data>
<data name="TriggerWeeklyMultWeeks" xml:space="preserve">
<value>O godzinie {0:t}, dzień: {1}, odstęp w tygodniach: {2}, data początkowa: {0:d}</value>
</data>
<data name="WWAllWeeks" xml:space="preserve">
<value>Każdy</value>
</data>
<data name="WWFifthWeek" xml:space="preserve">
<value>Piąty</value>
</data>
<data name="WWFirstWeek" xml:space="preserve">
<value>Pierwszy</value>
</data>
<data name="WWFourthWeek" xml:space="preserve">
<value>Czwarty</value>
</data>
<data name="WWLastWeek" xml:space="preserve">
<value>Ostatni</value>
</data>
<data name="WWSecondWeek" xml:space="preserve">
<value>Drugi</value>
</data>
<data name="WWThirdWeek" xml:space="preserve">
<value>Trzeci</value>
</data>
<data name="Error_TriggerEndBeforeStart" xml:space="preserve">
<value>Data i godzina wygaśnięcia wyzwalacza musi być późniejsza niż godzina jego uruchomienia lub aktywacji.</value>
</data>
</root>

View File

@ -0,0 +1,357 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="ActionTypeComHandler" xml:space="preserve">
<value>Call a COM object</value>
</data>
<data name="ActionTypeExecute" xml:space="preserve">
<value>Start a program</value>
</data>
<data name="ActionTypeSendEmail" xml:space="preserve">
<value>Send an e-mail</value>
</data>
<data name="ActionTypeShowMessage" xml:space="preserve">
<value>Display a message</value>
</data>
<data name="ComHandlerAction" xml:space="preserve">
<value>{3} {0:P}</value>
<comment>0 = Class GUID; 1 = Data; 2 = Id; 3 = Name</comment>
</data>
<data name="DOWAllDays" xml:space="preserve">
<value>every day</value>
</data>
<data name="EmailAction" xml:space="preserve">
<value>{1} {0}</value>
<comment>0 = Subject; 1 = To; 2 = Cc, 3 = Bcc, 4 = From, 5 = ReplyTo, 6 = Body, 7 = Server, 8 = Id</comment>
</data>
<data name="EndSentence" xml:space="preserve">
<value>.</value>
</data>
<data name="ExecAction" xml:space="preserve">
<value>{0} {1}</value>
<comment>0 = Executable Path; 1 = Arguments; 2 = WorkingDirectory; 3 = Id</comment>
</data>
<data name="HyphenSeparator" xml:space="preserve">
<value>-</value>
</data>
<data name="ListSeparator" xml:space="preserve">
<value>,</value>
</data>
<data name="MOYAllMonths" xml:space="preserve">
<value>every month</value>
</data>
<data name="MultipleActions" xml:space="preserve">
<value>Multiple actions defined</value>
</data>
<data name="MultipleTriggers" xml:space="preserve">
<value>Multiple triggers defined</value>
</data>
<data name="ShowMessageAction" xml:space="preserve">
<value>{0}</value>
<comment>0 = Title; 1 = MessageBody; 2 = Id</comment>
</data>
<data name="TaskDefaultPrincipal" xml:space="preserve">
<value>Author</value>
</data>
<data name="TaskStateDisabled" xml:space="preserve">
<value>Disabled</value>
</data>
<data name="TaskStateQueued" xml:space="preserve">
<value>Queued</value>
</data>
<data name="TaskStateReady" xml:space="preserve">
<value>Ready</value>
</data>
<data name="TaskStateRunning" xml:space="preserve">
<value>Running</value>
</data>
<data name="TaskStateUnknown" xml:space="preserve">
<value>Unknown</value>
</data>
<data name="TriggerAnyUser" xml:space="preserve">
<value>any user</value>
</data>
<data name="TriggerBoot1" xml:space="preserve">
<value>At system startup</value>
</data>
<data name="TriggerCustom1" xml:space="preserve">
<value>Custom Trigger</value>
</data>
<data name="TriggerDaily1" xml:space="preserve">
<value>At {0:t} every day</value>
</data>
<data name="TriggerDaily2" xml:space="preserve">
<value>At {0:t} every {1} days</value>
</data>
<data name="TriggerDuration0" xml:space="preserve">
<value>indefinitely</value>
</data>
<data name="TriggerDurationNot0" xml:space="preserve">
<value>for a duration of {0}</value>
<comment>0 = Duration</comment>
</data>
<data name="TriggerDurationNot0Short" xml:space="preserve">
<value>for {0}</value>
<comment>0 = Duration</comment>
</data>
<data name="TriggerEndBoundary" xml:space="preserve">
<value>Trigger expires at {0:G}.</value>
<comment>0 = EndBoundary</comment>
</data>
<data name="TriggerEvent1" xml:space="preserve">
<value>Custom event filter</value>
</data>
<data name="TriggerEventBasic1" xml:space="preserve">
<value>On event - Log: {0}</value>
<comment>0 = Log name</comment>
</data>
<data name="TriggerEventBasic2" xml:space="preserve">
<value>, Source: {0}</value>
<comment>0 = Source name (appended after log)</comment>
</data>
<data name="TriggerEventBasic3" xml:space="preserve">
<value>, EventID: {0}</value>
<comment>0 = Event ID (appended after log or source)</comment>
</data>
<data name="TriggerIdle1" xml:space="preserve">
<value>When computer is idle</value>
</data>
<data name="TriggerLogon1" xml:space="preserve">
<value>At log on of {0}</value>
</data>
<data name="TriggerMonthly1" xml:space="preserve">
<value>At {0:t} on day {1} of {2}, starting {0:d}</value>
<comment>0 = StartBoundary; 1 = list of Days; 2 = list of Months</comment>
</data>
<data name="TriggerMonthlyDOW1" xml:space="preserve">
<value>At {0:t} on {1} {2:f} each {3}, starting {0:d}</value>
<comment>0 = StartBoundary; 1 = list of weeks of Month; 2 = list of Week Days; 3 = list of Months</comment>
</data>
<data name="TriggerRegistration1" xml:space="preserve">
<value>When the task is created or modified</value>
</data>
<data name="TriggerRepetition" xml:space="preserve">
<value>After triggered, repeat every {0} {1}.</value>
<comment>0 = Interval; 1= Duration string</comment>
</data>
<data name="TriggerRepetitionShort" xml:space="preserve">
<value>Every {0} {1}.</value>
<comment>0 = Interval; 1= Duration string</comment>
</data>
<data name="TriggerSessionConsoleConnect" xml:space="preserve">
<value>On local connection to {0}.</value>
<comment>0 = UserId</comment>
</data>
<data name="TriggerSessionConsoleDisconnect" xml:space="preserve">
<value>On local disconnect from {0}.</value>
<comment>0 = UserId</comment>
</data>
<data name="TriggerSessionRemoteConnect" xml:space="preserve">
<value>On remote connection to {0}.</value>
<comment>0 = UserId</comment>
</data>
<data name="TriggerSessionRemoteDisconnect" xml:space="preserve">
<value>On remote disconnect from {0}.</value>
<comment>0 = UserId</comment>
</data>
<data name="TriggerSessionSessionLock" xml:space="preserve">
<value>On workstation lock of {0}.</value>
<comment>0 = UserId</comment>
</data>
<data name="TriggerSessionSessionUnlock" xml:space="preserve">
<value>On workstation unlock of {0}.</value>
<comment>0 = UserId</comment>
</data>
<data name="TriggerSessionUserSession" xml:space="preserve">
<value>user session of {0}</value>
<comment>0 = UserId</comment>
</data>
<data name="TriggerTime1" xml:space="preserve">
<value>At {0:t} on {0:d}</value>
<comment>0 = StartBoundary</comment>
</data>
<data name="TriggerTypeBoot" xml:space="preserve">
<value>At startup</value>
</data>
<data name="TriggerTypeCustom" xml:space="preserve">
<value>Custom Trigger</value>
</data>
<data name="TriggerTypeDaily" xml:space="preserve">
<value>Daily</value>
</data>
<data name="TriggerTypeEvent" xml:space="preserve">
<value>On an event</value>
</data>
<data name="TriggerTypeIdle" xml:space="preserve">
<value>On idle</value>
</data>
<data name="TriggerTypeLogon" xml:space="preserve">
<value>At log on</value>
</data>
<data name="TriggerTypeMonthly" xml:space="preserve">
<value>Monthly</value>
</data>
<data name="TriggerTypeMonthlyDOW" xml:space="preserve">
<value>Monthly</value>
</data>
<data name="TriggerTypeRegistration" xml:space="preserve">
<value>At task creation/modification</value>
</data>
<data name="TriggerTypeSessionStateChange" xml:space="preserve">
<value>On state change</value>
</data>
<data name="TriggerTypeTime" xml:space="preserve">
<value>One time</value>
</data>
<data name="TriggerTypeWeekly" xml:space="preserve">
<value>Weekly</value>
</data>
<data name="TriggerWeekly1Week" xml:space="preserve">
<value>At {0:t} every {1} of every week, starting {0:d}</value>
<comment>0 = StartBoundary; 1 = list of Week Days</comment>
</data>
<data name="TriggerWeeklyMultWeeks" xml:space="preserve">
<value>At {0:t} every {1} of every {2} weeks, starting {0:d}</value>
<comment>0 = StartBoundary; 1 = list of Week Days; 2 = WeekInterval</comment>
</data>
<data name="WWAllWeeks" xml:space="preserve">
<value>every</value>
</data>
<data name="WWFifthWeek" xml:space="preserve">
<value>fifth</value>
</data>
<data name="WWFirstWeek" xml:space="preserve">
<value>first</value>
</data>
<data name="WWFourthWeek" xml:space="preserve">
<value>fourth</value>
</data>
<data name="WWLastWeek" xml:space="preserve">
<value>last</value>
</data>
<data name="WWSecondWeek" xml:space="preserve">
<value>second</value>
</data>
<data name="WWThirdWeek" xml:space="preserve">
<value>third</value>
</data>
<data name="Error_TriggerEndBeforeStart" xml:space="preserve">
<value>The date and time a trigger expires must be later than the time time it starts or is activated.</value>
</data>
</root>

View File

@ -0,0 +1,333 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="ActionTypeComHandler" xml:space="preserve">
<value>Вызов COM-объекта</value>
</data>
<data name="ActionTypeExecute" xml:space="preserve">
<value>Запуск программы</value>
</data>
<data name="ActionTypeSendEmail" xml:space="preserve">
<value>Отправить сообщение</value>
</data>
<data name="ActionTypeShowMessage" xml:space="preserve">
<value>Вывод сообщения</value>
</data>
<data name="ComHandlerAction" xml:space="preserve">
<value>{3} {0:P}</value>
</data>
<data name="DOWAllDays" xml:space="preserve">
<value>каждый день</value>
</data>
<data name="EmailAction" xml:space="preserve">
<value>{1} {0}</value>
</data>
<data name="EndSentence" xml:space="preserve">
<value>.</value>
</data>
<data name="ExecAction" xml:space="preserve">
<value>{0} {1}</value>
</data>
<data name="HyphenSeparator" xml:space="preserve">
<value>-</value>
</data>
<data name="ListSeparator" xml:space="preserve">
<value>,</value>
</data>
<data name="MOYAllMonths" xml:space="preserve">
<value>каждый месяц</value>
</data>
<data name="MultipleActions" xml:space="preserve">
<value>Определено несколько действий</value>
</data>
<data name="MultipleTriggers" xml:space="preserve">
<value>Определено несколько триггеров</value>
</data>
<data name="ShowMessageAction" xml:space="preserve">
<value>{0}</value>
</data>
<data name="TaskDefaultPrincipal" xml:space="preserve">
<value>Создатель</value>
</data>
<data name="TaskStateQueued" xml:space="preserve">
<value>В очереди</value>
</data>
<data name="TaskStateReady" xml:space="preserve">
<value>Готово</value>
</data>
<data name="TaskStateRunning" xml:space="preserve">
<value>Выполняется</value>
</data>
<data name="TaskStateUnknown" xml:space="preserve">
<value>Неизвестно</value>
</data>
<data name="TriggerAnyUser" xml:space="preserve">
<value>Пользователь</value>
</data>
<data name="TriggerBoot1" xml:space="preserve">
<value>При запуске системы</value>
</data>
<data name="TriggerCustom1" xml:space="preserve">
<value>Пользовательский триггер</value>
</data>
<data name="TriggerDaily1" xml:space="preserve">
<value>В {0:t} каждый день</value>
</data>
<data name="TriggerDaily2" xml:space="preserve">
<value>В {0:t} каждые {1} дн.</value>
</data>
<data name="TriggerDuration0" xml:space="preserve">
<value>без окончания</value>
</data>
<data name="TriggerDurationNot0" xml:space="preserve">
<value>в течение {0}</value>
</data>
<data name="TriggerDurationNot0Short" xml:space="preserve">
<value>на {0}</value>
</data>
<data name="TriggerEndBoundary" xml:space="preserve">
<value>Срок истечения действия триггера: {0:G}.</value>
</data>
<data name="TriggerEvent1" xml:space="preserve">
<value>Настраиваемое</value>
</data>
<data name="TriggerEventBasic1" xml:space="preserve">
<value>При событии - журнал: {0}</value>
</data>
<data name="TriggerEventBasic2" xml:space="preserve">
<value>, Источник: {0}</value>
</data>
<data name="TriggerEventBasic3" xml:space="preserve">
<value>, EventID: {0}</value>
</data>
<data name="TriggerIdle1" xml:space="preserve">
<value>При бездействии компьютера</value>
</data>
<data name="TriggerLogon1" xml:space="preserve">
<value>При входе {0}</value>
</data>
<data name="TriggerMonthly1" xml:space="preserve">
<value>В {0:t} в {1} день месяца {2}, начиная с {0:d} </value>
</data>
<data name="TriggerMonthlyDOW1" xml:space="preserve">
<value>В {0:t} по {1} {2:f} каждую {3}, начиная c {0:d} </value>
</data>
<data name="TriggerRegistration1" xml:space="preserve">
<value>При создании или изменении задачи</value>
</data>
<data name="TriggerRepetition" xml:space="preserve">
<value>После срабатывания, повторять каждые {0} {1}.</value>
</data>
<data name="TriggerRepetitionShort" xml:space="preserve">
<value>Каждые {0} {1}.</value>
</data>
<data name="TriggerSessionConsoleConnect" xml:space="preserve">
<value>При локальном подключении к {0}.</value>
</data>
<data name="TriggerSessionConsoleDisconnect" xml:space="preserve">
<value>При локальном отключении от {0}.</value>
</data>
<data name="TriggerSessionRemoteConnect" xml:space="preserve">
<value>При удаленном подключении к {0}.</value>
</data>
<data name="TriggerSessionRemoteDisconnect" xml:space="preserve">
<value>При удаленном отключении от {0}.</value>
</data>
<data name="TriggerSessionSessionLock" xml:space="preserve">
<value>При блокировке рабочей станции {0}.</value>
</data>
<data name="TriggerSessionSessionUnlock" xml:space="preserve">
<value>При разблокировке рабочей станции {0}.</value>
</data>
<data name="TriggerSessionUserSession" xml:space="preserve">
<value>Сеанс пользователя {0}</value>
</data>
<data name="TriggerTime1" xml:space="preserve">
<value>В {0:t} на {0:d}</value>
</data>
<data name="TriggerTypeBoot" xml:space="preserve">
<value>При запуске</value>
</data>
<data name="TriggerTypeCustom" xml:space="preserve">
<value>Пользовательский триггер</value>
</data>
<data name="TriggerTypeDaily" xml:space="preserve">
<value>Ежедневно</value>
</data>
<data name="TriggerTypeEvent" xml:space="preserve">
<value>При событии</value>
</data>
<data name="TriggerTypeIdle" xml:space="preserve">
<value>При простое</value>
</data>
<data name="TriggerTypeLogon" xml:space="preserve">
<value>При входе в систему</value>
</data>
<data name="TriggerTypeMonthly" xml:space="preserve">
<value>Ежемесячно</value>
</data>
<data name="TriggerTypeMonthlyDOW" xml:space="preserve">
<value>Ежемесячно</value>
</data>
<data name="TriggerTypeRegistration" xml:space="preserve">
<value>При создании или изменении задачи</value>
</data>
<data name="TriggerTypeSessionStateChange" xml:space="preserve">
<value>При изменении состояния</value>
</data>
<data name="TriggerTypeTime" xml:space="preserve">
<value>Однократно</value>
</data>
<data name="TriggerTypeWeekly" xml:space="preserve">
<value>Еженедельно</value>
</data>
<data name="TriggerWeekly1Week" xml:space="preserve">
<value>В {0:t} по {1} еженедельно, начиная с {0:d}</value>
</data>
<data name="TriggerWeeklyMultWeeks" xml:space="preserve">
<value>В {0:t} по {1} каждую {2} неделю, начиная с {0:d}</value>
</data>
<data name="WWAllWeeks" xml:space="preserve">
<value>каждую</value>
</data>
<data name="WWFifthWeek" xml:space="preserve">
<value>5-ю</value>
</data>
<data name="WWFirstWeek" xml:space="preserve">
<value>1-ю</value>
</data>
<data name="WWFourthWeek" xml:space="preserve">
<value>4-ю</value>
</data>
<data name="WWLastWeek" xml:space="preserve">
<value>последнюю</value>
</data>
<data name="WWSecondWeek" xml:space="preserve">
<value>2-ю</value>
</data>
<data name="WWThirdWeek" xml:space="preserve">
<value>3-ю</value>
</data>
<data name="TaskStateDisabled" xml:space="preserve">
<value>Отключено</value>
</data>
<data name="Error_TriggerEndBeforeStart" xml:space="preserve">
<value>Дата и время окончания триггера должны быть позже времени, когда он запускается или активируется.</value>
</data>
</root>

View File

@ -0,0 +1,333 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="ActionTypeComHandler" xml:space="preserve">
<value>调用COM对象</value>
</data>
<data name="ActionTypeExecute" xml:space="preserve">
<value>启动程序</value>
</data>
<data name="ActionTypeSendEmail" xml:space="preserve">
<value>发送电子邮件</value>
</data>
<data name="ActionTypeShowMessage" xml:space="preserve">
<value>显示一条消息</value>
</data>
<data name="ComHandlerAction" xml:space="preserve">
<value>{3} {0:P}</value>
</data>
<data name="DOWAllDays" xml:space="preserve">
<value>每天</value>
</data>
<data name="EmailAction" xml:space="preserve">
<value>{1} {0}</value>
</data>
<data name="EndSentence" xml:space="preserve">
<value>.</value>
</data>
<data name="ExecAction" xml:space="preserve">
<value>{0} {1}</value>
</data>
<data name="HyphenSeparator" xml:space="preserve">
<value>-</value>
</data>
<data name="ListSeparator" xml:space="preserve">
<value>,</value>
</data>
<data name="MOYAllMonths" xml:space="preserve">
<value>每月</value>
</data>
<data name="MultipleActions" xml:space="preserve">
<value>已定义多个操作</value>
</data>
<data name="MultipleTriggers" xml:space="preserve">
<value>已定义多个触发器</value>
</data>
<data name="ShowMessageAction" xml:space="preserve">
<value>{0}</value>
</data>
<data name="TaskDefaultPrincipal" xml:space="preserve">
<value>创建者</value>
</data>
<data name="TaskStateDisabled" xml:space="preserve">
<value>禁用</value>
</data>
<data name="TaskStateQueued" xml:space="preserve">
<value>排队</value>
</data>
<data name="TaskStateReady" xml:space="preserve">
<value>准备</value>
</data>
<data name="TaskStateRunning" xml:space="preserve">
<value>运行中</value>
</data>
<data name="TaskStateUnknown" xml:space="preserve">
<value>未知</value>
</data>
<data name="TriggerAnyUser" xml:space="preserve">
<value>任何人</value>
</data>
<data name="TriggerBoot1" xml:space="preserve">
<value>当系统启动</value>
</data>
<data name="TriggerDaily1" xml:space="preserve">
<value>每天 {0:t}</value>
</data>
<data name="TriggerDaily2" xml:space="preserve">
<value>每 {1} 天 {0:t}</value>
</data>
<data name="TriggerDuration0" xml:space="preserve">
<value>无限</value>
</data>
<data name="TriggerDurationNot0" xml:space="preserve">
<value>持续时间{0}</value>
</data>
<data name="TriggerEndBoundary" xml:space="preserve">
<value>触发器过期于{0:G}</value>
</data>
<data name="TriggerEvent1" xml:space="preserve">
<value>自定义时间过滤器</value>
</data>
<data name="TriggerEventBasic1" xml:space="preserve">
<value>当时间 日志: {0}</value>
</data>
<data name="TriggerEventBasic2" xml:space="preserve">
<value>, 源: {0}</value>
</data>
<data name="TriggerEventBasic3" xml:space="preserve">
<value>, 事件ID: {0}</value>
</data>
<data name="TriggerIdle1" xml:space="preserve">
<value>当计算机空闲</value>
</data>
<data name="TriggerLogon1" xml:space="preserve">
<value>在用户 {0} 登陆</value>
</data>
<data name="TriggerMonthly1" xml:space="preserve">
<value>每年 {2} 的 {1} {0:t}, 从 {0:d} 开始</value>
</data>
<data name="TriggerMonthlyDOW1" xml:space="preserve">
<value>每年 {3} 的 {1} 的 {2:f} {0:t}, 从 {0:d} 开始</value>
</data>
<data name="TriggerRegistration1" xml:space="preserve">
<value>当任务被创建或修改</value>
</data>
<data name="TriggerRepetition" xml:space="preserve">
<value>触发后,每 {0}{1}</value>
</data>
<data name="TriggerSessionConsoleConnect" xml:space="preserve">
<value>当用户 {0} 本地连线</value>
</data>
<data name="TriggerSessionConsoleDisconnect" xml:space="preserve">
<value>当用户 {0} 本地断线。</value>
</data>
<data name="TriggerSessionRemoteConnect" xml:space="preserve">
<value>当用户 {0} 远程连线。</value>
</data>
<data name="TriggerSessionRemoteDisconnect" xml:space="preserve">
<value>当用户 {0} 远程断线。</value>
</data>
<data name="TriggerSessionSessionLock" xml:space="preserve">
<value>当用户 {0} 工作站被锁。</value>
</data>
<data name="TriggerSessionSessionUnlock" xml:space="preserve">
<value>当用户 {0} 工作站解锁。</value>
</data>
<data name="TriggerSessionUserSession" xml:space="preserve">
<value>用户 {0} 的会话</value>
</data>
<data name="TriggerTime1" xml:space="preserve">
<value>当 {0:d} {0:t}</value>
</data>
<data name="TriggerTypeBoot" xml:space="preserve">
<value>当启动</value>
</data>
<data name="TriggerTypeDaily" xml:space="preserve">
<value>每天</value>
</data>
<data name="TriggerTypeEvent" xml:space="preserve">
<value>当事件</value>
</data>
<data name="TriggerTypeIdle" xml:space="preserve">
<value>当空闲</value>
</data>
<data name="TriggerTypeLogon" xml:space="preserve">
<value>当登录</value>
</data>
<data name="TriggerTypeMonthly" xml:space="preserve">
<value>每月</value>
</data>
<data name="TriggerTypeMonthlyDOW" xml:space="preserve">
<value>每月</value>
</data>
<data name="TriggerTypeRegistration" xml:space="preserve">
<value>在創建或修改一個任務</value>
</data>
<data name="TriggerTypeSessionStateChange" xml:space="preserve">
<value>当状态改变</value>
</data>
<data name="TriggerTypeTime" xml:space="preserve">
<value>一次</value>
</data>
<data name="TriggerTypeWeekly" xml:space="preserve">
<value>每周</value>
</data>
<data name="TriggerWeekly1Week" xml:space="preserve">
<value>每周的 {1} {0:t}, 从 {0:d} 开始</value>
</data>
<data name="TriggerWeeklyMultWeeks" xml:space="preserve">
<value>每 {2} 周的 {1} {0:t}, 从 {0:d} 开始</value>
</data>
<data name="WWAllWeeks" xml:space="preserve">
<value>每</value>
</data>
<data name="WWFifthWeek" xml:space="preserve">
<value>第五周</value>
</data>
<data name="WWFirstWeek" xml:space="preserve">
<value>第一周</value>
</data>
<data name="WWFourthWeek" xml:space="preserve">
<value>第四周</value>
</data>
<data name="WWLastWeek" xml:space="preserve">
<value>上周</value>
</data>
<data name="WWSecondWeek" xml:space="preserve">
<value>第二周</value>
</data>
<data name="WWThirdWeek" xml:space="preserve">
<value>第三周</value>
</data>
<data name="TriggerTypeCustom" xml:space="preserve">
<value>定制触发器</value>
</data>
<data name="TriggerCustom1" xml:space="preserve">
<value>定制触发器</value>
</data>
<data name="TriggerRepetitionShort" xml:space="preserve">
<value>每隔{0}{1}</value>
</data>
<data name="TriggerDurationNot0Short" xml:space="preserve">
<value>{0}</value>
</data>
<data name="Error_TriggerEndBeforeStart" xml:space="preserve">
<value>触发器到期的日期和时间必须晚于其启动或激活的时间。</value>
</data>
</root>

View File

@ -2,6 +2,8 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Management;
using System.Text.RegularExpressions;
@ -267,57 +269,7 @@ namespace winPEAS
return results;
}
//////////////////////////////////////
/////// Get Autorun Registry ////////
//////////////////////////////////////
/// Find Autoru registry where you have write or equivalent access
public static List<Dictionary<string, string>> GetRegistryAutoRuns(Dictionary<string,string> NtAccountNames)
{
List<Dictionary<string, string>> results = new List<Dictionary<string, string>>();
try
{
string[] autorunLocations = new string[] {
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run",
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce",
"SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Run",
"SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\RunOnce",
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunService",
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnceService",
"SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\RunService",
"SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\RunOnceService"
};
foreach (string autorunLocation in autorunLocations)
{
Dictionary<string, object> settings = MyUtils.GetRegValues("HKLM", autorunLocation);
if ((settings != null) && (settings.Count != 0))
{
foreach (KeyValuePair<string, object> kvp in settings)
{
RegistryKey key = Registry.LocalMachine.OpenSubKey(autorunLocation);
string filepath = Environment.ExpandEnvironmentVariables(String.Format("{0}", kvp.Value));
string folder = System.IO.Path.GetDirectoryName(filepath.Replace("'", "").Replace("\"", ""));
results.Add(new Dictionary<string, string>() {
{ "Reg", "HKLM\\"+autorunLocation },
{ "Folder", folder },
{ "File", filepath },
{ "RegPermissions", string.Join(", ", MyUtils.GetMyPermissionsR(key, NtAccountNames)) },
{ "interestingFolderRights", String.Join(", ", MyUtils.GetPermissionsFolder(folder, Program.currentUserSIDs))},
{ "interestingFileRights", String.Join(", ", MyUtils.GetPermissionsFile(filepath, Program.currentUserSIDs))},
{ "isUnquotedSpaced", MyUtils.CheckQuoteAndSpace(filepath).ToString() }
});
}
}
}
}
catch (Exception ex)
{
Beaprint.GrayPrint(String.Format(" [X] Exception: {0}", ex.Message));
}
return results;
}
//////////////////////////////////////
//////// PATH DLL Hijacking /////////
//////////////////////////////////////

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,616 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Xml.Serialization;
using JetBrains.Annotations;
namespace Microsoft.Win32.TaskScheduler
{
/// <summary>
/// Options for when to convert actions to PowerShell equivalents.
/// </summary>
[Flags]
public enum PowerShellActionPlatformOption
{
/// <summary>
/// Never convert any actions to PowerShell. This will force exceptions to be thrown when unsupported actions our action quantities are found.
/// </summary>
Never = 0,
/// <summary>
/// Convert actions under Version 1 of the library (Windows XP or Windows Server 2003 and earlier). This option supports multiple actions of all types.
/// If not specified, only a single <see cref="ExecAction"/> is supported. Developer must ensure that PowerShell v2 or higher is installed on the target computer.
/// </summary>
Version1 = 1,
/// <summary>
/// Convert all <see cref="ShowMessageAction"/> and <see cref="EmailAction"/> references to their PowerShell equivalents on systems on or after Windows 8 / Server 2012.
/// </summary>
Version2 = 2,
/// <summary>
/// Convert all actions regardless of version or operating system.
/// </summary>
All = 3
}
/// <summary>
/// Collection that contains the actions that are performed by the task.
/// </summary>
[XmlRoot("Actions", Namespace = TaskDefinition.tns, IsNullable = false)]
[PublicAPI]
public sealed class ActionCollection : IList<Action>, IDisposable, IXmlSerializable, IList
{
internal const int MaxActions = 32;
private List<Action> v1Actions;
private V1Interop.ITask v1Task;
private V2Interop.IActionCollection v2Coll;
private V2Interop.ITaskDefinition v2Def;
private PowerShellActionPlatformOption psConvert = PowerShellActionPlatformOption.Version2;
private static readonly string psV2IdRegex = $"(?:; )?{nameof(PowerShellConversion)}=(?<v>0|1)";
internal ActionCollection([NotNull] V1Interop.ITask task)
{
v1Task = task;
v1Actions = GetV1Actions();
PowerShellConversion = Action.TryParse(v1Task.GetDataItem(nameof(PowerShellConversion)), psConvert | PowerShellActionPlatformOption.Version2);
}
internal ActionCollection([NotNull] V2Interop.ITaskDefinition iTaskDef)
{
v2Def = iTaskDef;
v2Coll = iTaskDef.Actions;
System.Text.RegularExpressions.Match match;
if (iTaskDef.Data != null && (match = System.Text.RegularExpressions.Regex.Match(iTaskDef.Data, psV2IdRegex)).Success)
{
var on = false;
try { on = bool.Parse(match.Groups["v"].Value); } catch { try { on = int.Parse(match.Groups["v"].Value) == 1; } catch { } }
if (on)
psConvert |= PowerShellActionPlatformOption.Version2;
else
psConvert &= ~PowerShellActionPlatformOption.Version2;
}
UnconvertUnsupportedActions();
}
/// <summary>
/// Gets or sets the identifier of the principal for the task.
/// </summary>
[XmlAttribute]
[DefaultValue(null)]
[CanBeNull]
public string Context
{
get
{
if (v2Coll != null)
return v2Coll.Context;
return v1Task.GetDataItem("ActionCollectionContext");
}
set
{
if (v2Coll != null)
v2Coll.Context = value;
else
v1Task.SetDataItem("ActionCollectionContext", value);
}
}
/// <summary>
/// Gets the number of actions in the collection.
/// </summary>
public int Count => (v2Coll != null) ? v2Coll.Count : v1Actions.Count;
bool ICollection.IsSynchronized => false;
object ICollection.SyncRoot => this;
bool ICollection<Action>.IsReadOnly => false;
bool IList.IsFixedSize => false;
bool IList.IsReadOnly => false;
/// <summary>Gets or sets the systems under which unsupported actions will be converted to PowerShell <see cref="ExecAction"/> instances.</summary>
/// <value>The PowerShell platform options.</value>
/// <remarks>This property will affect how many actions are physically stored in the system and is tied to the version of Task Scheduler.
/// <para>If set to <see cref="PowerShellActionPlatformOption.Never"/>, then no actions will ever be converted to PowerShell. This will force exceptions to be thrown when unsupported actions our action quantities are found.</para>
/// <para>If set to <see cref="PowerShellActionPlatformOption.Version1"/>, then actions will be converted only under Version 1 of the library (Windows XP or Windows Server 2003 and earlier). This option supports multiple actions of all types. If not specified, only a single <see cref="ExecAction"/> is supported. Developer must ensure that PowerShell v2 or higher is installed on the target computer.</para>
/// <para>If set to <see cref="PowerShellActionPlatformOption.Version2"/> (which is the default value), then <see cref="ShowMessageAction"/> and <see cref="EmailAction"/> references will be converted to their PowerShell equivalents on systems on or after Windows 8 / Server 2012.</para>
/// <para>If set to <see cref="PowerShellActionPlatformOption.All"/>, then any actions not supported by the Task Scheduler version will be converted to PowerShell.</para>
/// </remarks>
[DefaultValue(typeof(PowerShellActionPlatformOption), "Version2")]
public PowerShellActionPlatformOption PowerShellConversion
{
get { return psConvert; }
set
{
if (psConvert != value)
{
psConvert = value;
if (v1Task != null)
v1Task.SetDataItem(nameof(PowerShellConversion), value.ToString());
if (v2Def != null)
{
if (!string.IsNullOrEmpty(v2Def.Data))
v2Def.Data = System.Text.RegularExpressions.Regex.Replace(v2Def.Data, psV2IdRegex, "");
if (!SupportV2Conversion)
v2Def.Data = string.Format("{0}; {1}=0", v2Def.Data, nameof(PowerShellConversion));
}
}
}
}
private bool SupportV1Conversion => (PowerShellConversion & PowerShellActionPlatformOption.Version1) != 0;
private bool SupportV2Conversion => (PowerShellConversion & PowerShellActionPlatformOption.Version2) != 0;
object IList.this[int index]
{
get { return this[index]; }
set { this[index] = (Action)value; }
}
/// <summary>
/// Gets or sets a an action at the specified index.
/// </summary>
/// <value>The zero-based index of the action to get or set.</value>
[NotNull]
public Action this[int index]
{
get
{
if (v2Coll != null)
return Action.CreateAction(v2Coll[++index]);
if (v1Task != null)
{
if (SupportV1Conversion)
return v1Actions[index];
else
{
if (index == 0)
return v1Actions[0];
}
}
throw new ArgumentOutOfRangeException();
}
set
{
if (Count <= index)
throw new ArgumentOutOfRangeException(nameof(index), index, "Index is not a valid index in the ActionCollection");
if (v2Coll != null)
{
Insert(index, value);
RemoveAt(index + 1);
}
else
{
v1Actions[index] = value;
SaveV1Actions();
}
}
}
/// <summary>
/// Adds an action to the task.
/// </summary>
/// <typeparam name="TAction">A type derived from <see cref="Action"/>.</typeparam>
/// <param name="action">A derived <see cref="Action"/> class.</param>
/// <returns>The bound <see cref="Action"/> that was added to the collection.</returns>
[NotNull]
public TAction Add<TAction>([NotNull] TAction action) where TAction : Action
{
if (action == null)
throw new ArgumentNullException(nameof(action));
if (v2Def != null)
action.Bind(v2Def);
else
{
if (!SupportV1Conversion && (v1Actions.Count >= 1 || !(action is ExecAction)))
throw new NotV1SupportedException($"Only a single {nameof(ExecAction)} is supported unless the {nameof(PowerShellConversion)} property includes the {nameof(PowerShellActionPlatformOption.Version1)} value.");
v1Actions.Add(action);
SaveV1Actions();
}
return action;
}
/// <summary>
/// Adds a new <see cref="Action"/> instance to the task.
/// </summary>
/// <param name="actionType">Type of task to be created</param>
/// <returns>Specialized <see cref="Action"/> instance.</returns>
[NotNull]
public Action AddNew(TaskActionType actionType)
{
if (Count >= MaxActions)
throw new ArgumentOutOfRangeException(nameof(actionType), "A maximum of 32 actions is allowed within a single task.");
if (v1Task != null)
{
if (!SupportV1Conversion && (v1Actions.Count >= 1 || actionType != TaskActionType.Execute))
throw new NotV1SupportedException($"Only a single {nameof(ExecAction)} is supported unless the {nameof(PowerShellConversion)} property includes the {nameof(PowerShellActionPlatformOption.Version1)} value.");
return Action.CreateAction(v1Task);
}
return Action.CreateAction(v2Coll.Create(actionType));
}
/// <summary>
/// Clears all actions from the task.
/// </summary>
public void Clear()
{
if (v2Coll != null)
v2Coll.Clear();
else
{
v1Actions.Clear();
SaveV1Actions();
}
}
/// <summary>
/// Determines whether the <see cref="T:System.Collections.Generic.ICollection`1" /> contains a specific value.
/// </summary>
/// <param name="item">The object to locate in the <see cref="T:System.Collections.Generic.ICollection`1" />.</param>
/// <returns>
/// true if <paramref name="item" /> is found in the <see cref="T:System.Collections.Generic.ICollection`1" />; otherwise, false.
/// </returns>
public bool Contains([NotNull] Action item) => Find(a => a.Equals(item)) != null;
/// <summary>
/// Copies the elements of the <see cref="ActionCollection" /> to an array of <see cref="Action" />, starting at a particular index.
/// </summary>
/// <param name="array">The <see cref="Action" /> array that is the destination of the elements copied from <see cref="ActionCollection" />. The <see cref="Action" /> array must have zero-based indexing.</param>
/// <param name="arrayIndex">The zero-based index in <see cref="Action" /> array at which copying begins.</param>
public void CopyTo(Action[] array, int arrayIndex)
{
CopyTo(0, array, arrayIndex, Count);
}
/// <summary>
/// Copies the elements of the <see cref="ActionCollection" /> to an <see cref="Action" /> array, starting at a particular <see cref="Action" /> array index.
/// </summary>
/// <param name="index">The zero-based index in the source at which copying begins.</param>
/// <param name="array">The <see cref="Action" /> array that is the destination of the elements copied from <see cref="ActionCollection" />. The <see cref="Action" /> array must have zero-based indexing.</param>
/// <param name="arrayIndex">The zero-based index in <see cref="Action" /> array at which copying begins.</param>
/// <param name="count">The number of elements to copy.</param>
/// <exception cref="System.ArgumentNullException"><paramref name="array" /> is null.</exception>
/// <exception cref="System.ArgumentOutOfRangeException"><paramref name="arrayIndex" /> is less than 0.</exception>
/// <exception cref="System.ArgumentException">The number of elements in the source <see cref="ActionCollection" /> is greater than the available space from <paramref name="arrayIndex" /> to the end of the destination <paramref name="array" />.</exception>
public void CopyTo(int index, [NotNull] Action[] array, int arrayIndex, int count)
{
if (array == null)
throw new ArgumentNullException(nameof(array));
if (index < 0 || index >= Count)
throw new ArgumentOutOfRangeException(nameof(index));
if (arrayIndex < 0)
throw new ArgumentOutOfRangeException(nameof(arrayIndex));
if (count < 0 || count > (Count - index))
throw new ArgumentOutOfRangeException(nameof(count));
if ((Count - index) > (array.Length - arrayIndex))
throw new ArgumentOutOfRangeException(nameof(arrayIndex));
for (int i = 0; i < count; i++)
array[arrayIndex + i] = (Action)this[index + i].Clone();
}
/// <summary>
/// Releases all resources used by this class.
/// </summary>
public void Dispose()
{
v1Task = null;
v2Def = null;
if (v2Coll != null) Marshal.ReleaseComObject(v2Coll);
}
/// <summary>
/// Searches for an <see cref="Action"/> that matches the conditions defined by the specified predicate, and returns the first occurrence within the entire collection.
/// </summary>
/// <param name="match">The <see cref="Predicate{Action}"/> delegate that defines the conditions of the <see cref="Action"/> to search for.</param>
/// <returns>The first <see cref="Action"/> that matches the conditions defined by the specified predicate, if found; otherwise, <c>null</c>.</returns>
public Action Find(Predicate<Action> match)
{
if (match == null)
throw new ArgumentNullException(nameof(match));
foreach (var item in this)
if (match(item)) return item;
return null;
}
/// <summary>
/// Searches for an <see cref="Action"/> that matches the conditions defined by the specified predicate, and returns the zero-based index of the first occurrence within the collection that starts at the specified index and contains the specified number of elements.
/// </summary>
/// <param name="startIndex">The zero-based starting index of the search.</param>
/// <param name="count">The number of elements in the collection to search.</param>
/// <param name="match">The <see cref="Predicate{Action}"/> delegate that defines the conditions of the element to search for.</param>
/// <returns>The zero-based index of the first occurrence of an element that matches the conditions defined by match, if found; otherwise, 1.</returns>
public int FindIndexOf(int startIndex, int count, [NotNull] Predicate<Action> match)
{
if (startIndex < 0 || startIndex >= Count)
throw new ArgumentOutOfRangeException(nameof(startIndex));
if (startIndex + count > Count)
throw new ArgumentOutOfRangeException(nameof(count));
if (match == null)
throw new ArgumentNullException(nameof(match));
for (int i = startIndex; i < startIndex + count; i++)
if (match(this[i])) return i;
return -1;
}
/// <summary>
/// Searches for an <see cref="Action"/> that matches the conditions defined by the specified predicate, and returns the zero-based index of the first occurrence within the collection.
/// </summary>
/// <param name="match">The <see cref="Predicate{Action}"/> delegate that defines the conditions of the element to search for.</param>
/// <returns>The zero-based index of the first occurrence of an element that matches the conditions defined by match, if found; otherwise, 1.</returns>
public int FindIndexOf([NotNull] Predicate<Action> match) => FindIndexOf(0, Count, match);
/// <summary>
/// Retrieves an enumeration of each of the actions.
/// </summary>
/// <returns>Returns an object that implements the <see cref="IEnumerator"/> interface and that can iterate through the <see cref="Action"/> objects within the <see cref="ActionCollection"/>.</returns>
public IEnumerator<Action> GetEnumerator()
{
if (v2Coll != null)
return new ComEnumerator<Action, V2Interop.IAction>(() => v2Coll.Count, i => v2Coll[i], Action.CreateAction);
return v1Actions.GetEnumerator();
}
void ICollection.CopyTo(Array array, int index)
{
if (array != null && array.Rank != 1)
throw new RankException("Multi-dimensional arrays are not supported.");
Action[] src = new Action[Count];
CopyTo(src, 0);
Array.Copy(src, 0, array, index, Count);
}
void ICollection<Action>.Add(Action item)
{
Add(item);
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
int IList.Add(object value)
{
Add((Action)value);
return Count - 1;
}
bool IList.Contains(object value) => Contains((Action)value);
int IList.IndexOf(object value) => IndexOf((Action)value);
void IList.Insert(int index, object value)
{
Insert(index, (Action)value);
}
void IList.Remove(object value)
{
Remove((Action)value);
}
/// <summary>
/// Determines the index of a specific item in the <see cref="T:System.Collections.Generic.IList`1" />.
/// </summary>
/// <param name="item">The object to locate in the <see cref="T:System.Collections.Generic.IList`1" />.</param>
/// <returns>
/// The index of <paramref name="item" /> if found in the list; otherwise, -1.
/// </returns>
public int IndexOf(Action item) => FindIndexOf(a => a.Equals(item));
/// <summary>
/// Inserts an action at the specified index.
/// </summary>
/// <param name="index">The zero-based index at which action should be inserted.</param>
/// <param name="action">The action to insert into the list.</param>
public void Insert(int index, [NotNull] Action action)
{
if (action == null)
throw new ArgumentNullException(nameof(action));
if (index < 0 || index > Count)
throw new ArgumentOutOfRangeException(nameof(index));
if (v2Coll != null)
{
Action[] pushItems = new Action[Count - index];
if (Count != index)
{
CopyTo(index, pushItems, 0, Count - index);
for (int j = Count - 1; j >= index; j--)
RemoveAt(j);
}
Add(action);
if (Count != index)
for (int k = 0; k < pushItems.Length; k++)
Add(pushItems[k]);
}
else
{
if (!SupportV1Conversion && (index > 0 || !(action is ExecAction)))
throw new NotV1SupportedException($"Only a single {nameof(ExecAction)} is supported unless the {nameof(PowerShellConversion)} property includes the {nameof(PowerShellActionPlatformOption.Version1)} value.");
v1Actions.Insert(index, action);
SaveV1Actions();
}
}
System.Xml.Schema.XmlSchema IXmlSerializable.GetSchema() => null;
void IXmlSerializable.ReadXml(System.Xml.XmlReader reader)
{
reader.ReadStartElement(XmlSerializationHelper.GetElementName(this), TaskDefinition.tns);
Context = reader.GetAttribute("Context");
while (reader.MoveToContent() == System.Xml.XmlNodeType.Element)
{
Action a = Action.CreateAction(Action.TryParse(reader.LocalName == "Exec" ? "Execute" : reader.LocalName, TaskActionType.Execute));
XmlSerializationHelper.ReadObject(reader, a);
this.Add(a);
}
reader.ReadEndElement();
}
void IXmlSerializable.WriteXml(System.Xml.XmlWriter writer)
{
// TODO:FIX if (!string.IsNullOrEmpty(Context)) writer.WriteAttributeString("Context", Context);
foreach (var item in this)
XmlSerializationHelper.WriteObject(writer, item);
}
/// <summary>
/// Removes the first occurrence of a specific object from the <see cref="T:System.Collections.Generic.ICollection`1" />.
/// </summary>
/// <param name="item">The object to remove from the <see cref="T:System.Collections.Generic.ICollection`1" />.</param>
/// <returns>
/// true if <paramref name="item" /> was successfully removed from the <see cref="T:System.Collections.Generic.ICollection`1" />; otherwise, false. This method also returns false if <paramref name="item" /> is not found in the original <see cref="T:System.Collections.Generic.ICollection`1" />.
/// </returns>
public bool Remove([NotNull] Action item)
{
int idx = IndexOf(item);
if (idx != -1)
{
try
{
RemoveAt(idx);
return true;
}
catch { }
}
return false;
}
/// <summary>
/// Removes the action at a specified index.
/// </summary>
/// <param name="index">Index of action to remove.</param>
/// <exception cref="ArgumentOutOfRangeException">Index out of range.</exception>
public void RemoveAt(int index)
{
if (index >= Count)
throw new ArgumentOutOfRangeException(nameof(index), index, "Failed to remove action. Index out of range.");
if (v2Coll != null)
v2Coll.Remove(++index);
else
{
v1Actions.RemoveAt(index);
SaveV1Actions();
}
}
/// <summary>
/// Returns a <see cref="System.String"/> that represents the actions in this collection.
/// </summary>
/// <returns>
/// A <see cref="System.String"/> that represents the actions in this collection.
/// </returns>
public override string ToString()
{
if (Count == 1)
return this[0].ToString();
if (Count > 1)
return winPEAS.Properties.Resources.MultipleActions;
return string.Empty;
}
internal void ConvertUnsupportedActions()
{
if (TaskService.LibraryVersion.Minor > 3 && SupportV2Conversion)
{
for (int i = 0; i < Count; i++)
{
Action action = this[i];
var bindable = action as IBindAsExecAction;
if (bindable != null && !(action is ComHandlerAction))
this[i] = ExecAction.ConvertToPowerShellAction(action);
}
}
}
private void UnconvertUnsupportedActions()
{
if (TaskService.LibraryVersion.Minor > 3)
{
for (int i = 0; i < Count; i++)
{
ExecAction action = this[i] as ExecAction;
if (action != null)
{
Action newAction = Action.ConvertFromPowerShellAction(action);
if (newAction != null)
this[i] = newAction;
}
}
}
}
private List<Action> GetV1Actions()
{
List<Action> ret = new List<Action>();
if (v1Task != null && v1Task.GetDataItem("ActionType") != "EMPTY")
{
var exec = new ExecAction(v1Task);
var items = exec.ParsePowerShellItems();
if (items != null)
{
if (items.Length == 2 && items[0] == "MULTIPLE")
{
PowerShellConversion |= PowerShellActionPlatformOption.Version1;
var mc = System.Text.RegularExpressions.Regex.Matches(items[1], @"<# (?<id>\w+):(?<t>\w+) #>\s*(?<c>[^<#]*)\s*");
foreach (System.Text.RegularExpressions.Match ms in mc)
{
var a = Action.ActionFromScript(ms.Groups["t"].Value, ms.Groups["c"].Value);
if (a != null)
{
if (ms.Groups["id"].Value != "NO_ID")
a.Id = ms.Groups["id"].Value;
ret.Add(a);
}
}
}
else
ret.Add(ExecAction.ConvertFromPowerShellAction(exec));
}
else if (!string.IsNullOrEmpty(exec.Path))
{
ret.Add(exec);
}
}
return ret;
}
private void SaveV1Actions()
{
if (v1Task == null)
throw new ArgumentNullException(nameof(v1Task));
if (v1Actions.Count == 0)
{
v1Task.SetApplicationName(string.Empty);
v1Task.SetParameters(string.Empty);
v1Task.SetWorkingDirectory(string.Empty);
v1Task.SetDataItem("ActionId", null);
v1Task.SetDataItem("ActionType", "EMPTY");
}
else if (v1Actions.Count == 1)
{
if (!SupportV1Conversion && v1Actions[0].ActionType != TaskActionType.Execute)
throw new NotV1SupportedException($"Only a single {nameof(ExecAction)} is supported unless the {nameof(PowerShellConversion)} property includes the {nameof(PowerShellActionPlatformOption.Version1)} value.");
v1Task.SetDataItem("ActionType", null);
v1Actions[0].Bind(v1Task);
}
else
{
if (!SupportV1Conversion)
throw new NotV1SupportedException($"Only a single {nameof(ExecAction)} is supported unless the {nameof(PowerShellConversion)} property includes the {nameof(PowerShellActionPlatformOption.Version1)} value.");
// Build list of internal PowerShell scripts
var sb = new System.Text.StringBuilder();
foreach (var item in v1Actions)
sb.Append($"<# {item.Id ?? "NO_ID"}:{item.ActionType} #> {item.GetPowerShellCommand()} ");
// Build and save PS ExecAction
var ea = ExecAction.CreatePowerShellAction("MULTIPLE", sb.ToString());
ea.Bind(v1Task);
v1Task.SetDataItem("ActionId", null);
v1Task.SetDataItem("ActionType", "MULTIPLE");
}
}
}
}

View File

@ -0,0 +1,16 @@
using System;
using System.Threading;
namespace Microsoft.Win32.TaskScheduler
{
internal class CultureSwitcher : IDisposable
{
private readonly System.Globalization.CultureInfo cur, curUI;
public void Dispose()
{
Thread.CurrentThread.CurrentCulture = cur;
Thread.CurrentThread.CurrentUICulture = curUI;
}
}
}

View File

@ -0,0 +1,79 @@
using System;
using System.Collections.Generic;
using System.Globalization;
namespace Microsoft.Win32.TaskScheduler
{
/// <summary>
/// Functions to provide localized strings for enumerated types and values.
/// </summary>
public static class TaskEnumGlobalizer
{
/// <summary>
/// Gets a string representing the localized value of the provided enum.
/// </summary>
/// <param name="enumValue">The enum value.</param>
/// <returns>A localized string, if available.</returns>
public static string GetString(object enumValue)
{
switch (enumValue.GetType().Name)
{
case "DaysOfTheWeek":
return GetCultureEquivalentString((DaysOfTheWeek)enumValue);
case "MonthsOfTheYear":
return GetCultureEquivalentString((MonthsOfTheYear)enumValue);
case "TaskTriggerType":
return BuildEnumString("TriggerType", enumValue);
case "WhichWeek":
return BuildEnumString("WW", enumValue);
case "TaskActionType":
return BuildEnumString("ActionType", enumValue);
case "TaskState":
return BuildEnumString("TaskState", enumValue);
}
return enumValue.ToString();
}
private static string GetCultureEquivalentString(DaysOfTheWeek val)
{
if (val == DaysOfTheWeek.AllDays)
return winPEAS.Properties.Resources.DOWAllDays;
var s = new List<string>(7);
var vals = Enum.GetValues(val.GetType());
for (var i = 0; i < vals.Length - 1; i++)
{
if ((val & (DaysOfTheWeek)vals.GetValue(i)) > 0)
s.Add(DateTimeFormatInfo.CurrentInfo.GetDayName((DayOfWeek)i));
}
return string.Join(winPEAS.Properties.Resources.ListSeparator, s.ToArray());
}
private static string GetCultureEquivalentString(MonthsOfTheYear val)
{
if (val == MonthsOfTheYear.AllMonths)
return winPEAS.Properties.Resources.MOYAllMonths;
var s = new List<string>(12);
var vals = Enum.GetValues(val.GetType());
for (var i = 0; i < vals.Length - 1; i++)
{
if ((val & (MonthsOfTheYear)vals.GetValue(i)) > 0)
s.Add(DateTimeFormatInfo.CurrentInfo.GetMonthName(i+1));
}
return string.Join(winPEAS.Properties.Resources.ListSeparator, s.ToArray());
}
private static string BuildEnumString(string preface, object enumValue)
{
var vals = enumValue.ToString().Split(new[] { ", " }, StringSplitOptions.None);
if (vals.Length == 0)
return string.Empty;
for (var i = 0; i < vals.Length; i++)
vals[i] = winPEAS.Properties.Resources.ResourceManager.GetString(preface + vals[i]);
return string.Join(winPEAS.Properties.Resources.ListSeparator, vals);
}
}
}

View File

@ -0,0 +1,280 @@
/* MIT License
Copyright (c) 2016 JetBrains http://www.jetbrains.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. */
using System;
#pragma warning disable 1591
// ReSharper disable UnusedMember.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable IntroduceOptionalParameters.Global
// ReSharper disable MemberCanBeProtected.Global
// ReSharper disable InconsistentNaming
namespace JetBrains.Annotations
{
/// <summary>
/// Indicates that the value of the marked element could be <c>null</c> sometimes,
/// so the check for <c>null</c> is necessary before its usage.
/// </summary>
/// <example><code>
/// [CanBeNull] object Test() => null;
///
/// void UseTest() {
/// var p = Test();
/// var s = p.ToString(); // Warning: Possible 'System.NullReferenceException'
/// }
/// </code></example>
[AttributeUsage(
AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property |
AttributeTargets.Delegate | AttributeTargets.Field | AttributeTargets.Event |
AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.GenericParameter)]
internal sealed class CanBeNullAttribute : Attribute { }
/// <summary>
/// Indicates that the value of the marked element could never be <c>null</c>.
/// </summary>
/// <example><code>
/// [NotNull] object Foo() {
/// return null; // Warning: Possible 'null' assignment
/// }
/// </code></example>
[AttributeUsage(
AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property |
AttributeTargets.Delegate | AttributeTargets.Field | AttributeTargets.Event |
AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.GenericParameter)]
internal sealed class NotNullAttribute : Attribute { }
/// <summary>
/// Can be appplied to symbols of types derived from IEnumerable as well as to symbols of Task
/// and Lazy classes to indicate that the value of a collection item, of the Task.Result property
/// or of the Lazy.Value property can never be null.
/// </summary>
[AttributeUsage(
AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property |
AttributeTargets.Delegate | AttributeTargets.Field)]
internal sealed class ItemNotNullAttribute : Attribute { }
/// <summary>
/// When applied to a target attribute, specifies a requirement for any type marked
/// with the target attribute to implement or inherit specific type or types.
/// </summary>
/// <example><code>
/// [BaseTypeRequired(typeof(IComponent)] // Specify requirement
/// class ComponentAttribute : Attribute { }
///
/// [Component] // ComponentAttribute requires implementing IComponent interface
/// class MyComponent : IComponent { }
/// </code></example>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
[BaseTypeRequired(typeof(Attribute))]
internal sealed class BaseTypeRequiredAttribute : Attribute
{
public BaseTypeRequiredAttribute([NotNull] Type baseType)
{
BaseType = baseType;
}
[NotNull] public Type BaseType { get; private set; }
}
/// <summary>
/// Indicates that the marked symbol is used implicitly (e.g. via reflection, in external library),
/// so this symbol will not be marked as unused (as well as by other usage inspections).
/// </summary>
[AttributeUsage(AttributeTargets.All)]
internal sealed class UsedImplicitlyAttribute : Attribute
{
public UsedImplicitlyAttribute()
: this(ImplicitUseKindFlags.Default, ImplicitUseTargetFlags.Default) { }
public UsedImplicitlyAttribute(ImplicitUseKindFlags useKindFlags, ImplicitUseTargetFlags targetFlags)
{
UseKindFlags = useKindFlags;
TargetFlags = targetFlags;
}
public ImplicitUseKindFlags UseKindFlags { get; private set; }
public ImplicitUseTargetFlags TargetFlags { get; private set; }
}
/// <summary>
/// Should be used on attributes and causes ReSharper to not mark symbols marked with such attributes
/// as unused (as well as by other usage inspections)
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.GenericParameter)]
internal sealed class MeansImplicitUseAttribute : Attribute
{
public MeansImplicitUseAttribute(ImplicitUseTargetFlags targetFlags)
: this(ImplicitUseKindFlags.Default, targetFlags) { }
public MeansImplicitUseAttribute(ImplicitUseKindFlags useKindFlags, ImplicitUseTargetFlags targetFlags)
{
UseKindFlags = useKindFlags;
TargetFlags = targetFlags;
}
[UsedImplicitly] public ImplicitUseKindFlags UseKindFlags { get; private set; }
[UsedImplicitly] public ImplicitUseTargetFlags TargetFlags { get; private set; }
}
[Flags]
internal enum ImplicitUseKindFlags
{
Default = Access | Assign | InstantiatedWithFixedConstructorSignature,
/// <summary>Only entity marked with attribute considered used.</summary>
Access = 1,
/// <summary>Indicates implicit assignment to a member.</summary>
Assign = 2,
/// <summary>
/// Indicates implicit instantiation of a type with fixed constructor signature.
/// That means any unused constructor parameters won't be reported as such.
/// </summary>
InstantiatedWithFixedConstructorSignature = 4,
/// <summary>Indicates implicit instantiation of a type.</summary>
InstantiatedNoFixedConstructorSignature = 8,
}
/// <summary>
/// Specify what is considered used implicitly when marked
/// with <see cref="MeansImplicitUseAttribute"/> or <see cref="UsedImplicitlyAttribute"/>.
/// </summary>
[Flags]
internal enum ImplicitUseTargetFlags
{
Default = Itself,
Itself = 1,
/// <summary>Members of entity marked with attribute are considered used.</summary>
Members = 2,
/// <summary>Entity marked with attribute and all its members considered used.</summary>
WithMembers = Itself | Members
}
/// <summary>
/// This attribute is intended to mark publicly available API
/// which should not be removed and so is treated as used.
/// </summary>
[MeansImplicitUse(ImplicitUseTargetFlags.WithMembers)]
internal sealed class PublicAPIAttribute : Attribute
{
public PublicAPIAttribute() { }
}
/// <summary>
/// An extension method marked with this attribute is processed by ReSharper code completion
/// as a 'Source Template'. When extension method is completed over some expression, it's source code
/// is automatically expanded like a template at call site.
/// </summary>
/// <remarks>
/// Template method body can contain valid source code and/or special comments starting with '$'.
/// Text inside these comments is added as source code when the template is applied. Template parameters
/// can be used either as additional method parameters or as identifiers wrapped in two '$' signs.
/// Use the <see cref="MacroAttribute"/> attribute to specify macros for parameters.
/// </remarks>
/// <example>
/// In this example, the 'forEach' method is a source template available over all values
/// of enumerable types, producing ordinary C# 'foreach' statement and placing caret inside block:
/// <code>
/// [SourceTemplate]
/// public static void forEach&lt;T&gt;(this IEnumerable&lt;T&gt; xs) {
/// foreach (var x in xs) {
/// //$ $END$
/// }
/// }
/// </code>
/// </example>
[AttributeUsage(AttributeTargets.Method)]
internal sealed class SourceTemplateAttribute : Attribute { }
/// <summary>
/// Allows specifying a macro for a parameter of a <see cref="SourceTemplateAttribute">source template</see>.
/// </summary>
/// <remarks>
/// You can apply the attribute on the whole method or on any of its additional parameters. The macro expression
/// is defined in the <see cref="MacroAttribute.Expression"/> property. When applied on a method, the target
/// template parameter is defined in the <see cref="MacroAttribute.Target"/> property. To apply the macro silently
/// for the parameter, set the <see cref="MacroAttribute.Editable"/> property value = -1.
/// </remarks>
/// <example>
/// Applying the attribute on a source template method:
/// <code>
/// [SourceTemplate, Macro(Target = "item", Expression = "suggestVariableName()")]
/// public static void forEach&lt;T&gt;(this IEnumerable&lt;T&gt; collection) {
/// foreach (var item in collection) {
/// //$ $END$
/// }
/// }
/// </code>
/// Applying the attribute on a template method parameter:
/// <code>
/// [SourceTemplate]
/// public static void something(this Entity x, [Macro(Expression = "guid()", Editable = -1)] string newguid) {
/// /*$ var $x$Id = "$newguid$" + x.ToString();
/// x.DoSomething($x$Id); */
/// }
/// </code>
/// </example>
[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method, AllowMultiple = true)]
internal sealed class MacroAttribute : Attribute
{
/// <summary>
/// Allows specifying a macro that will be executed for a <see cref="SourceTemplateAttribute">source template</see>
/// parameter when the template is expanded.
/// </summary>
[CanBeNull] public string Expression { get; set; }
/// <summary>
/// Allows specifying which occurrence of the target parameter becomes editable when the template is deployed.
/// </summary>
/// <remarks>
/// If the target parameter is used several times in the template, only one occurrence becomes editable;
/// other occurrences are changed synchronously. To specify the zero-based index of the editable occurrence,
/// use values >= 0. To make the parameter non-editable when the template is expanded, use -1.
/// </remarks>>
public int Editable { get; set; }
/// <summary>
/// Identifies the target parameter of a <see cref="SourceTemplateAttribute">source template</see> if the
/// <see cref="MacroAttribute"/> is applied on a template method.
/// </summary>
[CanBeNull] public string Target { get; set; }
}
/// <summary>
/// Indicates that the marked method is assertion method, i.e. it halts control flow if
/// one of the conditions is satisfied. To set the condition, mark one of the parameters with
/// <see cref="AssertionConditionAttribute"/> attribute.
/// </summary>
[AttributeUsage(AttributeTargets.Method)]
internal sealed class AssertionMethodAttribute : Attribute { }
/// <summary>
/// Indicates the condition parameter of the assertion method. The method itself should be
/// marked by <see cref="AssertionMethodAttribute"/> attribute. The mandatory argument of
/// the attribute is the assertion type.
/// </summary>
[AttributeUsage(AttributeTargets.Parameter)]
internal sealed class AssertionConditionAttribute : Attribute { }
}

View File

@ -0,0 +1,562 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Xml.Serialization;
using Microsoft.Win32.TaskScheduler.V2Interop;
using JetBrains.Annotations;
namespace Microsoft.Win32.TaskScheduler
{
/// <summary>
/// Pair of name and value.
/// </summary>
[PublicAPI]
public class NameValuePair : IXmlSerializable, INotifyPropertyChanged, ICloneable, IEquatable<NameValuePair>, IEquatable<ITaskNamedValuePair>
{
private readonly ITaskNamedValuePair v2Pair;
private string name, value;
/// <summary>
/// Occurs when a property has changed.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Initializes a new instance of the <see cref="NameValuePair"/> class.
/// </summary>
public NameValuePair() { }
internal NameValuePair([NotNull] ITaskNamedValuePair iPair)
{
v2Pair = iPair;
}
internal NameValuePair([NotNull] string name, [NotNull] string value)
{
if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(value))
throw new ArgumentException("Both name and value must be non-empty strings.");
this.name = name; this.value = value;
}
[XmlIgnore]
internal bool AttributedXmlFormat { get; set; } = true;
/// <summary>
/// Gets or sets the name.
/// </summary>
/// <value>
/// The name.
/// </value>
[NotNull]
public string Name
{
get { return v2Pair == null ? name : v2Pair.Name; }
set { if (string.IsNullOrEmpty(value)) throw new ArgumentNullException(nameof(Name)); if (v2Pair == null) name = value; else v2Pair.Name = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Name))); }
}
/// <summary>
/// Gets or sets the value.
/// </summary>
/// <value>
/// The value.
/// </value>
[NotNull]
public string Value
{
get { return v2Pair == null ? value : v2Pair.Value; }
set { if (string.IsNullOrEmpty(value)) throw new ArgumentNullException(nameof(Value)); if (v2Pair == null) this.value = value; else v2Pair.Value = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Value))); }
}
/// <summary>
/// Clones this instance.
/// </summary>
/// <returns>A copy of an unbound <see cref="NameValuePair"/>.</returns>
[NotNull]
public NameValuePair Clone() => new NameValuePair(Name, Value);
object ICloneable.Clone() => Clone();
/// <summary>
/// Determines whether the specified <see cref="System.Object"/>, is equal to this instance.
/// </summary>
/// <param name="obj">The <see cref="System.Object" /> to compare with this instance.</param>
/// <returns>
/// <c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>.
/// </returns>
public override bool Equals(object obj)
{
var valuePair = obj as ITaskNamedValuePair;
if (valuePair != null)
return (this as IEquatable<ITaskNamedValuePair>).Equals(valuePair);
var pair = obj as NameValuePair;
if (pair != null)
return Equals(pair);
return base.Equals(obj);
}
/// <summary>Indicates whether the current object is equal to another object of the same type.</summary>
/// <param name="other">An object to compare with this object.</param>
/// <returns>true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.</returns>
public bool Equals([NotNull] NameValuePair other) => other.Name == Name && other.Value == Value;
/// <summary>Indicates whether the current object is equal to another object of the same type.</summary>
/// <param name="other">An object to compare with this object.</param>
/// <returns>true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.</returns>
bool IEquatable<ITaskNamedValuePair>.Equals(ITaskNamedValuePair other) => other.Name == Name && other.Value == Value;
/// <summary>
/// Returns a hash code for this instance.
/// </summary>
/// <returns>
/// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
/// </returns>
public override int GetHashCode() => new { A = Name, B = Value }.GetHashCode();
/// <summary>
/// Returns a <see cref="System.String" /> that represents this instance.
/// </summary>
/// <returns>
/// A <see cref="System.String" /> that represents this instance.
/// </returns>
public override string ToString() => $"{Name}={Value}";
/// <summary>
/// Implements the operator implicit NameValuePair.
/// </summary>
/// <param name="kvp">The KeyValuePair.</param>
/// <returns>
/// The result of the operator.
/// </returns>
public static implicit operator NameValuePair(KeyValuePair<string, string> kvp) => new NameValuePair(kvp.Key, kvp.Value);
System.Xml.Schema.XmlSchema IXmlSerializable.GetSchema() => null;
void IXmlSerializable.ReadXml(System.Xml.XmlReader reader)
{
if (reader.MoveToContent() == System.Xml.XmlNodeType.Element && reader.LocalName == "Value")
{
Name = reader.GetAttribute("name");
Value = reader.ReadString();
reader.Read();
}
else
{
reader.ReadStartElement();
XmlSerializationHelper.ReadObjectProperties(reader, this);
reader.ReadEndElement();
}
}
void IXmlSerializable.WriteXml(System.Xml.XmlWriter writer)
{
if (AttributedXmlFormat)
{
writer.WriteAttributeString("name", Name);
writer.WriteString(Value);
}
else
{
XmlSerializationHelper.WriteObjectProperties(writer, this);
}
}
}
/// <summary>
/// Contains a collection of name-value pairs.
/// </summary>
[PublicAPI]
public sealed class NamedValueCollection : IDisposable, ICollection<NameValuePair>, IDictionary<string, string>, INotifyCollectionChanged, INotifyPropertyChanged
{
private ITaskNamedValueCollection v2Coll;
private readonly List<NameValuePair> unboundDict;
/// <summary>
/// Occurs when the collection has changed.
/// </summary>
public event NotifyCollectionChangedEventHandler CollectionChanged;
/// <summary>
/// Occurs when a property has changed.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
internal NamedValueCollection([NotNull] ITaskNamedValueCollection iColl) { v2Coll = iColl; }
internal NamedValueCollection()
{
unboundDict = new List<NameValuePair>(5);
}
[XmlIgnore]
internal bool AttributedXmlFormat { get; set; } = true;
internal void Bind([NotNull] ITaskNamedValueCollection iTaskNamedValueCollection)
{
v2Coll = iTaskNamedValueCollection;
v2Coll.Clear();
foreach (var item in unboundDict)
v2Coll.Create(item.Name, item.Value);
}
/// <summary>
/// Copies current <see cref="NamedValueCollection"/> to another.
/// </summary>
/// <param name="destCollection">The destination collection.</param>
public void CopyTo([NotNull] NamedValueCollection destCollection)
{
if (v2Coll != null)
{
for (var i = 1; i <= Count; i++)
destCollection.Add(v2Coll[i].Name, v2Coll[i].Value);
}
else
{
foreach (var item in unboundDict)
destCollection.Add(item.Name, item.Value);
}
}
/// <summary>
/// Releases all resources used by this class.
/// </summary>
public void Dispose()
{
if (v2Coll != null) Marshal.ReleaseComObject(v2Coll);
}
/// <summary>
/// Gets the number of items in the collection.
/// </summary>
public int Count => v2Coll?.Count ?? unboundDict.Count;
/// <summary>
/// Gets a collection of the names.
/// </summary>
/// <value>
/// The names.
/// </value>
[ItemNotNull, NotNull]
public ICollection<string> Names
{
get
{
if (v2Coll == null)
return unboundDict.ConvertAll(p => p.Name);
var ret = new List<string>(v2Coll.Count);
foreach (var item in this)
ret.Add(item.Name);
return ret;
}
}
/// <summary>
/// Gets a collection of the values.
/// </summary>
/// <value>
/// The values.
/// </value>
[ItemNotNull, NotNull]
public ICollection<string> Values
{
get
{
if (v2Coll == null)
return unboundDict.ConvertAll(p => p.Value);
var ret = new List<string>(v2Coll.Count);
foreach (var item in this)
ret.Add(item.Value);
return ret;
}
}
/// <summary>
/// Gets the value of the item with the specified name.
/// </summary>
/// <param name="name">Name to get the value for.</param>
/// <returns>Value for the name, or null if not found.</returns>
public string this[string name]
{
[CanBeNull]
get
{
string ret;
TryGetValue(name, out ret);
return ret;
}
[NotNull]
set
{
int idx;
NameValuePair old = null;
var nvp = new NameValuePair(name, value);
if (v2Coll == null)
{
idx = unboundDict.FindIndex(p => p.Name == name);
if (idx == -1)
unboundDict.Add(nvp);
else
{
old = unboundDict[idx];
unboundDict[idx] = nvp;
}
}
else
{
var array = new KeyValuePair<string, string>[Count];
((ICollection<KeyValuePair<string, string>>)this).CopyTo(array, 0);
idx = Array.FindIndex(array, p => p.Key == name);
if (idx == -1)
v2Coll.Create(name, value);
else
{
old = array[idx];
array[idx] = new KeyValuePair<string, string>(name, value);
v2Coll.Clear();
foreach (KeyValuePair<string, string> t in array)
v2Coll.Create(t.Key, t.Value);
}
}
if (idx == -1)
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, nvp));
else
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, nvp, old, idx));
}
}
/// <summary>
/// Adds an item to the <see cref="T:System.Collections.Generic.ICollection`1" />.
/// </summary>
/// <param name="item">The object to add to the <see cref="T:System.Collections.Generic.ICollection`1" />.</param>
public void Add([NotNull] NameValuePair item)
{
if (v2Coll != null)
v2Coll.Create(item.Name, item.Value);
else
unboundDict.Add(item);
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item));
}
/// <summary>
/// Adds a name-value pair to the collection.
/// </summary>
/// <param name="name">The name associated with a value in a name-value pair.</param>
/// <param name="value">The value associated with a name in a name-value pair.</param>
public void Add([NotNull] string name, [NotNull] string value)
{
Add(new NameValuePair(name, value));
}
/// <summary>
/// Clears the entire collection of name-value pairs.
/// </summary>
public void Clear()
{
if (v2Coll != null)
v2Coll.Clear();
else
unboundDict.Clear();
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Count)));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Item[]"));
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
/// <summary>
/// Returns an enumerator that iterates through the collection.
/// </summary>
/// <returns>
/// A <see cref="T:System.Collections.Generic.IEnumerator`1" /> that can be used to iterate through the collection.
/// </returns>
public IEnumerator<NameValuePair> GetEnumerator()
{
if (v2Coll == null)
return unboundDict.GetEnumerator();
return new ComEnumerator<NameValuePair, ITaskNamedValuePair>(() => v2Coll.Count, i => v2Coll[i], o => new NameValuePair(o));
}
private void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
if (e.NewItems != null)
foreach (NameValuePair item in e.NewItems)
item.AttributedXmlFormat = AttributedXmlFormat;
CollectionChanged?.Invoke(this, e);
}
/// <summary>
/// Removes the name-value pair with the specified key from the collection.
/// </summary>
/// <param name="name">The name associated with a value in a name-value pair.</param>
/// <returns><c>true</c> if item successfully removed; <c>false</c> otherwise.</returns>
public bool Remove([NotNull] string name)
{
var i = -1;
NameValuePair nvp = null;
try
{
if (v2Coll == null)
{
i = unboundDict.FindIndex(p => p.Name == name);
if (i != -1)
{
nvp = unboundDict[i];
unboundDict.RemoveAt(i);
}
return (i != -1);
}
for (i = 0; i < v2Coll.Count; i++)
{
if (name == v2Coll[i].Name)
{
nvp = new NameValuePair(v2Coll[i]).Clone();
v2Coll.Remove(i);
return true;
}
}
i = -1;
}
finally
{
if (i != -1)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Count)));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Item[]"));
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, nvp, i));
}
}
return false;
}
/// <summary>
/// Gets the value associated with the specified name.
/// </summary>
/// <param name="name">The name whose value to get.</param>
/// <param name="value">When this method returns, the value associated with the specified name, if the name is found; otherwise, <c>null</c>. This parameter is passed uninitialized.</param>
/// <returns><c>true</c> if the collection contains an element with the specified name; otherwise, <c>false</c>.</returns>
public bool TryGetValue(string name, out string value)
{
if (v2Coll != null)
{
foreach (var item in this)
{
if (string.CompareOrdinal(item.Name, name) == 0)
{
value = item.Value;
return true;
}
}
value = null;
return false;
}
var nvp = unboundDict.Find(p => p.Name == name);
value = nvp?.Value;
return nvp != null;
}
/// <summary>
/// Gets the collection enumerator for the name-value collection.
/// </summary>
/// <returns>An <see cref="System.Collections.IEnumerator"/> for the collection.</returns>
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator();
bool ICollection<NameValuePair>.Contains(NameValuePair item)
{
if (v2Coll == null)
return unboundDict.Contains(item);
foreach (var invp in this)
if (Equals(item, invp)) return true;
return false;
}
void ICollection<NameValuePair>.CopyTo(NameValuePair[] array, int arrayIndex)
{
if (v2Coll == null)
unboundDict.CopyTo(array, arrayIndex);
else
{
if (array.Length - arrayIndex < v2Coll.Count)
throw new ArgumentException("Items in collection exceed available items in destination array.");
if (arrayIndex < 0)
throw new ArgumentException(@"Array index must be 0 or greater.", nameof(arrayIndex));
for (var i = 0; i < v2Coll.Count; i++)
array[i + arrayIndex] = new NameValuePair(v2Coll[i]);
}
}
bool ICollection<NameValuePair>.IsReadOnly => false;
ICollection<string> IDictionary<string, string>.Keys => Names;
bool ICollection<KeyValuePair<string, string>>.IsReadOnly => false;
bool ICollection<NameValuePair>.Remove(NameValuePair item)
{
var i = -1;
try
{
if (v2Coll == null)
{
if ((i = unboundDict.IndexOf(item)) != -1)
return unboundDict.Remove(item);
}
else
{
for (i = 0; i < v2Coll.Count; i++)
{
if (item.Equals(v2Coll[i]))
{
v2Coll.Remove(i);
return true;
}
}
}
i = -1;
}
finally
{
if (i != -1)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Count)));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Item[]"));
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item, i));
}
}
return false;
}
bool IDictionary<string, string>.ContainsKey(string key) => Names.Contains(key);
void ICollection<KeyValuePair<string, string>>.Add(KeyValuePair<string, string> item)
{
Add(item.Key, item.Value);
}
bool ICollection<KeyValuePair<string, string>>.Contains(KeyValuePair<string, string> item) =>
((ICollection<NameValuePair>)this).Contains(new NameValuePair(item.Key, item.Value));
void ICollection<KeyValuePair<string, string>>.CopyTo(KeyValuePair<string, string>[] array, int arrayIndex)
{
if (array.Length < Count + arrayIndex)
throw new ArgumentOutOfRangeException(nameof(array), @"Array has insufficient capacity to support copy.");
foreach (var item in ((IEnumerable<KeyValuePair<string, string>>)this))
array[arrayIndex++] = item;
}
bool ICollection<KeyValuePair<string, string>>.Remove(KeyValuePair<string, string> item) =>
((ICollection<NameValuePair>)this).Remove(new NameValuePair(item.Key, item.Value));
IEnumerator<KeyValuePair<string, string>> IEnumerable<KeyValuePair<string, string>>.GetEnumerator()
{
foreach (var nvp in this)
yield return new KeyValuePair<string, string>(nvp.Name, nvp.Value);
}
}
}

View File

@ -0,0 +1,24 @@
using System;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
namespace Microsoft.Win32
{
internal static partial class NativeMethods
{
const string ADVAPI32 = "advapi32.dll";
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail), DllImport(ADVAPI32, CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern int LogonUser(string lpszUserName, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, out SafeTokenHandle phToken);
public partial class SafeTokenHandle
{
private const Int32 ERROR_NO_TOKEN = 0x000003F0;
private const Int32 ERROR_INSUFFICIENT_BUFFER = 122;
private static SafeTokenHandle currentProcessToken = null;
}
}
}

View File

@ -0,0 +1,89 @@
using System.Linq;
namespace System.Security.AccessControl
{
/// <summary>Extensions for classes in the System.Security.AccessControl namespace.</summary>
public static class AccessControlExtension
{
/// <summary>Canonicalizes the specified Access Control List.</summary>
/// <param name="acl">The Access Control List.</param>
public static void Canonicalize(this RawAcl acl)
{
if (acl == null) throw new ArgumentNullException(nameof(acl));
// Extract aces to list
var aces = new Collections.Generic.List<GenericAce>(acl.Cast<GenericAce>());
// Sort aces based on canonical order
aces.Sort((a, b) => Collections.Generic.Comparer<byte>.Default.Compare(GetComparisonValue(a), GetComparisonValue(b)));
// Add sorted aces back to ACL
while (acl.Count > 0) acl.RemoveAce(0);
var aceIndex = 0;
aces.ForEach(ace => acl.InsertAce(aceIndex++, ace));
}
/// <summary>Sort ACEs according to canonical form for this <see cref="ObjectSecurity"/>.</summary>
/// <param name="objectSecurity">The object security whose DiscretionaryAcl will be made canonical.</param>
public static void CanonicalizeAccessRules(this ObjectSecurity objectSecurity)
{
if (objectSecurity == null) throw new ArgumentNullException(nameof(objectSecurity));
if (objectSecurity.AreAccessRulesCanonical) return;
// Get raw SD from objectSecurity and canonicalize DACL
var sd = new RawSecurityDescriptor(objectSecurity.GetSecurityDescriptorBinaryForm(), 0);
sd.DiscretionaryAcl.Canonicalize();
// Convert SD back into objectSecurity
objectSecurity.SetSecurityDescriptorBinaryForm(sd.GetBinaryForm());
}
/// <summary>Returns an array of byte values that represents the information contained in this <see cref="GenericSecurityDescriptor"/> object.</summary>
/// <param name="sd">The <see cref="GenericSecurityDescriptor"/> object.</param>
/// <returns>The byte array into which the contents of the <see cref="GenericSecurityDescriptor"/> is marshaled.</returns>
public static byte[] GetBinaryForm(this GenericSecurityDescriptor sd)
{
if (sd == null) throw new ArgumentNullException(nameof(sd));
var bin = new byte[sd.BinaryLength];
sd.GetBinaryForm(bin, 0);
return bin;
}
// A canonical ACL must have ACES sorted according to the following order:
// 1. Access-denied on the object
// 2. Access-denied on a child or property
// 3. Access-allowed on the object
// 4. Access-allowed on a child or property
// 5. All inherited ACEs
private static byte GetComparisonValue(GenericAce ace)
{
if ((ace.AceFlags & AceFlags.Inherited) != 0)
return 5;
switch (ace.AceType)
{
case AceType.AccessDenied:
case AceType.AccessDeniedCallback:
case AceType.SystemAudit:
case AceType.SystemAlarm:
case AceType.SystemAuditCallback:
case AceType.SystemAlarmCallback:
return 0;
case AceType.AccessDeniedObject:
case AceType.AccessDeniedCallbackObject:
case AceType.SystemAuditObject:
case AceType.SystemAlarmObject:
case AceType.SystemAuditCallbackObject:
case AceType.SystemAlarmCallbackObject:
return 1;
case AceType.AccessAllowed:
case AceType.AccessAllowedCallback:
return 2;
case AceType.AccessAllowedObject:
case AceType.AccessAllowedCallbackObject:
return 3;
default:
return 4;
}
}
}
}

View File

@ -0,0 +1,57 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
namespace System
{
internal static class EnumUtil
{
public static void CheckIsEnum<T>(bool checkHasFlags = false)
{
if (!typeof(T).IsEnum)
throw new ArgumentException($"Type '{typeof(T).FullName}' is not an enum");
if (checkHasFlags && !IsFlags<T>())
throw new ArgumentException($"Type '{typeof(T).FullName}' doesn't have the 'Flags' attribute");
}
public static bool IsFlags<T>() => Attribute.IsDefined(typeof(T), typeof(FlagsAttribute));
public static bool IsFlagSet<T>(this T flags, T flag) where T : struct, IConvertible
{
CheckIsEnum<T>(true);
var flagValue = Convert.ToInt64(flag);
return (Convert.ToInt64(flags) & flagValue) == flagValue;
}
public static bool IsValidFlagValue<T>(this T flags) where T : struct, IConvertible
{
CheckIsEnum<T>(true);
var found = 0L;
foreach (T flag in Enum.GetValues(typeof(T)))
{
if (flags.IsFlagSet(flag))
found |= Convert.ToInt64(flag);
}
return found == Convert.ToInt64(flags);
}
public static void SetFlags<T>(ref T flags, T flag, bool set = true) where T : struct, IConvertible
{
CheckIsEnum<T>(true);
var flagsValue = Convert.ToInt64(flags);
var flagValue = Convert.ToInt64(flag);
if (set)
flagsValue |= flagValue;
else
flagsValue &= (~flagValue);
flags = (T)Enum.ToObject(typeof(T), flagsValue);
}
public static T SetFlags<T>(this T flags, T flag, bool set = true) where T : struct, IConvertible
{
var ret = flags;
SetFlags<T>(ref ret, flag, set);
return ret;
}
}
}

View File

@ -0,0 +1,53 @@
using System.Collections;
using System.Collections.Generic;
// ReSharper disable once CheckNamespace
namespace System.Runtime.InteropServices
{
internal class ComEnumerator<T, TIn> : IEnumerator<T> where T : class where TIn : class
{
protected readonly Func<TIn, T> converter;
protected IEnumerator<TIn> iEnum;
public ComEnumerator(Func<int> getCount, Func<int, TIn> indexer, Func<TIn, T> converter)
{
IEnumerator<TIn> Enumerate()
{
for (var x = 1; x <= getCount(); x++)
yield return indexer(x);
}
this.converter = converter;
iEnum = Enumerate();
}
public ComEnumerator(Func<int> getCount, Func<object, TIn> indexer, Func<TIn, T> converter)
{
IEnumerator<TIn> Enumerate()
{
for (var x = 1; x <= getCount(); x++)
yield return indexer(x);
}
this.converter = converter;
iEnum = Enumerate();
}
object IEnumerator.Current => Current;
public virtual T Current => converter(iEnum?.Current);
public virtual void Dispose()
{
iEnum?.Dispose();
iEnum = null;
}
public virtual bool MoveNext() => iEnum?.MoveNext() ?? false;
public virtual void Reset()
{
iEnum?.Reset();
}
}
}

View File

@ -0,0 +1,26 @@
using System;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
namespace Microsoft.Win32
{
internal static partial class NativeMethods
{
const string KERNEL32 = "Kernel32.dll";
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), DllImport(KERNEL32, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CloseHandle(IntPtr handle);
public partial class SafeTokenHandle : Microsoft.Win32.SafeHandles.SafeHandleZeroOrMinusOneIsInvalid
{
internal SafeTokenHandle(IntPtr handle, bool own = true) : base(own)
{
SetHandle(handle);
}
protected override bool ReleaseHandle() => CloseHandle(handle);
}
}
}

View File

@ -0,0 +1,230 @@
using System;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using System.Security;
namespace Microsoft.Win32
{
internal static partial class NativeMethods
{
private const string NTDSAPI = "ntdsapi.dll";
/// <summary>
/// Defines the errors returned by the status member of the DS_NAME_RESULT_ITEM structure. These are potential errors that may be encountered while a name is converted by the DsCrackNames function.
/// </summary>
public enum DS_NAME_ERROR : uint
{
/// <summary>The conversion was successful.</summary>
DS_NAME_NO_ERROR = 0,
///<summary>Generic processing error occurred.</summary>
DS_NAME_ERROR_RESOLVING = 1,
///<summary>The name cannot be found or the caller does not have permission to access the name.</summary>
DS_NAME_ERROR_NOT_FOUND = 2,
///<summary>The input name is mapped to more than one output name or the desired format did not have a single, unique value for the object found.</summary>
DS_NAME_ERROR_NOT_UNIQUE = 3,
///<summary>The input name was found, but the associated output format cannot be found. This can occur if the object does not have all the required attributes.</summary>
DS_NAME_ERROR_NO_MAPPING = 4,
///<summary>Unable to resolve entire name, but was able to determine in which domain object resides. The caller is expected to retry the call at a domain controller for the specified domain. The entire name cannot be resolved, but the domain that the object resides in could be determined. The pDomain member of the DS_NAME_RESULT_ITEM contains valid data when this error is specified.</summary>
DS_NAME_ERROR_DOMAIN_ONLY = 5,
///<summary>A syntactical mapping cannot be performed on the client without transmitting over the network.</summary>
DS_NAME_ERROR_NO_SYNTACTICAL_MAPPING = 6,
///<summary>The name is from an external trusted forest.</summary>
DS_NAME_ERROR_TRUST_REFERRAL = 7
}
/// <summary>
/// Used to define how the name syntax will be cracked. These flags are used by the DsCrackNames function.
/// </summary>
[Flags]
public enum DS_NAME_FLAGS
{
/// <summary>Indicate that there are no associated flags.</summary>
DS_NAME_NO_FLAGS = 0x0,
///<summary>Perform a syntactical mapping at the client without transferring over the network. The only syntactic mapping supported is from DS_FQDN_1779_NAME to DS_CANONICAL_NAME or DS_CANONICAL_NAME_EX.</summary>
DS_NAME_FLAG_SYNTACTICAL_ONLY = 0x1,
///<summary>Force a trip to the DC for evaluation, even if this could be locally cracked syntactically.</summary>
DS_NAME_FLAG_EVAL_AT_DC = 0x2,
///<summary>The call fails if the domain controller is not a global catalog server.</summary>
DS_NAME_FLAG_GCVERIFY = 0x4,
///<summary>Enable cross forest trust referral.</summary>
DS_NAME_FLAG_TRUST_REFERRAL = 0x8
}
/// <summary>
/// Provides formats to use for input and output names for the DsCrackNames function.
/// </summary>
public enum DS_NAME_FORMAT
{
///<summary>Indicates the name is using an unknown name type. This format can impact performance because it forces the server to attempt to match all possible formats. Only use this value if the input format is unknown.</summary>
DS_UNKNOWN_NAME = 0,
///<summary>Indicates that the fully qualified distinguished name is used. For example: "CN = someone, OU = Users, DC = Engineering, DC = Fabrikam, DC = Com"</summary>
DS_FQDN_1779_NAME = 1,
///<summary>Indicates a Windows NT 4.0 account name. For example: "Engineering\someone" The domain-only version includes two trailing backslashes (\\).</summary>
DS_NT4_ACCOUNT_NAME = 2,
///<summary>Indicates a user-friendly display name, for example, Jeff Smith. The display name is not necessarily the same as relative distinguished name (RDN).</summary>
DS_DISPLAY_NAME = 3,
///<summary>Indicates a GUID string that the IIDFromString function returns. For example: "{4fa050f0-f561-11cf-bdd9-00aa003a77b6}"</summary>
DS_UNIQUE_ID_NAME = 6,
///<summary>Indicates a complete canonical name. For example: "engineering.fabrikam.com/software/someone" The domain-only version includes a trailing forward slash (/).</summary>
DS_CANONICAL_NAME = 7,
///<summary>Indicates that it is using the user principal name (UPN). For example: "someone@engineering.fabrikam.com"</summary>
DS_USER_PRINCIPAL_NAME = 8,
///<summary>This element is the same as DS_CANONICAL_NAME except that the rightmost forward slash (/) is replaced with a newline character (\n), even in a domain-only case. For example: "engineering.fabrikam.com/software\nsomeone"</summary>
DS_CANONICAL_NAME_EX = 9,
///<summary>Indicates it is using a generalized service principal name. For example: "www/www.fabrikam.com@fabrikam.com"</summary>
DS_SERVICE_PRINCIPAL_NAME = 10,
///<summary>Indicates a Security Identifier (SID) for the object. This can be either the current SID or a SID from the object SID history. The SID string can use either the standard string representation of a SID, or one of the string constants defined in Sddl.h. For more information about converting a binary SID into a SID string, see SID Strings. The following is an example of a SID string: "S-1-5-21-397955417-626881126-188441444-501"</summary>
DS_SID_OR_SID_HISTORY_NAME = 11,
}
/// <summary>
/// Class that provides methods against a AD domain service.
/// </summary>
/// <seealso cref="System.IDisposable" />
[SuppressUnmanagedCodeSecurity, ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public class DomainService : IDisposable
{
IntPtr handle = IntPtr.Zero;
/// <summary>
/// Initializes a new instance of the <see cref="DomainService"/> class.
/// </summary>
/// <param name="domainControllerName">Name of the domain controller.</param>
/// <param name="dnsDomainName">Name of the DNS domain.</param>
/// <exception cref="System.ComponentModel.Win32Exception"></exception>
public DomainService(string domainControllerName = null, string dnsDomainName = null)
{
DsBind(domainControllerName, dnsDomainName, out handle);
}
/// <summary>
/// Converts a directory service object name from any format to the UPN.
/// </summary>
/// <param name="name">The name to convert.</param>
/// <returns>The corresponding UPN.</returns>
/// <exception cref="System.Security.SecurityException">Unable to resolve user name.</exception>
public string CrackName(string name)
{
var res = CrackNames(new string[] { name });
if (res == null || res.Length == 0 || res[0].status != NativeMethods.DS_NAME_ERROR.DS_NAME_NO_ERROR)
throw new SecurityException("Unable to resolve user name.");
return res[0].pName;
}
/// <summary>
/// Converts an array of directory service object names from one format to another. Name conversion enables client applications to map between the multiple names used to identify various directory service objects.
/// </summary>
/// <param name="names">The names to convert.</param>
/// <param name="flags">Values used to determine how the name syntax will be cracked.</param>
/// <param name="formatOffered">Format of the input names.</param>
/// <param name="formatDesired">Desired format for the output names.</param>
/// <returns>An array of DS_NAME_RESULT_ITEM structures. Each element of this array represents a single converted name.</returns>
public DS_NAME_RESULT_ITEM[] CrackNames(string[] names = null, DS_NAME_FLAGS flags = DS_NAME_FLAGS.DS_NAME_NO_FLAGS, DS_NAME_FORMAT formatOffered = DS_NAME_FORMAT.DS_UNKNOWN_NAME, DS_NAME_FORMAT formatDesired = DS_NAME_FORMAT.DS_USER_PRINCIPAL_NAME)
{
IntPtr pResult;
uint err = DsCrackNames(handle, flags, formatOffered, formatDesired, (uint)(names?.Length ?? 0), names, out pResult);
if (err != (uint)DS_NAME_ERROR.DS_NAME_NO_ERROR)
throw new System.ComponentModel.Win32Exception((int)err);
try
{
// Next convert the returned structure to managed environment
DS_NAME_RESULT Result = (DS_NAME_RESULT)Marshal.PtrToStructure(pResult, typeof(DS_NAME_RESULT));
return Result.Items;
}
finally
{
DsFreeNameResult(pResult);
}
}
public void Dispose()
{
uint ret = DsUnBind(ref handle);
System.Diagnostics.Debug.WriteLineIf(ret != 0, "Error unbinding :\t" + ret.ToString());
}
}
[DllImport(NTDSAPI, CharSet = CharSet.Auto, PreserveSig = false)]
public static extern void DsBind(
string DomainControllerName, // in, optional
string DnsDomainName, // in, optional
out IntPtr phDS);
[DllImport(NTDSAPI, CharSet = CharSet.Auto)]
public static extern uint DsCrackNames(
IntPtr hDS,
DS_NAME_FLAGS flags,
DS_NAME_FORMAT formatOffered,
DS_NAME_FORMAT formatDesired,
uint cNames,
[MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPTStr, SizeParamIndex = 4)] string[] rpNames,
out IntPtr ppResult);
[DllImport(NTDSAPI, CharSet = CharSet.Auto)]
public static extern void DsFreeNameResult(IntPtr pResult /* DS_NAME_RESULT* */);
[DllImport(NTDSAPI, CharSet = CharSet.Auto)]
public static extern uint DsUnBind(ref IntPtr phDS);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct DS_NAME_RESULT
{
public uint cItems;
internal IntPtr rItems; // PDS_NAME_RESULT_ITEM
public DS_NAME_RESULT_ITEM[] Items
{
get
{
if (rItems == IntPtr.Zero)
return new DS_NAME_RESULT_ITEM[0];
var ResultArray = new DS_NAME_RESULT_ITEM[cItems];
Type strType = typeof(DS_NAME_RESULT_ITEM);
int stSize = Marshal.SizeOf(strType);
IntPtr curptr;
for (uint i = 0; i < cItems; i++)
{
curptr = new IntPtr(rItems.ToInt64() + (i * stSize));
ResultArray[i] = (DS_NAME_RESULT_ITEM)Marshal.PtrToStructure(curptr, strType);
}
return ResultArray;
}
}
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct DS_NAME_RESULT_ITEM
{
public DS_NAME_ERROR status;
public string pDomain;
public string pName;
public override string ToString()
{
if (status == DS_NAME_ERROR.DS_NAME_NO_ERROR)
return pName;
return string.Empty;
}
}
}
}

View File

@ -0,0 +1,8 @@
namespace Microsoft.Win32
{
internal static partial class NativeMethods
{
}
}

View File

@ -0,0 +1,99 @@
using System;
using System.Runtime.InteropServices;
namespace Microsoft.Win32
{
internal static partial class NativeMethods
{
[StructLayout(LayoutKind.Sequential, Pack = 2)]
internal struct SYSTEMTIME : IConvertible
{
public ushort Year;
public ushort Month;
public ushort DayOfWeek;
public ushort Day;
public ushort Hour;
public ushort Minute;
public ushort Second;
public ushort Milliseconds;
public SYSTEMTIME(DateTime dt)
{
dt = dt.ToLocalTime();
Year = Convert.ToUInt16(dt.Year);
Month = Convert.ToUInt16(dt.Month);
DayOfWeek = Convert.ToUInt16(dt.DayOfWeek);
Day = Convert.ToUInt16(dt.Day);
Hour = Convert.ToUInt16(dt.Hour);
Minute = Convert.ToUInt16(dt.Minute);
Second = Convert.ToUInt16(dt.Second);
Milliseconds = Convert.ToUInt16(dt.Millisecond);
}
public static implicit operator DateTime(SYSTEMTIME st)
{
if (st.Year == 0 || st == MinValue)
return DateTime.MinValue;
if (st == MaxValue)
return DateTime.MaxValue;
return new DateTime(st.Year, st.Month, st.Day, st.Hour, st.Minute, st.Second, st.Milliseconds, DateTimeKind.Local);
}
public static implicit operator SYSTEMTIME(DateTime dt) => new SYSTEMTIME(dt);
public static bool operator ==(SYSTEMTIME s1, SYSTEMTIME s2) => (s1.Year == s2.Year && s1.Month == s2.Month && s1.Day == s2.Day && s1.Hour == s2.Hour && s1.Minute == s2.Minute && s1.Second == s2.Second && s1.Milliseconds == s2.Milliseconds);
public static bool operator !=(SYSTEMTIME s1, SYSTEMTIME s2) => !(s1 == s2);
public static readonly SYSTEMTIME MinValue, MaxValue;
public override bool Equals(object obj)
{
if (obj is SYSTEMTIME)
return ((SYSTEMTIME)obj) == this;
if (obj is DateTime)
return ((DateTime)this).Equals(obj);
return base.Equals(obj);
}
public override int GetHashCode() => ((DateTime)this).GetHashCode();
public override string ToString() => ((DateTime)this).ToString();
TypeCode IConvertible.GetTypeCode() => ((IConvertible)(DateTime)this).GetTypeCode();
bool IConvertible.ToBoolean(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToBoolean(provider);
byte IConvertible.ToByte(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToByte(provider);
char IConvertible.ToChar(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToChar(provider);
DateTime IConvertible.ToDateTime(IFormatProvider provider) => (DateTime)this;
decimal IConvertible.ToDecimal(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToDecimal(provider);
double IConvertible.ToDouble(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToDouble(provider);
short IConvertible.ToInt16(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToInt16(provider);
int IConvertible.ToInt32(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToInt32(provider);
long IConvertible.ToInt64(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToInt64(provider);
sbyte IConvertible.ToSByte(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToSByte(provider);
float IConvertible.ToSingle(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToSingle(provider);
string IConvertible.ToString(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToString(provider);
object IConvertible.ToType(Type conversionType, IFormatProvider provider) => ((IConvertible)(DateTime)this).ToType(conversionType, provider);
ushort IConvertible.ToUInt16(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToUInt16(provider);
uint IConvertible.ToUInt32(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToUInt32(provider);
ulong IConvertible.ToUInt64(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToUInt64(provider);
}
}
}

View File

@ -0,0 +1,80 @@
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Security.Principal;
namespace Microsoft.Win32
{
/// <summary>
/// Impersonation of a user. Allows to execute code under another
/// user context.
/// Please note that the account that instantiates the Impersonator class
/// needs to have the 'Act as part of operating system' privilege set.
/// </summary>
internal class WindowsImpersonatedIdentity : IDisposable, IIdentity
{
private const int LOGON_TYPE_NEW_CREDENTIALS = 9;
private const int LOGON32_LOGON_INTERACTIVE = 2;
private const int LOGON32_PROVIDER_DEFAULT = 0;
private const int LOGON32_PROVIDER_WINNT50 = 3;
#if NETSTANDARD || NETCOREAPP
#else
private WindowsImpersonationContext impersonationContext = null;
#endif
NativeMethods.SafeTokenHandle token;
private WindowsIdentity identity = null;
/// <summary>
/// Constructor. Starts the impersonation with the given credentials.
/// Please note that the account that instantiates the Impersonator class
/// needs to have the 'Act as part of operating system' privilege set.
/// </summary>
/// <param name="userName">The name of the user to act as.</param>
/// <param name="domainName">The domain name of the user to act as.</param>
/// <param name="password">The password of the user to act as.</param>
public WindowsImpersonatedIdentity(string userName, string domainName, string password)
{
if (string.IsNullOrEmpty(userName) && string.IsNullOrEmpty(domainName) && string.IsNullOrEmpty(password))
{
identity = WindowsIdentity.GetCurrent();
}
else
{
if (NativeMethods.LogonUser(userName, domainName, password, domainName == null ? LOGON_TYPE_NEW_CREDENTIALS : LOGON32_LOGON_INTERACTIVE, domainName == null ? LOGON32_PROVIDER_WINNT50 : LOGON32_PROVIDER_DEFAULT, out token) != 0)
{
#if NETSTANDARD || NETCOREAPP
if (!NativeMethods.ImpersonateLoggedOnUser(token.DangerousGetHandle()))
throw new Win32Exception();
#else
identity = new WindowsIdentity(token.DangerousGetHandle());
impersonationContext = identity.Impersonate();
#endif
}
else
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
}
}
public string AuthenticationType => identity?.AuthenticationType;
public bool IsAuthenticated => identity == null ? false : identity.IsAuthenticated;
public string Name => identity == null ? null : identity.Name;
public void Dispose()
{
#if NETSTANDARD || NETCOREAPP
NativeMethods.RevertToSelf();
#else
if (impersonationContext != null)
impersonationContext.Undo();
#endif
token?.Dispose();
if (identity != null)
identity.Dispose();
}
}
}

View File

@ -0,0 +1,116 @@
using System;
using System.Diagnostics;
using System.Runtime.Serialization;
using System.Security;
using System.Security.Permissions;
using JetBrains.Annotations;
namespace Microsoft.Win32.TaskScheduler
{
/// <summary>
/// Abstract class for throwing a method specific exception.
/// </summary>
[DebuggerStepThrough, Serializable]
[PublicAPI]
public abstract class TSNotSupportedException : Exception
{
/// <summary>Defines the minimum supported version for the action not allowed by this exception.</summary>
protected readonly TaskCompatibility min;
private readonly string myMessage;
/// <summary>
/// Initializes a new instance of the <see cref="TSNotSupportedException"/> class.
/// </summary>
/// <param name="serializationInfo">The serialization information.</param>
/// <param name="streamingContext">The streaming context.</param>
protected TSNotSupportedException(SerializationInfo serializationInfo, StreamingContext streamingContext)
: base(serializationInfo, streamingContext)
{
try { min = (TaskCompatibility)serializationInfo.GetValue("min", typeof(TaskCompatibility)); }
catch { min = TaskCompatibility.V1; }
}
internal TSNotSupportedException(TaskCompatibility minComp)
{
min = minComp;
var stackTrace = new StackTrace();
var stackFrame = stackTrace.GetFrame(2);
var methodBase = stackFrame.GetMethod();
myMessage = $"{methodBase.DeclaringType?.Name}.{methodBase.Name} is not supported on {LibName}";
}
internal TSNotSupportedException(string message, TaskCompatibility minComp)
{
myMessage = message;
min = minComp;
}
internal abstract string LibName { get; }
/// <summary>
/// Gets the object data.
/// </summary>
/// <param name="info">The information.</param>
/// <param name="context">The context.</param>
[SecurityCritical, SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
if (info == null)
throw new ArgumentNullException(nameof(info));
info.AddValue("min", min);
base.GetObjectData(info, context);
}
}
/// <summary>
/// Thrown when the calling method is not supported by Task Scheduler 1.0.
/// </summary>
[DebuggerStepThrough, Serializable]
public class NotV1SupportedException : TSNotSupportedException
{
/// <summary>
/// Initializes a new instance of the <see cref="NotV1SupportedException" /> class.
/// </summary>
/// <param name="serializationInfo">The serialization information.</param>
/// <param name="streamingContext">The streaming context.</param>
protected NotV1SupportedException(SerializationInfo serializationInfo, StreamingContext streamingContext) : base(serializationInfo, streamingContext) { }
internal NotV1SupportedException() : base(TaskCompatibility.V2) { }
/// <summary>
/// Initializes a new instance of the <see cref="NotV1SupportedException" /> class.
/// </summary>
/// <param name="message">The message.</param>
public NotV1SupportedException(string message) : base(message, TaskCompatibility.V2) { }
internal override string LibName => "Task Scheduler 1.0";
}
/// <summary>
/// Thrown when the calling method is not supported by Task Scheduler 2.0.
/// </summary>
[DebuggerStepThrough, Serializable]
public class NotV2SupportedException : TSNotSupportedException
{
/// <summary>
/// Initializes a new instance of the <see cref="NotV1SupportedException" /> class.
/// </summary>
/// <param name="serializationInfo">The serialization information.</param>
/// <param name="streamingContext">The streaming context.</param>
internal NotV2SupportedException() : base(TaskCompatibility.V1) { }
internal NotV2SupportedException(string message) : base(message, TaskCompatibility.V1) { }
internal override string LibName => "Task Scheduler 2.0 (1.2)";
}
/// <summary>
/// Thrown when the calling method is not supported by Task Scheduler versions prior to the one specified.
/// </summary>
[DebuggerStepThrough, Serializable]
public class NotSupportedPriorToException : TSNotSupportedException
{
/// <summary>
/// Initializes a new instance of the <see cref="NotV1SupportedException" /> class.
/// </summary>
/// <param name="serializationInfo">The serialization information.</param>
/// <param name="streamingContext">The streaming context.</param>
internal NotSupportedPriorToException(TaskCompatibility supportedVersion) : base(supportedVersion) { }
internal override string LibName => $"Task Scheduler versions prior to 2.{((int)min) - 2} (1.{(int)min})";
}
}

View File

@ -0,0 +1,120 @@
namespace System.Reflection
{
/// <summary>Extensions related to <c>System.Reflection</c></summary>
internal static class ReflectionHelper
{
/// <summary>Loads a type from a named assembly.</summary>
/// <param name="typeName">Name of the type.</param>
/// <param name="asmRef">The name or path of the file that contains the manifest of the assembly.</param>
/// <returns>The <see cref="Type"/> reference, or <c>null</c> if type or assembly not found.</returns>
public static Type LoadType(string typeName, string asmRef)
{
Type ret = null;
if (!TryGetType(Assembly.GetCallingAssembly(), typeName, ref ret))
if (!TryGetType(asmRef, typeName, ref ret))
if (!TryGetType(Assembly.GetExecutingAssembly(), typeName, ref ret))
TryGetType(Assembly.GetEntryAssembly(), typeName, ref ret);
return ret;
}
/// <summary>Tries the retrieve a <see cref="Type"/> reference from an assembly.</summary>
/// <param name="typeName">Name of the type.</param>
/// <param name="asmRef">The assembly reference name from which to load the type.</param>
/// <param name="type">The <see cref="Type"/> reference, if found.</param>
/// <returns><c>true</c> if the type was found in the assembly; otherwise, <c>false</c>.</returns>
private static bool TryGetType(string asmRef, string typeName, ref Type type)
{
try
{
if (System.IO.File.Exists(asmRef))
return TryGetType(Assembly.LoadFrom(asmRef), typeName, ref type);
}
catch { }
return false;
}
/// <summary>Tries the retrieve a <see cref="Type"/> reference from an assembly.</summary>
/// <param name="typeName">Name of the type.</param>
/// <param name="asm">The assembly from which to load the type.</param>
/// <param name="type">The <see cref="Type"/> reference, if found.</param>
/// <returns><c>true</c> if the type was found in the assembly; otherwise, <c>false</c>.</returns>
private static bool TryGetType(Assembly asm, string typeName, ref Type type)
{
if (asm != null)
{
try
{
type = asm.GetType(typeName, false, false);
return (type != null);
}
catch { }
}
return false;
}
/// <summary>Invokes a named method on a created instance of a type with parameters.</summary>
/// <typeparam name="T">The expected type of the method's return value.</typeparam>
/// <param name="type">The type to be instantiated and then used to invoke the method.</param>
/// <param name="instArgs">The arguments to supply to the constructor.</param>
/// <param name="methodName">Name of the method.</param>
/// <param name="args">The arguments to provide to the method invocation.</param>
/// <returns>The value returned from the method.</returns>
public static T InvokeMethod<T>(Type type, object[] instArgs, string methodName, params object[] args)
{
object o = Activator.CreateInstance(type, instArgs);
return InvokeMethod<T>(o, methodName, args);
}
/// <summary>Invokes a named method on an object with parameters and no return value.</summary>
/// <param name="obj">The object on which to invoke the method.</param>
/// <param name="methodName">Name of the method.</param>
/// <param name="args">The arguments to provide to the method invocation.</param>
public static T InvokeMethod<T>(object obj, string methodName, params object[] args)
{
Type[] argTypes = (args == null || args.Length == 0) ? Type.EmptyTypes : Array.ConvertAll(args, delegate(object o) { return o == null ? typeof(object) : o.GetType(); });
return InvokeMethod<T>(obj, methodName, argTypes, args);
}
/// <summary>Invokes a named method on an object with parameters and no return value.</summary>
/// <typeparam name="T">The expected type of the method's return value.</typeparam>
/// <param name="obj">The object on which to invoke the method.</param>
/// <param name="methodName">Name of the method.</param>
/// <param name="argTypes">The types of the <paramref name="args"/>.</param>
/// <param name="args">The arguments to provide to the method invocation.</param>
/// <returns>The value returned from the method.</returns>
public static T InvokeMethod<T>(object obj, string methodName, Type[] argTypes, object[] args)
{
MethodInfo mi = obj?.GetType().GetMethod(methodName, argTypes);
if (mi != null)
return (T)Convert.ChangeType(mi.Invoke(obj, args), typeof(T));
return default(T);
}
/// <summary>Gets a named property value from an object.</summary>
/// <typeparam name="T">The expected type of the property to be returned.</typeparam>
/// <param name="obj">The object from which to retrieve the property.</param>
/// <param name="propName">Name of the property.</param>
/// <param name="defaultValue">The default value to return in the instance that the property is not found.</param>
/// <returns>The property value, if found, or the <paramref name="defaultValue"/> if not.</returns>
public static T GetProperty<T>(object obj, string propName, T defaultValue = default(T))
{
if (obj != null)
{
try { return (T)Convert.ChangeType(obj.GetType().InvokeMember(propName, BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, obj, null, null), typeof(T)); }
catch { }
}
return defaultValue;
}
/// <summary>Sets a named property on an object.</summary>
/// <typeparam name="T">The type of the property to be set.</typeparam>
/// <param name="obj">The object on which to set the property.</param>
/// <param name="propName">Name of the property.</param>
/// <param name="value">The property value to set on the object.</param>
public static void SetProperty<T>(object obj, string propName, T value)
{
try { obj?.GetType().InvokeMember(propName, BindingFlags.SetProperty | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, obj, new object[] { value }, null); }
catch { }
}
}
}

View File

@ -0,0 +1,52 @@
using System;
using System.Runtime.InteropServices;
using System.Text;
using JetBrains.Annotations;
namespace Microsoft.Win32.TaskScheduler
{
/// <summary>
/// Some string values of <see cref="TaskDefinition"/> properties can be set to retrieve their value from existing DLLs as a resource. This class facilitates creating those reference strings.
/// </summary>
[PublicAPI]
public class ResourceReferenceValue
{
/// <summary>
/// Initializes a new instance of the <see cref="ResourceReferenceValue"/> class.
/// </summary>
/// <param name="dllPath">The DLL path.</param>
/// <param name="resourceId">The resource identifier.</param>
public ResourceReferenceValue([NotNull] string dllPath, int resourceId)
{
ResourceFilePath = dllPath;
ResourceIdentifier = resourceId;
}
/// <summary>
/// Gets or sets the resource file path. This can be a relative path, full path or lookup path (e.g. %SystemRoot%\System32\ResourceName.dll).
/// </summary>
/// <value>
/// The resource file path.
/// </value>
public string ResourceFilePath { get; set; }
/// <summary>
/// Gets or sets the resource identifier.
/// </summary>
/// <value>The resource identifier.</value>
public int ResourceIdentifier { get; set; }
/// <summary>
/// Performs an implicit conversion from <see cref="Microsoft.Win32.TaskScheduler.ResourceReferenceValue" /> to <see cref="System.String" />.
/// </summary>
/// <param name="value">The value.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator string(ResourceReferenceValue value) => value.ToString();
/// <summary>
/// Returns a <see cref="System.String" /> in the format required by the Task Scheduler to reference a string in a DLL.
/// </summary>
/// <returns>A formatted <see cref="System.String" /> in the format $(@ [Dll], [ResourceID]).</returns>
public override string ToString() => $"$(@ {ResourceFilePath}, {ResourceIdentifier})";
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,366 @@
using JetBrains.Annotations;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
namespace Microsoft.Win32.TaskScheduler
{
/// <summary>
/// Collection of running tasks in a <see cref="TaskService"/>. This class has no public constructor and can only be accessed via the
/// properties and functions within <see cref="TaskService"/>.
/// </summary>
public sealed class RunningTaskCollection : IReadOnlyList<RunningTask>, IDisposable
{
private readonly TaskService svc;
private readonly V2Interop.IRunningTaskCollection v2Coll;
internal RunningTaskCollection([NotNull] TaskService svc) => this.svc = svc;
internal RunningTaskCollection([NotNull] TaskService svc, [NotNull] V2Interop.IRunningTaskCollection iTaskColl)
{
this.svc = svc;
v2Coll = iTaskColl;
}
/// <summary>Gets the number of registered tasks in the collection.</summary>
public int Count
{
get
{
if (v2Coll != null)
return v2Coll.Count;
var i = 0;
var v1Enum = new V1RunningTaskEnumerator(svc);
while (v1Enum.MoveNext())
i++;
return i;
}
}
/// <summary>Gets the specified running task from the collection.</summary>
/// <param name="index">The index of the running task to be retrieved.</param>
/// <returns>A <see cref="RunningTask"/> instance.</returns>
public RunningTask this[int index]
{
get
{
if (v2Coll != null)
{
var irt = v2Coll[++index];
return new RunningTask(svc, TaskService.GetTask(svc.v2TaskService, irt.Path), irt);
}
var i = 0;
var v1Enum = new V1RunningTaskEnumerator(svc);
while (v1Enum.MoveNext())
if (i++ == index)
return v1Enum.Current;
throw new ArgumentOutOfRangeException(nameof(index));
}
}
/// <summary>Releases all resources used by this class.</summary>
public void Dispose()
{
if (v2Coll != null)
Marshal.ReleaseComObject(v2Coll);
}
/// <summary>Gets an IEnumerator instance for this collection.</summary>
/// <returns>An enumerator.</returns>
public IEnumerator<RunningTask> GetEnumerator()
{
if (v2Coll != null)
return new ComEnumerator<RunningTask, V2Interop.IRunningTask>(() => v2Coll.Count, (object o) => v2Coll[o], o =>
{
V2Interop.IRegisteredTask task = null;
try { task = TaskService.GetTask(svc.v2TaskService, o.Path); } catch { }
return task == null ? null : new RunningTask(svc, task, o);
});
return new V1RunningTaskEnumerator(svc);
}
/// <summary>Returns a <see cref="System.String"/> that represents this instance.</summary>
/// <returns>A <see cref="System.String"/> that represents this instance.</returns>
public override string ToString() => $"RunningTaskCollection; Count: {Count}";
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator();
private class V1RunningTaskEnumerator : IEnumerator<RunningTask>
{
private readonly TaskService svc;
private readonly TaskCollection.V1TaskEnumerator tEnum;
internal V1RunningTaskEnumerator([NotNull] TaskService svc)
{
this.svc = svc;
tEnum = new TaskCollection.V1TaskEnumerator(svc);
}
public RunningTask Current => new RunningTask(svc, tEnum.ICurrent);
object System.Collections.IEnumerator.Current => Current;
/// <summary>Releases all resources used by this class.</summary>
public void Dispose() => tEnum.Dispose();
public bool MoveNext() => tEnum.MoveNext() && (tEnum.Current?.State == TaskState.Running || MoveNext());
public void Reset() => tEnum.Reset();
}
}
/// <summary>
/// Contains all the tasks that are registered within a <see cref="TaskFolder"/>. This class has no public constructor and can only be
/// accessed via the properties and functions within <see cref="TaskFolder"/>.
/// </summary>
/// <remarks>
/// 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.
/// </remarks>
/// <example>
/// <code>public class Program
/// {
/// bool RootFolderHasTask(string taskName)
/// {
/// if (TaskService.Instance.RootFolder.Tasks.Count &gt; 0)
/// {
/// return TaskService.Instance.RootFolder.Tasks.Exists(taskName);
/// }
/// return false;
/// }
///
/// TaskCollection GetRootTasksStartingWith(string value)
/// {
/// var pattern = $"^{Regex.Escape(value)}.*$";
/// return TaskService.Instance.RootFolder.GetTasks(new Regex(pattern));
/// }
///
/// public static void Main()
/// {
/// foreach (var task in GetRootTasksStartingWith("MyCo"))
/// if (RootFolderHasTask(task.Name))
/// Console.WriteLine(task.Name);
/// }
/// }</code>
/// </example>
[PublicAPI]
public sealed class TaskCollection : IReadOnlyList<Task>, IDisposable
{
private readonly TaskFolder fld;
private readonly TaskService svc;
private readonly V2Interop.IRegisteredTaskCollection v2Coll;
private Regex filter;
private V1Interop.ITaskScheduler v1TS;
internal TaskCollection([NotNull] TaskService svc, Regex filter = null)
{
this.svc = svc;
Filter = filter;
v1TS = svc.v1TaskScheduler;
}
internal TaskCollection([NotNull] TaskFolder folder, [NotNull] V2Interop.IRegisteredTaskCollection iTaskColl, Regex filter = null)
{
svc = folder.TaskService;
Filter = filter;
fld = folder;
v2Coll = iTaskColl;
}
/// <summary>Gets the number of registered tasks in the collection.</summary>
public int Count
{
get
{
var i = 0;
if (v2Coll != null)
{
var v2Enum = new V2TaskEnumerator(fld, v2Coll, filter);
while (v2Enum.MoveNext())
i++;
}
else
{
var v1Enum = new V1TaskEnumerator(svc, filter);
return v1Enum.Count;
}
return i;
}
}
/// <summary>Gets or sets the regular expression filter for task names.</summary>
/// <value>The regular expression filter.</value>
private Regex Filter
{
get => filter;
set
{
var sfilter = value?.ToString().TrimStart('^').TrimEnd('$') ?? string.Empty;
if (sfilter == string.Empty || sfilter == "*")
filter = null;
else
{
if (value != null && value.ToString().TrimEnd('$').EndsWith("\\.job", StringComparison.InvariantCultureIgnoreCase))
filter = new Regex(value.ToString().Replace("\\.job", ""));
else
filter = value;
}
}
}
/// <summary>Gets the specified registered task from the collection.</summary>
/// <param name="index">The index of the registered task to be retrieved.</param>
/// <returns>A <see cref="Task"/> instance that contains the requested context.</returns>
public Task this[int index]
{
get
{
var i = 0;
var te = GetEnumerator();
while (te.MoveNext())
if (i++ == index)
return te.Current;
throw new ArgumentOutOfRangeException(nameof(index));
}
}
/// <summary>Releases all resources used by this class.</summary>
public void Dispose()
{
v1TS = null;
if (v2Coll != null)
Marshal.ReleaseComObject(v2Coll);
}
/// <summary>Gets the collection enumerator for the register task collection.</summary>
/// <returns>An <see cref="System.Collections.IEnumerator"/> for this collection.</returns>
public IEnumerator<Task> GetEnumerator()
{
if (v1TS != null)
return new V1TaskEnumerator(svc, filter);
return new V2TaskEnumerator(fld, v2Coll, filter);
}
/// <summary>Returns a <see cref="System.String"/> that represents this instance.</summary>
/// <returns>A <see cref="System.String"/> that represents this instance.</returns>
public override string ToString() => $"TaskCollection; Count: {Count}";
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator();
internal class V1TaskEnumerator : IEnumerator<Task>
{
private readonly Regex filter;
private readonly TaskService svc;
private readonly V1Interop.IEnumWorkItems wienum;
private string curItem;
private V1Interop.ITaskScheduler ts;
/// <summary>Internal constructor</summary>
/// <param name="svc">TaskService instance</param>
/// <param name="filter">The filter.</param>
internal V1TaskEnumerator(TaskService svc, Regex filter = null)
{
this.svc = svc;
this.filter = filter;
ts = svc.v1TaskScheduler;
wienum = ts?.Enum();
Reset();
}
/// <summary>Retrieves the current task. See <see cref="System.Collections.IEnumerator.Current"/> for more information.</summary>
public Task Current => new Task(svc, ICurrent);
object System.Collections.IEnumerator.Current => Current;
internal int Count
{
get
{
var i = 0;
Reset();
while (MoveNext())
i++;
Reset();
return i;
}
}
internal V1Interop.ITask ICurrent => TaskService.GetTask(ts, curItem);
/// <summary>Releases all resources used by this class.</summary>
public void Dispose()
{
if (wienum != null) Marshal.ReleaseComObject(wienum);
ts = null;
}
/// <summary>Moves to the next task. See MoveNext for more information.</summary>
/// <returns>true if next task found, false if no more tasks.</returns>
public bool MoveNext()
{
var names = IntPtr.Zero;
var valid = false;
do
{
curItem = null;
uint uFetched = 0;
try
{
wienum?.Next(1, out names, out uFetched);
if (uFetched != 1)
break;
using (var name = new V1Interop.CoTaskMemString(Marshal.ReadIntPtr(names)))
curItem = name.ToString();
if (curItem != null && curItem.EndsWith(".job", StringComparison.InvariantCultureIgnoreCase))
curItem = curItem.Remove(curItem.Length - 4);
}
catch { }
finally { Marshal.FreeCoTaskMem(names); names = IntPtr.Zero; }
// If name doesn't match filter, look for next item
if (filter != null && curItem != null)
{
if (!filter.IsMatch(curItem))
continue;
}
V1Interop.ITask itask = null;
try { itask = ICurrent; valid = true; }
catch { valid = false; }
finally { Marshal.ReleaseComObject(itask); }
} while (!valid);
return (curItem != null);
}
/// <summary>Reset task enumeration. See Reset for more information.</summary>
public void Reset()
{
curItem = null;
wienum?.Reset();
}
}
private class V2TaskEnumerator : ComEnumerator<Task, V2Interop.IRegisteredTask>
{
private readonly Regex filter;
internal V2TaskEnumerator(TaskFolder folder, V2Interop.IRegisteredTaskCollection iTaskColl, Regex filter = null) :
base(() => iTaskColl.Count, (object o) => iTaskColl[o], o => Task.CreateTask(folder.TaskService, o)) => this.filter = filter;
public override bool MoveNext()
{
var hasNext = base.MoveNext();
while (hasNext)
{
if (filter == null || filter.IsMatch(iEnum?.Current?.Name ?? ""))
break;
hasNext = base.MoveNext();
}
return hasNext;
}
}
}
}

View File

@ -0,0 +1,715 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.Eventing.Reader;
using JetBrains.Annotations;
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace Microsoft.Win32.TaskScheduler
{
/// <summary>
/// Changes to tasks and the engine that cause events.
/// </summary>
public enum StandardTaskEventId
{
/// <summary>Task Scheduler started an instance of a task for a user.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd348558(v=ws.10).aspx">Event ID 100</a> on TechNet.</remarks>
JobStart = 100,
/// <summary>Task Scheduler failed to start a task for a user.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd315710(v=ws.10).aspx">Event ID 101</a> on TechNet.</remarks>
JobStartFailed = 101,
/// <summary>Task Scheduler successfully finished an instance of a task for a user.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd348530(v=ws.10).aspx">Event ID 102</a> on TechNet.</remarks>
JobSuccess = 102,
/// <summary>Task Scheduler failed to start an instance of a task for a user.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd315643(v=ws.10).aspx">Event ID 103</a> on TechNet.</remarks>
JobFailure = 103,
/// <summary>Task Scheduler failed to log on the user.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/cc727217(v=ws.10).aspx">Event ID 104</a> on TechNet.</remarks>
LogonFailure = 104,
/// <summary>Task Scheduler failed to impersonate a user.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd348541(v=ws.10).aspx">Event ID 105</a> on TechNet.</remarks>
ImpersonationFailure = 105,
/// <summary>The a user registered the Task Scheduler a task.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd363640(v=ws.10).aspx">Event ID 106</a> on TechNet.</remarks>
JobRegistered = 106,
/// <summary>Task Scheduler launched an instance of a task due to a time trigger.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd348590(v=ws.10).aspx">Event ID 107</a> on TechNet.</remarks>
TimeTrigger = 107,
/// <summary>Task Scheduler launched an instance of a task due to an event trigger.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/cc727031(v=ws.10).aspx">Event ID 108</a> on TechNet.</remarks>
EventTrigger = 108,
/// <summary>Task Scheduler launched an instance of a task due to a registration trigger.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd363702(v=ws.10).aspx">Event ID 109</a> on TechNet.</remarks>
ImmediateTrigger = 109,
/// <summary>Task Scheduler launched an instance of a task for a user.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd363721(v=ws.10).aspx">Event ID 110</a> on TechNet.</remarks>
Run = 110,
/// <summary>Task Scheduler terminated an instance of a task due to exceeding the time allocated for execution, as configured in the task definition.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd315549(v=ws.10).aspx">Event ID 111</a> on TechNet.</remarks>
JobTermination = 111,
/// <summary>Task Scheduler could not start a task because the network was unavailable. Ensure the computer is connected to the required network as specified in the task.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd363779(v=ws.10).aspx">Event ID 112</a> on TechNet.</remarks>
JobNoStartWithoutNetwork = 112,
/// <summary>The Task Scheduler registered the a task, but not all the specified triggers will start the task. Ensure all the task triggers are valid.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd315656(v=ws.10).aspx">Event ID 113</a> on TechNet.</remarks>
TaskRegisteredWithoutSomeTriggers = 113,
/// <summary>Task Scheduler could not launch a task as scheduled. Instance is started now as required by the configuration option to start the task when available, if the scheduled time is missed.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/cc775066(v=ws.10).aspx">Event ID 114</a> on TechNet.</remarks>
MissedTaskLaunched = 114,
/// <summary>Task Scheduler failed to roll back a transaction when updating or deleting a task.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd315711(v=ws.10).aspx">Event ID 115</a> on TechNet.</remarks>
TransactionRollbackFailure = 115,
/// <summary>Task Scheduler saved the configuration for a task, but the credentials used to run the task could not be stored.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd363682(v=ws.10).aspx">Event ID 116</a> on TechNet.</remarks>
TaskRegisteredWithoutCredentials = 116,
/// <summary>Task Scheduler launched an instance of a task due to an idle condition.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd315755(v=ws.10).aspx">Event ID 117</a> on TechNet.</remarks>
IdleTrigger = 117,
/// <summary>Task Scheduler launched an instance of a task due to system startup.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/cc775107(v=ws.10).aspx">Event ID 118</a> on TechNet.</remarks>
BootTrigger = 118,
/// <summary>Task Scheduler launched an instance of a task due to a user logon.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd315498(v=ws.10).aspx">Event ID 119</a> on TechNet.</remarks>
LogonTrigger = 119,
/// <summary>Task Scheduler launched an instance of a task due to a user connecting to the console.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd315609(v=ws.10).aspx">Event ID 120</a> on TechNet.</remarks>
ConsoleConnectTrigger = 120,
/// <summary>Task Scheduler launched an instance of a task due to a user disconnecting from the console.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd363748(v=ws.10).aspx">Event ID 121</a> on TechNet.</remarks>
ConsoleDisconnectTrigger = 121,
/// <summary>Task Scheduler launched an instance of a task due to a user remotely connecting.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/cc774994(v=ws.10).aspx">Event ID 122</a> on TechNet.</remarks>
RemoteConnectTrigger = 122,
/// <summary>Task Scheduler launched an instance of a task due to a user remotely disconnecting.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/cc775034(v=ws.10).aspx">Event ID 123</a> on TechNet.</remarks>
RemoteDisconnectTrigger = 123,
/// <summary>Task Scheduler launched an instance of a task due to a user locking the computer.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd315499(v=ws.10).aspx">Event ID 124</a> on TechNet.</remarks>
SessionLockTrigger = 124,
/// <summary>Task Scheduler launched an instance of a task due to a user unlocking the computer.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/cc727048(v=ws.10).aspx">Event ID 125</a> on TechNet.</remarks>
SessionUnlockTrigger = 125,
/// <summary>Task Scheduler failed to execute a task. Task Scheduler is attempting to restart the task.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd363647(v=ws.10).aspx">Event ID 126</a> on TechNet.</remarks>
FailedTaskRestart = 126,
/// <summary>Task Scheduler failed to execute a task due to a shutdown race condition. Task Scheduler is attempting to restart the task.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/cc726976(v=ws.10).aspx">Event ID 127</a> on TechNet.</remarks>
RejectedTaskRestart = 127,
/// <summary>Task Scheduler did not launch a task because the current time exceeds the configured task end time.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd315638(v=ws.10).aspx">Event ID 128</a> on TechNet.</remarks>
IgnoredTaskStart = 128,
/// <summary>Task Scheduler launched an instance of a task in a new process.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd315544(v=ws.10).aspx">Event ID 129</a> on TechNet.</remarks>
CreatedTaskProcess = 129,
/// <summary>The Task Scheduler service failed to start a task due to the service being busy.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd315521(v=ws.10).aspx">Event ID 130</a> on TechNet.</remarks>
TaskNotRunServiceBusy = 130,
/// <summary>Task Scheduler failed to start a task because the number of tasks in the task queue exceeds the quota currently configured.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd363733(v=ws.10).aspx">Event ID 131</a> on TechNet.</remarks>
TaskNotStartedTaskQueueQuotaExceeded = 131,
/// <summary>The Task Scheduler task launching queue quota is approaching its preset limit of tasks currently configured.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd363705(v=ws.10).aspx">Event ID 132</a> on TechNet.</remarks>
TaskQueueQuotaApproaching = 132,
/// <summary>Task Scheduler failed to start a task in the task engine for a user.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd315645(v=ws.10).aspx">Event ID 133</a> on TechNet.</remarks>
TaskNotStartedEngineQuotaExceeded = 133,
/// <summary>Task Engine for a user is approaching its preset limit of tasks.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/cc774865(v=ws.10).aspx">Event ID 134</a> on TechNet.</remarks>
EngineQuotaApproaching = 134,
/// <summary>Task Scheduler did not launch a task because launch condition not met, machine not idle.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd363654(v=ws.10).aspx">Event ID 135</a> on TechNet.</remarks>
NotStartedWithoutIdle = 135,
/// <summary>A user updated Task Scheduler a task</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd363717(v=ws.10).aspx">Event ID 140</a> on TechNet.</remarks>
TaskUpdated = 140,
/// <summary>A user deleted Task Scheduler a task</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd348535(v=ws.10).aspx">Event ID 141</a> on TechNet.</remarks>
TaskDeleted = 141,
/// <summary>A user disabled Task Scheduler a task</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd363727(v=ws.10).aspx">Event ID 142</a> on TechNet.</remarks>
TaskDisabled = 142,
/// <summary>Task Scheduler woke up the computer to run a task.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/cc775065(v=ws.10).aspx">Event ID 145</a> on TechNet.</remarks>
TaskStartedOnComputerWakeup = 145,
/// <summary>Task Scheduler failed to subscribe the event trigger for a task.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd315495(v=ws.10).aspx">Event ID 150</a> on TechNet.</remarks>
TaskEventSubscriptionFailed = 150,
/// <summary>Task Scheduler launched an action in an instance of a task.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/cc775088(v=ws.10).aspx">Event ID 200</a> on TechNet.</remarks>
ActionStart = 200,
/// <summary>Task Scheduler successfully completed a task instance and action.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd348568(v=ws.10).aspx">Event ID 201</a> on TechNet.</remarks>
ActionSuccess = 201,
/// <summary>Task Scheduler failed to complete an instance of a task with an action.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd315592(v=ws.10).aspx">Event ID 202</a> on TechNet.</remarks>
ActionFailure = 202,
/// <summary>Task Scheduler failed to launch an action in a task instance.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd363729(v=ws.10).aspx">Event ID 203</a> on TechNet.</remarks>
ActionLaunchFailure = 203,
/// <summary>Task Scheduler failed to retrieve the event triggering values for a task . The event will be ignored.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd348579(v=ws.10).aspx">Event ID 204</a> on TechNet.</remarks>
EventRenderFailed = 204,
/// <summary>Task Scheduler failed to match the pattern of events for a task. The events will be ignored.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd363661(v=ws.10).aspx">Event ID 205</a> on TechNet.</remarks>
EventAggregateFailed = 205,
/// <summary>Task Scheduler is shutting down the a task engine.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd348583(v=ws.10).aspx">Event ID 301</a> on TechNet.</remarks>
SessionExit = 301,
/// <summary>Task Scheduler is shutting down the a task engine due to an error. </summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/cc727080(v=ws.10).aspx">Event ID 303</a> on TechNet.</remarks>
SessionError = 303,
/// <summary>Task Scheduler sent a task to a task engine.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd315534(v=ws.10).aspx">Event ID 304</a> on TechNet.</remarks>
SessionSentJob = 304,
/// <summary>Task Scheduler did not send a task to a task engine.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd363776(v=ws.10).aspx">Event ID 305</a> on TechNet.</remarks>
SessionSentJobFailed = 305,
/// <summary>For a Task Scheduler task engine, the thread pool failed to process the message.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd315525(v=ws.10).aspx">Event ID 306</a> on TechNet.</remarks>
SessionFailedToProcessMessage = 306,
/// <summary>The Task Scheduler service failed to connect to a task engine process.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd315605(v=ws.10).aspx">Event ID 307</a> on TechNet.</remarks>
SessionManagerConnectFailed = 307,
/// <summary>Task Scheduler connected to a task engine process.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd315746(v=ws.10).aspx">Event ID 308</a> on TechNet.</remarks>
SessionConnected = 308,
/// <summary>There are Task Scheduler tasks orphaned during a task engine shutdown.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd348580(v=ws.10).aspx">Event ID 309</a> on TechNet.</remarks>
SessionJobsOrphaned = 309,
/// <summary>Task Scheduler started a task engine process.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd315668(v=ws.10).aspx">Event ID 310</a> on TechNet.</remarks>
SessionProcessStarted = 310,
/// <summary>Task Scheduler failed to start a task engine process due to an error.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd363691(v=ws.10).aspx">Event ID 311</a> on TechNet.</remarks>
SessionProcessLaunchFailed = 311,
/// <summary>Task Scheduler created the Win32 job object for a task engine.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/cc775071(v=ws.10).aspx">Event ID 312</a> on TechNet.</remarks>
SessionWin32ObjectCreated = 312,
/// <summary>The Task Scheduler channel is ready to send and receive messages.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd363685(v=ws.10).aspx">Event ID 313</a> on TechNet.</remarks>
SessionChannelReady = 313,
/// <summary>Task Scheduler has no tasks running for a task engine, and the idle timer has started.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd315517(v=ws.10).aspx">Event ID 314</a> on TechNet.</remarks>
SessionIdle = 314,
/// <summary>A task engine process failed to connect to the Task Scheduler service.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd363798(v=ws.10).aspx">Event ID 315</a> on TechNet.</remarks>
SessionProcessConnectFailed = 315,
/// <summary>A task engine failed to send a message to the Task Scheduler service.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd315748(v=ws.10).aspx">Event ID 316</a> on TechNet.</remarks>
SessionMessageSendFailed = 316,
/// <summary>Task Scheduler started a task engine process.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd315663(v=ws.10).aspx">Event ID 317</a> on TechNet.</remarks>
SessionProcessMainStarted = 317,
/// <summary>Task Scheduler shut down a task engine process.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/cc727204(v=ws.10).aspx">Event ID 318</a> on TechNet.</remarks>
SessionProcessMainShutdown = 318,
/// <summary>A task engine received a message from the Task Scheduler service requesting to launch a task.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd363712(v=ws.10).aspx">Event ID 319</a> on TechNet.</remarks>
SessionProcessReceivedStartJob = 319,
/// <summary>A task engine received a message from the Task Scheduler service requesting to stop a task instance.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/cc774993(v=ws.10).aspx">Event ID 320</a> on TechNet.</remarks>
SessionProcessReceivedStopJob = 320,
/// <summary>Task Scheduler did not launch a task because an instance of the same task is already running.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd315618(v=ws.10).aspx">Event ID 322</a> on TechNet.</remarks>
NewInstanceIgnored = 322,
/// <summary>Task Scheduler stopped an instance of a task in order to launch a new instance.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd315542(v=ws.10).aspx">Event ID 323</a> on TechNet.</remarks>
RunningInstanceStopped = 323,
/// <summary>Task Scheduler queued an instance of a task and will launch it as soon as another instance completes.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd363759(v=ws.10).aspx">Event ID 324</a> on TechNet.</remarks>
NewInstanceQueued = 324,
/// <summary>Task Scheduler queued an instance of a task that will launch immediately.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd363654(v=ws.10).aspx">Event ID 325</a> on TechNet.</remarks>
InstanceQueued = 325,
/// <summary>Task Scheduler did not launch a task because the computer is running on batteries. If launching the task on batteries is required, change the respective flag in the task configuration.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd315644(v=ws.10).aspx">Event ID 326</a> on TechNet.</remarks>
NoStartOnBatteries = 326,
/// <summary>Task Scheduler stopped an instance of a task because the computer is switching to battery power.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd348611(v=ws.10).aspx">Event ID 327</a> on TechNet.</remarks>
StoppingOnBatteries = 327,
/// <summary>Task Scheduler stopped an instance of a task because the computer is no longer idle.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd363732(v=ws.10).aspx">Event ID 328</a> on TechNet.</remarks>
StoppingOffIdle = 328,
/// <summary>Task Scheduler stopped an instance of a task because the task timed out.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd348536(v=ws.10).aspx">Event ID 329</a> on TechNet.</remarks>
StoppingOnTimeout = 329,
/// <summary>Task Scheduler stopped an instance of a task as request by a user .</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd348610(v=ws.10).aspx">Event ID 330</a> on TechNet.</remarks>
StoppingOnRequest = 330,
/// <summary>Task Scheduler will continue to execute an instance of a task even after the designated timeout, due to a failure to create the timeout mechanism.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd315673(v=ws.10).aspx">Event ID 331</a> on TechNet.</remarks>
TimeoutWontWork = 331,
/// <summary>Task Scheduler did not launch a task because a user was not logged on when the launching conditions were met. Ensure the user is logged on or change the task definition to allow the task to launch when the user is logged off.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd315612(v=ws.10).aspx">Event ID 332</a> on TechNet.</remarks>
NoStartUserNotLoggedOn = 332,
/// <summary>The Task Scheduler service has started.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd315626(v=ws.10).aspx">Event ID 400</a> on TechNet.</remarks>
ScheduleServiceStart = 400,
/// <summary>The Task Scheduler service failed to start due to an error.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd363598(v=ws.10).aspx">Event ID 401</a> on TechNet.</remarks>
ScheduleServiceStartFailed = 401,
/// <summary>Task Scheduler service is shutting down.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd363724(v=ws.10).aspx">Event ID 402</a> on TechNet.</remarks>
ScheduleServiceStop = 402,
/// <summary>The Task Scheduler service has encountered an error.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd315744(v=ws.10).aspx">Event ID 403</a> on TechNet.</remarks>
ScheduleServiceError = 403,
/// <summary>The Task Scheduler service has encountered an RPC initialization error.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd363713(v=ws.10).aspx">Event ID 404</a> on TechNet.</remarks>
ScheduleServiceRpcInitError = 404,
/// <summary>The Task Scheduler service has failed to initialize COM.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd363728(v=ws.10).aspx">Event ID 405</a> on TechNet.</remarks>
ScheduleServiceComInitError = 405,
/// <summary>The Task Scheduler service failed to initialize the credentials store.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd315727(v=ws.10).aspx">Event ID 406</a> on TechNet.</remarks>
ScheduleServiceCredStoreInitError = 406,
/// <summary>Task Scheduler service failed to initialize LSA.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd315580(v=ws.10).aspx">Event ID 407</a> on TechNet.</remarks>
ScheduleServiceLsaInitError = 407,
/// <summary>Task Scheduler service failed to initialize idle state detection module. Idle tasks may not be started as required.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd315523(v=ws.10).aspx">Event ID 408</a> on TechNet.</remarks>
ScheduleServiceIdleServiceInitError = 408,
/// <summary>The Task Scheduler service failed to initialize a time change notification. System time updates may not be picked by the service and task schedules may not be updated.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/cc774954(v=ws.10).aspx">Event ID 409</a> on TechNet.</remarks>
ScheduleServiceTimeChangeInitError = 409,
/// <summary>Task Scheduler service received a time system change notification.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd315633(v=ws.10).aspx">Event ID 411</a> on TechNet.</remarks>
ScheduleServiceTimeChangeSignaled = 411,
/// <summary>Task Scheduler service failed to launch tasks triggered by computer startup. Restart the Task Scheduler service.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd315637(v=ws.10).aspx">Event ID 412</a> on TechNet.</remarks>
ScheduleServiceRunBootJobsFailed = 412,
/// <summary>Task Scheduler service started Task Compatibility module.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/cc727087(v=ws.10).aspx">Event ID 700</a> on TechNet.</remarks>
CompatStart = 700,
/// <summary>Task Scheduler service failed to start Task Compatibility module. Tasks may not be able to register on previous Window versions.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd315530(v=ws.10).aspx">Event ID 701</a> on TechNet.</remarks>
CompatStartFailed = 701,
/// <summary>Task Scheduler failed to initialize the RPC server for starting the Task Compatibility module. Tasks may not be able to register on previous Window versions.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd315721(v=ws.10).aspx">Event ID 702</a> on TechNet.</remarks>
CompatStartRpcFailed = 702,
/// <summary>Task Scheduler failed to initialize Net Schedule API for starting the Task Compatibility module. Tasks may not be able to register on previous Window versions.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd348604(v=ws.10).aspx">Event ID 703</a> on TechNet.</remarks>
CompatStartNetscheduleFailed = 703,
/// <summary>Task Scheduler failed to initialize LSA for starting the Task Compatibility module. Tasks may not be able to register on previous Window versions.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd315572(v=ws.10).aspx">Event ID 704</a> on TechNet.</remarks>
CompatStartLsaFailed = 704,
/// <summary>Task Scheduler failed to start directory monitoring for the Task Compatibility module.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/cc727147(v=ws.10).aspx">Event ID 705</a> on TechNet.</remarks>
CompatDirectoryMonitorFailed = 705,
/// <summary>Task Compatibility module failed to update a task to the required status.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd315682(v=ws.10).aspx">Event ID 706</a> on TechNet.</remarks>
CompatTaskStatusUpdateFailed = 706,
/// <summary>Task Compatibility module failed to delete a task.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd348545(v=ws.10).aspx">Event ID 707</a> on TechNet.</remarks>
CompatTaskDeleteFailed = 707,
/// <summary>Task Compatibility module failed to set a security descriptor for a task.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd315719(v=ws.10).aspx">Event ID 708</a> on TechNet.</remarks>
CompatTaskSetSdFailed = 708,
/// <summary>Task Compatibility module failed to update a task.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd363614(v=ws.10).aspx">Event ID 709</a> on TechNet.</remarks>
CompatTaskUpdateFailed = 709,
/// <summary>Task Compatibility module failed to upgrade existing tasks. Upgrade will be attempted again next time 'Task Scheduler' service starts.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd363608(v=ws.10).aspx">Event ID 710</a> on TechNet.</remarks>
CompatUpgradeStartFailed = 710,
/// <summary>Task Compatibility module failed to upgrade NetSchedule account.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd348554(v=ws.10).aspx">Event ID 711</a> on TechNet.</remarks>
CompatUpgradeNsAccountFailed = 711,
/// <summary>Task Compatibility module failed to read existing store to upgrade tasks.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd315519(v=ws.10).aspx">Event ID 712</a> on TechNet.</remarks>
CompatUpgradeStoreEnumFailed = 712,
/// <summary>Task Compatibility module failed to load a task for upgrade.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd315728(v=ws.10).aspx">Event ID 713</a> on TechNet.</remarks>
CompatUpgradeTaskLoadFailed = 713,
/// <summary>Task Compatibility module failed to register a task for upgrade.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd363701(v=ws.10).aspx">Event ID 714</a> on TechNet.</remarks>
CompatUpgradeTaskRegistrationFailed = 714,
/// <summary>Task Compatibility module failed to delete LSA store for upgrade.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd348581(v=ws.10).aspx">Event ID 715</a> on TechNet.</remarks>
CompatUpgradeLsaCleanupFailed = 715,
/// <summary>Task Compatibility module failed to upgrade existing scheduled tasks.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd315624(v=ws.10).aspx">Event ID 716</a> on TechNet.</remarks>
CompatUpgradeFailed = 716,
/// <summary>Task Compatibility module failed to determine if upgrade is needed.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd315731(v=ws.10).aspx">Event ID 717</a> on TechNet.</remarks>
CompatUpgradeNeedNotDetermined = 717,
/// <summary>Task scheduler was unable to upgrade the credential store from the Beta 2 version. You may need to re-register any tasks that require passwords.</summary>
/// <remarks>For detailed information, see the documentation for <a href="https://technet.microsoft.com/en-us/library/dd348576(v=ws.10).aspx">Event ID 718</a> on TechNet.</remarks>
VistaBeta2CredstoreUpgradeFailed = 718,
/// <summary>A unknown value.</summary>
Unknown = -2
}
/// <summary>
/// Historical event information for a task. This class wraps and extends the <see cref="EventRecord"/> class.
/// </summary>
/// <remarks>
/// For events on systems prior to Windows Vista, this class will only have information for the TaskPath, TimeCreated and EventId properties.
/// </remarks>
[PublicAPI]
public sealed class TaskEvent : IComparable<TaskEvent>
{
internal TaskEvent([NotNull] EventRecord rec)
{
EventId = rec.Id;
EventRecord = rec;
Version = rec.Version;
TaskCategory = rec.TaskDisplayName;
OpCode = rec.OpcodeDisplayName;
TimeCreated = rec.TimeCreated;
RecordId = rec.RecordId;
ActivityId = rec.ActivityId;
Level = rec.LevelDisplayName;
UserId = rec.UserId;
ProcessId = rec.ProcessId;
TaskPath = rec.Properties.Count > 0 ? rec.Properties[0]?.Value?.ToString() : null;
DataValues = new EventDataValues(rec as EventLogRecord);
}
internal TaskEvent([NotNull] string taskPath, StandardTaskEventId id, DateTime time)
{
EventId = (int)id;
TaskPath = taskPath;
TimeCreated = time;
}
/// <summary>
/// Gets the activity id. This value is <c>null</c> for V1 events.
/// </summary>
public Guid? ActivityId { get; internal set; }
/// <summary>
/// An indexer that gets the value of each of the data item values. This value is <c>null</c> for V1 events.
/// </summary>
/// <value>
/// The data values.
/// </value>
public EventDataValues DataValues { get; }
/// <summary>
/// Gets the event id.
/// </summary>
public int EventId { get; internal set; }
/// <summary>
/// Gets the underlying <see cref="EventRecord"/>. This value is <c>null</c> for V1 events.
/// </summary>
public EventRecord EventRecord { get; internal set; }
/// <summary>
/// Gets the level. This value is <c>null</c> for V1 events.
/// </summary>
public string Level { get; internal set; }
/// <summary>
/// Gets the op code. This value is <c>null</c> for V1 events.
/// </summary>
public string OpCode { get; internal set; }
/// <summary>
/// Gets the process id. This value is <c>null</c> for V1 events.
/// </summary>
public int? ProcessId { get; internal set; }
/// <summary>
/// Gets the record id. This value is <c>null</c> for V1 events.
/// </summary>
public long? RecordId { get; internal set; }
/// <summary>
/// Gets the task category. This value is <c>null</c> for V1 events.
/// </summary>
public string TaskCategory { get; internal set; }
/// <summary>
/// Gets the task path.
/// </summary>
public string TaskPath { get; internal set; }
/// <summary>
/// Gets the time created.
/// </summary>
public DateTime? TimeCreated { get; internal set; }
/// <summary>
/// Gets the user id. This value is <c>null</c> for V1 events.
/// </summary>
public System.Security.Principal.SecurityIdentifier UserId { get; internal set; }
/// <summary>
/// Gets the version. This value is <c>null</c> for V1 events.
/// </summary>
public byte? Version { get; internal set; }
/// <summary>
/// Returns a <see cref="System.String"/> that represents this instance.
/// </summary>
/// <returns>
/// A <see cref="System.String"/> that represents this instance.
/// </returns>
public override string ToString() => EventRecord?.FormatDescription() ?? TaskPath;
/// <summary>
/// Compares the current object with another object of the same type.
/// </summary>
/// <param name="other">An object to compare with this object.</param>
/// <returns>
/// A 32-bit signed integer that indicates the relative order of the objects being compared. The return value has the following meanings: Value Meaning Less than zero This object is less than the other parameter.Zero This object is equal to other. Greater than zero This object is greater than other.
/// </returns>
public int CompareTo(TaskEvent other)
{
int i = string.Compare(TaskPath, other.TaskPath, StringComparison.Ordinal);
if (i == 0 && EventRecord != null)
{
i = string.Compare(ActivityId.ToString(), other.ActivityId.ToString(), StringComparison.Ordinal);
if (i == 0)
i = Convert.ToInt32(RecordId - other.RecordId);
}
return i;
}
/// <summary>
/// Get indexer class for <see cref="EventLogRecord"/> data values.
/// </summary>
public class EventDataValues
{
private readonly EventLogRecord rec;
internal EventDataValues(EventLogRecord eventRec)
{
rec = eventRec;
}
}
}
/// <summary>
/// An enumerator over a task's history of events.
/// </summary>
public sealed class TaskEventEnumerator : IEnumerator<TaskEvent>
{
private EventRecord curRec;
private EventLogReader log;
internal TaskEventEnumerator([NotNull] EventLogReader log)
{
this.log = log;
}
/// <summary>
/// Gets the element in the collection at the current position of the enumerator.
/// </summary>
/// <returns>
/// The element in the collection at the current position of the enumerator.
/// </returns>
public TaskEvent Current => new TaskEvent(curRec);
/// <summary>
/// Gets the element in the collection at the current position of the enumerator.
/// </summary>
/// <returns>
/// The element in the collection at the current position of the enumerator.
/// </returns>
object System.Collections.IEnumerator.Current => Current;
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
log.CancelReading();
log.Dispose();
log = null;
}
/// <summary>
/// Advances the enumerator to the next element of the collection.
/// </summary>
/// <returns>
/// true if the enumerator was successfully advanced to the next element; false if the enumerator has passed the end of the collection.
/// </returns>
/// <exception cref="T:System.InvalidOperationException">
/// The collection was modified after the enumerator was created.
/// </exception>
public bool MoveNext() => (curRec = log.ReadEvent()) != null;
/// <summary>
/// Sets the enumerator to its initial position, which is before the first element in the collection.
/// </summary>
/// <exception cref="T:System.InvalidOperationException">
/// The collection was modified after the enumerator was created.
/// </exception>
public void Reset()
{
log.Seek(System.IO.SeekOrigin.Begin, 0L);
}
}
/// <summary>
/// Historical event log for a task. Only available for Windows Vista and Windows Server 2008 and later systems.
/// </summary>
/// <remarks>Many applications have the need to audit the execution of the tasks they supply. To enable this, the library provides the TaskEventLog class that allows for TaskEvent instances to be enumerated. This can be done for single tasks or the entire system. It can also be filtered by specific events or criticality.</remarks>
/// <example><code lang="cs"><![CDATA[
/// // Create a log instance for the Maint task in the root directory
/// TaskEventLog log = new TaskEventLog(@"\Maint",
/// // Specify the event id(s) you want to enumerate
/// new int[] { 141 /* TaskDeleted */, 201 /* ActionSuccess */ },
/// // Specify the start date of the events to enumerate. Here, we look at the last week.
/// DateTime.Now.AddDays(-7));
///
/// // Tell the enumerator to expose events 'newest first'
/// log.EnumerateInReverse = false;
///
/// // Enumerate the events
/// foreach (TaskEvent ev in log)
/// {
/// // TaskEvents can interpret event ids into a well known, readable, enumerated type
/// if (ev.StandardEventId == StandardTaskEventId.TaskDeleted)
/// output.WriteLine($" Task '{ev.TaskPath}' was deleted");
///
/// // TaskEvent exposes a number of properties regarding the event
/// else if (ev.EventId == 201)
/// output.WriteLine($" Completed action '{ev.DataValues["ActionName"]}',
/// ({ev.DataValues["ResultCode"]}) at {ev.TimeCreated.Value}.");
/// }
/// ]]></code></example>
public sealed class TaskEventLog : IEnumerable<TaskEvent>
{
private const string TSEventLogPath = "Microsoft-Windows-TaskScheduler/Operational";
private static readonly bool IsVistaOrLater = Environment.OSVersion.Version.Major >= 6;
/// <summary>
/// Initializes a new instance of the <see cref="TaskEventLog" /> class.
/// </summary>
/// <param name="machineName">Name of the machine.</param>
/// <param name="taskPath">The task path. This can be retrieved using the <see cref="Task.Path" /> property.</param>
/// <param name="domain">The domain.</param>
/// <param name="user">The user.</param>
/// <param name="password">The password.</param>
/// <exception cref="NotSupportedException">Thrown when instantiated on an OS prior to Windows Vista.</exception>
public TaskEventLog([NotNull] string machineName, [CanBeNull] string taskPath, string domain = null, string user = null, string password = null)
{
Initialize(machineName, BuildQuery(taskPath), true, domain, user, password);
}
/// <summary>
/// Initializes a new instance of the <see cref="TaskEventLog" /> class.
/// </summary>
/// <param name="taskName">Name of the task.</param>
/// <param name="eventIDs">The event ids.</param>
/// <param name="levels">The levels.</param>
/// <param name="startTime">The start time.</param>
/// <param name="machineName">Name of the machine (optional).</param>
/// <param name="domain">The domain.</param>
/// <param name="user">The user.</param>
/// <param name="password">The password.</param>
public TaskEventLog(string taskName = null, int[] eventIDs = null, int[] levels = null, DateTime? startTime = null, string machineName = null, string domain = null, string user = null, string password = null)
{
Initialize(machineName, BuildQuery(taskName, eventIDs, startTime, levels), true, domain, user, password);
}
internal static string BuildQuery(string taskName = null, int[] eventIDs = null, DateTime? startTime = null, int[] levels = null)
{
const string queryString =
"<QueryList>" +
" <Query Id=\"0\" Path=\"" + TSEventLogPath + "\">" +
" <Select Path=\"" + TSEventLogPath + "\">{0}</Select>" +
" </Query>" +
"</QueryList>";
const string OR = " or ";
const string AND = " and ";
System.Text.StringBuilder sb = new System.Text.StringBuilder("*");
if (eventIDs != null && eventIDs.Length > 0)
{
if (sb.Length > 1) sb.Append(AND);
sb.AppendFormat("({0})", string.Join(OR, Array.ConvertAll(eventIDs, i => $"EventID={i}")));
}
if (levels != null && levels.Length > 0)
{
if (sb.Length > 1) sb.Append(AND);
sb.AppendFormat("({0})", string.Join(OR, Array.ConvertAll(levels, i => $"Level={i}")));
}
if (startTime.HasValue)
{
if (sb.Length > 1) sb.Append(AND);
sb.AppendFormat("TimeCreated[@SystemTime>='{0}']", System.Xml.XmlConvert.ToString(startTime.Value, System.Xml.XmlDateTimeSerializationMode.RoundtripKind));
}
if (sb.Length > 1)
{
sb.Insert(1, "[System[Provider[@Name='Microsoft-Windows-TaskScheduler'] and ");
sb.Append(']');
}
if (!string.IsNullOrEmpty(taskName))
{
if (sb.Length == 1)
sb.Append('[');
else
sb.Append("]" + AND + "*[");
sb.AppendFormat("EventData[Data[@Name='TaskName']='{0}']", taskName);
}
if (sb.Length > 1)
sb.Append(']');
return string.Format(queryString, sb);
}
private void Initialize(string machineName, string query, bool revDir, string domain = null, string user = null, string password = null)
{
if (!IsVistaOrLater)
throw new NotSupportedException("Enumeration of task history not available on systems prior to Windows Vista and Windows Server 2008.");
System.Security.SecureString spwd = null;
if (password != null)
{
spwd = new System.Security.SecureString();
foreach (char c in password)
spwd.AppendChar(c);
}
Query = new EventLogQuery(TSEventLogPath, PathType.LogName, query) { ReverseDirection = revDir };
if (machineName != null && machineName != "." && !machineName.Equals(Environment.MachineName, StringComparison.InvariantCultureIgnoreCase))
Query.Session = new EventLogSession(machineName, domain, user, spwd, SessionAuthentication.Default);
}
/// <summary>
/// Gets or sets a value indicating whether to enumerate in reverse when calling the default enumerator (typically with foreach statement).
/// </summary>
/// <value>
/// <c>true</c> if enumerates in reverse (newest to oldest) by default; otherwise, <c>false</c> to enumerate oldest to newest.
/// </value>
[System.ComponentModel.DefaultValue(false)]
public bool EnumerateInReverse { get; set; }
/// <summary>
/// Returns an enumerator that iterates through the collection.
/// </summary>
/// <returns>
/// A <see cref="T:System.Collections.Generic.IEnumerator`1"/> that can be used to iterate through the collection.
/// </returns>
IEnumerator<TaskEvent> IEnumerable<TaskEvent>.GetEnumerator() => GetEnumerator(EnumerateInReverse);
/// <summary>
/// Returns an enumerator that iterates through the collection.
/// </summary>
/// <param name="reverse">if set to <c>true</c> reverse.</param>
/// <returns>
/// A <see cref="TaskEventEnumerator" /> that can be used to iterate through the collection.
/// </returns>
[NotNull]
public TaskEventEnumerator GetEnumerator(bool reverse)
{
Query.ReverseDirection = !reverse;
return new TaskEventEnumerator(new EventLogReader(Query));
}
/// <summary>
/// Returns an enumerator that iterates through a collection.
/// </summary>
/// <returns>
/// An <see cref="T:System.Collections.IEnumerator"/> object that can be used to iterate through the collection.
/// </returns>
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator(false);
internal EventLogQuery Query { get; private set; }
}
}

View File

@ -0,0 +1,699 @@
using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Diagnostics.Eventing.Reader;
using System.IO;
using JetBrains.Annotations;
namespace Microsoft.Win32.TaskScheduler
{
/// <summary>
/// Information about the task event.
/// </summary>
[PublicAPI]
public class TaskEventArgs : EventArgs
{
private readonly TaskService taskService;
internal TaskEventArgs([NotNull] TaskEvent evt, TaskService ts = null)
{
TaskEvent = evt;
TaskPath = evt.TaskPath;
taskService = ts;
}
/// <summary>
/// Gets the <see cref="TaskEvent"/>.
/// </summary>
/// <value>
/// The TaskEvent.
/// </value>
[NotNull]
public TaskEvent TaskEvent { get; }
/// <summary>
/// Gets the task path.
/// </summary>
/// <value>
/// The task path.
/// </value>
public string TaskPath { get; }
}
/// <summary>
/// Watches system events related to tasks and issues a <see cref="TaskEventWatcher.EventRecorded"/> event when the filtered conditions are met.
/// <note>Only available for Task Scheduler 2.0 on Windows Vista or Windows Server 2003 and later.</note>
/// </summary>
/// <remarks>Sometimes, a developer will need to know about events as they occur. In this case, they can use the TaskEventWatcher component that enables the developer to watch a task, a folder, or the entire system for filtered events.</remarks>
/// <example>
/// <para>Below is information on how to watch a folder for all task events. For a complete example, look at this sample project: TestTaskWatcher.zip</para>
/// <code lang="cs"><![CDATA[
/// private TaskEventWatcher watcher;
///
/// // Create and configure a new task watcher for the task folder
/// private void SetupWatcher(TaskFolder tf)
/// {
/// if (tf != null)
/// {
/// // Set up a watch over the supplied task folder.
/// watcher = new TaskEventWatcher(tf);
///
/// // Assign a SynchronizingObject to a local UI class to synchronize the events in this thread.
/// watcher.SynchronizingObject = this;
///
/// // Only watch for tasks that start with my company name
/// watcher.Filter.TaskName = "MyCo*";
///
/// // Only watch for task events that are informational
/// watcher.Filter.EventLevels = new int[]
/// { 0 /* StandardEventLevel.LogAlways */, (int)StandardEventLevel.Informational };
///
/// // Assign an event handler for when events are recorded
/// watcher.EventRecorded += Watcher_EventRecorded;
///
/// // Start watching the folder by enabling the watcher
/// watcher.Enabled = true;
/// }
/// }
///
/// // Cleanup and release the task watcher
/// private void TearDownWatcher()
/// {
/// if (watcher != null)
/// {
/// // Unhook the event
/// watcher.EventRecorded -= Watcher_EventRecorded;
/// // Stop watching for events
/// watcher.Enabled = false;
/// // Initiate garbage collection for the watcher
/// watcher = null;
/// }
/// }
///
/// // Update ListView instance when task events occur
/// private void Watcher_EventRecorded(object sender, TaskEventArgs e)
/// {
/// int idx = IndexOfTask(e.TaskName);
///
/// // If event is for a task we already have in the list...
/// if (idx != -1)
/// {
/// // If event indicates that task has been deleted, remove it from the list
/// if (e.TaskEvent.StandardEventId == StandardTaskEventId.TaskDeleted)
/// {
/// listView1.Items.RemoveAt(idx);
/// }
///
/// // If event is anything else, it most likely represents a change,
/// // so update the item using information supplied through the
/// // TaskEventArgs instance.
/// else
/// {
/// var lvi = listView1.Items[idx];
/// lvi.Subitems[0].Text = e.TaskName;
/// lvi.Subitems[1].Text = e.Task.State.ToString();
/// lvi.Subitems[2].Text = GetNextRunTimeString(e.Task);
/// }
/// }
///
/// // If event is for a task we don't have in our list, add it
/// else
/// {
/// var lvi = new ListViewItem(new string[] { e.TaskName,
/// e.Task.State.ToString(), GetNextRunTimeString(e.Task) });
/// listView1.Items.Add(lvi);
/// listView1.Sort();
/// }
/// }
///
/// // Get the next run time for a task
/// private string GetNextRunTimeString(Task t)
/// {
/// if (t.State == TaskState.Disabled || t.NextRunTime < DateTime.Now)
/// return string.Empty;
/// return t.NextRunTime.ToString("G");
/// }
/// ]]></code></example>
[DefaultEvent(nameof(EventRecorded)), DefaultProperty(nameof(Folder))]
#if DESIGNER
[Designer(typeof(Design.TaskEventWatcherDesigner))]
#endif
[ToolboxItem(true), Serializable]
[PublicAPI]
public class TaskEventWatcher : Component, ISupportInitialize
{
private const string root = "\\";
private const string star = "*";
private static readonly TimeSpan MaxV1EventLapse = TimeSpan.FromSeconds(1);
private bool disposed;
private bool enabled;
private string folder = root;
private bool includeSubfolders;
private bool initializing;
private StandardTaskEventId lastId = 0;
private DateTime lastIdTime = DateTime.MinValue;
private TaskService ts;
private FileSystemWatcher v1Watcher;
private EventLogWatcher watcher;
private ISynchronizeInvoke synchronizingObject;
/// <summary>
/// Initializes a new instance of the <see cref="TaskEventWatcher"/> class. If other
/// properties are not set, this will watch for all events for all tasks on the local machine.
/// </summary>
public TaskEventWatcher() : this(TaskService.Instance)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="TaskEventWatcher" /> class watching only
/// those events for the task with the provided path on the local machine.
/// </summary>
/// <param name="taskPath">The full path (folders and name) of the task to watch.</param>
/// <param name="taskService">The task service.</param>
/// <exception cref="System.ArgumentException">$Invalid task name: {taskPath}</exception>
public TaskEventWatcher(string taskPath, TaskService taskService = null) : this(taskService ?? TaskService.Instance)
{
InitTask(taskPath);
}
private TaskEventWatcher(TaskService ts)
{
TaskService = ts;
Filter = new EventFilter(this);
}
/// <summary>
/// Occurs when a task or the task engine records an event.
/// </summary>
[Category("Action"), Description("Event recorded by a task or the task engine.")]
public event EventHandler<TaskEventArgs> EventRecorded;
/// <summary>
/// Gets or sets a value indicating whether the component is enabled.
/// </summary>
/// <value>
/// <c>true</c> if enabled; otherwise, <c>false</c>.
/// </value>
[DefaultValue(false), Category("Behavior"), Description("Indicates whether the component is enabled.")]
public bool Enabled
{
get { return enabled; }
set
{
if (enabled != value)
{
System.Diagnostics.Debug.WriteLine($"TaskEventWather: Set {nameof(Enabled)} = {value}");
enabled = value;
if (!IsSuspended())
{
if (enabled)
StartRaisingEvents();
else
StopRaisingEvents();
}
}
}
}
/// <summary>
/// Gets the filter for this <see cref="TaskEventWatcher"/>.
/// </summary>
/// <value>
/// The filter.
/// </value>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Category("Behavior"), Description("Indicates the filter for the watcher.")]
public EventFilter Filter { get; }
/// <summary>
/// Gets or sets the folder to watch.
/// </summary>
/// <value>
/// The folder path to watch. This value should include the leading "\" to indicate the root folder.
/// </value>
/// <exception cref="System.ArgumentException">Thrown if the folder specified does not exist or contains invalid characters.</exception>
[DefaultValue(root), Category("Behavior"), Description("Indicates the folder to watch.")]
public string Folder
{
get { return folder; }
set
{
if (string.IsNullOrEmpty(value))
value = root;
if (!value.EndsWith("\\"))
value += "\\";
if (string.Compare(folder, value, StringComparison.OrdinalIgnoreCase) == 0) return;
if ((DesignMode && (value.IndexOfAny(new[] { '*', '?' }) != -1 || value.IndexOfAny(Path.GetInvalidPathChars()) != -1)) || (TaskService.GetFolder(value == root ? value : value.TrimEnd('\\')) == null))
throw new ArgumentException($"Invalid folder name: {value}");
folder = value;
}
}
/// <summary>
/// Gets or sets a value indicating whether to include events from subfolders when the
/// <see cref="Folder"/> property is set. If the <see cref="TaskEventWatcher.EventFilter.TaskName"/> property is set,
/// this property is ignored.
/// </summary>
/// <value><c>true</c> if include events from subfolders; otherwise, <c>false</c>.</value>
[DefaultValue(false), Category("Behavior"), Description("Indicates whether to include events from subfolders.")]
public bool IncludeSubfolders
{
get { return includeSubfolders; }
set
{
if (includeSubfolders == value) return;
includeSubfolders = value;
Restart();
}
}
/// <summary>
/// Gets or sets the synchronizing object.
/// </summary>
/// <value>
/// The synchronizing object.
/// </value>
[Browsable(false), DefaultValue(null)]
public ISynchronizeInvoke SynchronizingObject
{
get
{
if (synchronizingObject == null && DesignMode)
{
var so = ((IDesignerHost)GetService(typeof(IDesignerHost)))?.RootComponent as ISynchronizeInvoke;
if (so != null)
synchronizingObject = so;
}
return synchronizingObject;
}
set { synchronizingObject = value; }
}
/// <summary>
/// Gets or sets the name of the computer that is running the Task Scheduler service that the user is connected to.
/// </summary>
[Category("Connection"), Description("The name of the computer to connect to."), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public string TargetServer
{
get { return TaskService.TargetServer; }
set
{
if (value == null || value.Trim() == string.Empty) value = null;
if (string.Compare(value, TaskService.TargetServer, StringComparison.OrdinalIgnoreCase) == 0) return;
TaskService.TargetServer = value;
Restart();
}
}
/// <summary>
/// Gets or sets the <see cref="TaskService"/> instance associated with this event watcher. Setting this value
/// will override any values set for <see cref="TargetServer"/>, <see cref="UserAccountDomain"/>,
/// <see cref="UserName"/>, and <see cref="UserPassword"/> and set them to those values in the supplied
/// <see cref="TaskService"/> instance.
/// </summary>
/// <value>The TaskService.</value>
[Category("Data"), Description("The TaskService for this event watcher.")]
public TaskService TaskService
{
get { return ts; }
set { ts = value; Restart(); }
}
/// <summary>
/// Gets or sets the user account domain to be used when connecting to the <see cref="TargetServer"/>.
/// </summary>
/// <value>The user account domain.</value>
[Category("Connection"), Description("The user account domain to be used when connecting."), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public string UserAccountDomain
{
get { return TaskService.UserAccountDomain; }
set
{
if (value == null || value.Trim() == string.Empty) value = null;
if (string.Compare(value, TaskService.UserAccountDomain, StringComparison.OrdinalIgnoreCase) == 0) return;
TaskService.UserAccountDomain = value;
Restart();
}
}
/// <summary>
/// Gets or sets the user name to be used when connecting to the <see cref="TargetServer"/>.
/// </summary>
/// <value>The user name.</value>
[Category("Connection"), Description("The user name to be used when connecting."), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public string UserName
{
get { return TaskService.UserName; }
set
{
if (value == null || value.Trim() == string.Empty) value = null;
if (string.Compare(value, TaskService.UserName, StringComparison.OrdinalIgnoreCase) == 0) return;
TaskService.UserName = value;
Restart();
}
}
/// <summary>
/// Gets or sets the user password to be used when connecting to the <see cref="TargetServer"/>.
/// </summary>
/// <value>The user password.</value>
[Category("Connection"), Description("The user password to be used when connecting."), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public string UserPassword
{
get { return TaskService.UserPassword; }
set
{
if (value == null || value.Trim() == string.Empty) value = null;
if (string.Compare(value, TaskService.UserPassword, StringComparison.OrdinalIgnoreCase) == 0) return;
TaskService.UserPassword = value;
Restart();
}
}
/// <summary>
/// Gets a value indicating if watching is available.
/// </summary>
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
private bool IsHandleInvalid => IsV1 ? v1Watcher == null : watcher == null;
private static bool IsV1 => Environment.OSVersion.Version.Major < 6;
/// <summary>
/// Signals the object that initialization is starting.
/// </summary>
public void BeginInit()
{
System.Diagnostics.Debug.WriteLine($"TaskEventWather: {nameof(BeginInit)}");
initializing = true;
var localEnabled = enabled;
StopRaisingEvents();
enabled = localEnabled;
TaskService.BeginInit();
}
/// <summary>
/// Signals the object that initialization is complete.
/// </summary>
public void EndInit()
{
System.Diagnostics.Debug.WriteLine($"TaskEventWather: {nameof(EndInit)}");
initializing = false;
TaskService.EndInit();
if (enabled)
StartRaisingEvents();
}
/// <summary>
/// Releases the unmanaged resources used by the FileSystemWatcher and optionally releases the managed resources.
/// </summary>
/// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
protected override void Dispose(bool disposing)
{
try
{
if (disposing)
{
StopRaisingEvents();
TaskService = null;
}
else
{
StopListening();
}
}
finally
{
disposed = true;
base.Dispose(disposing);
}
}
/// <summary>
/// Fires the <see cref="EventRecorded"/> event.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The <see cref="Microsoft.Win32.TaskScheduler.TaskEventArgs" /> instance containing the event data.</param>
protected virtual void OnEventRecorded(object sender, TaskEventArgs e)
{
var h = EventRecorded;
if (h == null) return;
if (SynchronizingObject != null && SynchronizingObject.InvokeRequired)
SynchronizingObject.BeginInvoke(h, new object[] { this, e });
else
h(sender, e);
}
private void InitTask(string taskPath)
{
Filter.TaskName = Path.GetFileNameWithoutExtension(taskPath);
Folder = Path.GetDirectoryName(taskPath);
}
private bool IsSuspended() => initializing || DesignMode;
private void ReleaseWatcher()
{
if (IsV1)
{
if (v1Watcher == null) return;
v1Watcher.EnableRaisingEvents = false;
v1Watcher.Changed -= Watcher_DirectoryChanged;
v1Watcher.Created -= Watcher_DirectoryChanged;
v1Watcher.Deleted -= Watcher_DirectoryChanged;
v1Watcher.Renamed -= Watcher_DirectoryChanged;
v1Watcher = null;
}
else
{
if (watcher == null) return;
watcher.Enabled = false;
watcher.EventRecordWritten -= Watcher_EventRecordWritten;
watcher = null;
}
}
private void Restart()
{
if (IsSuspended() || !enabled) return;
System.Diagnostics.Debug.WriteLine($"TaskEventWather: {nameof(Restart)}");
StopRaisingEvents();
StartRaisingEvents();
}
private void SetupWatcher()
{
ReleaseWatcher();
string taskPath = null;
if (Filter.Wildcard == null)
taskPath = Path.Combine(folder, Filter.TaskName);
if (IsV1)
{
var di = new DirectoryInfo(Environment.GetFolderPath(Environment.SpecialFolder.System));
string dir = di.Parent != null ? Path.Combine(di.Parent.FullName, "Tasks") : "Tasks";
v1Watcher = new FileSystemWatcher(dir, "*.job") { NotifyFilter = NotifyFilters.Size | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.Attributes };
v1Watcher.Changed += Watcher_DirectoryChanged;
v1Watcher.Created += Watcher_DirectoryChanged;
v1Watcher.Deleted += Watcher_DirectoryChanged;
v1Watcher.Renamed += Watcher_DirectoryChanged;
}
else
{
var log = new TaskEventLog(taskPath, Filter.EventIds, Filter.EventLevels, DateTime.UtcNow, TargetServer, UserAccountDomain, UserName, UserPassword);
log.Query.ReverseDirection = false;
watcher = new EventLogWatcher(log.Query);
watcher.EventRecordWritten += Watcher_EventRecordWritten;
}
}
private void StartRaisingEvents()
{
if (disposed)
throw new ObjectDisposedException(GetType().Name);
if (IsSuspended()) return;
System.Diagnostics.Debug.WriteLine($"TaskEventWather: {nameof(StartRaisingEvents)}");
enabled = true;
SetupWatcher();
if (IsV1)
try { v1Watcher.EnableRaisingEvents = true; } catch { }
else
try { watcher.Enabled = true; } catch { }
}
private void StopListening()
{
enabled = false;
ReleaseWatcher();
}
private void StopRaisingEvents()
{
System.Diagnostics.Debug.WriteLine($"TaskEventWather: {nameof(StopRaisingEvents)}");
if (IsSuspended())
enabled = false;
else if (!IsHandleInvalid)
StopListening();
}
private void Watcher_DirectoryChanged(object sender, FileSystemEventArgs e)
{
StandardTaskEventId id = StandardTaskEventId.TaskUpdated;
if (e.ChangeType == WatcherChangeTypes.Deleted)
id = StandardTaskEventId.TaskDeleted;
else if (e.ChangeType == WatcherChangeTypes.Created)
id = StandardTaskEventId.JobRegistered;
if (lastId == id && DateTime.Now.Subtract(lastIdTime) <= MaxV1EventLapse) return;
OnEventRecorded(this, new TaskEventArgs(new TaskEvent(Path.Combine("\\", e.Name.Replace(".job", "")), id, DateTime.Now), TaskService));
lastId = id;
lastIdTime = DateTime.Now;
}
private void Watcher_EventRecordWritten(object sender, EventRecordWrittenEventArgs e)
{
try
{
var taskEvent = new TaskEvent(e.EventRecord);
System.Diagnostics.Debug.WriteLine("Task event: " + taskEvent.ToString());
// Get the task name and folder
if (string.IsNullOrEmpty(taskEvent.TaskPath)) return;
int cpos = taskEvent.TaskPath.LastIndexOf('\\');
string name = taskEvent.TaskPath.Substring(cpos + 1);
string fld = taskEvent.TaskPath.Substring(0, cpos + 1);
// Check folder and name filters
if (!string.IsNullOrEmpty(Filter.TaskName) && string.Compare(Filter.TaskName, taskEvent.TaskPath, StringComparison.OrdinalIgnoreCase) != 0)
{
if (Filter.Wildcard != null && !Filter.Wildcard.IsMatch(name))
return;
if (IncludeSubfolders && !fld.StartsWith(folder, StringComparison.OrdinalIgnoreCase))
return;
if (!IncludeSubfolders && string.Compare(folder, fld, StringComparison.OrdinalIgnoreCase) != 0)
return;
}
OnEventRecorded(this, new TaskEventArgs(taskEvent, TaskService));
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"{nameof(Watcher_EventRecordWritten)} has failed. Error: {ex.ToString()}");
}
}
/// <summary>
/// Holds filter information for a <see cref="TaskEventWatcher"/>.
/// </summary>
[TypeConverter(typeof(ExpandableObjectConverter)), Serializable]
[PublicAPI]
public class EventFilter
{
private string filter = star;
private int[] ids;
private int[] levels;
private readonly TaskEventWatcher parent;
internal EventFilter([NotNull] TaskEventWatcher parent)
{
this.parent = parent;
}
/// <summary>
/// Gets or sets an optional array of event identifiers to use when filtering those events that will fire a <see cref="TaskEventWatcher.EventRecorded"/> event.
/// </summary>
/// <value>
/// The array of event identifier filters. All know task event identifiers are declared in the <see cref="StandardTaskEventId"/> enumeration.
/// </value>
[DefaultValue(null), Category("Filter"), Description("An array of event identifiers to use when filtering.")]
public int[] EventIds
{
get { return ids; }
set
{
if (ids != value)
{
ids = value;
parent.Restart();
}
}
}
/// <summary>
/// Gets or sets an optional array of event levels to use when filtering those events that will fire a <see cref="TaskEventWatcher.EventRecorded"/> event.
/// </summary>
/// <value>
/// The array of event levels. While event providers can define custom levels, most will use integers defined in the System.Diagnostics.Eventing.Reader.StandardEventLevel enumeration.
/// </value>
[DefaultValue(null), Category("Filter"), Description("An array of event levels to use when filtering.")]
public int[] EventLevels
{
get { return levels; }
set
{
if (levels != value)
{
levels = value;
parent.Restart();
}
}
}
/// <summary>
/// Gets or sets the task name, which can utilize wildcards, to look for when watching a folder.
/// </summary>
/// <value>A task name or wildcard.</value>
[DefaultValue(star), Category("Filter"), Description("A task name, which can utilize wildcards, for filtering.")]
public string TaskName
{
get { return filter; }
set
{
if (string.IsNullOrEmpty(value))
value = star;
if (string.Compare(filter, value, StringComparison.OrdinalIgnoreCase) != 0)
{
filter = value;
Wildcard = (value.IndexOfAny(new[] { '?', '*' }) == -1) ? null : new Wildcard(value);
parent.Restart();
}
}
}
internal Wildcard Wildcard { get; private set; } = new Wildcard(star);
/// <summary>
/// Returns a <see cref="System.String" /> that represents this instance.
/// </summary>
/// <returns>
/// A <see cref="System.String" /> that represents this instance.
/// </returns>
public override string ToString() => filter + (levels == null ? "" : " +levels") + (ids == null ? "" : " +id's");
}
}
#if DESIGNER
namespace Design
{
internal class TaskEventWatcherDesigner : ComponentDesigner
{
public override void InitializeNewComponent(IDictionary defaultValues)
{
base.InitializeNewComponent(defaultValues);
var refs = GetService<IReferenceService>();
var tsColl = refs?.GetReferences(typeof(TaskService));
System.Diagnostics.Debug.Assert(refs != null && tsColl != null && tsColl.Length > 0, "Designer couldn't find host, reference service, or existing TaskService.");
if (tsColl != null && tsColl.Length > 0)
{
TaskEventWatcher tsComp = Component as TaskEventWatcher;
TaskService ts = tsColl[0] as TaskService;
if (tsComp != null)
tsComp.TaskService = ts;
}
}
protected virtual T GetService<T>() => (T)Component?.Site?.GetService(typeof(T));
}
}
#endif
}

View File

@ -0,0 +1,401 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.AccessControl;
using System.Text.RegularExpressions;
using JetBrains.Annotations;
using Microsoft.Win32.TaskScheduler.V1Interop;
using Microsoft.Win32.TaskScheduler.V2Interop;
namespace Microsoft.Win32.TaskScheduler
{
/// <summary>
/// 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.
/// </summary>
[PublicAPI]
public sealed class TaskFolder : IDisposable, IComparable<TaskFolder>
{
private ITaskScheduler v1List;
private readonly ITaskFolder v2Folder;
internal const string rootString = @"\";
internal TaskFolder([NotNull] TaskService svc)
{
TaskService = svc;
v1List = svc.v1TaskScheduler;
}
internal TaskFolder([NotNull] TaskService svc, [NotNull] ITaskFolder iFldr)
{
TaskService = svc;
v2Folder = iFldr;
}
/// <summary>
/// Releases all resources used by this class.
/// </summary>
public void Dispose()
{
if (v2Folder != null)
Marshal.ReleaseComObject(v2Folder);
v1List = null;
}
/// <summary>
/// Gets the path to where the folder is stored.
/// </summary>
[NotNull]
public string Path => (v2Folder == null) ? rootString : v2Folder.Path;
/// <summary>
/// Gets all the subfolders in the folder.
/// </summary>
[NotNull, ItemNotNull]
public TaskFolderCollection SubFolders
{
get
{
try
{
if (v2Folder != null)
return new TaskFolderCollection(this, v2Folder.GetFolders(0));
} catch { }
return new TaskFolderCollection();
}
}
/// <summary>
/// Gets a collection of all the tasks in the folder.
/// </summary>
[NotNull, ItemNotNull]
public TaskCollection Tasks => GetTasks();
/// <summary>
/// Gets or sets the <see cref="TaskService"/> that manages this task.
/// </summary>
/// <value>The task service.</value>
public TaskService TaskService { get; }
/// <summary>
/// Compares the current object with another object of the same type.
/// </summary>
/// <param name="other">An object to compare with this object.</param>
/// <returns>
/// A value that indicates the relative order of the objects being compared. The return value has the following meanings: Value Meaning Less than zero This object is less than the <paramref name="other" /> parameter.Zero This object is equal to <paramref name="other" />. Greater than zero This object is greater than <paramref name="other" />.
/// </returns>
int IComparable<TaskFolder>.CompareTo(TaskFolder other) => string.Compare(Path, other.Path, true);
/// <summary>
/// Creates a folder for related tasks. Not available to Task Scheduler 1.0.
/// </summary>
/// <param name="subFolderName">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 <see cref="TaskFolder" /> 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.</param>
/// <param name="sddlForm">The security descriptor associated with the folder.</param>
/// <param name="exceptionOnExists">Set this value to false to avoid having an exception called if the folder already exists.</param>
/// <returns>A <see cref="TaskFolder" /> instance that represents the new subfolder.</returns>
/// <exception cref="System.Security.SecurityException">Security descriptor mismatch between specified credentials and credentials on existing folder by same name.</exception>
/// <exception cref="System.ArgumentException">Invalid SDDL form.</exception>
/// <exception cref="Microsoft.Win32.TaskScheduler.NotV1SupportedException">Not supported under Task Scheduler 1.0.</exception>
public TaskFolder CreateFolder([NotNull] string subFolderName, string sddlForm = null, bool exceptionOnExists = true)
{
if (v2Folder == null) throw new NotV1SupportedException();
ITaskFolder ifld = null;
try { ifld = v2Folder.CreateFolder(subFolderName, sddlForm); }
catch (COMException ce)
{
int serr = ce.ErrorCode & 0x0000FFFF;
if (serr == 0xb7) // ERROR_ALREADY_EXISTS
{
if (exceptionOnExists) throw;
try
{
ifld = v2Folder.GetFolder(subFolderName);
if (ifld != null && sddlForm != null && sddlForm.Trim().Length > 0)
{
string sd = ifld.GetSecurityDescriptor((int)Task.defaultSecurityInfosSections);
if (string.Compare(sddlForm, sd, StringComparison.OrdinalIgnoreCase) != 0)
throw new SecurityException("Security descriptor mismatch between specified credentials and credentials on existing folder by same name.");
}
}
catch
{
if (ifld != null)
Marshal.ReleaseComObject(ifld);
throw;
}
}
else if (serr == 0x534 || serr == 0x538 || serr == 0x539 || serr == 0x53A || serr == 0x519 || serr == 0x57)
throw new ArgumentException(@"Invalid SDDL form", nameof(sddlForm), ce);
else
throw;
}
return new TaskFolder(TaskService, ifld);
}
/// <summary>
/// Deletes a subfolder from the parent folder. Not available to Task Scheduler 1.0.
/// </summary>
/// <param name="subFolderName">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.</param>
/// <param name="exceptionOnNotExists">Set this value to false to avoid having an exception called if the folder does not exist.</param>
/// <exception cref="Microsoft.Win32.TaskScheduler.NotV1SupportedException">Not supported under Task Scheduler 1.0.</exception>
public void DeleteFolder([NotNull] string subFolderName, bool exceptionOnNotExists = true)
{
if (v2Folder != null)
{
try
{
v2Folder.DeleteFolder(subFolderName, 0);
}
catch (Exception e)
{
if (!(e is FileNotFoundException || e is DirectoryNotFoundException) || exceptionOnNotExists)
throw;
}
}
else
throw new NotV1SupportedException();
}
/// <summary>Determines whether the specified <see cref="System.Object"/>, is equal to this instance.</summary>
/// <param name="obj">The <see cref="System.Object"/> to compare with this instance.</param>
/// <returns><c>true</c> if the specified <see cref="System.Object"/> is equal to this instance; otherwise, <c>false</c>.</returns>
public override bool Equals(object obj)
{
var folder = obj as TaskFolder;
if (folder != null)
return Path == folder.Path && TaskService.TargetServer == folder.TaskService.TargetServer && GetSecurityDescriptorSddlForm() == folder.GetSecurityDescriptorSddlForm();
return false;
}
/// <summary>Returns a hash code for this instance.</summary>
/// <returns>A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.</returns>
public override int GetHashCode() => new { A = Path, B = TaskService.TargetServer, C = GetSecurityDescriptorSddlForm() }.GetHashCode();
/// <summary>
/// Gets the security descriptor for the folder. Not available to Task Scheduler 1.0.
/// </summary>
/// <param name="includeSections">Section(s) of the security descriptor to return.</param>
/// <returns>The security descriptor for the folder.</returns>
/// <exception cref="NotV1SupportedException">Not supported under Task Scheduler 1.0.</exception>
public string GetSecurityDescriptorSddlForm(SecurityInfos includeSections = Task.defaultSecurityInfosSections)
{
if (v2Folder != null)
return v2Folder.GetSecurityDescriptor((int)includeSections);
throw new NotV1SupportedException();
}
/// <summary>
/// Gets a collection of all the tasks in the folder whose name matches the optional <paramref name="filter"/>.
/// </summary>
/// <param name="filter">The optional name filter expression.</param>
/// <returns>Collection of all matching tasks.</returns>
[NotNull, ItemNotNull]
public TaskCollection GetTasks(Regex filter = null)
{
if (v2Folder != null)
return new TaskCollection(this, v2Folder.GetTasks(1), filter);
return new TaskCollection(TaskService, filter);
}
/// <summary>
/// Registers (creates) a task in a specified location using a <see cref="TaskDefinition"/> instance to define a task.
/// </summary>
/// <param name="path">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.</param>
/// <param name="definition">The <see cref="TaskDefinition"/> of the registered task.</param>
/// <returns>A <see cref="Task"/> instance that represents the new task.</returns>
/// <example>
/// <code lang="cs"><![CDATA[
/// // Create a new task definition for the local machine and assign properties
/// TaskDefinition td = TaskService.Instance.NewTask();
/// td.RegistrationInfo.Description = "Does something";
///
/// // Add a trigger that, starting tomorrow, will fire every other week on Monday and Saturday
/// td.Triggers.Add(new WeeklyTrigger(DaysOfTheWeek.Monday | DaysOfTheWeek.Saturday, 2));
///
/// // Create an action that will launch Notepad whenever the trigger fires
/// td.Actions.Add("notepad.exe", "c:\\test.log");
///
/// // Register the task in the root folder of the local machine using the current user and the S4U logon type
/// TaskService.Instance.RootFolder.RegisterTaskDefinition("Test", td);
/// ]]></code></example>
public Task RegisterTaskDefinition(string path, [NotNull] TaskDefinition definition) => RegisterTaskDefinition(path, definition, TaskCreation.CreateOrUpdate,
definition.Principal.ToString(), null, definition.Principal.LogonType);
/// <summary>
/// Registers (creates) a task in a specified location using a <see cref="TaskDefinition" /> instance to define a task.
/// </summary>
/// <param name="path">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.</param>
/// <param name="definition">The <see cref="TaskDefinition" /> of the registered task.</param>
/// <param name="createType">A union of <see cref="TaskCreation" /> flags.</param>
/// <param name="userId">The user credentials used to register the task.</param>
/// <param name="password">The password for the userId used to register the task.</param>
/// <param name="logonType">A <see cref="TaskLogonType" /> value that defines what logon technique is used to run the registered task.</param>
/// <param name="sddl">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.</param>
/// <returns>
/// A <see cref="Task" /> instance that represents the new task. This will return <c>null</c> if <paramref name="createType"/> is set to <c>ValidateOnly</c> and there are no validation errors.
/// </returns>
/// <exception cref="System.ArgumentOutOfRangeException">
/// Task names may not include any characters which are invalid for file names.
/// or
/// Task names ending with a period followed by three or fewer characters cannot be retrieved due to a bug in the native library.
/// </exception>
/// <exception cref="NotV1SupportedException">This LogonType is not supported on Task Scheduler 1.0.
/// or
/// Security settings are not available on Task Scheduler 1.0.
/// or
/// Registration triggers are not available on Task Scheduler 1.0.
/// or
/// XML validation not available on Task Scheduler 1.0.</exception>
/// <remarks>This method is effectively the "Save" method for tasks. It takes a modified <c>TaskDefinition</c> instance and registers it in the folder defined by this <c>TaskFolder</c> instance. Optionally, you can use this method to override the user, password and logon type defined in the definition and supply security against the task.</remarks>
/// <example>
/// <para>This first example registers a simple task with a single trigger and action using the default security.</para>
/// <code lang="cs"><![CDATA[
/// // Create a new task definition for the local machine and assign properties
/// TaskDefinition td = TaskService.Instance.NewTask();
/// td.RegistrationInfo.Description = "Does something";
///
/// // Add a trigger that, starting tomorrow, will fire every other week on Monday and Saturday
/// td.Triggers.Add(new WeeklyTrigger(DaysOfTheWeek.Monday | DaysOfTheWeek.Saturday, 2));
///
/// // Create an action that will launch Notepad whenever the trigger fires
/// td.Actions.Add("notepad.exe", "c:\\test.log");
///
/// // Register the task in the root folder of the local machine using the current user and the S4U logon type
/// TaskService.Instance.RootFolder.RegisterTaskDefinition("Test", td);
/// ]]></code>
/// <para>This example registers that same task using the SYSTEM account.</para>
/// <code lang="cs"><![CDATA[
/// TaskService.Instance.RootFolder.RegisterTaskDefinition("TaskName", taskDefinition, TaskCreation.CreateOrUpdate, "SYSTEM", null, TaskLogonType.ServiceAccount);
/// ]]></code>
/// <para>This example registers that same task using a specific username and password along with a security definition.</para>
/// <code lang="cs"><![CDATA[
/// TaskService.Instance.RootFolder.RegisterTaskDefinition("TaskName", taskDefinition, TaskCreation.CreateOrUpdate, "userDomain\\userName", "userPassword", TaskLogonType.Password, @"O:BAG:DUD:(A;ID;0x1f019f;;;BA)(A;ID;0x1f019f;;;SY)(A;ID;FA;;;BA)(A;;FR;;;BU)");
/// ]]></code></example>
public Task RegisterTaskDefinition([NotNull] string path, [NotNull] TaskDefinition definition, TaskCreation createType, string userId, string password = null, TaskLogonType logonType = TaskLogonType.S4U, string sddl = null)
{
if (definition.Actions.Count < 1 || definition.Actions.Count > 32)
throw new ArgumentOutOfRangeException(nameof(definition.Actions), @"A task must be registered with at least one action and no more than 32 actions.");
userId = userId ?? definition.Principal.Account;
if (userId == string.Empty) userId = null;
User user = new User(userId);
if (v2Folder != null)
{
definition.Actions.ConvertUnsupportedActions();
if (logonType == TaskLogonType.ServiceAccount)
{
if (string.IsNullOrEmpty(userId) || !user.IsServiceAccount)
throw new ArgumentException(@"A valid system account name must be supplied for TaskLogonType.ServiceAccount. Valid entries are ""NT AUTHORITY\SYSTEM"", ""SYSTEM"", ""NT AUTHORITY\LOCALSERVICE"", or ""NT AUTHORITY\NETWORKSERVICE"".", nameof(userId));
if (password != null)
throw new ArgumentException(@"A password cannot be supplied when specifying TaskLogonType.ServiceAccount.", nameof(password));
}
/*else if ((LogonType == TaskLogonType.Password || LogonType == TaskLogonType.InteractiveTokenOrPassword ||
(LogonType == TaskLogonType.S4U && UserId != null && !user.IsCurrent)) && password == null)
{
throw new ArgumentException("A password must be supplied when specifying TaskLogonType.Password or TaskLogonType.InteractiveTokenOrPassword or TaskLogonType.S4U from another account.", nameof(password));
}*/
else if (logonType == TaskLogonType.Group && password != null)
{
throw new ArgumentException(@"A password cannot be supplied when specifying TaskLogonType.Group.", nameof(password));
}
// The following line compensates for an omission in the native library that never actually sets the registration date (thanks ixm7).
if (definition.RegistrationInfo.Date == DateTime.MinValue) definition.RegistrationInfo.Date = DateTime.Now;
var iRegTask = v2Folder.RegisterTaskDefinition(path, definition.v2Def, (int)createType, userId ?? user.Name, password, logonType, sddl);
if (createType == TaskCreation.ValidateOnly && iRegTask == null)
return null;
return Task.CreateTask(TaskService, iRegTask);
}
// Check for V1 invalid task names
string invChars = Regex.Escape(new string(System.IO.Path.GetInvalidFileNameChars()));
if (Regex.IsMatch(path, @"[" + invChars + @"]"))
throw new ArgumentOutOfRangeException(nameof(path), @"Task names may not include any characters which are invalid for file names.");
if (Regex.IsMatch(path, @"\.[^" + invChars + @"]{0,3}\z"))
throw new ArgumentOutOfRangeException(nameof(path), @"Task names ending with a period followed by three or fewer characters cannot be retrieved due to a bug in the native library.");
// Adds ability to set a password for a V1 task. Provided by Arcao.
TaskFlags flags = definition.v1Task.GetFlags();
if (logonType == TaskLogonType.InteractiveTokenOrPassword && string.IsNullOrEmpty(password))
logonType = TaskLogonType.InteractiveToken;
switch (logonType)
{
case TaskLogonType.Group:
case TaskLogonType.S4U:
case TaskLogonType.None:
throw new NotV1SupportedException("This LogonType is not supported on Task Scheduler 1.0.");
case TaskLogonType.InteractiveToken:
flags |= (TaskFlags.RunOnlyIfLoggedOn | TaskFlags.Interactive);
definition.v1Task.SetAccountInformation(user.Name, IntPtr.Zero);
break;
case TaskLogonType.ServiceAccount:
flags &= ~(TaskFlags.Interactive | TaskFlags.RunOnlyIfLoggedOn);
definition.v1Task.SetAccountInformation((String.IsNullOrEmpty(userId) || user.IsSystem) ? String.Empty : user.Name, IntPtr.Zero);
break;
case TaskLogonType.InteractiveTokenOrPassword:
flags |= TaskFlags.Interactive;
using (CoTaskMemString cpwd = new CoTaskMemString(password))
definition.v1Task.SetAccountInformation(user.Name, cpwd.DangerousGetHandle());
break;
case TaskLogonType.Password:
using (CoTaskMemString cpwd = new CoTaskMemString(password))
definition.v1Task.SetAccountInformation(user.Name, cpwd.DangerousGetHandle());
break;
default:
throw new ArgumentOutOfRangeException(nameof(logonType), logonType, null);
}
definition.v1Task.SetFlags(flags);
switch (createType)
{
case TaskCreation.Create:
case TaskCreation.CreateOrUpdate:
case TaskCreation.Disable:
case TaskCreation.Update:
if (createType == TaskCreation.Disable)
definition.Settings.Enabled = false;
definition.V1Save(path);
break;
case TaskCreation.DontAddPrincipalAce:
throw new NotV1SupportedException("Security settings are not available on Task Scheduler 1.0.");
case TaskCreation.IgnoreRegistrationTriggers:
throw new NotV1SupportedException("Registration triggers are not available on Task Scheduler 1.0.");
case TaskCreation.ValidateOnly:
throw new NotV1SupportedException("XML validation not available on Task Scheduler 1.0.");
default:
throw new ArgumentOutOfRangeException(nameof(createType), createType, null);
}
return new Task(TaskService, definition.v1Task);
}
/// <summary>
/// Returns a <see cref="System.String"/> that represents this instance.
/// </summary>
/// <returns>
/// A <see cref="System.String"/> that represents this instance.
/// </returns>
public override string ToString() => Path;
/// <summary>
/// Enumerates the tasks in the specified folder and its child folders.
/// </summary>
/// <param name="folder">The folder in which to start enumeration.</param>
/// <param name="filter">An optional filter to apply to the task list.</param>
/// <param name="recurse"><c>true</c> if subfolders are to be queried recursively.</param>
/// <returns>A <see cref="System.Collections.Generic.IEnumerator{Task}"/> that can be used to iterate through the tasks.</returns>
internal static IEnumerable<Task> EnumerateFolderTasks(TaskFolder folder, Predicate<Task> filter = null, bool recurse = true)
{
foreach (var task in folder.Tasks)
if (filter == null || filter(task))
yield return task;
if (!recurse) yield break;
foreach (var sfld in folder.SubFolders)
foreach (var task in EnumerateFolderTasks(sfld, filter))
yield return task;
}
}
}

View File

@ -0,0 +1,157 @@
using System;
using System.Collections.Generic;
using JetBrains.Annotations;
namespace Microsoft.Win32.TaskScheduler
{
/// <summary>
/// Provides information and control for a collection of folders that contain tasks.
/// </summary>
public sealed class TaskFolderCollection : ICollection<TaskFolder>, IDisposable
{
private readonly TaskFolder parent;
private readonly TaskFolder[] v1FolderList;
private readonly V2Interop.ITaskFolderCollection v2FolderList;
internal TaskFolderCollection()
{
v1FolderList = new TaskFolder[0];
}
internal TaskFolderCollection([NotNull] TaskFolder folder, [NotNull] V2Interop.ITaskFolderCollection iCollection)
{
parent = folder;
v2FolderList = iCollection;
}
/// <summary>
/// Gets the number of items in the collection.
/// </summary>
public int Count => v2FolderList?.Count ?? v1FolderList.Length;
/// <summary>
/// Gets a value indicating whether the <see cref="T:System.Collections.Generic.ICollection`1" /> is read-only.
/// </summary>
bool ICollection<TaskFolder>.IsReadOnly => false;
/// <summary>
/// Adds an item to the <see cref="T:System.Collections.Generic.ICollection`1" />.
/// </summary>
/// <param name="item">The object to add to the <see cref="T:System.Collections.Generic.ICollection`1" />.</param>
/// <exception cref="System.NotImplementedException">This action is technically unfeasible due to limitations of the underlying library. Use the <see cref="TaskFolder.CreateFolder(string, string, bool)"/> instead.</exception>
public void Add([NotNull] TaskFolder item) { throw new NotImplementedException(); }
/// <summary>
/// Removes all items from the <see cref="T:System.Collections.Generic.ICollection`1" />.
/// </summary>
public void Clear()
{
if (v2FolderList != null)
{
for (int i = v2FolderList.Count; i > 0; i--)
parent.DeleteFolder(v2FolderList[i].Name, false);
}
}
/// <summary>
/// Determines whether the <see cref="T:System.Collections.Generic.ICollection`1" /> contains a specific value.
/// </summary>
/// <param name="item">The object to locate in the <see cref="T:System.Collections.Generic.ICollection`1" />.</param>
/// <returns>
/// true if <paramref name="item" /> is found in the <see cref="T:System.Collections.Generic.ICollection`1" />; otherwise, false.
/// </returns>
public bool Contains([NotNull] TaskFolder item)
{
if (v2FolderList != null)
{
for (int i = v2FolderList.Count; i > 0; i--)
if (string.Equals(item.Path, v2FolderList[i].Path, StringComparison.CurrentCultureIgnoreCase))
return true;
}
else
return item.Path == "\\";
return false;
}
/// <summary>
/// Copies the elements of the ICollection to an Array, starting at a particular Array index.
/// </summary>
/// <param name="array">The one-dimensional Array that is the destination of the elements copied from <see cref="ICollection{T}"/>. The Array must have zero-based indexing.</param>
/// <param name="arrayIndex">The zero-based index in array at which copying begins.</param>
public void CopyTo(TaskFolder[] array, int arrayIndex)
{
if (arrayIndex < 0) throw new ArgumentOutOfRangeException(nameof(arrayIndex));
if (array == null) throw new ArgumentNullException(nameof(array));
if (v2FolderList != null)
{
if (arrayIndex + Count > array.Length)
throw new ArgumentException();
foreach (var f in this)
array[arrayIndex++] = f;
}
else
{
if (arrayIndex + v1FolderList.Length > array.Length)
throw new ArgumentException();
v1FolderList.CopyTo(array, arrayIndex);
}
}
/// <summary>
/// Releases all resources used by this class.
/// </summary>
public void Dispose()
{
if (v1FolderList != null && v1FolderList.Length > 0)
{
v1FolderList[0].Dispose();
v1FolderList[0] = null;
}
if (v2FolderList != null)
System.Runtime.InteropServices.Marshal.ReleaseComObject(v2FolderList);
}
/// <summary>
/// Gets a list of items in a collection.
/// </summary>
/// <returns>Enumerated list of items in the collection.</returns>
public IEnumerator<TaskFolder> GetEnumerator()
{
if (v2FolderList != null)
return new System.Runtime.InteropServices.ComEnumerator<TaskFolder, V2Interop.ITaskFolder>(() => v2FolderList.Count, (object o) => v2FolderList[o], o => new TaskFolder(parent.TaskService, o));
return Array.AsReadOnly(v1FolderList).GetEnumerator();
}
/// <summary>
/// Removes the first occurrence of a specific object from the <see cref="T:System.Collections.Generic.ICollection`1" />.
/// </summary>
/// <param name="item">The object to remove from the <see cref="T:System.Collections.Generic.ICollection`1" />.</param>
/// <returns>
/// true if <paramref name="item" /> was successfully removed from the <see cref="T:System.Collections.Generic.ICollection`1" />; otherwise, false. This method also returns false if <paramref name="item" /> is not found in the original <see cref="T:System.Collections.Generic.ICollection`1" />.
/// </returns>
public bool Remove([NotNull] TaskFolder item)
{
if (v2FolderList != null)
{
for (int i = v2FolderList.Count; i > 0; i--)
{
if (string.Equals(item.Path, v2FolderList[i].Path, StringComparison.CurrentCultureIgnoreCase))
{
try
{
parent.DeleteFolder(v2FolderList[i].Name);
}
catch
{
return false;
}
return true;
}
}
}
return false;
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator();
}
}

View File

@ -0,0 +1,25 @@
using System.Runtime.InteropServices;
namespace Microsoft.Win32.TaskScheduler
{
/// <summary>
/// Provides the methods that are used by COM handlers to notify the Task Scheduler about the status of the handler.
/// </summary>
[ComImport, Guid("EAEC7A8F-27A0-4DDC-8675-14726A01A38A"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), System.Security.SuppressUnmanagedCodeSecurity]
public interface ITaskHandlerStatus
{
/// <summary>
/// Tells the Task Scheduler about the percentage of completion of the COM handler.
/// </summary>
/// <param name="percentComplete">A value that indicates the percentage of completion for the COM handler.</param>
/// <param name="statusMessage">The message that is displayed in the Task Scheduler UI.</param>
void UpdateStatus([In] short percentComplete, [In, MarshalAs(UnmanagedType.BStr)] string statusMessage);
/// <summary>
/// Tells the Task Scheduler that the COM handler is completed.
/// </summary>
/// <param name="taskErrCode">The error code that the Task Scheduler will raise as an event.</param>
void TaskCompleted([In, MarshalAs(UnmanagedType.Error)] int taskErrCode);
}
}

View File

@ -0,0 +1,269 @@
using System;
using System.Runtime;
using System.Security;
using System.Security.AccessControl;
using System.Security.Principal;
using JetBrains.Annotations;
namespace Microsoft.Win32.TaskScheduler
{
/// <summary>
/// Specifies the access control rights that can be applied to Task Scheduler tasks.
/// </summary>
[Flags]
public enum TaskRights
{
/// <summary>Specifies the right to exert full control over a task folder or task, and to modify access control and audit rules. This value represents the right to do anything with a task and is the combination of all rights in this enumeration.</summary>
FullControl = 0x1f01ff,
/// <summary>Specifies the right to create tasks and folders, and to add or remove data from tasks. This right includes the following rights: .</summary>
Write = 0x120116,
/// <summary>Specifies the right to open and copy folders or tasks as read-only. This right includes the following rights: .</summary>
Read = 0x120089,
/// <summary>Specifies the right run tasks. This right includes the following rights: .</summary>
Execute = 0x120089,
/// <summary>The right to wait on a task.</summary>
Synchronize = 0x100000,
/// <summary>The right to change the owner of a task.</summary>
TakeOwnership = 0x80000,
/// <summary>Specifies the right to change the security and audit rules associated with a task or folder.</summary>
ChangePermissions = 0x40000,
/// <summary>The right to open and copy the access rules and audit rules for a task.</summary>
ReadPermissions = 0x20000,
/// <summary>The right to delete a folder or task.</summary>
Delete = 0x10000,
/// <summary>Specifies the right to open and write file system attributes to a folder or file. This does not include the ability to write data, extended attributes, or access and audit rules.</summary>
WriteAttributes = 0x100,
/// <summary>Specifies the right to open and copy file system attributes from a folder or task. For example, this value specifies the right to view the file creation or modified date. This does not include the right to read data, extended file system attributes, or access and audit rules.</summary>
ReadAttributes = 0x80,
/// <summary>Specifies the right to delete a folder and any tasks contained within that folder.</summary>
DeleteChild = 0x40,
/// <summary>Specifies the right to run a task.</summary>
ExecuteFile = 0x20,
/// <summary>Specifies the right to open and write extended file system attributes to a folder or file. This does not include the ability to write data, attributes, or access and audit rules.</summary>
WriteExtendedAttributes = 0x10,
/// <summary>Specifies the right to open and copy extended system attributes from a folder or task. For example, this value specifies the right to view author and content information. This does not include the right to read data, system attributes, or access and audit rules.</summary>
ReadExtendedAttributes = 8,
/// <summary>Specifies the right to append data to the end of a file.</summary>
AppendData = 4,
/// <summary>Specifies the right to open and write to a file or folder. This does not include the right to open and write file system attributes, extended file system attributes, or access and audit rules.</summary>
WriteData = 2,
/// <summary>Specifies the right to open and copy a task or folder. This does not include the right to read file system attributes, extended file system attributes, or access and audit rules.</summary>
ReadData = 1,
}
/// <summary>
/// Represents a set of access rights allowed or denied for a user or group. This class cannot be inherited.
/// </summary>
public sealed class TaskAccessRule : AccessRule
{
/// <summary>
/// Initializes a new instance of the <see cref="TaskAccessRule"/> class, specifying the user or group the rule applies to, the access rights, and whether the specified access rights are allowed or denied.
/// </summary>
/// <param name="identity">The user or group the rule applies to. Must be of type <see cref="SecurityIdentifier"/> or a type such as <see cref="NTAccount"/> that can be converted to type <see cref="SecurityIdentifier"/>.</param>
/// <param name="eventRights">A bitwise combination of <see cref="TaskRights"/> values specifying the rights allowed or denied.</param>
/// <param name="type">One of the <see cref="AccessControlType"/> values specifying whether the rights are allowed or denied.</param>
public TaskAccessRule([NotNull] IdentityReference identity, TaskRights eventRights, AccessControlType type)
: this(identity, (int)eventRights, false, InheritanceFlags.None, PropagationFlags.None, type)
{
}
private TaskAccessRule([NotNull] IdentityReference identity, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AccessControlType type)
: base(identity, accessMask, isInherited, inheritanceFlags, propagationFlags, type)
{
}
/// <summary>
/// Gets the rights allowed or denied by the access rule.
/// </summary>
/// <value>
/// A bitwise combination of <see cref="TaskRights"/> values indicating the rights allowed or denied by the access rule.
/// </value>
public TaskRights TaskRights => (TaskRights)AccessMask;
}
/// <summary>
/// Represents a set of access rights to be audited for a user or group. This class cannot be inherited.
/// </summary>
public sealed class TaskAuditRule : AuditRule
{
internal TaskAuditRule([NotNull] IdentityReference identity, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AuditFlags flags)
: base(identity, accessMask, isInherited, inheritanceFlags, propagationFlags, flags)
{
}
/// <summary>
/// Gets the access rights affected by the audit rule.
/// </summary>
/// <value>
/// A bitwise combination of <see cref="TaskRights"/> values that indicates the rights affected by the audit rule.
/// </value>
/// <remarks><see cref="TaskAuditRule"/> objects are immutable. You can create a new audit rule representing a different user, different rights, or a different combination of AuditFlags values, but you cannot modify an existing audit rule.</remarks>
public TaskRights TaskRights => (TaskRights)AccessMask;
}
/// <summary>
/// Represents the Windows access control security for a Task Scheduler task. This class cannot be inherited.
/// </summary>
/// <remarks>
/// <para>A TaskSecurity object specifies access rights for a Task Scheduler task, and also specifies how access attempts are audited. Access rights to the task are expressed as rules, with each access rule represented by a <see cref="TaskAccessRule"/> object. Each auditing rule is represented by a <see cref="TaskAuditRule"/> object.</para>
/// <para>This mirrors the underlying Windows security system, in which each securable object has at most one discretionary access control list (DACL) that controls access to the secured object, and at most one system access control list (SACL) that specifies which access attempts are audited. The DACL and SACL are ordered lists of access control entries (ACE) that specify access and auditing for users and groups. A <see cref="TaskAccessRule"/> or <see cref="TaskAuditRule"/> object might represent more than one ACE.</para>
/// <para>Note</para>
/// <para>A <see cref="Task"/> object can represent a local task or a Task Scheduler task. Windows access control security is meaningful only for Task Scheduler tasks.</para>
/// <para>The TaskSecurity, <see cref="TaskAccessRule"/>, and <see cref="TaskAuditRule"/> classes hide the implementation details of ACLs and ACEs. They allow you to ignore the seventeen different ACE types and the complexity of correctly maintaining inheritance and propagation of access rights. These objects are also designed to prevent the following common access control errors:</para>
/// <list type="bullet">
/// <item><description>Creating a security descriptor with a null DACL. A null reference to a DACL allows any user to add access rules to an object, potentially creating a denial-of-service attack. A new TaskSecurity object always starts with an empty DACL, which denies all access for all users.</description></item>
/// <item><description>Violating the canonical ordering of ACEs. If the ACE list in the DACL is not kept in the canonical order, users might inadvertently be given access to the secured object. For example, denied access rights must always appear before allowed access rights. TaskSecurity objects maintain the correct order internally. </description></item>
/// <item><description>Manipulating security descriptor flags, which should be under resource manager control only.</description></item>
/// <item><description>Creating invalid combinations of ACE flags.</description></item>
/// <item><description>Manipulating inherited ACEs. Inheritance and propagation are handled by the resource manager, in response to changes you make to access and audit rules.</description></item>
/// <item><description>Inserting meaningless ACEs into ACLs.</description></item>
/// </list>
/// <para>The only capabilities not supported by the .NET security objects are dangerous activities that should be avoided by the majority of application developers, such as the following:</para>
/// <list type="bullet">
/// <item><description>Low-level tasks that are normally performed by the resource manager.</description></item>
/// <item><description>Adding or removing access control entries in ways that do not maintain the canonical ordering.</description></item>
/// </list>
/// <para>To modify Windows access control security for a task, use the <see cref="Task.GetAccessControl()"/> method to get the TaskSecurity object. Modify the security object by adding and removing rules, and then use the <see cref="Task.SetAccessControl"/> method to reattach it. </para>
/// <para>Important: Changes you make to a TaskSecurity object do not affect the access levels of the task until you call the <see cref="Task.SetAccessControl"/> method to assign the altered security object to the task.</para>
/// <para>To copy access control security from one task to another, use the <see cref="Task.GetAccessControl()"/> method to get a TaskSecurity object representing the access and audit rules for the first task, then use the <see cref="Task.SetAccessControl"/> method, or a constructor that accepts a TaskSecurity object, to assign those rules to the second task.</para>
/// <para>Users with an investment in the security descriptor definition language (SDDL) can use the <see cref="Task.SetSecurityDescriptorSddlForm"/> method to set access rules for a task, and the <see cref="Task.GetSecurityDescriptorSddlForm"/> method to obtain a string that represents the access rules in SDDL format. This is not recommended for new development.</para>
/// </remarks>
public sealed class TaskSecurity : CommonObjectSecurity
{
/// <summary>
/// Initializes a new instance of the <see cref="TaskSecurity"/> class with default values.
/// </summary>
public TaskSecurity()
: base(false)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="TaskSecurity" /> class with the specified sections of the access control security rules from the specified task.
/// </summary>
/// <param name="task">The task.</param>
/// <param name="sections">The sections of the ACL to retrieve.</param>
public TaskSecurity([NotNull] Task task, AccessControlSections sections = Task.defaultAccessControlSections)
: base(false)
{
SetSecurityDescriptorSddlForm(task.GetSecurityDescriptorSddlForm(Convert(sections)), sections);
this.CanonicalizeAccessRules();
}
/// <summary>
/// Gets the enumeration that the <see cref="TaskSecurity"/> class uses to represent access rights.
/// </summary>
/// <returns>A <see cref="Type"/> object representing the <see cref="TaskRights"/> enumeration.</returns>
public override Type AccessRightType => typeof(TaskRights);
/// <summary>
/// Gets the type that the TaskSecurity class uses to represent access rules.
/// </summary>
/// <returns>A <see cref="Type"/> object representing the <see cref="TaskAccessRule"/> class.</returns>
public override Type AccessRuleType => typeof(TaskAccessRule);
/// <summary>
/// Gets the type that the TaskSecurity class uses to represent audit rules.
/// </summary>
/// <returns>A <see cref="Type"/> object representing the <see cref="TaskAuditRule"/> class.</returns>
public override Type AuditRuleType => typeof(TaskAuditRule);
/// <summary>
/// Creates a new access control rule for the specified user, with the specified access rights, access control, and flags.
/// </summary>
/// <param name="identityReference">An <see cref="IdentityReference"/> that identifies the user or group the rule applies to.</param>
/// <param name="accessMask">A bitwise combination of <see cref="TaskRights"/> values specifying the access rights to allow or deny, cast to an integer.</param>
/// <param name="isInherited">Meaningless for tasks, because they have no hierarchy.</param>
/// <param name="inheritanceFlags">Meaningless for tasks, because they have no hierarchy.</param>
/// <param name="propagationFlags">Meaningless for tasks, because they have no hierarchy.</param>
/// <param name="type">One of the <see cref="AccessControlType"/> values specifying whether the rights are allowed or denied.</param>
/// <returns>
/// The <see cref="T:System.Security.AccessControl.AccessRule" /> object that this method creates.
/// </returns>
public override AccessRule AccessRuleFactory(IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AccessControlType type) => new TaskAccessRule(identityReference, (TaskRights)accessMask, type);
/// <summary>
/// Creates a new audit rule, specifying the user the rule applies to, the access rights to audit, and the outcome that triggers the audit rule.
/// </summary>
/// <param name="identityReference">An <see cref="IdentityReference"/> that identifies the user or group the rule applies to.</param>
/// <param name="accessMask">A bitwise combination of <see cref="TaskRights"/> values specifying the access rights to audit, cast to an integer.</param>
/// <param name="isInherited">Meaningless for tasks, because they have no hierarchy.</param>
/// <param name="inheritanceFlags">Meaningless for tasks, because they have no hierarchy.</param>
/// <param name="propagationFlags">Meaningless for tasks, because they have no hierarchy.</param>
/// <param name="flags">One of the <see cref="AuditFlags"/> values specifying whether to audit successful access, failed access, or both.</param>
/// <returns>
/// A <see cref="TaskAuditRule"/> object representing the specified audit rule for the specified user. The return type of the method is the base class, <see cref="AuditRule"/>, but the return value can be cast safely to the derived class.
/// </returns>
public override AuditRule AuditRuleFactory(IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AuditFlags flags) => new TaskAuditRule(identityReference, accessMask, isInherited, inheritanceFlags, propagationFlags, flags);
/// <summary>
/// Returns a <see cref="System.String" /> that represents this instance.
/// </summary>
/// <returns>
/// A <see cref="System.String" /> that represents this instance.
/// </returns>
public override string ToString() => GetSecurityDescriptorSddlForm(Task.defaultAccessControlSections);
private static SecurityInfos Convert(AccessControlSections si)
{
SecurityInfos ret = 0;
if ((si & AccessControlSections.Audit) != 0)
ret |= SecurityInfos.SystemAcl;
if ((si & AccessControlSections.Access) != 0)
ret |= SecurityInfos.DiscretionaryAcl;
if ((si & AccessControlSections.Group) != 0)
ret |= SecurityInfos.Group;
if ((si & AccessControlSections.Owner) != 0)
ret |= SecurityInfos.Owner;
return ret;
}
private AccessControlSections GetAccessControlSectionsFromChanges()
{
AccessControlSections none = AccessControlSections.None;
if (AccessRulesModified)
{
none = AccessControlSections.Access;
}
if (AuditRulesModified)
{
none |= AccessControlSections.Audit;
}
if (OwnerModified)
{
none |= AccessControlSections.Owner;
}
if (GroupModified)
{
none |= AccessControlSections.Group;
}
return none;
}
/// <summary>
/// Saves the specified sections of the security descriptor associated with this <see cref="TaskSecurity"/> object to permanent storage. We recommend that the values of the <paramref name="includeSections"/> parameters passed to the constructor and persist methods be identical.
/// </summary>
/// <param name="task">The task used to retrieve the persisted information.</param>
/// <param name="includeSections">One of the <see cref="AccessControlSections"/> enumeration values that specifies the sections of the security descriptor (access rules, audit rules, owner, primary group) of the securable object to save.</param>
[SecurityCritical]
internal void Persist([NotNull] Task task, AccessControlSections includeSections = Task.defaultAccessControlSections)
{
WriteLock();
try
{
AccessControlSections accessControlSectionsFromChanges = GetAccessControlSectionsFromChanges();
if (accessControlSectionsFromChanges != AccessControlSections.None)
{
task.SetSecurityDescriptorSddlForm(GetSecurityDescriptorSddlForm(accessControlSectionsFromChanges));
OwnerModified = GroupModified = AccessRulesModified = AuditRulesModified = false;
}
}
finally
{
WriteUnlock();
}
}
}
}

View File

@ -0,0 +1,751 @@
using JetBrains.Annotations;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Runtime.InteropServices;
namespace Microsoft.Win32.TaskScheduler
{
/// <summary>
/// Quick simple trigger types for the
/// <see cref="TaskService.AddTask(string,Microsoft.Win32.TaskScheduler.Trigger,Microsoft.Win32.TaskScheduler.Action,string,string,Microsoft.Win32.TaskScheduler.TaskLogonType,string)"/> method.
/// </summary>
public enum QuickTriggerType
{
/// <summary>At boot.</summary>
Boot,
/// <summary>On system idle.</summary>
Idle,
/// <summary>At logon of any user.</summary>
Logon,
/// <summary>When the task is registered.</summary>
TaskRegistration,
/// <summary>Hourly, starting now.</summary>
Hourly,
/// <summary>Daily, starting now.</summary>
Daily,
/// <summary>Weekly, starting now.</summary>
Weekly,
/// <summary>Monthly, starting now.</summary>
Monthly
}
/// <summary>
/// Known versions of the native Task Scheduler library. This can be used as a decoder for the
/// <see cref="TaskService.HighestSupportedVersion"/> and <see cref="TaskService.LibraryVersion"/> values.
/// </summary>
public static class TaskServiceVersion
{
/// <summary>Task Scheduler 1.0 (Windows Server™ 2003, Windows® XP, or Windows® 2000).</summary>
[Description("Task Scheduler 1.0 (Windows Server™ 2003, Windows® XP, or Windows® 2000).")]
public static readonly Version V1_1 = new Version(1, 1);
/// <summary>Task Scheduler 2.0 (Windows Vista™, Windows Server™ 2008).</summary>
[Description("Task Scheduler 2.0 (Windows Vista™, Windows Server™ 2008).")]
public static readonly Version V1_2 = new Version(1, 2);
/// <summary>Task Scheduler 2.1 (Windows® 7, Windows Server™ 2008 R2).</summary>
[Description("Task Scheduler 2.1 (Windows® 7, Windows Server™ 2008 R2).")]
public static readonly Version V1_3 = new Version(1, 3);
/// <summary>Task Scheduler 2.2 (Windows® 8.x, Windows Server™ 2012).</summary>
[Description("Task Scheduler 2.2 (Windows® 8.x, Windows Server™ 2012).")]
public static readonly Version V1_4 = new Version(1, 4);
/// <summary>Task Scheduler 2.3 (Windows® 10, Windows Server™ 2016).</summary>
[Description("Task Scheduler 2.3 (Windows® 10, Windows Server™ 2016).")]
public static readonly Version V1_5 = new Version(1, 5);
/// <summary>Task Scheduler 2.3 (Windows® 10, Windows Server™ 2016 post build 1703).</summary>
[Description("Task Scheduler 2.3 (Windows® 10, Windows Server™ 2016 post build 1703).")]
public static readonly Version V1_6 = new Version(1, 6);
}
/// <summary>Provides access to the Task Scheduler service for managing registered tasks.</summary>
[Description("Provides access to the Task Scheduler service.")]
[ToolboxItem(true), Serializable]
public sealed partial class TaskService : Component, ISupportInitialize, System.Runtime.Serialization.ISerializable
{
internal static readonly bool LibraryIsV2 = Environment.OSVersion.Version.Major >= 6;
internal static readonly Guid PowerShellActionGuid = new Guid("dab4c1e3-cd12-46f1-96fc-3981143c9bab");
private static Guid CLSID_Ctask = typeof(V1Interop.CTask).GUID;
private static Guid IID_ITask = typeof(V1Interop.ITask).GUID;
[ThreadStatic]
private static TaskService instance;
private static Version osLibVer;
internal V1Interop.ITaskScheduler v1TaskScheduler;
internal V2Interop.ITaskService v2TaskService;
private bool connecting;
private bool forceV1;
private bool initializing;
private Version maxVer;
private bool maxVerSet;
private string targetServer;
private bool targetServerSet;
private string userDomain;
private bool userDomainSet;
private string userName;
private bool userNameSet;
private string userPassword;
private bool userPasswordSet;
private WindowsImpersonatedIdentity v1Impersonation;
/// <summary>Creates a new instance of a TaskService connecting to the local machine as the current user.</summary>
public TaskService()
{
ResetHighestSupportedVersion();
Connect();
}
/// <summary>Initializes a new instance of the <see cref="TaskService"/> class.</summary>
/// <param name="targetServer">
/// 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.
/// </param>
/// <param name="userName">
/// The user name that is used during the connection to the computer. If the user is not specified, then the current token is used.
/// </param>
/// <param name="accountDomain">The domain of the user specified in the <paramref name="userName"/> parameter.</param>
/// <param name="password">
/// 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.
/// </param>
/// <param name="forceV1">If set to <c>true</c> force Task Scheduler 1.0 compatibility.</param>
public TaskService(string targetServer, string userName = null, string accountDomain = null, string password = null, bool forceV1 = false)
{
BeginInit();
TargetServer = targetServer;
UserName = userName;
UserAccountDomain = accountDomain;
UserPassword = password;
this.forceV1 = forceV1;
ResetHighestSupportedVersion();
EndInit();
}
/// <summary>Delegate for methods that support update calls during COM handler execution.</summary>
/// <param name="percentage">The percentage of completion (0 to 100).</param>
/// <param name="message">An optional message.</param>
public delegate void ComHandlerUpdate(short percentage, string message);
/// <summary>Occurs when the Task Scheduler is connected to the local or remote target.</summary>
public event EventHandler ServiceConnected;
/// <summary>Occurs when the Task Scheduler is disconnected from the local or remote target.</summary>
public event EventHandler ServiceDisconnected;
/// <summary>Gets a local instance of the <see cref="TaskService"/> using the current user's credentials.</summary>
/// <value>Local user <see cref="TaskService"/> instance.</value>
public static TaskService Instance
{
get
{
if (instance is null)
{
instance = new TaskService();
instance.ServiceDisconnected += Instance_ServiceDisconnected;
}
return instance;
}
}
/// <summary>
/// Gets the library version. This is the highest version supported by the local library. Tasks cannot be created using any
/// compatibility level higher than this version.
/// </summary>
/// <value>The library version.</value>
/// <remarks>
/// The following table list the various versions and their host operating system:
/// <list type="table">
/// <listheader>
/// <term>Version</term>
/// <term>Operating System</term>
/// </listheader>
/// <item>
/// <term>1.1</term>
/// <term>Task Scheduler 1.0 (Windows Server™ 2003, Windows® XP, or Windows® 2000).</term>
/// </item>
/// <item>
/// <term>1.2</term>
/// <term>Task Scheduler 2.0 (Windows Vista™, Windows Server™ 2008).</term>
/// </item>
/// <item>
/// <term>1.3</term>
/// <term>Task Scheduler 2.1 (Windows® 7, Windows Server™ 2008 R2).</term>
/// </item>
/// <item>
/// <term>1.4</term>
/// <term>Task Scheduler 2.2 (Windows® 8.x, Windows Server™ 2012).</term>
/// </item>
/// <item>
/// <term>1.5</term>
/// <term>Task Scheduler 2.3 (Windows® 10, Windows Server™ 2016).</term>
/// </item>
/// <item>
/// <term>1.6</term>
/// <term>Task Scheduler 2.4 (Windows® 10 Version 1703, Windows Server™ 2016 Version 1703).</term>
/// </item>
/// </list>
/// </remarks>
[Browsable(false)]
public static Version LibraryVersion { get; } = Instance.HighestSupportedVersion;
/// <summary>
/// Gets or sets a value indicating whether to allow tasks from later OS versions with new properties to be retrieved as read only tasks.
/// </summary>
/// <value><c>true</c> if allow read only tasks; otherwise, <c>false</c>.</value>
[DefaultValue(false), Category("Behavior"), Description("Allow tasks from later OS versions with new properties to be retrieved as read only tasks.")]
public bool AllowReadOnlyTasks { get; set; }
/// <summary>Gets the highest version of Task Scheduler that a computer supports.</summary>
/// <remarks>
/// The following table list the various versions and their host operating system:
/// <list type="table">
/// <listheader>
/// <term>Version</term>
/// <term>Operating System</term>
/// </listheader>
/// <item>
/// <term>1.1</term>
/// <term>Task Scheduler 1.0 (Windows Server™ 2003, Windows® XP, or Windows® 2000).</term>
/// </item>
/// <item>
/// <term>1.2</term>
/// <term>Task Scheduler 2.0 (Windows Vista™, Windows Server™ 2008).</term>
/// </item>
/// <item>
/// <term>1.3</term>
/// <term>Task Scheduler 2.1 (Windows® 7, Windows Server™ 2008 R2).</term>
/// </item>
/// <item>
/// <term>1.4</term>
/// <term>Task Scheduler 2.2 (Windows® 8.x, Windows Server™ 2012).</term>
/// </item>
/// <item>
/// <term>1.5</term>
/// <term>Task Scheduler 2.3 (Windows® 10, Windows Server™ 2016).</term>
/// </item>
/// <item>
/// <term>1.6</term>
/// <term>Task Scheduler 2.4 (Windows® 10 Version 1703, Windows Server™ 2016 Version 1703).</term>
/// </item>
/// </list>
/// </remarks>
[Category("Data"), TypeConverter(typeof(VersionConverter)), Description("Highest version of library that should be used.")]
public Version HighestSupportedVersion
{
get => maxVer;
set
{
if (value > GetLibraryVersionFromLocalOS())
throw new ArgumentOutOfRangeException(nameof(HighestSupportedVersion), @"The value of HighestSupportedVersion cannot exceed that of the underlying Windows version library.");
maxVer = value;
maxVerSet = true;
var localForceV1 = value <= TaskServiceVersion.V1_1;
if (localForceV1 == forceV1) return;
forceV1 = localForceV1;
Connect();
}
}
/// <summary>Gets the root ("\") folder. For Task Scheduler 1.0, this is the only folder.</summary>
[Browsable(false)]
public TaskFolder RootFolder => GetFolder(TaskFolder.rootString);
/// <summary>Gets or sets the name of the computer that is running the Task Scheduler service that the user is connected to.</summary>
[Category("Data"), DefaultValue(null), Description("The name of the computer to connect to.")]
public string TargetServer
{
get => ShouldSerializeTargetServer() ? targetServer : null;
set
{
if (value == null || value.Trim() == string.Empty) value = null;
if (string.Compare(value, targetServer, StringComparison.OrdinalIgnoreCase) != 0)
{
targetServerSet = true;
targetServer = value;
Connect();
}
}
}
/// <summary>Gets or sets the user account domain to be used when connecting to the <see cref="TargetServer"/>.</summary>
/// <value>The user account domain.</value>
[Category("Data"), DefaultValue(null), Description("The user account domain to be used when connecting.")]
public string UserAccountDomain
{
get => ShouldSerializeUserAccountDomain() ? userDomain : null;
set
{
if (value == null || value.Trim() == string.Empty) value = null;
if (string.Compare(value, userDomain, StringComparison.OrdinalIgnoreCase) != 0)
{
userDomainSet = true;
userDomain = value;
Connect();
}
}
}
/// <summary>Gets or sets the user name to be used when connecting to the <see cref="TargetServer"/>.</summary>
/// <value>The user name.</value>
[Category("Data"), DefaultValue(null), Description("The user name to be used when connecting.")]
public string UserName
{
get => ShouldSerializeUserName() ? userName : null;
set
{
if (value == null || value.Trim() == string.Empty) value = null;
if (string.Compare(value, userName, StringComparison.OrdinalIgnoreCase) != 0)
{
userNameSet = true;
userName = value;
Connect();
}
}
}
/// <summary>Gets or sets the user password to be used when connecting to the <see cref="TargetServer"/>.</summary>
/// <value>The user password.</value>
[Category("Data"), DefaultValue(null), Description("The user password to be used when connecting.")]
public string UserPassword
{
get => userPassword;
set
{
if (value == null || value.Trim() == string.Empty) value = null;
if (string.CompareOrdinal(value, userPassword) != 0)
{
userPasswordSet = true;
userPassword = value;
Connect();
}
}
}
/// <summary>Gets a Boolean value that indicates if you are connected to the Task Scheduler service.</summary>
[Browsable(false)]
public bool Connected => v2TaskService != null && v2TaskService.Connected || v1TaskScheduler != null;
/// <summary>Creates a new task, registers the task, and returns the instance.</summary>
/// <param name="path">
/// 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.
/// </param>
/// <param name="trigger">The <see cref="Trigger"/> to determine when to run the task.</param>
/// <param name="action">The <see cref="Action"/> to determine what happens when the task is triggered.</param>
/// <param name="userId">The user credentials used to register the task.</param>
/// <param name="password">The password for the userId used to register the task.</param>
/// <param name="logonType">
/// A <see cref="TaskLogonType"/> value that defines what logon technique is used to run the registered task.
/// </param>
/// <param name="description">The task description.</param>
/// <returns>A <see cref="Task"/> instance of the registered task.</returns>
/// <remarks>
/// This method is shorthand for creating a new TaskDescription, adding a trigger and action, and then registering it in the root folder.
/// </remarks>
/// <example>
/// <code lang="cs">
/// <![CDATA[
/// // Display a log file every other day
/// TaskService.Instance.AddTask("Test", new DailyTrigger { DaysInterval = 2 }, new ExecAction("notepad.exe", "c:\\test.log", null));
/// ]]>
/// </code>
/// </example>
public Task AddTask([NotNull] string path, [NotNull] Trigger trigger, [NotNull] Action action, string userId = null, string password = null, TaskLogonType logonType = TaskLogonType.InteractiveToken, string description = null)
{
var td = NewTask();
if (!string.IsNullOrEmpty(description))
td.RegistrationInfo.Description = description;
// Create a trigger that will fire the task at a specific date and time
td.Triggers.Add(trigger);
// Create an action that will launch Notepad whenever the trigger fires
td.Actions.Add(action);
// Register the task in the root folder
return RootFolder.RegisterTaskDefinition(path, td, TaskCreation.CreateOrUpdate, userId, password, logonType);
}
/// <summary>Signals the object that initialization is starting.</summary>
public void BeginInit() => initializing = true;
/// <summary>Signals the object that initialization is complete.</summary>
public void EndInit()
{
initializing = false;
Connect();
}
/// <summary>Determines whether the specified <see cref="System.Object"/>, is equal to this instance.</summary>
/// <param name="obj">The <see cref="System.Object"/> to compare with this instance.</param>
/// <returns><c>true</c> if the specified <see cref="System.Object"/> is equal to this instance; otherwise, <c>false</c>.</returns>
public override bool Equals(object obj)
{
var tsobj = obj as TaskService;
if (tsobj != null)
return tsobj.TargetServer == TargetServer && tsobj.UserAccountDomain == UserAccountDomain && tsobj.UserName == UserName && tsobj.UserPassword == UserPassword && tsobj.forceV1 == forceV1;
return base.Equals(obj);
}
/// <summary>Gets the path to a folder of registered tasks.</summary>
/// <param name="folderName">
/// 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.
/// </param>
/// <returns><see cref="TaskFolder"/> instance for the requested folder or <c>null</c> if <paramref name="folderName"/> was unrecognized.</returns>
/// <exception cref="NotV1SupportedException">
/// Folder other than the root (\) was requested on a system not supporting Task Scheduler 2.0.
/// </exception>
public TaskFolder GetFolder(string folderName)
{
TaskFolder f = null;
if (v2TaskService != null)
{
if (string.IsNullOrEmpty(folderName)) folderName = TaskFolder.rootString;
try
{
var ifld = v2TaskService.GetFolder(folderName);
if (ifld != null)
f = new TaskFolder(this, ifld);
}
catch (System.IO.DirectoryNotFoundException) { }
catch (System.IO.FileNotFoundException) { }
}
else if (folderName == TaskFolder.rootString || string.IsNullOrEmpty(folderName))
f = new TaskFolder(this);
else
throw new NotV1SupportedException("Folder other than the root (\\) was requested on a system only supporting Task Scheduler 1.0.");
return f;
}
/// <summary>Returns a hash code for this instance.</summary>
/// <returns>A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.</returns>
public override int GetHashCode() => new { A = TargetServer, B = UserAccountDomain, C = UserName, D = UserPassword, E = forceV1 }.GetHashCode();
/// <summary>
/// Returns an empty task definition object to be filled in with settings and properties and then registered using the
/// <see cref="TaskFolder.RegisterTaskDefinition(string, TaskDefinition)"/> method.
/// </summary>
/// <returns>A <see cref="TaskDefinition"/> instance for setting properties.</returns>
public TaskDefinition NewTask()
{
if (v2TaskService != null)
return new TaskDefinition(v2TaskService.NewTask(0));
var v1Name = "Temp" + Guid.NewGuid().ToString("B");
return new TaskDefinition(v1TaskScheduler.NewWorkItem(v1Name, CLSID_Ctask, IID_ITask), v1Name);
}
[System.Security.SecurityCritical]
void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
{
info.AddValue("TargetServer", TargetServer, typeof(string));
info.AddValue("UserName", UserName, typeof(string));
info.AddValue("UserAccountDomain", UserAccountDomain, typeof(string));
info.AddValue("UserPassword", UserPassword, typeof(string));
info.AddValue("forceV1", forceV1, typeof(bool));
}
internal static V2Interop.IRegisteredTask GetTask([NotNull] V2Interop.ITaskService iSvc, [NotNull] string name)
{
V2Interop.ITaskFolder fld = null;
try
{
fld = iSvc.GetFolder("\\");
return fld.GetTask(name);
}
catch
{
return null;
}
finally
{
if (fld != null) Marshal.ReleaseComObject(fld);
}
}
internal static V1Interop.ITask GetTask([NotNull] V1Interop.ITaskScheduler iSvc, [NotNull] string name)
{
if (string.IsNullOrEmpty(name))
throw new ArgumentNullException(nameof(name));
try
{
return iSvc.Activate(name, IID_ITask);
}
catch (UnauthorizedAccessException)
{
// TODO: Take ownership of the file and try again
throw;
}
catch (ArgumentException)
{
return iSvc.Activate(name + ".job", IID_ITask);
}
catch (FileNotFoundException)
{
return null;
}
}
/// <summary>
/// Releases the unmanaged resources used by the <see cref="T:System.ComponentModel.Component"/> and optionally releases the managed resources.
/// </summary>
/// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
protected override void Dispose(bool disposing)
{
if (v2TaskService != null)
{
try
{
Marshal.ReleaseComObject(v2TaskService);
}
catch { }
v2TaskService = null;
}
if (v1TaskScheduler != null)
{
try
{
Marshal.ReleaseComObject(v1TaskScheduler);
}
catch { }
v1TaskScheduler = null;
}
if (v1Impersonation != null)
{
v1Impersonation.Dispose();
v1Impersonation = null;
}
if (!connecting)
ServiceDisconnected?.Invoke(this, EventArgs.Empty);
base.Dispose(disposing);
}
private static Version GetLibraryVersionFromLocalOS()
{
if (osLibVer == null)
{
if (Environment.OSVersion.Version.Major < 6)
osLibVer = TaskServiceVersion.V1_1;
else
{
if (Environment.OSVersion.Version.Minor == 0)
osLibVer = TaskServiceVersion.V1_2;
else if (Environment.OSVersion.Version.Minor == 1)
osLibVer = TaskServiceVersion.V1_3;
else
{
try
{
var fvi = System.Diagnostics.FileVersionInfo.GetVersionInfo(Path.Combine(Environment.SystemDirectory, "taskschd.dll"));
if (fvi.FileBuildPart > 9600 && fvi.FileBuildPart <= 14393)
osLibVer = TaskServiceVersion.V1_5;
else if (fvi.FileBuildPart >= 15063)
osLibVer = TaskServiceVersion.V1_6;
else // fvi.FileBuildPart <= 9600
osLibVer = TaskServiceVersion.V1_4;
}
catch { /* ignored */ };
}
}
if (osLibVer == null)
throw new NotSupportedException(@"The Task Scheduler library version for this system cannot be determined.");
}
return osLibVer;
}
private static void Instance_ServiceDisconnected(object sender, EventArgs e) => instance?.Connect();
/// <summary>Connects this instance of the <see cref="TaskService"/> class to a running Task Scheduler.</summary>
private void Connect()
{
ResetUnsetProperties();
if (!initializing && !DesignMode)
{
if (!string.IsNullOrEmpty(userDomain) && !string.IsNullOrEmpty(userName) && !string.IsNullOrEmpty(userPassword) || string.IsNullOrEmpty(userDomain) && string.IsNullOrEmpty(userName) && string.IsNullOrEmpty(userPassword))
{
// Clear stuff if already connected
connecting = true;
Dispose(true);
if (LibraryIsV2 && !forceV1)
{
v2TaskService = new V2Interop.ITaskService();
if (!string.IsNullOrEmpty(targetServer))
{
// Check to ensure character only server name. (Suggested by bigsan)
if (targetServer.StartsWith(@"\"))
targetServer = targetServer.TrimStart('\\');
// Make sure null is provided for local machine to compensate for a native library oddity (Found by ctrollen)
if (targetServer.Equals(Environment.MachineName, StringComparison.CurrentCultureIgnoreCase))
targetServer = null;
}
else
targetServer = null;
v2TaskService.Connect(targetServer, userName, userDomain, userPassword);
targetServer = v2TaskService.TargetServer;
userName = v2TaskService.ConnectedUser;
userDomain = v2TaskService.ConnectedDomain;
maxVer = GetV2Version();
}
else
{
v1Impersonation = new WindowsImpersonatedIdentity(userName, userDomain, userPassword);
v1TaskScheduler = new V1Interop.ITaskScheduler();
if (!string.IsNullOrEmpty(targetServer))
{
// Check to ensure UNC format for server name. (Suggested by bigsan)
if (!targetServer.StartsWith(@"\\"))
targetServer = @"\\" + targetServer;
}
else
targetServer = null;
v1TaskScheduler.SetTargetComputer(targetServer);
targetServer = v1TaskScheduler.GetTargetComputer();
maxVer = TaskServiceVersion.V1_1;
}
ServiceConnected?.Invoke(this, EventArgs.Empty);
connecting = false;
}
else
{
throw new ArgumentException("A username, password, and domain must be provided.");
}
}
}
/// <summary>Finds the task in folder.</summary>
/// <param name="fld">The folder.</param>
/// <param name="taskName">The wildcard expression to compare task names with.</param>
/// <param name="results">The results.</param>
/// <param name="recurse">if set to <c>true</c> recurse folders.</param>
/// <returns>True if any tasks are found, False if not.</returns>
private bool FindTaskInFolder([NotNull] TaskFolder fld, System.Text.RegularExpressions.Regex taskName, ref System.Collections.Generic.List<Task> results, bool recurse = true)
{
results.AddRange(fld.GetTasks(taskName));
if (recurse)
{
foreach (var f in fld.SubFolders)
{
if (FindTaskInFolder(f, taskName, ref results))
return true;
}
}
return false;
}
/// <summary>Finds the task in folder.</summary>
/// <param name="fld">The folder.</param>
/// <param name="filter">The filter to use when looking for tasks.</param>
/// <param name="results">The results.</param>
/// <param name="recurse">if set to <c>true</c> recurse folders.</param>
/// <returns>True if any tasks are found, False if not.</returns>
private bool FindTaskInFolder([NotNull] TaskFolder fld, Predicate<Task> filter, ref System.Collections.Generic.List<Task> results, bool recurse = true)
{
foreach (var t in fld.GetTasks())
try
{
if (filter(t))
results.Add(t);
}
catch
{
System.Diagnostics.Debug.WriteLine($"Unable to evaluate filter for task '{t.Path}'.");
}
if (recurse)
{
foreach (var f in fld.SubFolders)
{
if (FindTaskInFolder(f, filter, ref results))
return true;
}
}
return false;
}
private Version GetV2Version()
{
var v = v2TaskService.HighestVersion;
return new Version((int)(v >> 16), (int)(v & 0x0000FFFF));
}
private void ResetHighestSupportedVersion() => maxVer = Connected ? (v2TaskService != null ? GetV2Version() : TaskServiceVersion.V1_1) : GetLibraryVersionFromLocalOS();
private void ResetUnsetProperties()
{
if (!maxVerSet) ResetHighestSupportedVersion();
if (!targetServerSet) targetServer = null;
if (!userDomainSet) userDomain = null;
if (!userNameSet) userName = null;
if (!userPasswordSet) userPassword = null;
}
private bool ShouldSerializeTargetServer() => targetServer != null && !targetServer.Trim('\\').Equals(Environment.MachineName.Trim('\\'), StringComparison.InvariantCultureIgnoreCase);
private bool ShouldSerializeUserAccountDomain() => userDomain != null && !userDomain.Equals(Environment.UserDomainName, StringComparison.InvariantCultureIgnoreCase);
private bool ShouldSerializeUserName() => userName != null && !userName.Equals(Environment.UserName, StringComparison.InvariantCultureIgnoreCase);
/// <summary>
/// Represents a valid, connected session to a Task Scheduler instance. This token is thread-safe and should be the means of passing
/// information about a <see cref="TaskService"/> between threads.
/// </summary>
public struct ConnectionToken
{
internal int token;
internal ConnectionToken(int value) => token = value;
}
private class ComHandlerThread
{
private readonly System.Threading.AutoResetEvent completed = new System.Threading.AutoResetEvent(false);
private readonly string Data;
private readonly Type objType;
private readonly TaskHandlerStatus status;
private readonly int Timeout;
private class TaskHandlerStatus : ITaskHandlerStatus
{
private readonly Action<int> OnCompleted;
private readonly ComHandlerUpdate OnUpdate;
public void TaskCompleted([In, MarshalAs(UnmanagedType.Error)] int taskErrCode) => OnCompleted?.Invoke(taskErrCode);
public void UpdateStatus([In] short percentComplete, [In, MarshalAs(UnmanagedType.BStr)] string statusMessage) => OnUpdate?.Invoke(percentComplete, statusMessage);
}
}
// This private class holds information needed to create a new TaskService instance
private class ConnectionData : IEquatable<ConnectionData>
{
public bool ForceV1;
public string TargetServer, UserAccountDomain, UserName, UserPassword;
public bool Equals(ConnectionData other) => string.Equals(TargetServer, other.TargetServer, StringComparison.InvariantCultureIgnoreCase) &&
string.Equals(UserAccountDomain, other.UserAccountDomain, StringComparison.InvariantCultureIgnoreCase) &&
string.Equals(UserName, other.UserName, StringComparison.InvariantCultureIgnoreCase) &&
string.Equals(UserPassword, other.UserPassword, StringComparison.InvariantCultureIgnoreCase) &&
ForceV1 == other.ForceV1;
}
private class VersionConverter : TypeConverter
{
}
}
}

View File

@ -0,0 +1,71 @@
using System;
using System.Collections.Generic;
using System.Linq;
using JetBrains.Annotations;
namespace Microsoft.Win32.TaskScheduler
{
public abstract partial class Trigger
{
internal class CronExpression
{
private FieldVal[] Fields = new FieldVal[5];
private CronExpression() { }
public enum CronFieldType { Minutes, Hours, Days, Months, DaysOfWeek };
public struct FieldVal
{
private const string rangeRegEx = @"^(?:(?<A>\*)|(?<D1>\d+)(?:-(?<D2>\d+))?)(?:\/(?<I>\d+))?$";
private readonly static Dictionary<string, string> dow = new Dictionary<string, string>(7)
{
{ "SUN", "0" },
{ "MON", "1" },
{ "TUE", "2" },
{ "WED", "3" },
{ "THU", "4" },
{ "FRI", "5" },
{ "SAT", "6" },
};
private readonly static Dictionary<string, string> mon = new Dictionary<string, string>(12)
{
{ "JAN", "1" },
{ "FEB", "2" },
{ "MAR", "3" },
{ "APR", "4" },
{ "MAY", "5" },
{ "JUN", "6" },
{ "JUL", "7" },
{ "AUG", "8" },
{ "SEP", "9" },
{ "OCT", "10" },
{ "NOV", "11" },
{ "DEC", "12" },
};
private readonly static Dictionary<CronFieldType, MinMax> validRange = new Dictionary<CronFieldType, MinMax>(5)
{
{ CronFieldType.Days, new MinMax(1, 31) },
{ CronFieldType.DaysOfWeek, new MinMax(0, 6) },
{ CronFieldType.Hours, new MinMax(0, 23) },
{ CronFieldType.Minutes, new MinMax(0, 59) },
{ CronFieldType.Months, new MinMax(1, 12) },
};
private CronFieldType cft;
private FieldFlags flags;
private int incr;
private int[] vals;
enum FieldFlags { List, Every, Range, Increment };
public override string ToString() => $"Type:{flags}; Vals:{string.Join(",", vals.Select(i => i.ToString()).ToArray())}; Incr:{incr}";
private struct MinMax
{
public int Min, Max;
public MinMax(int min, int max) { Min = min; Max = max; }
}
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,407 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Xml.Serialization;
using JetBrains.Annotations;
namespace Microsoft.Win32.TaskScheduler
{
/// <summary>
/// Provides the methods that are used to add to, remove from, and get the triggers of a task.
/// </summary>
[XmlRoot("Triggers", Namespace = TaskDefinition.tns, IsNullable = false)]
public sealed class TriggerCollection : IList<Trigger>, IDisposable, IXmlSerializable, IList
{
private V1Interop.ITask v1Task;
private readonly V2Interop.ITriggerCollection v2Coll;
private V2Interop.ITaskDefinition v2Def;
internal TriggerCollection([NotNull] V1Interop.ITask iTask)
{
v1Task = iTask;
}
internal TriggerCollection([NotNull] V2Interop.ITaskDefinition iTaskDef)
{
v2Def = iTaskDef;
v2Coll = v2Def.Triggers;
}
/// <summary>
/// Gets the number of triggers in the collection.
/// </summary>
public int Count => v2Coll?.Count ?? v1Task.GetTriggerCount();
bool ICollection.IsSynchronized => false;
object ICollection.SyncRoot => this;
bool ICollection<Trigger>.IsReadOnly => false;
bool IList.IsFixedSize => false;
bool IList.IsReadOnly => false;
object IList.this[int index]
{
get { return this[index]; }
set { this[index] = (Trigger)value; }
}
/// <summary>
/// Gets a specified trigger from the collection.
/// </summary>
/// <param name="index">The index of the trigger to be retrieved.</param>
/// <returns>Specialized <see cref="Trigger"/> instance.</returns>
public Trigger this[int index]
{
get
{
if (v2Coll != null)
return Trigger.CreateTrigger(v2Coll[++index], v2Def);
return Trigger.CreateTrigger(v1Task.GetTrigger((ushort)index));
}
set
{
if (Count <= index)
throw new ArgumentOutOfRangeException(nameof(index), index, @"Index is not a valid index in the TriggerCollection");
Insert(index, value);
RemoveAt(index + 1);
}
}
/// <summary>
/// Add an unbound <see cref="Trigger"/> to the task.
/// </summary>
/// <typeparam name="TTrigger">A type derived from <see cref="Trigger"/>.</typeparam>
/// <param name="unboundTrigger"><see cref="Trigger"/> derivative to add to the task.</param>
/// <returns>Bound trigger.</returns>
/// <exception cref="System.ArgumentNullException"><c>unboundTrigger</c> is <c>null</c>.</exception>
public TTrigger Add<TTrigger>([NotNull] TTrigger unboundTrigger) where TTrigger : Trigger
{
if (unboundTrigger == null)
throw new ArgumentNullException(nameof(unboundTrigger));
if (v2Def != null)
unboundTrigger.Bind(v2Def);
else
unboundTrigger.Bind(v1Task);
return unboundTrigger;
}
/// <summary>
/// Add a new trigger to the collections of triggers for the task.
/// </summary>
/// <param name="taskTriggerType">The type of trigger to create.</param>
/// <returns>A <see cref="Trigger"/> instance of the specified type.</returns>
public Trigger AddNew(TaskTriggerType taskTriggerType)
{
if (v1Task != null)
{
ushort idx;
return Trigger.CreateTrigger(v1Task.CreateTrigger(out idx), Trigger.ConvertToV1TriggerType(taskTriggerType));
}
return Trigger.CreateTrigger(v2Coll.Create(taskTriggerType), v2Def);
}
/// <summary>
/// Clears all triggers from the task.
/// </summary>
public void Clear()
{
if (v2Coll != null)
v2Coll.Clear();
else
{
for (int i = Count - 1; i >= 0; i--)
RemoveAt(i);
}
}
/// <summary>
/// Determines whether the <see cref="T:System.Collections.Generic.ICollection`1" /> contains a specific value.
/// </summary>
/// <param name="item">The object to locate in the <see cref="T:System.Collections.Generic.ICollection`1" />.</param>
/// <returns>
/// true if <paramref name="item" /> is found in the <see cref="T:System.Collections.Generic.ICollection`1" />; otherwise, false.
/// </returns>
public bool Contains([NotNull] Trigger item) => Find(a => a.Equals(item)) != null;
/// <summary>
/// Copies the elements of the <see cref="T:System.Collections.Generic.ICollection`1" /> to an <see cref="Array"/>, starting at a particular <see cref="Array"/> index.
/// </summary>
/// <param name="array">The one-dimensional <see cref="Array"/> that is the destination of the elements copied from <see cref="T:System.Collections.Generic.ICollection`1" />. The <see cref="Array"/> must have zero-based indexing.</param>
/// <param name="arrayIndex">The zero-based index in <paramref name="array"/> at which copying begins.</param>
public void CopyTo(Trigger[] array, int arrayIndex) { CopyTo(0, array, arrayIndex, Count); }
/// <summary>
/// Copies the elements of the <see cref="TriggerCollection" /> to a <see cref="Trigger" /> array, starting at a particular <see cref="Trigger" /> array index.
/// </summary>
/// <param name="index">The zero-based index in the source at which copying begins.</param>
/// <param name="array">The <see cref="Trigger" /> array that is the destination of the elements copied from <see cref="TriggerCollection" />. The <see cref="Trigger" /> array must have zero-based indexing.</param>
/// <param name="arrayIndex">The zero-based index in <see cref="Trigger" /> array at which copying begins.</param>
/// <param name="count">The number of elements to copy.</param>
/// <exception cref="System.ArgumentNullException"><paramref name="array" /> is null.</exception>
/// <exception cref="System.ArgumentOutOfRangeException"><paramref name="arrayIndex" /> is less than 0.</exception>
/// <exception cref="System.ArgumentException">The number of elements in the source <see cref="TriggerCollection" /> is greater than the available space from <paramref name="arrayIndex" /> to the end of the destination <paramref name="array" />.</exception>
public void CopyTo(int index, Trigger[] array, int arrayIndex, int count)
{
if (array == null)
throw new ArgumentNullException(nameof(array));
if (index < 0 || index >= Count)
throw new ArgumentOutOfRangeException(nameof(index));
if (arrayIndex < 0)
throw new ArgumentOutOfRangeException(nameof(arrayIndex));
if (count < 0 || count > (Count - index))
throw new ArgumentOutOfRangeException(nameof(count));
if ((Count - index) > (array.Length - arrayIndex))
throw new ArgumentOutOfRangeException(nameof(arrayIndex));
for (int i = 0; i < count; i++)
array[arrayIndex + i] = (Trigger)this[index + i].Clone();
}
/// <summary>
/// Releases all resources used by this class.
/// </summary>
public void Dispose()
{
if (v2Coll != null) Marshal.ReleaseComObject(v2Coll);
v2Def = null;
v1Task = null;
}
/// <summary>
/// Searches for an <see cref="Trigger"/> that matches the conditions defined by the specified predicate, and returns the first occurrence within the entire collection.
/// </summary>
/// <param name="match">The <see cref="Predicate{Trigger}"/> delegate that defines the conditions of the <see cref="Trigger"/> to search for.</param>
/// <returns>The first <see cref="Trigger"/> that matches the conditions defined by the specified predicate, if found; otherwise, <c>null</c>.</returns>
public Trigger Find([NotNull] Predicate<Trigger> match)
{
if (match == null)
throw new ArgumentNullException(nameof(match));
foreach (var item in this)
if (match(item)) return item;
return null;
}
/// <summary>
/// Searches for an <see cref="Trigger"/> that matches the conditions defined by the specified predicate, and returns the zero-based index of the first occurrence within the collection that starts at the specified index and contains the specified number of elements.
/// </summary>
/// <param name="startIndex">The zero-based starting index of the search.</param>
/// <param name="count">The number of elements in the collection to search.</param>
/// <param name="match">The <see cref="Predicate{Trigger}"/> delegate that defines the conditions of the element to search for.</param>
/// <returns>The zero-based index of the first occurrence of an element that matches the conditions defined by match, if found; otherwise, 1.</returns>
public int FindIndexOf(int startIndex, int count, [NotNull] Predicate<Trigger> match)
{
if (startIndex < 0 || startIndex >= Count)
throw new ArgumentOutOfRangeException(nameof(startIndex));
if (startIndex + count > Count)
throw new ArgumentOutOfRangeException(nameof(count));
if (match == null)
throw new ArgumentNullException(nameof(match));
for (int i = startIndex; i < startIndex + count; i++)
if (match(this[i])) return i;
return -1;
}
/// <summary>
/// Searches for an <see cref="Trigger"/> that matches the conditions defined by the specified predicate, and returns the zero-based index of the first occurrence within the collection.
/// </summary>
/// <param name="match">The <see cref="Predicate{Trigger}"/> delegate that defines the conditions of the element to search for.</param>
/// <returns>The zero-based index of the first occurrence of an element that matches the conditions defined by match, if found; otherwise, 1.</returns>
public int FindIndexOf([NotNull] Predicate<Trigger> match) => FindIndexOf(0, Count, match);
/// <summary>
/// Gets the collection enumerator for this collection.
/// </summary>
/// <returns>The <see cref="IEnumerator{T}"/> for this collection.</returns>
public IEnumerator<Trigger> GetEnumerator()
{
if (v1Task != null)
return new V1TriggerEnumerator(v1Task);
return new ComEnumerator<Trigger, V2Interop.ITrigger>(() => v2Coll.Count, i => v2Coll[i], o => Trigger.CreateTrigger(o, v2Def));
}
void ICollection.CopyTo(Array array, int index)
{
if (array != null && array.Rank != 1)
throw new RankException("Multi-dimensional arrays are not supported.");
var src = new Trigger[Count];
CopyTo(src, 0);
Array.Copy(src, 0, array, index, Count);
}
void ICollection<Trigger>.Add(Trigger item) { Add(item); }
int IList.Add(object value)
{
Add((Trigger)value);
return Count - 1;
}
bool IList.Contains(object value) => Contains((Trigger)value);
int IList.IndexOf(object value) => IndexOf((Trigger)value);
void IList.Insert(int index, object value) { Insert(index, (Trigger)value); }
void IList.Remove(object value) { Remove((Trigger)value); }
/// <summary>
/// Determines the index of a specific item in the <see cref="T:System.Collections.Generic.IList`1" />.
/// </summary>
/// <param name="item">The object to locate in the <see cref="T:System.Collections.Generic.IList`1" />.</param>
/// <returns>
/// The index of <paramref name="item" /> if found in the list; otherwise, -1.
/// </returns>
public int IndexOf([NotNull] Trigger item) => FindIndexOf(a => a.Equals(item));
/// <summary>
/// Inserts an trigger at the specified index.
/// </summary>
/// <param name="index">The zero-based index at which trigger should be inserted.</param>
/// <param name="trigger">The trigger to insert into the list.</param>
public void Insert(int index, [NotNull] Trigger trigger)
{
if (trigger == null)
throw new ArgumentNullException(nameof(trigger));
if (index >= Count)
throw new ArgumentOutOfRangeException(nameof(index));
Trigger[] pushItems = new Trigger[Count - index];
CopyTo(index, pushItems, 0, Count - index);
for (int j = Count - 1; j >= index; j--)
RemoveAt(j);
Add(trigger);
foreach (Trigger t in pushItems)
Add(t);
}
System.Xml.Schema.XmlSchema IXmlSerializable.GetSchema() => null;
void IXmlSerializable.ReadXml(System.Xml.XmlReader reader)
{
reader.ReadStartElement(XmlSerializationHelper.GetElementName(this), TaskDefinition.tns);
while (reader.MoveToContent() == System.Xml.XmlNodeType.Element)
{
switch (reader.LocalName)
{
case "BootTrigger":
XmlSerializationHelper.ReadObject(reader, AddNew(TaskTriggerType.Boot));
break;
case "IdleTrigger":
XmlSerializationHelper.ReadObject(reader, AddNew(TaskTriggerType.Idle));
break;
case "TimeTrigger":
XmlSerializationHelper.ReadObject(reader, AddNew(TaskTriggerType.Time));
break;
case "LogonTrigger":
XmlSerializationHelper.ReadObject(reader, AddNew(TaskTriggerType.Logon));
break;
case "CalendarTrigger":
Add(CalendarTrigger.GetTriggerFromXml(reader));
break;
default:
reader.Skip();
break;
}
}
reader.ReadEndElement();
}
void IXmlSerializable.WriteXml(System.Xml.XmlWriter writer)
{
foreach (var t in this)
XmlSerializationHelper.WriteObject(writer, t);
}
/// <summary>
/// Removes the first occurrence of a specific object from the <see cref="T:System.Collections.Generic.ICollection`1" />.
/// </summary>
/// <param name="item">The object to remove from the <see cref="T:System.Collections.Generic.ICollection`1" />.</param>
/// <returns>
/// true if <paramref name="item" /> was successfully removed from the <see cref="T:System.Collections.Generic.ICollection`1" />; otherwise, false. This method also returns false if <paramref name="item" /> is not found in the original <see cref="T:System.Collections.Generic.ICollection`1" />.
/// </returns>
public bool Remove([NotNull] Trigger item)
{
int idx = IndexOf(item);
if (idx != -1)
{
try
{
RemoveAt(idx);
return true;
}
catch { }
}
return false;
}
/// <summary>
/// Removes the trigger at a specified index.
/// </summary>
/// <param name="index">Index of trigger to remove.</param>
/// <exception cref="ArgumentOutOfRangeException">Index out of range.</exception>
public void RemoveAt(int index)
{
if (index >= Count)
throw new ArgumentOutOfRangeException(nameof(index), index, @"Failed to remove Trigger. Index out of range.");
if (v2Coll != null)
v2Coll.Remove(++index);
else
v1Task.DeleteTrigger((ushort)index); //Remove the trigger from the Task Scheduler
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
/// <summary>
/// Returns a <see cref="System.String"/> that represents the triggers in this collection.
/// </summary>
/// <returns>
/// A <see cref="System.String"/> that represents the triggers in this collection.
/// </returns>
public override string ToString()
{
if (Count == 1)
return this[0].ToString();
if (Count > 1)
return winPEAS.Properties.Resources.MultipleTriggers;
return string.Empty;
}
internal void Bind()
{
foreach (Trigger t in this)
t.SetV1TriggerData();
}
private sealed class V1TriggerEnumerator : IEnumerator<Trigger>
{
private short curItem = -1;
private V1Interop.ITask iTask;
internal V1TriggerEnumerator(V1Interop.ITask task) { iTask = task; }
public Trigger Current => Trigger.CreateTrigger(iTask.GetTrigger((ushort)curItem));
object IEnumerator.Current => Current;
/// <summary>
/// Releases all resources used by this class.
/// </summary>
public void Dispose() { iTask = null; }
public bool MoveNext() => (++curItem < iTask.GetTriggerCount());
public void Reset() { curItem = -1; }
}
}
}

View File

@ -0,0 +1,130 @@
using System;
using System.Security.Principal;
namespace Microsoft.Win32.TaskScheduler
{
/// <summary>Represents a system account.</summary>
internal class User : IEquatable<User>, IDisposable
{
private static readonly WindowsIdentity cur = WindowsIdentity.GetCurrent();
private SecurityIdentifier sid;
/// <summary>Initializes a new instance of the <see cref="User"/> class.</summary>
/// <param name="userName">
/// Name of the user. This can be in the format <c>DOMAIN\username</c> or <c>username@domain.com</c> or <c>username</c> or
/// <c>null</c> (for current user).
/// </param>
public User(string userName = null)
{
if (string.IsNullOrEmpty(userName)) userName = null;
// 2018-03-02: Hopefully not a breaking change, but by adding in the comparison of an account name without a domain and the
// current user, there is a chance that current implementations will break given the condition that a local account with the same
// name as a domain account exists and the intention was to prefer the local account. In such a case, the developer should
// prepend the user name in TaskDefinition.Principal.UserId with the machine name of the local machine.
if (userName == null || cur.Name.Equals(userName, StringComparison.InvariantCultureIgnoreCase) || GetUser(cur.Name).Equals(userName, StringComparison.InvariantCultureIgnoreCase))
{
Identity = cur;
sid = Identity.User;
}
else if (userName.Contains("\\") && !userName.StartsWith(@"NT AUTHORITY\"))
{
try
{
using (var ds = new NativeMethods.DomainService())
{
Identity = new WindowsIdentity(ds.CrackName(userName));
sid = Identity.User;
}
}
catch { }
}
if (Identity == null)
{
if (userName != null && userName.Contains("@"))
{
Identity = new WindowsIdentity(userName);
sid = Identity.User;
}
if (Identity == null && userName != null)
{
var ntacct = new NTAccount(userName);
try { sid = (SecurityIdentifier)ntacct.Translate(typeof(SecurityIdentifier)); } catch { }
}
}
string GetUser(string domUser)
{
var split = domUser.Split('\\');
return split.Length == 2 ? split[1] : domUser;
}
}
/// <summary>Initializes a new instance of the <see cref="User"/> class.</summary>
/// <param name="wid">The <see cref="WindowsIdentity"/>.</param>
internal User(WindowsIdentity wid) { Identity = wid; sid = wid.User; }
/// <summary>Gets the identity.</summary>
/// <value>The identity.</value>
public WindowsIdentity Identity { get; private set; }
/// <summary>Gets a value indicating whether this instance is a service account.</summary>
/// <value><c>true</c> if this instance is a service account; otherwise, <c>false</c>.</value>
public bool IsServiceAccount
{
get
{
try
{
return (sid != null && (sid.IsWellKnown(WellKnownSidType.LocalSystemSid) || sid.IsWellKnown(WellKnownSidType.NetworkServiceSid) || sid.IsWellKnown(WellKnownSidType.LocalServiceSid)));
}
catch { }
return false;
}
}
/// <summary>Gets a value indicating whether this instance is the SYSTEM account.</summary>
/// <value><c>true</c> if this instance is the SYSTEM account; otherwise, <c>false</c>.</value>
public bool IsSystem => sid != null && sid.IsWellKnown(WellKnownSidType.LocalSystemSid);
/// <summary>Gets the NT name (DOMAIN\username).</summary>
/// <value>The name of the user.</value>
public string Name => Identity?.Name ?? ((NTAccount)sid?.Translate(typeof(NTAccount)))?.Value;
/// <summary>Create a <see cref="User"/> instance from a SID string.</summary>
/// <param name="sid">The SID string.</param>
/// <returns>A <see cref="User"/> instance.</returns>
public static User FromSidString(string sid) => new User(((NTAccount)new SecurityIdentifier(sid).Translate(typeof(NTAccount))).Value);
/// <summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.</summary>
public void Dispose() => Identity?.Dispose();
/// <summary>Determines whether the specified <see cref="System.Object"/>, is equal to this instance.</summary>
/// <param name="obj">The <see cref="System.Object"/> to compare with this instance.</param>
/// <returns><c>true</c> if the specified <see cref="System.Object"/> is equal to this instance; otherwise, <c>false</c>.</returns>
public override bool Equals(object obj)
{
if (obj is User user)
return Equals(user);
if (obj is WindowsIdentity wid && sid != null)
return sid.Equals(wid.User);
try
{
if (obj is string un)
return Equals(new User(un));
}
catch { }
return base.Equals(obj);
}
/// <summary>Indicates whether the current object is equal to another object of the same type.</summary>
/// <param name="other">An object to compare with this object.</param>
/// <returns>true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.</returns>
public bool Equals(User other) => (other != null && sid != null) ? sid.Equals(other.sid) : false;
/// <summary>Returns a hash code for this instance.</summary>
/// <returns>A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.</returns>
public override int GetHashCode() => sid?.GetHashCode() ?? 0;
}
}

View File

@ -0,0 +1,453 @@
using System;
using System.Runtime.InteropServices;
using JetBrains.Annotations;
// ReSharper disable InconsistentNaming
// ReSharper disable FieldCanBeMadeReadOnly.Global
namespace Microsoft.Win32.TaskScheduler.V1Interop
{
#region class HRESULT -- Values peculiar to the task scheduler.
internal class HResult
{
// The task is ready to run at its next scheduled time.
public const int SCHED_S_TASK_READY = 0x00041300;
// The task is currently running.
public const int SCHED_S_TASK_RUNNING = 0x00041301;
// The task will not run at the scheduled times because it has been disabled.
public const int SCHED_S_TASK_DISABLED = 0x00041302;
// The task has not yet run.
public const int SCHED_S_TASK_HAS_NOT_RUN = 0x00041303;
// There are no more runs scheduled for this task.
public const int SCHED_S_TASK_NO_MORE_RUNS = 0x00041304;
// One or more of the properties that are needed to run this task on a schedule have not been set.
public const int SCHED_S_TASK_NOT_SCHEDULED = 0x00041305;
// The last run of the task was terminated by the user.
public const int SCHED_S_TASK_TERMINATED = 0x00041306;
// Either the task has no triggers or the existing triggers are disabled or not set.
public const int SCHED_S_TASK_NO_VALID_TRIGGERS = 0x00041307;
// Event triggers don't have set run times.
public const int SCHED_S_EVENT_TRIGGER = 0x00041308;
// Trigger not found.
public const int SCHED_E_TRIGGER_NOT_FOUND = unchecked((int)0x80041309);
// One or more of the properties that are needed to run this task have not been set.
public const int SCHED_E_TASK_NOT_READY = unchecked((int)0x8004130A);
// There is no running instance of the task to terminate.
public const int SCHED_E_TASK_NOT_RUNNING = unchecked((int)0x8004130B);
// The Task Scheduler Service is not installed on this computer.
public const int SCHED_E_SERVICE_NOT_INSTALLED = unchecked((int)0x8004130C);
// The task object could not be opened.
public const int SCHED_E_CANNOT_OPEN_TASK = unchecked((int)0x8004130D);
// The object is either an invalid task object or is not a task object.
public const int SCHED_E_INVALID_TASK = unchecked((int)0x8004130E);
// No account information could be found in the Task Scheduler security database for the task indicated.
public const int SCHED_E_ACCOUNT_INFORMATION_NOT_SET = unchecked((int)0x8004130F);
// Unable to establish existence of the account specified.
public const int SCHED_E_ACCOUNT_NAME_NOT_FOUND = unchecked((int)0x80041310);
// Corruption was detected in the Task Scheduler security database; the database has been reset.
public const int SCHED_E_ACCOUNT_DBASE_CORRUPT = unchecked((int)0x80041311);
// Task Scheduler security services are available only on Windows NT.
public const int SCHED_E_NO_SECURITY_SERVICES = unchecked((int)0x80041312);
// The task object version is either unsupported or invalid.
public const int SCHED_E_UNKNOWN_OBJECT_VERSION = unchecked((int)0x80041313);
// The task has been configured with an unsupported combination of account settings and run time options.
public const int SCHED_E_UNSUPPORTED_ACCOUNT_OPTION = unchecked((int)0x80041314);
// The Task Scheduler Service is not running.
public const int SCHED_E_SERVICE_NOT_RUNNING = unchecked((int)0x80041315);
// The Task Scheduler service must be configured to run in the System account to function properly. Individual tasks may be configured to run in other accounts.
public const int SCHED_E_SERVICE_NOT_LOCALSYSTEM = unchecked((int)0x80041316);
}
#endregion
#region Enums
/// <summary>
/// Options for a task, used for the Flags property of a Task. Uses the
/// "Flags" attribute, so these values are combined with |.
/// Some flags are documented as Windows 95 only, but they have a
/// user interface in Windows XP so that may not be true.
/// </summary>
[Flags]
internal enum TaskFlags
{
/// <summary>
/// The interactive flag is set if the task is intended to be displayed to the user.
/// If the flag is not set, no user interface associated with the task is presented
/// to the user when the task is executed.
/// </summary>
Interactive = 0x1,
/// <summary>
/// The task will be deleted when there are no more scheduled run times.
/// </summary>
DeleteWhenDone = 0x2,
/// <summary>
/// The task is disabled. This is useful to temporarily prevent a task from running
/// at the scheduled time(s).
/// </summary>
Disabled = 0x4,
/// <summary>
/// The task begins only if the computer is not in use at the scheduled start time. Windows 95 only.
/// </summary>
StartOnlyIfIdle = 0x10,
/// <summary>
/// The task terminates if the computer makes an idle to non-idle transition while the task is running.
/// The computer is not considered idle until the IdleWait triggers' time elapses with no user input.
/// Windows 95 only. For information regarding idle triggers, see <see cref="IdleTrigger"/>.
/// </summary>
KillOnIdleEnd = 0x20,
/// <summary>
/// The task does not start if its target computer is running on battery power. Windows 95 only.
/// </summary>
DontStartIfOnBatteries = 0x40,
/// <summary>
/// The task ends, and the associated application quits if the task's target computer switches
/// to battery power. Windows 95 only.
/// </summary>
KillIfGoingOnBatteries = 0x80,
/// <summary>
/// The task runs only if the system is docked. Windows 95 only.
/// </summary>
RunOnlyIfDocked = 0x100,
/// <summary>
/// The work item created will be hidden.
/// </summary>
Hidden = 0x200,
/// <summary>
/// The task runs only if there is currently a valid Internet connection.
/// This feature is currently not implemented.
/// </summary>
RunIfConnectedToInternet = 0x400,
/// <summary>
/// The task starts again if the computer makes a non-idle to idle transition before all the
/// task's task_triggers elapse. (Use this flag in conjunction with KillOnIdleEnd.) Windows 95 only.
/// </summary>
RestartOnIdleResume = 0x800,
/// <summary>
/// The task runs only if the SYSTEM account is available.
/// </summary>
SystemRequired = 0x1000,
/// <summary>
/// The task runs only if the user specified in SetAccountInformation is logged on interactively.
/// This flag has no effect on work items set to run in the local account.
/// </summary>
RunOnlyIfLoggedOn = 0x2000
}
/// <summary>
/// Status values returned for a task. Some values have been determined to occur although
/// they do no appear in the Task Scheduler system documentation.
/// </summary>
internal enum TaskStatus
{
/// <summary>The task is ready to run at its next scheduled time.</summary>
Ready = HResult.SCHED_S_TASK_READY,
/// <summary>The task is currently running.</summary>
Running = HResult.SCHED_S_TASK_RUNNING,
/// <summary>One or more of the properties that are needed to run this task on a schedule have not been set. </summary>
NotScheduled = HResult.SCHED_S_TASK_NOT_SCHEDULED,
/// <summary>The task has not yet run.</summary>
NeverRun = HResult.SCHED_S_TASK_HAS_NOT_RUN,
/// <summary>The task will not run at the scheduled times because it has been disabled.</summary>
Disabled = HResult.SCHED_S_TASK_DISABLED,
/// <summary>There are no more runs scheduled for this task.</summary>
NoMoreRuns = HResult.SCHED_S_TASK_NO_MORE_RUNS,
/// <summary>The last run of the task was terminated by the user.</summary>
Terminated = HResult.SCHED_S_TASK_TERMINATED,
/// <summary>Either the task has no triggers or the existing triggers are disabled or not set.</summary>
NoTriggers = HResult.SCHED_S_TASK_NO_VALID_TRIGGERS,
/// <summary>Event triggers don't have set run times.</summary>
NoTriggerTime = HResult.SCHED_S_EVENT_TRIGGER
}
/// <summary>Valid types of triggers</summary>
internal enum TaskTriggerType
{
/// <summary>Trigger is set to run the task a single time. </summary>
RunOnce = 0,
/// <summary>Trigger is set to run the task on a daily interval. </summary>
RunDaily = 1,
/// <summary>Trigger is set to run the work item on specific days of a specific week of a specific month. </summary>
RunWeekly = 2,
/// <summary>Trigger is set to run the task on a specific day(s) of the month.</summary>
RunMonthly = 3,
/// <summary>Trigger is set to run the task on specific days, weeks, and months.</summary>
RunMonthlyDOW = 4,
/// <summary>Trigger is set to run the task if the system remains idle for the amount of time specified by the idle wait time of the task.</summary>
OnIdle = 5,
/// <summary>Trigger is set to run the task at system startup.</summary>
OnSystemStart = 6,
/// <summary>Trigger is set to run the task when a user logs on. </summary>
OnLogon = 7
}
[Flags]
internal enum TaskTriggerFlags : uint
{
HasEndDate = 0x1,
KillAtDurationEnd = 0x2,
Disabled = 0x4
}
#endregion
#region Structs
[StructLayout(LayoutKind.Sequential)]
internal struct Daily
{
public ushort DaysInterval;
}
[StructLayout(LayoutKind.Sequential)]
internal struct Weekly
{
public ushort WeeksInterval;
public DaysOfTheWeek DaysOfTheWeek;
}
[StructLayout(LayoutKind.Sequential)]
internal struct MonthlyDate
{
public uint Days;
public MonthsOfTheYear Months;
}
[StructLayout(LayoutKind.Sequential)]
internal struct MonthlyDOW
{
public ushort WhichWeek;
public DaysOfTheWeek DaysOfTheWeek;
public MonthsOfTheYear Months;
public WhichWeek V2WhichWeek
{
get
{
return (WhichWeek)(1 << ((short)WhichWeek - 1));
}
set
{
int idx = Array.IndexOf(new short[] { 0x1, 0x2, 0x4, 0x8, 0x10 }, (short)value);
if (idx >= 0)
WhichWeek = (ushort)(idx + 1);
else
throw new NotV1SupportedException("Only a single week can be set with Task Scheduler 1.0.");
}
}
}
[StructLayout(LayoutKind.Explicit)]
internal struct TriggerTypeData
{
[FieldOffset(0)]
public Daily daily;
[FieldOffset(0)]
public Weekly weekly;
[FieldOffset(0)]
public MonthlyDate monthlyDate;
[FieldOffset(0)]
public MonthlyDOW monthlyDOW;
}
[StructLayout(LayoutKind.Sequential)]
internal struct TaskTrigger
{
public ushort TriggerSize; // Structure size.
public ushort Reserved1; // Reserved. Must be zero.
public ushort BeginYear; // Trigger beginning date year.
public ushort BeginMonth; // Trigger beginning date month.
public ushort BeginDay; // Trigger beginning date day.
public ushort EndYear; // Optional trigger ending date year.
public ushort EndMonth; // Optional trigger ending date month.
public ushort EndDay; // Optional trigger ending date day.
public ushort StartHour; // Run bracket start time hour.
public ushort StartMinute; // Run bracket start time minute.
public uint MinutesDuration; // Duration of run bracket.
public uint MinutesInterval; // Run bracket repetition interval.
public TaskTriggerFlags Flags; // Trigger flags.
public TaskTriggerType Type; // Trigger type.
public TriggerTypeData Data; // Trigger data peculiar to this type (union).
public ushort Reserved2; // Reserved. Must be zero.
public ushort RandomMinutesInterval; // Maximum number of random minutes after start time.
public DateTime BeginDate
{
get { try { return BeginYear == 0 ? DateTime.MinValue : new DateTime(BeginYear, BeginMonth, BeginDay, StartHour, StartMinute, 0, DateTimeKind.Unspecified); } catch { return DateTime.MinValue; } }
set
{
if (value != DateTime.MinValue)
{
DateTime local = value.Kind == DateTimeKind.Utc ? value.ToLocalTime() : value;
BeginYear = (ushort)local.Year;
BeginMonth = (ushort)local.Month;
BeginDay = (ushort)local.Day;
StartHour = (ushort)local.Hour;
StartMinute = (ushort)local.Minute;
}
else
BeginYear = BeginMonth = BeginDay = StartHour = StartMinute = 0;
}
}
public DateTime? EndDate
{
get { try { return EndYear == 0 ? (DateTime?)null : new DateTime(EndYear, EndMonth, EndDay); } catch { return DateTime.MaxValue; } }
set
{
if (value.HasValue)
{
EndYear = (ushort)value.Value.Year;
EndMonth = (ushort)value.Value.Month;
EndDay = (ushort)value.Value.Day;
Flags |= TaskTriggerFlags.HasEndDate;
}
else
{
EndYear = EndMonth = EndDay = 0;
Flags &= ~TaskTriggerFlags.HasEndDate;
}
}
}
public override string ToString() => $"Trigger Type: {Type};\n> Start: {BeginDate}; End: {(EndYear == 0 ? "null" : EndDate?.ToString())};\n> DurMin: {MinutesDuration}; DurItv: {MinutesInterval};\n>";
}
#endregion
[ComImport, Guid("148BD527-A2AB-11CE-B11F-00AA00530503"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), System.Security.SuppressUnmanagedCodeSecurity, CoClass(typeof(CTaskScheduler))]
internal interface ITaskScheduler
{
void SetTargetComputer([In, MarshalAs(UnmanagedType.LPWStr)] string Computer);
CoTaskMemString GetTargetComputer();
[return: MarshalAs(UnmanagedType.Interface)]
IEnumWorkItems Enum();
[return: MarshalAs(UnmanagedType.Interface)]
ITask Activate([In, MarshalAs(UnmanagedType.LPWStr)][NotNull] string Name, [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid);
[return: MarshalAs(UnmanagedType.Interface)]
ITask NewWorkItem([In, MarshalAs(UnmanagedType.LPWStr)][NotNull] string TaskName, [In, MarshalAs(UnmanagedType.LPStruct)] Guid rclsid, [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid);
}
[Guid("148BD528-A2AB-11CE-B11F-00AA00530503"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), System.Security.SuppressUnmanagedCodeSecurity]
internal interface IEnumWorkItems
{
[PreserveSig()]
//int Next([In] uint celt, [Out, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr, SizeParamIndex = 0)] out string[] rgpwszNames, [Out] out uint pceltFetched);
int Next([In] uint RequestCount, [Out] out IntPtr Names, [Out] out uint Fetched);
void Skip([In] uint Count);
void Reset();
[return: MarshalAs(UnmanagedType.Interface)]
IEnumWorkItems Clone();
}
#if WorkItem
// The IScheduledWorkItem interface is actually never used because ITask inherits all of its
// methods. As ITask is the only kind of WorkItem (in 2002) it is the only interface we need.
[Guid("a6b952f0-a4b1-11d0-997d-00aa006887ec"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IScheduledWorkItem
{
void CreateTrigger([Out] out ushort NewTriggerIndex, [Out, MarshalAs(UnmanagedType.Interface)] out ITaskTrigger Trigger);
void DeleteTrigger([In] ushort TriggerIndex);
void GetTriggerCount([Out] out ushort Count);
void GetTrigger([In] ushort TriggerIndex, [Out, MarshalAs(UnmanagedType.Interface)] out ITaskTrigger Trigger);
void GetTriggerString([In] ushort TriggerIndex, out System.IntPtr TriggerString);
void GetRunTimes([In, MarshalAs(UnmanagedType.Struct)] SystemTime Begin, [In, MarshalAs(UnmanagedType.Struct)] SystemTime End, ref ushort Count, [Out] out System.IntPtr TaskTimes);
void GetNextRunTime([In, Out, MarshalAs(UnmanagedType.Struct)] ref SystemTime NextRun);
void SetIdleWait([In] ushort IdleMinutes, [In] ushort DeadlineMinutes);
void GetIdleWait([Out] out ushort IdleMinutes, [Out] out ushort DeadlineMinutes);
void Run();
void Terminate();
void EditWorkItem([In] uint hParent, [In] uint dwReserved);
void GetMostRecentRunTime([In, Out, MarshalAs(UnmanagedType.Struct)] ref SystemTime LastRun);
void GetStatus([Out, MarshalAs(UnmanagedType.Error)] out int Status);
void GetExitCode([Out] out uint ExitCode);
void SetComment([In, MarshalAs(UnmanagedType.LPWStr)] string Comment);
void GetComment(out System.IntPtr Comment);
void SetCreator([In, MarshalAs(UnmanagedType.LPWStr)] string Creator);
void GetCreator(out System.IntPtr Creator);
void SetWorkItemData([In] ushort DataLen, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0, ArraySubType=UnmanagedType.U1)] byte[] Data);
void GetWorkItemData([Out] out ushort DataLen, [Out] out System.IntPtr Data);
void SetErrorRetryCount([In] ushort RetryCount);
void GetErrorRetryCount([Out] out ushort RetryCount);
void SetErrorRetryInterval([In] ushort RetryInterval);
void GetErrorRetryInterval([Out] out ushort RetryInterval);
void SetFlags([In] uint Flags);
void GetFlags([Out] out uint Flags);
void SetAccountInformation([In, MarshalAs(UnmanagedType.LPWStr)] string AccountName, [In, MarshalAs(UnmanagedType.LPWStr)] string Password);
void GetAccountInformation(out System.IntPtr AccountName);
}
#endif
[ComImport, Guid("148BD524-A2AB-11CE-B11F-00AA00530503"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), System.Security.SuppressUnmanagedCodeSecurity, CoClass(typeof(CTask))]
internal interface ITask
{
[return: MarshalAs(UnmanagedType.Interface)]
ITaskTrigger CreateTrigger([Out] out ushort NewTriggerIndex);
void DeleteTrigger([In] ushort TriggerIndex);
[return: MarshalAs(UnmanagedType.U2)]
ushort GetTriggerCount();
[return: MarshalAs(UnmanagedType.Interface)]
ITaskTrigger GetTrigger([In] ushort TriggerIndex);
[return: MarshalAs(UnmanagedType.Struct)]
void SetIdleWait([In] ushort IdleMinutes, [In] ushort DeadlineMinutes);
void GetIdleWait([Out] out ushort IdleMinutes, [Out] out ushort DeadlineMinutes);
TaskStatus GetStatus();
void SetComment([In, MarshalAs(UnmanagedType.LPWStr)] string Comment);
CoTaskMemString GetComment();
void SetCreator([In, MarshalAs(UnmanagedType.LPWStr)] string Creator);
CoTaskMemString GetCreator();
void SetWorkItemData([In] ushort DataLen, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0, ArraySubType = UnmanagedType.U1)] byte[] Data);
void GetWorkItemData(out ushort DataLen, [Out] out IntPtr Data);
void SetFlags([In] TaskFlags Flags);
TaskFlags GetFlags();
void SetAccountInformation([In, MarshalAs(UnmanagedType.LPWStr)] string AccountName, [In] IntPtr Password);
CoTaskMemString GetAccountInformation();
void SetApplicationName([In, MarshalAs(UnmanagedType.LPWStr)] string ApplicationName);
CoTaskMemString GetApplicationName();
void SetParameters([In, MarshalAs(UnmanagedType.LPWStr)] string Parameters);
CoTaskMemString GetParameters();
void SetWorkingDirectory([In, MarshalAs(UnmanagedType.LPWStr)] string WorkingDirectory);
CoTaskMemString GetWorkingDirectory();
void SetPriority([In] uint Priority);
uint GetPriority();
void SetTaskFlags([In] uint Flags);
void SetMaxRunTime([In] uint MaxRunTimeMS);
uint GetMaxRunTime();
}
[Guid("148BD52B-A2AB-11CE-B11F-00AA00530503"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), System.Security.SuppressUnmanagedCodeSecurity]
internal interface ITaskTrigger
{
void SetTrigger([In, Out, MarshalAs(UnmanagedType.Struct)] ref TaskTrigger Trigger);
[return: MarshalAs(UnmanagedType.Struct)]
TaskTrigger GetTrigger();
CoTaskMemString GetTriggerString();
}
[ComImport, Guid("148BD52A-A2AB-11CE-B11F-00AA00530503"), System.Security.SuppressUnmanagedCodeSecurity, ClassInterface(ClassInterfaceType.None)]
internal class CTaskScheduler
{
}
[ComImport, Guid("148BD520-A2AB-11CE-B11F-00AA00530503"), System.Security.SuppressUnmanagedCodeSecurity, ClassInterface(ClassInterfaceType.None)]
internal class CTask
{
}
internal sealed class CoTaskMemString : SafeHandle
{
public CoTaskMemString() : base(IntPtr.Zero, true) { }
public CoTaskMemString(IntPtr handle) : this() { SetHandle(handle); }
public CoTaskMemString(string text) : this() { SetHandle(Marshal.StringToCoTaskMemUni(text)); }
public static implicit operator string (CoTaskMemString cmem) => cmem.ToString();
public override bool IsInvalid => handle == IntPtr.Zero;
protected override bool ReleaseHandle()
{
Marshal.FreeCoTaskMem(handle);
return true;
}
public override string ToString() => Marshal.PtrToStringUni(handle);
}
}

View File

@ -0,0 +1,554 @@
using System;
using System.Collections;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using JetBrains.Annotations;
namespace Microsoft.Win32.TaskScheduler.V2Interop
{
[ComImport, Guid("BAE54997-48B1-4CBE-9965-D6BE263EBEA4"), InterfaceType(ComInterfaceType.InterfaceIsDual), System.Security.SuppressUnmanagedCodeSecurity]
internal interface IAction
{
TaskActionType Type { get; }
}
[ComImport, Guid("02820E19-7B98-4ED2-B2E8-FDCCCEFF619B"), InterfaceType(ComInterfaceType.InterfaceIsDual), System.Security.SuppressUnmanagedCodeSecurity]
internal interface IActionCollection
{
int Count { get; }
IAction this[int index] { [return: MarshalAs(UnmanagedType.Interface)] get; }
[return: MarshalAs(UnmanagedType.Interface)]
IAction Create([In] TaskActionType Type);
void Remove([In, MarshalAs(UnmanagedType.Struct)][NotNull] object index);
void Clear();
string Context { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
}
[ComImport, Guid("2A9C35DA-D357-41F4-BBC1-207AC1B1F3CB"), InterfaceType(ComInterfaceType.InterfaceIsDual), System.Security.SuppressUnmanagedCodeSecurity]
internal interface IBootTrigger : ITrigger
{
new TaskTriggerType Type { get; }
new string Id { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new IRepetitionPattern Repetition { [return: MarshalAs(UnmanagedType.Interface)] get; [param: In, MarshalAs(UnmanagedType.Interface)] set; }
new string ExecutionTimeLimit { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new string StartBoundary { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new string EndBoundary { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new bool Enabled { get; [param: In] set; }
string Delay { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
}
[ComImport, Guid("6D2FD252-75C5-4F66-90BA-2A7D8CC3039F"), InterfaceType(ComInterfaceType.InterfaceIsDual), System.Security.SuppressUnmanagedCodeSecurity]
internal interface IComHandlerAction : IAction
{
new string Id { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new TaskActionType Type { get; }
string ClassId { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
string Data { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
}
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsDual), Guid("126C5CD8-B288-41D5-8DBF-E491446ADC5C"), System.Security.SuppressUnmanagedCodeSecurity]
internal interface IDailyTrigger : ITrigger
{
new TaskTriggerType Type { get; }
new string Id { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new IRepetitionPattern Repetition { [return: MarshalAs(UnmanagedType.Interface)] get; [param: In, MarshalAs(UnmanagedType.Interface)] set; }
new string ExecutionTimeLimit { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new string StartBoundary { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new string EndBoundary { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new bool Enabled { get; [param: In] set; }
short DaysInterval { get; [param: In] set; }
string RandomDelay { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
}
[ComImport, Guid("10F62C64-7E16-4314-A0C2-0C3683F99D40"), InterfaceType(ComInterfaceType.InterfaceIsDual), System.Security.SuppressUnmanagedCodeSecurity]
internal interface IEmailAction : IAction
{
new string Id { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new TaskActionType Type { get; }
string Server { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
string Subject { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
string To { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
string Cc { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
string Bcc { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
string ReplyTo { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
string From { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
ITaskNamedValueCollection HeaderFields { [return: MarshalAs(UnmanagedType.Interface)] get; [param: In, MarshalAs(UnmanagedType.Interface)] set; }
string Body { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
object[] Attachments { [return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_VARIANT)] get; [param: In, MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_VARIANT)] set; }
}
[ComImport, Guid("D45B0167-9653-4EEF-B94F-0732CA7AF251"), InterfaceType(ComInterfaceType.InterfaceIsDual), System.Security.SuppressUnmanagedCodeSecurity]
internal interface IEventTrigger : ITrigger
{
new TaskTriggerType Type { get; }
new string Id { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new IRepetitionPattern Repetition { [return: MarshalAs(UnmanagedType.Interface)] get; [param: In, MarshalAs(UnmanagedType.Interface)] set; }
new string ExecutionTimeLimit { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new string StartBoundary { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new string EndBoundary { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new bool Enabled { get; [param: In] set; }
string Subscription { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
string Delay { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
ITaskNamedValueCollection ValueQueries { [return: MarshalAs(UnmanagedType.Interface)] get; [param: In, MarshalAs(UnmanagedType.Interface)] set; }
}
[ComImport, Guid("4C3D624D-FD6B-49A3-B9B7-09CB3CD3F047"), InterfaceType(ComInterfaceType.InterfaceIsDual), System.Security.SuppressUnmanagedCodeSecurity]
internal interface IExecAction : IAction
{
new string Id { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new TaskActionType Type { get; }
string Path { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
string Arguments { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
string WorkingDirectory { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
}
[ComImport, Guid("84594461-0053-4342-A8FD-088FABF11F32"), InterfaceType(ComInterfaceType.InterfaceIsDual), System.Security.SuppressUnmanagedCodeSecurity]
internal interface IIdleSettings
{
string IdleDuration { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
string WaitTimeout { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
bool StopOnIdleEnd { get; [param: In] set; }
bool RestartOnIdle { get; [param: In] set; }
}
[ComImport, Guid("D537D2B0-9FB3-4D34-9739-1FF5CE7B1EF3"), InterfaceType(ComInterfaceType.InterfaceIsDual), System.Security.SuppressUnmanagedCodeSecurity]
internal interface IIdleTrigger : ITrigger
{
new TaskTriggerType Type { get; }
new string Id { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new IRepetitionPattern Repetition { [return: MarshalAs(UnmanagedType.Interface)] get; [param: In, MarshalAs(UnmanagedType.Interface)] set; }
new string ExecutionTimeLimit { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new string StartBoundary { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new string EndBoundary { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new bool Enabled { get; [param: In] set; }
}
[ComImport, Guid("72DADE38-FAE4-4B3E-BAF4-5D009AF02B1C"), InterfaceType(ComInterfaceType.InterfaceIsDual), System.Security.SuppressUnmanagedCodeSecurity]
internal interface ILogonTrigger : ITrigger
{
new TaskTriggerType Type { get; }
new string Id { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new IRepetitionPattern Repetition { [return: MarshalAs(UnmanagedType.Interface)] get; [param: In, MarshalAs(UnmanagedType.Interface)] set; }
new string ExecutionTimeLimit { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new string StartBoundary { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new string EndBoundary { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new bool Enabled { get; [param: In] set; }
string Delay { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
string UserId { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
}
[ComImport, Guid("77D025A3-90FA-43AA-B52E-CDA5499B946A"), InterfaceType(ComInterfaceType.InterfaceIsDual), System.Security.SuppressUnmanagedCodeSecurity]
internal interface IMonthlyDOWTrigger : ITrigger
{
new TaskTriggerType Type { get; }
new string Id { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new IRepetitionPattern Repetition { [return: MarshalAs(UnmanagedType.Interface)] get; [param: In, MarshalAs(UnmanagedType.Interface)] set; }
new string ExecutionTimeLimit { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new string StartBoundary { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new string EndBoundary { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new bool Enabled { get; [param: In] set; }
short DaysOfWeek { get; [param: In] set; }
short WeeksOfMonth { get; [param: In] set; }
short MonthsOfYear { get; [param: In] set; }
bool RunOnLastWeekOfMonth { get; [param: In] set; }
string RandomDelay { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
}
[ComImport, Guid("97C45EF1-6B02-4A1A-9C0E-1EBFBA1500AC"), InterfaceType(ComInterfaceType.InterfaceIsDual), System.Security.SuppressUnmanagedCodeSecurity]
internal interface IMonthlyTrigger : ITrigger
{
new TaskTriggerType Type { get; }
new string Id { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new IRepetitionPattern Repetition { [return: MarshalAs(UnmanagedType.Interface)] get; [param: In, MarshalAs(UnmanagedType.Interface)] set; }
new string ExecutionTimeLimit { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new string StartBoundary { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new string EndBoundary { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new bool Enabled { get; [param: In] set; }
int DaysOfMonth { get; [param: In] set; }
short MonthsOfYear { get; [param: In] set; }
bool RunOnLastDayOfMonth { get; [param: In] set; }
string RandomDelay { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
}
[ComImport, Guid("9F7DEA84-C30B-4245-80B6-00E9F646F1B4"), InterfaceType(ComInterfaceType.InterfaceIsDual), System.Security.SuppressUnmanagedCodeSecurity]
internal interface INetworkSettings
{
string Name { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
string Id { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
}
[ComImport, Guid("D98D51E5-C9B4-496A-A9C1-18980261CF0F"), InterfaceType(ComInterfaceType.InterfaceIsDual), System.Security.SuppressUnmanagedCodeSecurity]
internal interface IPrincipal
{
string Id { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
string DisplayName { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
string UserId { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
TaskLogonType LogonType { get; set; }
string GroupId { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
TaskRunLevel RunLevel { get; set; }
}
[ComImport, Guid("248919AE-E345-4A6D-8AEB-E0D3165C904E"), InterfaceType(ComInterfaceType.InterfaceIsDual), System.Security.SuppressUnmanagedCodeSecurity]
internal interface IPrincipal2
{
TaskProcessTokenSidType ProcessTokenSidType { get; [param: In] set; }
int RequiredPrivilegeCount { get; }
string this[int index] { [return: MarshalAs(UnmanagedType.BStr)] get; }
void AddRequiredPrivilege([In, MarshalAs(UnmanagedType.BStr)] string privilege);
}
[ComImport, Guid("9C86F320-DEE3-4DD1-B972-A303F26B061E"), InterfaceType(ComInterfaceType.InterfaceIsDual), System.Security.SuppressUnmanagedCodeSecurity, DefaultMember("Path")]
internal interface IRegisteredTask
{
string Name { [return: MarshalAs(UnmanagedType.BStr)] get; }
string Path { [return: MarshalAs(UnmanagedType.BStr)] get; }
TaskState State { get; }
bool Enabled { get; set; }
[return: MarshalAs(UnmanagedType.Interface)]
IRunningTask Run([In, MarshalAs(UnmanagedType.Struct)] object parameters);
[return: MarshalAs(UnmanagedType.Interface)]
IRunningTask RunEx([In, MarshalAs(UnmanagedType.Struct)] object parameters, [In] int flags, [In] int sessionID, [In, MarshalAs(UnmanagedType.BStr)] string user);
[return: MarshalAs(UnmanagedType.Interface)]
IRunningTaskCollection GetInstances(int flags);
DateTime LastRunTime { get; }
int LastTaskResult { get; }
int NumberOfMissedRuns { get; }
DateTime NextRunTime { get; }
ITaskDefinition Definition { [return: MarshalAs(UnmanagedType.Interface)] get; }
string Xml { [return: MarshalAs(UnmanagedType.BStr)] get; }
[return: MarshalAs(UnmanagedType.BStr)]
string GetSecurityDescriptor(int securityInformation);
void SetSecurityDescriptor([In, MarshalAs(UnmanagedType.BStr)] string sddl, [In] int flags);
void Stop(int flags);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(0x60020011)]
void GetRunTimes([In] ref Microsoft.Win32.NativeMethods.SYSTEMTIME pstStart, [In] ref Microsoft.Win32.NativeMethods.SYSTEMTIME pstEnd, [In, Out] ref uint pCount, [In, Out] ref IntPtr pRunTimes);
}
[ComImport, Guid("86627EB4-42A7-41E4-A4D9-AC33A72F2D52"), InterfaceType(ComInterfaceType.InterfaceIsDual), System.Security.SuppressUnmanagedCodeSecurity]
internal interface IRegisteredTaskCollection
{
int Count { get; }
IRegisteredTask this[object index] { [return: MarshalAs(UnmanagedType.Interface)] get; }
[return: MarshalAs(UnmanagedType.Interface)]
IEnumerator GetEnumerator();
}
[ComImport, Guid("416D8B73-CB41-4EA1-805C-9BE9A5AC4A74"), InterfaceType(ComInterfaceType.InterfaceIsDual), System.Security.SuppressUnmanagedCodeSecurity]
internal interface IRegistrationInfo
{
string Description { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
string Author { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
string Version { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
string Date { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
string Documentation { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
string XmlText { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
string URI { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
object SecurityDescriptor { [return: MarshalAs(UnmanagedType.Struct)] get; [param: In, MarshalAs(UnmanagedType.Struct)] set; }
string Source { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
}
[ComImport, Guid("4C8FEC3A-C218-4E0C-B23D-629024DB91A2"), InterfaceType(ComInterfaceType.InterfaceIsDual), System.Security.SuppressUnmanagedCodeSecurity]
internal interface IRegistrationTrigger : ITrigger
{
new TaskTriggerType Type { get; }
new string Id { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new IRepetitionPattern Repetition { [return: MarshalAs(UnmanagedType.Interface)] get; [param: In, MarshalAs(UnmanagedType.Interface)] set; }
new string ExecutionTimeLimit { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new string StartBoundary { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new string EndBoundary { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new bool Enabled { get; [param: In] set; }
string Delay { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
}
[ComImport, Guid("7FB9ACF1-26BE-400E-85B5-294B9C75DFD6"), InterfaceType(ComInterfaceType.InterfaceIsDual), System.Security.SuppressUnmanagedCodeSecurity]
internal interface IRepetitionPattern
{
string Interval { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
string Duration { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
bool StopAtDurationEnd { get; [param: In] set; }
}
[ComImport, Guid("653758FB-7B9A-4F1E-A471-BEEB8E9B834E"), InterfaceType(ComInterfaceType.InterfaceIsDual), System.Security.SuppressUnmanagedCodeSecurity, DefaultMember("InstanceGuid")]
internal interface IRunningTask
{
string Name { [return: MarshalAs(UnmanagedType.BStr)] get; }
string InstanceGuid { [return: MarshalAs(UnmanagedType.BStr)] get; }
string Path { [return: MarshalAs(UnmanagedType.BStr)] get; }
TaskState State { get; }
string CurrentAction { [return: MarshalAs(UnmanagedType.BStr)] get; }
void Stop();
void Refresh();
uint EnginePID { get; }
}
[ComImport, Guid("6A67614B-6828-4FEC-AA54-6D52E8F1F2DB"), InterfaceType(ComInterfaceType.InterfaceIsDual), System.Security.SuppressUnmanagedCodeSecurity]
internal interface IRunningTaskCollection
{
int Count { get; }
IRunningTask this[object index] { [return: MarshalAs(UnmanagedType.Interface)] get; }
[return: MarshalAs(UnmanagedType.Interface)]
IEnumerator GetEnumerator();
}
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsDual), Guid("754DA71B-4385-4475-9DD9-598294FA3641"), System.Security.SuppressUnmanagedCodeSecurity]
internal interface ISessionStateChangeTrigger : ITrigger
{
new TaskTriggerType Type { get; }
new string Id { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new IRepetitionPattern Repetition { [return: MarshalAs(UnmanagedType.Interface)] get; [param: In, MarshalAs(UnmanagedType.Interface)] set; }
new string ExecutionTimeLimit { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new string StartBoundary { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new string EndBoundary { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new bool Enabled { get; [param: In] set; }
string Delay { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
string UserId { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
TaskSessionStateChangeType StateChange { get; [param: In] set; }
}
[ComImport, Guid("505E9E68-AF89-46B8-A30F-56162A83D537"), InterfaceType(ComInterfaceType.InterfaceIsDual), System.Security.SuppressUnmanagedCodeSecurity]
internal interface IShowMessageAction : IAction
{
new string Id { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new TaskActionType Type { get; }
string Title { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
string MessageBody { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
}
[ComImport, Guid("F5BC8FC5-536D-4F77-B852-FBC1356FDEB6"), InterfaceType(ComInterfaceType.InterfaceIsDual), System.Security.SuppressUnmanagedCodeSecurity]
internal interface ITaskDefinition
{
IRegistrationInfo RegistrationInfo { [return: MarshalAs(UnmanagedType.Interface)] get; [param: In, MarshalAs(UnmanagedType.Interface)] set; }
ITriggerCollection Triggers { [return: MarshalAs(UnmanagedType.Interface)] get; [param: In, MarshalAs(UnmanagedType.Interface)] set; }
ITaskSettings Settings { [return: MarshalAs(UnmanagedType.Interface)] get; [param: In, MarshalAs(UnmanagedType.Interface)] set; }
string Data { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
IPrincipal Principal { [return: MarshalAs(UnmanagedType.Interface)] get; [param: In, MarshalAs(UnmanagedType.Interface)] set; }
IActionCollection Actions { [return: MarshalAs(UnmanagedType.Interface)] get; [param: In, MarshalAs(UnmanagedType.Interface)] set; }
string XmlText { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
}
[ComImport, Guid("8CFAC062-A080-4C15-9A88-AA7C2AF80DFC"), InterfaceType(ComInterfaceType.InterfaceIsDual), System.Security.SuppressUnmanagedCodeSecurity, DefaultMember("Path")]
internal interface ITaskFolder
{
string Name { [return: MarshalAs(UnmanagedType.BStr)] get; }
string Path { [return: MarshalAs(UnmanagedType.BStr)] get; }
[return: MarshalAs(UnmanagedType.Interface)]
ITaskFolder GetFolder([MarshalAs(UnmanagedType.BStr)] string Path);
[return: MarshalAs(UnmanagedType.Interface)]
ITaskFolderCollection GetFolders(int flags);
[return: MarshalAs(UnmanagedType.Interface)]
ITaskFolder CreateFolder([In, MarshalAs(UnmanagedType.BStr)] string subFolderName, [In, Optional, MarshalAs(UnmanagedType.Struct)] object sddl);
void DeleteFolder([MarshalAs(UnmanagedType.BStr)] string subFolderName, [In] int flags);
[return: MarshalAs(UnmanagedType.Interface)]
IRegisteredTask GetTask([MarshalAs(UnmanagedType.BStr)][NotNull] string Path);
[return: MarshalAs(UnmanagedType.Interface)]
IRegisteredTaskCollection GetTasks(int flags);
void DeleteTask([In, MarshalAs(UnmanagedType.BStr)][NotNull] string Name, [In] int flags);
[return: MarshalAs(UnmanagedType.Interface)]
IRegisteredTask RegisterTask([In, MarshalAs(UnmanagedType.BStr)][NotNull] string Path, [In, MarshalAs(UnmanagedType.BStr)][NotNull] string XmlText, [In] int flags, [In, MarshalAs(UnmanagedType.Struct)] object UserId, [In, MarshalAs(UnmanagedType.Struct)] object password, [In] TaskLogonType LogonType, [In, Optional, MarshalAs(UnmanagedType.Struct)] object sddl);
[return: MarshalAs(UnmanagedType.Interface)]
IRegisteredTask RegisterTaskDefinition([In, MarshalAs(UnmanagedType.BStr)][NotNull] string Path, [In, MarshalAs(UnmanagedType.Interface)][NotNull] ITaskDefinition pDefinition, [In] int flags, [In, MarshalAs(UnmanagedType.Struct)] object UserId, [In, MarshalAs(UnmanagedType.Struct)] object password, [In] TaskLogonType LogonType, [In, Optional, MarshalAs(UnmanagedType.Struct)] object sddl);
[return: MarshalAs(UnmanagedType.BStr)]
string GetSecurityDescriptor(int securityInformation);
void SetSecurityDescriptor([In, MarshalAs(UnmanagedType.BStr)] string sddl, [In] int flags);
}
[ComImport, Guid("79184A66-8664-423F-97F1-637356A5D812"), InterfaceType(ComInterfaceType.InterfaceIsDual), System.Security.SuppressUnmanagedCodeSecurity]
internal interface ITaskFolderCollection
{
int Count { get; }
ITaskFolder this[object index] { [return: MarshalAs(UnmanagedType.Interface)] get; }
[return: MarshalAs(UnmanagedType.Interface)]
IEnumerator GetEnumerator();
}
[ComImport, Guid("B4EF826B-63C3-46E4-A504-EF69E4F7EA4D"), InterfaceType(ComInterfaceType.InterfaceIsDual), System.Security.SuppressUnmanagedCodeSecurity]
internal interface ITaskNamedValueCollection
{
int Count { get; }
ITaskNamedValuePair this[int index] { [return: MarshalAs(UnmanagedType.Interface)] get; }
[return: MarshalAs(UnmanagedType.Interface)]
IEnumerator GetEnumerator();
[return: MarshalAs(UnmanagedType.Interface)]
ITaskNamedValuePair Create([In, MarshalAs(UnmanagedType.BStr)][NotNull] string Name, [In, MarshalAs(UnmanagedType.BStr)] string Value);
void Remove([In] int index);
void Clear();
}
[ComImport, Guid("39038068-2B46-4AFD-8662-7BB6F868D221"), InterfaceType(ComInterfaceType.InterfaceIsDual), System.Security.SuppressUnmanagedCodeSecurity, DefaultMember("Name")]
internal interface ITaskNamedValuePair
{
string Name { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
string Value { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
}
[ComImport, DefaultMember("TargetServer"), Guid("2FABA4C7-4DA9-4013-9697-20CC3FD40F85"), System.Security.SuppressUnmanagedCodeSecurity, CoClass(typeof(TaskSchedulerClass))]
internal interface ITaskService
{
[return: MarshalAs(UnmanagedType.Interface)]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(1)]
ITaskFolder GetFolder([In, MarshalAs(UnmanagedType.BStr)][NotNull] string Path);
[return: MarshalAs(UnmanagedType.Interface)]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(2)]
IRunningTaskCollection GetRunningTasks(int flags);
[return: MarshalAs(UnmanagedType.Interface)]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(3)]
ITaskDefinition NewTask([In] uint flags);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(4)]
void Connect([In, Optional, MarshalAs(UnmanagedType.Struct)] object serverName, [In, Optional, MarshalAs(UnmanagedType.Struct)] object user, [In, Optional, MarshalAs(UnmanagedType.Struct)] object domain, [In, Optional, MarshalAs(UnmanagedType.Struct)] object password);
[DispId(5)]
bool Connected { [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(5)] get; }
[DispId(0)]
string TargetServer { [return: MarshalAs(UnmanagedType.BStr)] [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(0)] get; }
[DispId(6)]
string ConnectedUser { [return: MarshalAs(UnmanagedType.BStr)] [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(6)] get; }
[DispId(7)]
string ConnectedDomain { [return: MarshalAs(UnmanagedType.BStr)] [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(7)] get; }
[DispId(8)]
uint HighestVersion { [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(8)] get; }
}
[ComImport, DefaultMember("TargetServer"), Guid("0F87369F-A4E5-4CFC-BD3E-73E6154572DD"), ClassInterface((short)0), System.Security.SuppressUnmanagedCodeSecurity]
internal class TaskSchedulerClass
{
}
[ComImport, Guid("8FD4711D-2D02-4C8C-87E3-EFF699DE127E"), InterfaceType(ComInterfaceType.InterfaceIsDual), System.Security.SuppressUnmanagedCodeSecurity]
internal interface ITaskSettings
{
bool AllowDemandStart { get; [param: In] set; }
string RestartInterval { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
int RestartCount { get; [param: In] set; }
TaskInstancesPolicy MultipleInstances { get; [param: In] set; }
bool StopIfGoingOnBatteries { get; [param: In] set; }
bool DisallowStartIfOnBatteries { get; [param: In] set; }
bool AllowHardTerminate { get; [param: In] set; }
bool StartWhenAvailable { get; [param: In] set; }
string XmlText { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
bool RunOnlyIfNetworkAvailable { get; [param: In] set; }
string ExecutionTimeLimit { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
bool Enabled { get; [param: In] set; }
string DeleteExpiredTaskAfter { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
int Priority { get; [param: In] set; }
TaskCompatibility Compatibility { get; [param: In] set; }
bool Hidden { get; [param: In] set; }
IIdleSettings IdleSettings { [return: MarshalAs(UnmanagedType.Interface)] get; [param: In, MarshalAs(UnmanagedType.Interface)] set; }
bool RunOnlyIfIdle { get; [param: In] set; }
bool WakeToRun { get; [param: In] set; }
INetworkSettings NetworkSettings { [return: MarshalAs(UnmanagedType.Interface)] get; [param: In, MarshalAs(UnmanagedType.Interface)] set; }
}
[ComImport, Guid("2C05C3F0-6EED-4c05-A15F-ED7D7A98A369"), InterfaceType(ComInterfaceType.InterfaceIsDual), System.Security.SuppressUnmanagedCodeSecurity]
internal interface ITaskSettings2
{
bool DisallowStartOnRemoteAppSession { get; [param: In] set; }
bool UseUnifiedSchedulingEngine { get; [param: In] set; }
}
[ComImport, Guid("0AD9D0D7-0C7F-4EBB-9A5F-D1C648DCA528"), InterfaceType(ComInterfaceType.InterfaceIsDual), System.Security.SuppressUnmanagedCodeSecurity]
internal interface ITaskSettings3 : ITaskSettings
{
new bool AllowDemandStart { get; [param: In] set; }
new string RestartInterval { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new int RestartCount { get; [param: In] set; }
new TaskInstancesPolicy MultipleInstances { get; [param: In] set; }
new bool StopIfGoingOnBatteries { get; [param: In] set; }
new bool DisallowStartIfOnBatteries { get; [param: In] set; }
new bool AllowHardTerminate { get; [param: In] set; }
new bool StartWhenAvailable { get; [param: In] set; }
new string XmlText { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new bool RunOnlyIfNetworkAvailable { get; [param: In] set; }
new string ExecutionTimeLimit { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new bool Enabled { get; [param: In] set; }
new string DeleteExpiredTaskAfter { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new int Priority { get; [param: In] set; }
new TaskCompatibility Compatibility { get; [param: In] set; }
new bool Hidden { get; [param: In] set; }
new IIdleSettings IdleSettings { [return: MarshalAs(UnmanagedType.Interface)] get; [param: In, MarshalAs(UnmanagedType.Interface)] set; }
new bool RunOnlyIfIdle { get; [param: In] set; }
new bool WakeToRun { get; [param: In] set; }
new INetworkSettings NetworkSettings { [return: MarshalAs(UnmanagedType.Interface)] get; [param: In, MarshalAs(UnmanagedType.Interface)] set; }
bool DisallowStartOnRemoteAppSession { get; [param: In] set; }
bool UseUnifiedSchedulingEngine { get; [param: In] set; }
IMaintenanceSettings MaintenanceSettings { [return: MarshalAs(UnmanagedType.Interface)] get; [param: In, MarshalAs(UnmanagedType.Interface)] set; }
[return: MarshalAs(UnmanagedType.Interface)]
IMaintenanceSettings CreateMaintenanceSettings();
bool Volatile { get; [param: In] set; }
}
[ComImport, Guid("A6024FA8-9652-4ADB-A6BF-5CFCD877A7BA"), InterfaceType(ComInterfaceType.InterfaceIsDual), System.Security.SuppressUnmanagedCodeSecurity]
internal interface IMaintenanceSettings
{
string Period { [param: In, MarshalAs(UnmanagedType.BStr)] set; [return: MarshalAs(UnmanagedType.BStr)] get; }
string Deadline { [param: In, MarshalAs(UnmanagedType.BStr)] set; [return: MarshalAs(UnmanagedType.BStr)] get; }
bool Exclusive { [param: In] set; get; }
}
[ComImport, Guid("B45747E0-EBA7-4276-9F29-85C5BB300006"), InterfaceType(ComInterfaceType.InterfaceIsDual), System.Security.SuppressUnmanagedCodeSecurity]
internal interface ITimeTrigger : ITrigger
{
new TaskTriggerType Type { get; }
new string Id { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new IRepetitionPattern Repetition { [return: MarshalAs(UnmanagedType.Interface)] get; [param: In, MarshalAs(UnmanagedType.Interface)] set; }
new string ExecutionTimeLimit { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new string StartBoundary { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new string EndBoundary { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new bool Enabled { get; [param: In] set; }
string RandomDelay { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
}
[ComImport, Guid("09941815-EA89-4B5B-89E0-2A773801FAC3"), InterfaceType(ComInterfaceType.InterfaceIsDual), System.Security.SuppressUnmanagedCodeSecurity]
internal interface ITrigger
{
TaskTriggerType Type { get; }
string Id { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
IRepetitionPattern Repetition { [return: MarshalAs(UnmanagedType.Interface)] get; [param: In, MarshalAs(UnmanagedType.Interface)] set; }
string ExecutionTimeLimit { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
string StartBoundary { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
string EndBoundary { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
bool Enabled { get; [param: In] set; }
}
[ComImport, Guid("85DF5081-1B24-4F32-878A-D9D14DF4CB77"), InterfaceType(ComInterfaceType.InterfaceIsDual), System.Security.SuppressUnmanagedCodeSecurity]
internal interface ITriggerCollection
{
int Count { get; }
ITrigger this[int index] { [return: MarshalAs(UnmanagedType.Interface)] get; }
[return: MarshalAs(UnmanagedType.Interface)]
IEnumerator GetEnumerator();
[return: MarshalAs(UnmanagedType.Interface)]
ITrigger Create([In] TaskTriggerType Type);
void Remove([In, MarshalAs(UnmanagedType.Struct)] object index);
void Clear();
}
[ComImport, Guid("5038FC98-82FF-436D-8728-A512A57C9DC1"), InterfaceType(ComInterfaceType.InterfaceIsDual), System.Security.SuppressUnmanagedCodeSecurity]
internal interface IWeeklyTrigger : ITrigger
{
new TaskTriggerType Type { get; }
new string Id { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new IRepetitionPattern Repetition { [return: MarshalAs(UnmanagedType.Interface)] get; [param: In, MarshalAs(UnmanagedType.Interface)] set; }
new string ExecutionTimeLimit { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new string StartBoundary { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new string EndBoundary { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
new bool Enabled { get; [param: In] set; }
short DaysOfWeek { get; [param: In] set; }
short WeeksInterval { get; [param: In] set; }
string RandomDelay { [return: MarshalAs(UnmanagedType.BStr)] get; [param: In, MarshalAs(UnmanagedType.BStr)] set; }
}
}

View File

@ -0,0 +1,37 @@
using System.Text.RegularExpressions;
using JetBrains.Annotations;
namespace Microsoft.Win32.TaskScheduler
{
/// <summary>
/// Represents a wildcard running on the
/// <see cref="System.Text.RegularExpressions"/> engine.
/// </summary>
public class Wildcard : Regex
{
/// <summary>
/// Initializes a wildcard with the given search pattern and options.
/// </summary>
/// <param name="pattern">The wildcard pattern to match.</param>
/// <param name="options">A combination of one or more <see cref="System.Text.RegularExpressions.RegexOptions"/>.</param>
public Wildcard([NotNull] string pattern, RegexOptions options = RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace)
: base(WildcardToRegex(pattern), options)
{
}
/// <summary>
/// Converts a wildcard to a regular expression.
/// </summary>
/// <param name="pattern">The wildcard pattern to convert.</param>
/// <returns>A regular expression equivalent of the given wildcard.</returns>
public static string WildcardToRegex([NotNull] string pattern)
{
string s = Regex.Escape(pattern);
s = Regex.Replace(s, @"(?<!\\)\\\*", @".*"); // Negative Lookbehind
s = Regex.Replace(s, @"\\\\\\\*", @"\*");
s = Regex.Replace(s, @"(?<!\\)\\\?", @"."); // Negative Lookbehind
s = Regex.Replace(s, @"\\\\\\\?", @"\?");
return string.Concat("^", Regex.Replace(s, @"\\\\\\\\", @"\\"), "$");
}
}
}

View File

@ -0,0 +1,526 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using JetBrains.Annotations;
namespace Microsoft.Win32.TaskScheduler
{
internal static class XmlSerializationHelper
{
public static object GetDefaultValue([NotNull] PropertyInfo prop)
{
var attributes = prop.GetCustomAttributes(typeof(DefaultValueAttribute), true);
if (attributes.Length > 0)
{
var defaultAttr = (DefaultValueAttribute)attributes[0];
return defaultAttr.Value;
}
// Attribute not found, fall back to default value for the type
if (prop.PropertyType.IsValueType)
return Activator.CreateInstance(prop.PropertyType);
return null;
}
private static bool GetPropertyValue(object obj, [NotNull] string property, ref object outVal)
{
PropertyInfo pi = obj?.GetType().GetProperty(property);
if (pi != null)
{
outVal = pi.GetValue(obj, null);
return true;
}
return false;
}
private static bool GetAttributeValue(Type objType, Type attrType, string property, bool inherit, ref object outVal)
{
object[] attrs = objType.GetCustomAttributes(attrType, inherit);
if (attrs.Length > 0)
return GetPropertyValue(attrs[0], property, ref outVal);
return false;
}
private static bool GetAttributeValue([NotNull] PropertyInfo propInfo, Type attrType, string property, bool inherit, ref object outVal)
{
Attribute attr = Attribute.GetCustomAttribute(propInfo, attrType, inherit);
return GetPropertyValue(attr, property, ref outVal);
}
private static bool IsStandardType(Type type) => type.IsPrimitive || type == typeof(DateTime) || type == typeof(DateTimeOffset) || type == typeof(Decimal) || type == typeof(Guid) || type == typeof(TimeSpan) || type == typeof(string) || type.IsEnum;
private static bool HasMembers([NotNull] object obj)
{
if (obj is IXmlSerializable)
{
using (System.IO.MemoryStream mem = new System.IO.MemoryStream())
{
using (XmlTextWriter tw = new XmlTextWriter(mem, Encoding.UTF8))
{
((IXmlSerializable)obj).WriteXml(tw);
tw.Flush();
return mem.Length > 3;
}
}
}
// Enumerate each public property
PropertyInfo[] props = obj.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);
foreach (var pi in props)
{
if (!Attribute.IsDefined(pi, typeof(XmlIgnoreAttribute), false))
{
object value = pi.GetValue(obj, null);
if (!Equals(value, GetDefaultValue(pi)))
{
if (!IsStandardType(pi.PropertyType))
{
if (HasMembers(value))
return true;
}
else
return true;
}
}
}
return false;
}
public static string GetPropertyAttributeName([NotNull] PropertyInfo pi)
{
object oVal = null;
string eName = pi.Name;
if (GetAttributeValue(pi, typeof(XmlAttributeAttribute), "AttributeName", false, ref oVal))
eName = oVal.ToString();
return eName;
}
public static string GetPropertyElementName([NotNull] PropertyInfo pi)
{
object oVal = null;
string eName = pi.Name;
if (GetAttributeValue(pi, typeof(XmlElementAttribute), "ElementName", false, ref oVal))
eName = oVal.ToString();
else if (GetAttributeValue(pi.PropertyType, typeof(XmlRootAttribute), "ElementName", true, ref oVal))
eName = oVal.ToString();
return eName;
}
public delegate bool PropertyConversionHandler([NotNull] PropertyInfo pi, Object obj, ref Object value);
public static bool WriteProperty([NotNull] XmlWriter writer, [NotNull] PropertyInfo pi, [NotNull] Object obj, PropertyConversionHandler handler = null)
{
if (Attribute.IsDefined(pi, typeof(XmlIgnoreAttribute), false) || Attribute.IsDefined(pi, typeof(XmlAttributeAttribute), false))
return false;
object value = pi.GetValue(obj, null);
object defValue = GetDefaultValue(pi);
if ((value == null && defValue == null) || (value != null && value.Equals(defValue)))
return false;
Type propType = pi.PropertyType;
if (handler != null && handler(pi, obj, ref value))
propType = value.GetType();
bool isStdType = IsStandardType(propType);
bool rw = pi.CanRead && pi.CanWrite;
bool ro = pi.CanRead && !pi.CanWrite;
string eName = GetPropertyElementName(pi);
if (isStdType && rw)
{
string output = GetXmlValue(value, propType);
if (output != null)
writer.WriteElementString(eName, output);
}
else if (!isStdType)
{
object outVal = null;
if (propType.GetInterface("IXmlSerializable") == null && GetAttributeValue(pi, typeof(XmlArrayAttribute), "ElementName", true, ref outVal) && propType.GetInterface("IEnumerable") != null)
{
if (string.IsNullOrEmpty(outVal.ToString())) outVal = eName;
writer.WriteStartElement(outVal.ToString());
var attributes = Attribute.GetCustomAttributes(pi, typeof(XmlArrayItemAttribute), true);
var dict = new Dictionary<Type, string>(attributes.Length);
foreach (XmlArrayItemAttribute a in attributes)
dict.Add(a.Type, a.ElementName);
foreach (object item in ((System.Collections.IEnumerable)value))
{
string aeName;
Type itemType = item.GetType();
if (dict.TryGetValue(itemType, out aeName))
{
if (IsStandardType(itemType))
writer.WriteElementString(aeName, GetXmlValue(item, itemType));
else
WriteObject(writer, item, null, false, aeName);
}
}
writer.WriteEndElement();
}
else
WriteObject(writer, value);
}
return false;
}
private static string GetXmlValue([NotNull] object value, Type propType)
{
string output = null;
if (propType.IsEnum)
{
if (Attribute.IsDefined(propType, typeof(FlagsAttribute), false))
output = Convert.ChangeType(value, Enum.GetUnderlyingType(propType)).ToString();
else
output = value.ToString();
}
else
{
switch (propType.FullName)
{
case "System.Boolean":
output = XmlConvert.ToString((System.Boolean)value);
break;
case "System.Byte":
output = XmlConvert.ToString((System.Byte)value);
break;
case "System.Char":
output = XmlConvert.ToString((System.Char)value);
break;
case "System.DateTime":
output = XmlConvert.ToString((System.DateTime)value, XmlDateTimeSerializationMode.RoundtripKind);
break;
case "System.DateTimeOffset":
output = XmlConvert.ToString((System.DateTimeOffset)value);
break;
case "System.Decimal":
output = XmlConvert.ToString((System.Decimal)value);
break;
case "System.Double":
output = XmlConvert.ToString((System.Double)value);
break;
case "System.Single":
output = XmlConvert.ToString((System.Single)value);
break;
case "System.Guid":
output = XmlConvert.ToString((System.Guid)value);
break;
case "System.Int16":
output = XmlConvert.ToString((System.Int16)value);
break;
case "System.Int32":
output = XmlConvert.ToString((System.Int32)value);
break;
case "System.Int64":
output = XmlConvert.ToString((System.Int64)value);
break;
case "System.SByte":
output = XmlConvert.ToString((System.SByte)value);
break;
case "System.TimeSpan":
output = XmlConvert.ToString((System.TimeSpan)value);
break;
case "System.UInt16":
output = XmlConvert.ToString((System.UInt16)value);
break;
case "System.UInt32":
output = XmlConvert.ToString((System.UInt32)value);
break;
case "System.UInt64":
output = XmlConvert.ToString((System.UInt64)value);
break;
default:
output = value == null ? string.Empty : value.ToString();
break;
}
}
return output;
}
public static void WriteObjectAttributes([NotNull] XmlWriter writer, [NotNull] object obj, PropertyConversionHandler handler = null)
{
// Enumerate each property
foreach (var pi in obj.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public))
if (Attribute.IsDefined(pi, typeof(XmlAttributeAttribute), false))
WriteObjectAttribute(writer, pi, obj, handler);
}
public static void WriteObjectAttribute([NotNull] XmlWriter writer, [NotNull] PropertyInfo pi, [NotNull] object obj, PropertyConversionHandler handler = null)
{
object value = pi.GetValue(obj, null);
object defValue = GetDefaultValue(pi);
if ((value == null && defValue == null) || (value != null && value.Equals(defValue)))
return;
Type propType = pi.PropertyType;
if (handler != null && handler(pi, obj, ref value))
propType = value.GetType();
writer.WriteAttributeString(GetPropertyAttributeName(pi), GetXmlValue(value, propType));
}
public static void WriteObjectProperties([NotNull] XmlWriter writer, [NotNull] object obj, PropertyConversionHandler handler = null)
{
// Enumerate each public property
foreach (var pi in obj.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public))
WriteProperty(writer, pi, obj, handler);
}
public static void WriteObject([NotNull] XmlWriter writer, [NotNull] object obj, PropertyConversionHandler handler = null, bool includeNS = false, string elemName = null)
{
if (obj == null)
return;
// Get name of top level element
string oName = elemName ?? GetElementName(obj);
if (!HasMembers(obj))
return;
if (includeNS)
writer.WriteStartElement(oName, GetTopLevelNamespace(obj));
else
writer.WriteStartElement(oName);
if (obj is IXmlSerializable)
{
((IXmlSerializable)obj).WriteXml(writer);
}
else
{
WriteObjectAttributes(writer, obj, handler);
WriteObjectProperties(writer, obj, handler);
}
writer.WriteEndElement();
}
public static string GetElementName([NotNull] object obj)
{
object oVal = null;
return GetAttributeValue(obj.GetType(), typeof(XmlRootAttribute), "ElementName", true, ref oVal) ? oVal.ToString() : obj.GetType().Name;
}
public static string GetTopLevelNamespace([NotNull] object obj)
{
object oVal = null;
return GetAttributeValue(obj.GetType(), typeof(XmlRootAttribute), "Namespace", true, ref oVal) ? oVal.ToString() : null;
}
public static void ReadObjectProperties([NotNull] XmlReader reader, [NotNull] object obj, PropertyConversionHandler handler = null)
{
// Build property lookup table
PropertyInfo[] props = obj.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);
Dictionary<string, PropertyInfo> attrHash = new Dictionary<string, PropertyInfo>(props.Length);
Dictionary<string, PropertyInfo> propHash = new Dictionary<string, PropertyInfo>(props.Length);
foreach (var pi in props)
{
if (!Attribute.IsDefined(pi, typeof(XmlIgnoreAttribute), false))
{
if (Attribute.IsDefined(pi, typeof(XmlAttributeAttribute), false))
attrHash.Add(GetPropertyAttributeName(pi), pi);
else
propHash.Add(GetPropertyElementName(pi), pi);
}
}
if (reader.HasAttributes)
{
for (int i = 0; i < reader.AttributeCount; i++)
{
PropertyInfo pi;
reader.MoveToAttribute(i);
if (attrHash.TryGetValue(reader.LocalName, out pi))
{
if (IsStandardType(pi.PropertyType))
{
object value = null;
if (pi.PropertyType.IsEnum)
value = Enum.Parse(pi.PropertyType, reader.Value);
else
value = Convert.ChangeType(reader.Value, pi.PropertyType);
if (handler != null)
handler(pi, obj, ref value);
pi.SetValue(obj, value, null);
}
}
}
}
while (reader.MoveToContent() == XmlNodeType.Element)
{
PropertyInfo pi;
object outVal = null;
if (propHash.TryGetValue(reader.LocalName, out pi))
{
var tc = TypeDescriptor.GetConverter(pi.PropertyType);
if (IsStandardType(pi.PropertyType))
{
object value = null;
if (pi.PropertyType.IsEnum)
value = Enum.Parse(pi.PropertyType, reader.ReadElementContentAsString());
else if (pi.PropertyType == typeof(Guid))
value = new GuidConverter().ConvertFromString(reader.ReadElementContentAsString());
else
value = reader.ReadElementContentAs(pi.PropertyType, null);
if (handler != null)
handler(pi, obj, ref value);
pi.SetValue(obj, value, null);
}
else if (pi.PropertyType == typeof(Version))
{
Version v = new Version(reader.ReadElementContentAsString());
pi.SetValue(obj, v, null);
}
else if (pi.PropertyType.GetInterface("IEnumerable") != null && pi.PropertyType.GetInterface("IXmlSerializable") == null && GetAttributeValue(pi, typeof(XmlArrayAttribute), "ElementName", true, ref outVal))
{
string elem = string.IsNullOrEmpty(outVal?.ToString()) ? pi.Name : outVal.ToString();
reader.ReadStartElement(elem);
var attributes = Attribute.GetCustomAttributes(pi, typeof(XmlArrayItemAttribute), true);
var dict = new Dictionary<string, Type>(attributes.Length);
foreach (XmlArrayItemAttribute a in attributes)
dict.Add(a.ElementName, a.Type);
List<object> output = new List<object>();
while (reader.MoveToContent() == XmlNodeType.Element)
{
Type itemType;
if (dict.TryGetValue(reader.LocalName, out itemType))
{
object o;
if (IsStandardType(itemType))
o = reader.ReadElementContentAs(itemType, null);
else
{
o = Activator.CreateInstance(itemType);
ReadObject(reader, o, handler);
}
if (o != null)
output.Add(o);
}
}
reader.ReadEndElement();
if (output.Count > 0)
{
System.Collections.IEnumerable par = output;
Type et = typeof(object);
if (dict.Count == 1)
{
foreach (var v in dict.Values) { et = v; break; }
}
/*else
{
Type t1 = output[0].GetType();
bool same = true;
foreach (var item in output)
if (item.GetType() != t1) { same = false; break; }
if (same)
et = t1;
}
if (et != typeof(object))
{
Array ao = Array.CreateInstance(et, output.Count);
for (int i = 0; i < output.Count; i++)
ao.SetValue(output[i], i);
par = ao;
}
else
par = output.ToArray();*/
bool done = false;
if (pi.PropertyType == par.GetType() || (pi.PropertyType.IsArray && (pi.PropertyType.GetElementType() == typeof(object) || pi.PropertyType.GetElementType() == et)))
try { pi.SetValue(obj, par, null); done = true; } catch { }
if (!done)
{
var mi = pi.PropertyType.GetMethod("AddRange", new Type[] { typeof(System.Collections.IEnumerable) });
if (mi != null)
try { mi.Invoke(pi.GetValue(obj, null), new object[] { par }); done = true; } catch { }
}
if (!done)
{
var mi = pi.PropertyType.GetMethod("Add", new Type[] { typeof(object) });
if (mi != null)
try { foreach (var i in par) mi.Invoke(pi.GetValue(obj, null), new object[] { i }); done = true; } catch { }
}
if (!done && et != typeof(Object))
{
var mi = pi.PropertyType.GetMethod("Add", new Type[] { et });
if (mi != null)
try { foreach (var i in par) mi.Invoke(pi.GetValue(obj, null), new object[] { i }); done = true; } catch { }
}
// Throw error if not done
}
}
else
{
object inst = pi.GetValue(obj, null) ?? Activator.CreateInstance(pi.PropertyType);
if (inst == null)
throw new InvalidOperationException($"Can't get instance of {pi.PropertyType.Name}.");
ReadObject(reader, inst, handler);
}
}
else
{
reader.Skip();
reader.MoveToContent();
}
}
}
public static void ReadObject([NotNull] XmlReader reader, [NotNull] object obj, PropertyConversionHandler handler = null)
{
if (obj == null)
throw new ArgumentNullException(nameof(obj));
reader.MoveToContent();
if (obj is IXmlSerializable)
{
((IXmlSerializable)obj).ReadXml(reader);
}
else
{
object oVal = null;
string oName = GetAttributeValue(obj.GetType(), typeof(XmlRootAttribute), "ElementName", true, ref oVal) ? oVal.ToString() : obj.GetType().Name;
if (reader.LocalName != oName)
throw new XmlException("XML element name does not match object.");
if (!reader.IsEmptyElement)
{
reader.ReadStartElement();
reader.MoveToContent();
ReadObjectProperties(reader, obj, handler);
reader.ReadEndElement();
}
else
reader.Skip();
}
}
public static void ReadObjectFromXmlText([NotNull] string xml, [NotNull] object obj, PropertyConversionHandler handler = null)
{
using (System.IO.StringReader sr = new System.IO.StringReader(xml))
{
using (XmlReader reader = XmlReader.Create(sr))
{
reader.MoveToContent();
ReadObject(reader, obj, handler);
}
}
}
public static string WriteObjectToXmlText([NotNull] object obj, PropertyConversionHandler handler = null)
{
StringBuilder sb = new StringBuilder();
using (XmlWriter writer = XmlWriter.Create(sb, new XmlWriterSettings() { Indent = true }))
WriteObject(writer, obj, handler, true);
return sb.ToString();
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -8,19 +8,12 @@
<input>
<loadpaths />
<asmlist>
<inputassembly refid="fff711fa-8d12-4b5f-b305-4ab8c99fe3b7">
<inputassembly refid="3405f3ce-f41d-4c64-bcb7-fed2e75c472a">
<option>honoroas</option>
<option>stripoa</option>
<option>library</option>
<option>transformxaml</option>
<file dir="D:\Users\cpolo\Downloads\privilege-escalation-awesome-scripts-suite-master\winPEAS\winPEASexe\winPEAS\bin\x86\Release" name="Microsoft.Win32.TaskScheduler.dll" />
</inputassembly>
<inputassembly refid="3ff1e92f-2dff-4435-8a92-71982586f013">
<option>honoroas</option>
<option>stripoa</option>
<option>library</option>
<option>transformxaml</option>
<file dir="D:\Users\cpolo\Downloads\privilege-escalation-awesome-scripts-suite-master\winPEAS\winPEASexe\winPEAS\bin\x86\Release" name="winPEAS.exe" />
<file dir="D:\Users\cpolo\Downloads\privilege-escalation-awesome-scripts-suite-master (1) - cambiado\privilege-escalation-awesome-scripts-suite-master\winPEAS\winPEASexe\winPEAS\bin\x86\Release" name="winPEAS.exe" />
</inputassembly>
</asmlist>
</input>

Some files were not shown because too many files have changed in this diff Show More