Skip to content

Commit 0d92cf1

Browse files
committed
Expose IsRebootRequired property
1 parent c021cdb commit 0d92cf1

File tree

8 files changed

+62
-12
lines changed

8 files changed

+62
-12
lines changed

docker/Tests/vswhere.tests.ps1

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,15 @@ Describe 'vswhere' {
103103
$instances = [xml](C:\bin\vswhere.exe -all -format xml)
104104
$instances.instances.instance.Count | Should Be 3
105105
}
106+
107+
It 'returns 1 instance where IsRebootRequired' {
108+
# Make sure PowerShell converts to a collection of PSCustomObjects before filtering.
109+
$instances = C:\bin\vswhere.exe -all -format json | ConvertFrom-Json
110+
111+
$instances = @($instances | Where-Object { $_.IsRebootRequired })
112+
$instances.Count | Should Be 1
113+
$instances[0].instanceId | Should Be 3
114+
}
106115
}
107116

108117
Context '-products' {

src/vswhere.lib/Formatter.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ Formatter::Formatter()
2525
{ L"isComplete", bind(&Formatter::GetIsComplete, this, _1, _2) },
2626
{ L"isLaunchable", bind(&Formatter::GetIsLaunchable, this, _1, _2) },
2727
{ L"isPrerelease", bind(&Formatter::GetIsPrerelease, this, _1, _2) },
28+
{ L"isRebootRequired", bind(&Formatter::GetIsRebootRequired, this, _1, _2) },
2829
{ L"displayName", bind(&Formatter::GetDisplayName, this, _1, _2) },
2930
{ L"description", bind(&Formatter::GetDescription, this, _1, _2) },
3031
};
@@ -532,6 +533,29 @@ HRESULT Formatter::GetIsPrerelease(_In_ ISetupInstance* pInstance, _Out_ VARIANT
532533
return hr;
533534
}
534535

