Skip to content

Commit ef131e3

Browse files
committed
Added the function to get listed packages for #18 (Reading pin information does not work correctly)
1 parent 7a03caa commit ef131e3

6 files changed

Lines changed: 383 additions & 0 deletions

File tree

src/WGet.NET/Components/WinGetPackageManager.cs

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ public class WinGetPackageManager : WinGetInfo
3131
private const string _importCmd = "import -i {0} --ignore-unavailable";
3232
private const string _hashCmd = "hash {0}";
3333
private const string _downloadCmd = "download {0} --download-directory {1}";
34+
private const string _pinListCmd = "pin list";
3435
private const string _pinAddCmd = "pin add \"{0}\"";
3536
private const string _pinAddByVersionCmd = "pin add \"{0}\" --version \"{1}\"";
3637
private const string _pinRemoveCmd = "pin remove \"{0}\"";
@@ -1612,6 +1613,88 @@ public async Task<bool> DownloadAsync(WinGetPackage package, DirectoryInfo direc
16121613
}
16131614
//---------------------------------------------------------------------------------------------
16141615

1616+
//---Pin List----------------------------------------------------------------------------------
1617+
/// <summary>
1618+
/// Gets a list of all pinned packages.
1619+
/// </summary>
1620+
/// <returns>
1621+
/// A <see cref="System.Collections.Generic.List{T}"/> of <see cref="WGetNET.WinGetPackage"/> instances.
1622+
/// </returns>
1623+
/// <exception cref="WGetNET.WinGetNotInstalledException">
1624+
/// WinGet is not installed or not found on the system.
1625+
/// </exception>
1626+
/// <exception cref="WGetNET.WinGetActionFailedException">
1627+
/// The current action failed for an unexpected reason.
1628+
/// Please see inner exception.
1629+
/// </exception>
1630+
/// <exception cref="WGetNET.WinGetFeatureNotSupportedException">
1631+
/// This feature is not supported in the installed WinGet version.
1632+
/// </exception>
1633+
public List<WinGetPinnedPackage> GetPinnedPackages()
1634+
{
1635+
if (!WinGetVersionIsMatchOrAbove(1, 5))
1636+
{
1637+
throw new WinGetFeatureNotSupportedException("1.5");
1638+
}
1639+
1640+
try
1641+
{
1642+
ProcessResult result =
1643+
_processManager.ExecuteWingetProcess(_pinListCmd);
1644+
1645+
return ProcessOutputReader.ToPinnedPackageList(result.Output);
1646+
}
1647+
catch (Win32Exception)
1648+
{
1649+
throw new WinGetNotInstalledException();
1650+
}
1651+
catch (Exception e)
1652+
{
1653+
throw new WinGetActionFailedException("Listing all pinned packages failed.", e);
1654+
}
1655+
}
1656+
1657+
/// <summary>
1658+
/// Asynchronously gets a list of all pinned packages.
1659+
/// </summary>
1660+
/// <returns>
1661+
/// A <see cref="System.Collections.Generic.List{T}"/> of <see cref="WGetNET.WinGetPackage"/> instances.
1662+
/// </returns>
1663+
/// <exception cref="WGetNET.WinGetNotInstalledException">
1664+
/// WinGet is not installed or not found on the system.
1665+
/// </exception>
1666+
/// <exception cref="WGetNET.WinGetActionFailedException">
1667+
/// The current action failed for an unexpected reason.
1668+
/// Please see inner exception.
1669+
/// </exception>
1670+
/// <exception cref="WGetNET.WinGetFeatureNotSupportedException">
1671+
/// This feature is not supported in the installed WinGet version.
1672+
/// </exception>
1673+
public async Task<List<WinGetPinnedPackage>> GetPinnedPackagesAsync()
1674+
{
1675+
if (!WinGetVersionIsMatchOrAbove(1, 5))
1676+
{
1677+
throw new WinGetFeatureNotSupportedException("1.5");
1678+
}
1679+
1680+
try
1681+
{
1682+
ProcessResult result =
1683+
await _processManager.ExecuteWingetProcessAsync(_pinListCmd);
1684+
1685+
return ProcessOutputReader.ToPinnedPackageList(result.Output);
1686+
}
1687+
catch (Win32Exception)
1688+
{
1689+
throw new WinGetNotInstalledException();
1690+
}
1691+
catch (Exception e)
1692+
{
1693+
throw new WinGetActionFailedException("Listing all pinned packages failed.", e);
1694+
}
1695+
}
1696+
//---------------------------------------------------------------------------------------------
1697+
16151698
//---Pin Add-----------------------------------------------------------------------------------
16161699
/// <summary>
16171700
/// Adds a pinned package to winget.

src/WGet.NET/Enums/PinType.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//--------------------------------------------------//
2+
// Created by basicx-StrgV //
3+
// https://github.com/basicx-StrgV/ //
4+
//--------------------------------------------------//
5+
namespace WGetNET
6+
{
7+
public enum PinType
8+
{
9+
Pinning,
10+
Blocking,
11+
Gating
12+
}
13+
}

src/WGet.NET/HelperClasses/ProcessOutputReader.cs

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,133 @@ private static List<WinGetPackage> CreatePackageListFromOutput(string[] output,
185185
return resultList;
186186
}
187187

188+
/// <summary>
189+
/// Converts a <see cref="System.Collections.Generic.List{T}"/>
190+
/// of output lines from a winget process to a list of <see cref="WGetNET.WinGetPinnedPackage"/>'s.
191+
/// </summary>
192+
/// <param name="output">
193+
/// A <see cref="System.Collections.Generic.List{T}"/> of output lines from a winget process.
194+
/// </param>
195+
/// <returns>
196+
/// A <see cref="System.Collections.Generic.List{T}"/> of <see cref="WGetNET.WinGetPinnedPackage"/>'s.
197+
/// </returns>
198+
public static List<WinGetPinnedPackage> ToPinnedPackageList(string[] output)
199+
{
200+
//Get top line index.
201+
//The array should always contain this line.
202+
//If it dose not contain this line the resulting out of range exception,
203+
//that will be thrown later, will be catched in the calling method.
204+
int labelLine = ArrayManager.GetEntryContains(output, "------") - 1;
205+
206+
int[] columnList = GetColumnList(output[labelLine]);
207+
208+
//Remove unneeded output Lines
209+
output = ArrayManager.RemoveRange(output, 0, labelLine + 2);
210+
211+
return CreatePinnedPackageListFromOutput(output, columnList);
212+
}
213+
214+
/// <summary>
215+
/// Creates a pinned package list from output.
216+
/// </summary>
217+
/// <param name="output">
218+
/// The <see langword="array"/> containing the output.
219+
/// </param>
220+
/// <param name="columnList">
221+
/// A <see cref="System.Int32"/> <see langword="array"/> containing the column start indexes.
222+
/// </param>
223+
/// <returns>
224+
/// A <see cref="System.Collections.Generic.List{T}"/> of <see cref="WGetNET.WinGetPinnedPackage"/>'s.
225+
/// </returns>
226+
private static List<WinGetPinnedPackage> CreatePinnedPackageListFromOutput(string[] output, int[] columnList)
227+
{
228+
List<WinGetPinnedPackage> resultList = new();
229+
230+
if (columnList.Length < 3)
231+
{
232+
return resultList;
233+
}
234+
235+
for (int i = 0; i < output.Length; i++)
236+
{
237+
// Stop parsing the output when the end of the list is reached.
238+
#if NETCOREAPP3_1_OR_GREATER
239+
if (string.IsNullOrWhiteSpace(output[i]) || output[i].Length < columnList[^1])
240+
{
241+
break;
242+
}
243+
#elif NETSTANDARD2_0
244+
if (string.IsNullOrWhiteSpace(output[i]) || output[i].Length < columnList[columnList.Length-1])
245+
{
246+
break;
247+
}
248+
#endif
249+
250+
#if NETCOREAPP3_1_OR_GREATER
251+
string packageName = output[i][columnList[0]..columnList[1]].Trim();
252+
string packageId = output[i][columnList[1]..columnList[2]].Trim();
253+
string packageVersion = output[i][columnList[2]..columnList[3]].Trim();
254+
string packageSource = output[i][columnList[3]..columnList[4]].Trim();
255+
string pinType = string.Empty;
256+
string pinnedVersion = string.Empty;
257+
if (columnList.Length > 5)
258+
{
259+
pinType = output[i][columnList[4]..columnList[5]].Trim();
260+
pinnedVersion = output[i][columnList[5]..].Trim();
261+
}
262+
else
263+
{
264+
pinType = output[i][columnList[4]..].Trim();
265+
}
266+
#elif NETSTANDARD2_0
267+
string packageName = output[i].Substring(columnList[0], (columnList[1] - columnList[0])).Trim();
268+
string packageId = output[i].Substring(columnList[1], (columnList[2] - columnList[1])).Trim();
269+
string packageVersion = output[i].Substring(columnList[2], (columnList[3] - columnList[2])).Trim();
270+
string packageSource = output[i].Substring(columnList[3], (columnList[4] - columnList[3])).Trim();
271+
string pinType = string.Empty;
272+
string pinnedVersion = string.Empty;
273+
if (columnList.Length > 5)
274+
{
275+
pinType = output[i].Substring(columnList[4], (columnList[5] - columnList[4])).Trim();
276+
pinnedVersion = output[i].Substring(columnList[5]).Trim();
277+
}
278+
else
279+
{
280+
pinType = output[i].Substring(columnList[4]).Trim();
281+
}
282+
#endif
283+
284+
// Check if the id is shortened
285+
bool isShortenedId = CheckShortenedId(packageId);
286+
if (isShortenedId)
287+
{
288+
// Remove the char at the end of the shortened id.
289+
packageId = packageId.Remove(packageId.Length - 1);
290+
}
291+
292+
WinGetPinnedPackage package = new(pinType, pinnedVersion, isShortenedId)
293+
{
294+
Name = packageName,
295+
Id = packageId,
296+
Version = packageVersion,
297+
AvailableVersion = packageVersion,
298+
SourceName = packageSource,
299+
};
300+
301+
302+
resultList.Add(package);
303+
}
304+
305+
// Check for secondery list in output.
306+
if (ArrayManager.GetEntryContains(output, "------") != -1)
307+
{
308+
List<WinGetPinnedPackage> seconderyList = ToPinnedPackageList(output);
309+
resultList.AddRange(seconderyList);
310+
}
311+
312+
return resultList;
313+
}
314+
188315
/// <summary>
189316
/// Converts a <see cref="System.Collections.Generic.List{T}"/>
190317
/// of output lines from a winget process to a list of <see cref="WGetNET.WinGetSource"/>'s.
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
//--------------------------------------------------//
2+
// Created by basicx-StrgV //
3+
// https://github.com/basicx-StrgV/ //
4+
//--------------------------------------------------//
5+
namespace WGetNET
6+
{
7+
/// <summary>
8+
/// Represents a winget pinned package
9+
/// </summary>
10+
public class WinGetPinnedPackage: WinGetPackage
11+
{
12+
/// <summary>
13+
/// Gets the pin type of the package as a <see cref="System.String"/>.
14+
/// </summary>
15+
public string PinTypeString
16+
{
17+
get
18+
{
19+
return _pinTypeString;
20+
}
21+
}
22+
23+
/// <summary>
24+
/// Gets the pinned version as a <see cref="System.String"/>.
25+
/// </summary>
26+
public string PinnedVersion
27+
{
28+
get
29+
{
30+
return _pinnedVersion;
31+
}
32+
}
33+
34+
/// <summary>
35+
/// Gets the pin type of the package.
36+
/// </summary>
37+
public PinType PinType
38+
{
39+
get
40+
{
41+
return _pinType;
42+
}
43+
}
44+
45+
private readonly string _pinTypeString;
46+
private readonly string _pinnedVersion;
47+
private readonly PinType _pinType;
48+
49+
/// <summary>
50+
/// Initializes a new instance of the <see cref="WGetNET.WinGetPinnedPackage"/> class.
51+
/// </summary>
52+
/// <param name="hasShortenedId">Sets if the id is shortened or not</param>
53+
internal WinGetPinnedPackage(string pinType, string pinnedVersion, bool hasShortenedId): base(hasShortenedId)
54+
{
55+
_pinTypeString = pinType;
56+
_pinnedVersion = pinnedVersion;
57+
58+
_pinType = _pinTypeString.ToUpper() switch
59+
{
60+
"PINNING" => PinType.Pinning,
61+
"BLOCKING" => PinType.Blocking,
62+
"GATING" => PinType.Gating,
63+
_ => PinType.Pinning,
64+
};
65+
}
66+
}
67+
}

0 commit comments

Comments
 (0)