536+
HRESULT Formatter::GetIsRebootRequired(_In_ ISetupInstance* pInstance, _Out_ VARIANT* pvtIsRebootRequired)
537+
{
538+
ISetupInstance2Ptr instance;
539+
variant_t vt;
540+
541+
auto hr = pInstance->QueryInterface(&instance);
542+
if (SUCCEEDED(hr))
543+
{
544+
auto state = InstanceState::eNone;
545+
546+
hr = instance->GetState(&state);
547+
if (SUCCEEDED(hr))
548+
{
549+
vt.vt = VT_BOOL;
550+
vt.boolVal = (state & InstanceState::eNoRebootRequired) == 0 ? VARIANT_TRUE : VARIANT_FALSE;
551+
552+
*pvtIsRebootRequired = vt.Detach();
553+
}
554+
}
555+
556+
return hr;
557+
}
558+
535559
HRESULT Formatter::GetDisplayName(_In_ ISetupInstance* pInstance, _Out_ VARIANT* pvtDisplayName)
536560
{
537561
auto lcid = ::GetUserDefaultLCID();

src/vswhere.lib/Formatter.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ class Formatter
7575
HRESULT GetIsComplete(_In_ ISetupInstance* pInstance, _Out_ VARIANT* pvtIsComplete);
7676
HRESULT GetIsLaunchable(_In_ ISetupInstance* pInstance, _Out_ VARIANT* pvtIsLaunchable);
7777
HRESULT GetIsPrerelease(_In_ ISetupInstance* pInstance, _Out_ VARIANT* pvtIsPrerelease);
78+
HRESULT GetIsRebootRequired(_In_ ISetupInstance* pInstance, _Out_ VARIANT* pvtIsRebootRequired);
7879
HRESULT GetDisplayName(_In_ ISetupInstance* pInstance, _Out_ VARIANT* pvtDisplayName);
7980
HRESULT GetDescription(_In_ ISetupInstance* pInstance, _Out_ VARIANT* pvtDescription);
8081

test/vswhere.test/JsonFormatterTests.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,8 @@ TEST_CLASS(JsonFormatterTests)
443443
L" \"instanceId\": \"a1b2c3\",\n"
444444
L" \"state\": 11,\n"
445445
L" \"isComplete\": true,\n"
446-
L" \"isLaunchable\": false\n"
446+
L" \"isLaunchable\": false,\n"
447+
L" \"isRebootRequired\": true\n"
447448
L" }\n"
448449
L"]\n";
449450

@@ -474,7 +475,8 @@ TEST_CLASS(JsonFormatterTests)
474475
L" \"instanceId\": \"a1b2c3\",\n"
475476
L" \"state\": 4294967295,\n"
476477
L" \"isComplete\": true,\n"
477-
L" \"isLaunchable\": true\n"
478+
L" \"isLaunchable\": true,\n"
479+
L" \"isRebootRequired\": false\n"
478480
L" }\n"
479481
L"]\n";
480482

test/vswhere.test/TestInstance.h

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class TestInstance :
1717
m_properties(list.begin(), list.end()),
1818
m_ulRef(1)
1919
{
20+
m_locale = ::_wcreate_locale(LC_ALL, L"en-US");
2021
}
2122

2223
TestInstance(
@@ -27,6 +28,8 @@ class TestInstance :
2728
m_properties(properties),
2829
m_ulRef(1)
2930
{
31+
m_locale = ::_wcreate_locale(LC_ALL, L"en-US");
32+
3033
for (const auto package : packages)
3134
{
3235
m_packages.push_back(package);
@@ -35,6 +38,10 @@ class TestInstance :
3538

3639
~TestInstance()
3740
{
41+
if (m_locale)
42+
{
43+
::_free_locale(m_locale);
44+
}
3845
}
3946

4047
// IUnknown
@@ -191,7 +198,7 @@ class TestInstance :
191198
_Out_ InstanceState* pState
192199
)
193200
{
194-
return TryGetLONGLONG(L"State", reinterpret_cast<PLONGLONG>(pState));
201+
return TryGetULONG(L"State", reinterpret_cast<PULONG>(pState));
195202
}
196203

197204
STDMETHODIMP GetPackages(
@@ -414,9 +421,9 @@ class TestInstance :
414421
return hr;
415422
}
416423

417-
STDMETHODIMP TryGetLONGLONG(_In_ LPCWSTR wszName, _Out_ PLONGLONG pll)
424+
STDMETHODIMP TryGetULONG(_In_ LPCWSTR wszName, _Out_ PULONG pul)
418425
{
419-
if (!pll)
426+
if (!pul)
420427
{
421428
return E_POINTER;
422429
}
@@ -426,10 +433,10 @@ class TestInstance :
426433
auto hr = TryGet(wszName, value);
427434
if (SUCCEEDED(hr))
428435
{
429-
*pll = _wtoi64(value.c_str());
430-
if (*pll == 0)
436+
*pul = _wcstoul_l(value.c_str(), NULL, 10, m_locale);
437+
if (*pul == 0 || *pul == ULONG_MAX)
431438
{
432-
if (errno == ERANGE || errno == EINVAL)
439+
if (errno == ERANGE)
433440
{
434441
hr = E_INVALIDARG;
435442
}
@@ -444,5 +451,6 @@ class TestInstance :
444451
MapType m_properties;
445452
TestPropertyStore m_catalogProperties;
446453
TestPropertyStore m_additionalProperties;
454+
_locale_t m_locale;
447455
ULONG m_ulRef;
448456
};

test/vswhere.test/TextFormatterTests.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,8 @@ TEST_CLASS(TextFormatterTests)
422422
L"instanceId: a1b2c3\n"
423423
L"state: 11\n"
424424
L"isComplete: 1\n"
425-
L"isLaunchable: 0\n";
425+
L"isLaunchable: 0\n"
426+
L"isRebootRequired: 1\n";
426427

427428
Assert::AreEqual(expected, console);
428429
}
@@ -449,7 +450,8 @@ TEST_CLASS(TextFormatterTests)
449450
L"instanceId: a1b2c3\n"
450451
L"state: 4294967295\n"
451452
L"isComplete: 1\n"
452-
L"isLaunchable: 1\n";
453+
L"isLaunchable: 1\n"
454+
L"isRebootRequired: 0\n";
453455

454456
Assert::AreEqual(expected, console);
455457
}

test/vswhere.test/ValueFormatterTests.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,8 @@ TEST_CLASS(ValueFormatterTests)
395395
L"a1b2c3\n"
396396
L"11\n"
397397
L"1\n"
398-
L"0\n";
398+
L"0\n"
399+
L"1\n";
399400

400401
Assert::AreEqual(expected, console);
401402
}
@@ -422,7 +423,8 @@ TEST_CLASS(ValueFormatterTests)
422423
L"a1b2c3\n"
423424
L"4294967295\n"
424425
L"1\n"
425-
L"1\n";
426+
L"1\n"
427+
L"0\n";
426428

427429
Assert::AreEqual(expected, console);
428430
}

test/vswhere.test/XmlFormatterTests.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,7 @@ TEST_CLASS(XmlFormatterTests)
456456
L" <state>11</state>\n"
457457
L" <isComplete>1</isComplete>\n"
458458
L" <isLaunchable>0</isLaunchable>\n"
459+
L" <isRebootRequired>1</isRebootRequired>\n"
459460
L" </instance>\n"
460461
L"</instances>\n";
461462

@@ -488,6 +489,7 @@ TEST_CLASS(XmlFormatterTests)
488489
L" <state>4294967295</state>\n"
489490
L" <isComplete>1</isComplete>\n"
490491
L" <isLaunchable>1</isLaunchable>\n"
492+
L" <isRebootRequired>0</isRebootRequired>\n"
491493
L" </instance>\n"
492494
L"</instances>\n";
493495

0 commit comments

Comments
 (0)