Skip to content

Commit

Permalink
Add -path parameter to get specific instance (#192)
Browse files Browse the repository at this point in the history
Fixes #191
  • Loading branch information
heaths authored Jul 26, 2019
1 parent a6d40ba commit 180c706
Show file tree
Hide file tree
Showing 11 changed files with 229 additions and 19 deletions.
37 changes: 37 additions & 0 deletions docker/Tests/vswhere.tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,43 @@ Describe 'vswhere' {
}
}

Context '-path' {
It 'returns nothing for non-installation path' {
$instances = C:\bin\vswhere.exe -path C:\ShouldNotExist -format json | ConvertFrom-Json
$instances | Should BeNullOrEmpty
}

It 'returns normal instance' {
$instances = C:\bin\vswhere.exe -path C:\VS\Enterprise -format json | ConvertFrom-Json
$instances.Count | Should Be 1
$instances[0].InstanceId | Should Be 2
}

It 'returns normal instance for normalized directory' {
$instances = C:\bin\vswhere.exe -path C:\VS\Enterprise\ -format json | ConvertFrom-Json
$instances.Count | Should Be 1
$instances[0].InstanceId | Should Be 2
}

It 'returns normal instance for file path' {
$instances = C:\bin\vswhere.exe -path C:\VS\Enterprise\Common7\Tools\VSDevCmd.bat -format json | ConvertFrom-Json
$instances.Count | Should Be 1
$instances[0].InstanceId | Should Be 2
}

It 'returns incomplete instance' {
$instances = C:\bin\vswhere.exe -path C:\VS\Professional -format json | ConvertFrom-Json
$instances.Count | Should Be 1
$instances[0].InstanceId | Should Be 3
}

It 'returns other instance' {
$instances = C:\bin\vswhere.exe -path C:\BuildTools -format json | ConvertFrom-Json
$instances.Count | Should Be 1
$instances[0].InstanceId | Should Be 4
}
}

# NOTE: microsoft/windowsservercore does not support setting the code page to anything other than 65001.
# Context 'encodes ja-JP' {
# BeforeAll {
Expand Down
24 changes: 22 additions & 2 deletions src/vswhere.lib/CommandArgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ void CommandArgs::Parse(_In_ LPCWSTR wszCommandLine)
CommandParser parser;
auto args = parser.Parse(wszCommandLine);

m_path = parser.get_Path();
m_applicationPath = parser.get_Path();

Parse(args);
}
Expand All @@ -39,13 +39,15 @@ void CommandArgs::Parse(_In_ int argc, _In_ LPCWSTR argv[])
CommandParser parser;
auto args = parser.Parse(argc, argv);

m_path = parser.get_Path();
m_applicationPath = parser.get_Path();

Parse(args);
}

void CommandArgs::Parse(_In_ vector<CommandParser::Token> args)
{
bool hasSelection = false;

for (auto it = args.begin(); it != args.end(); ++it)
{
auto& arg = *it;
Expand All @@ -60,26 +62,32 @@ void CommandArgs::Parse(_In_ vector<CommandParser::Token> args)
if (ArgumentEquals(arg.Value, L"all"))
{
m_all = true;
hasSelection = true;
}
else if (ArgumentEquals(arg.Value, L"products"))
{
ParseArgumentArray(it, args.end(), arg, m_products);
hasSelection = true;
}
else if (ArgumentEquals(arg.Value, L"requires"))
{
ParseArgumentArray(it, args.end(), arg, m_requires);
hasSelection = true;
}
else if (ArgumentEquals(arg.Value, L"requiresAny"))
{
m_requiresAny = true;
hasSelection = true;
}
else if (ArgumentEquals(arg.Value, L"version"))
{
m_version = ParseArgument(it, args.end(), arg);
hasSelection = true;
}
else if (ArgumentEquals(arg.Value, L"latest"))
{
m_latest = true;
hasSelection = true;
}
else if (ArgumentEquals(arg.Value, L"sort"))
{
Expand All @@ -88,10 +96,16 @@ void CommandArgs::Parse(_In_ vector<CommandParser::Token> args)
else if (ArgumentEquals(arg.Value, L"legacy"))
{
m_legacy = true;
hasSelection = true;
}
else if (ArgumentEquals(arg.Value, L"path"))
{
m_path = ParseArgument(it, args.end(), arg);
}
else if (ArgumentEquals(arg.Value, L"prerelease"))
{
m_prerelease = true;
hasSelection = true;
}
else if (ArgumentEquals(arg.Value, L"format"))
{
Expand Down Expand Up @@ -170,6 +184,12 @@ void CommandArgs::Parse(_In_ vector<CommandParser::Token> args)
{
m_format = L"value";
}

if (hasSelection && !m_path.empty())
{
auto message = ResourceManager::GetString(IDS_E_PATHINCOMPATIBLE);
throw win32_error(ERROR_INVALID_PARAMETER, message);
}
}

void CommandArgs::Usage(_In_ Console& console) const
Expand Down
27 changes: 17 additions & 10 deletions src/vswhere.lib/CommandArgs.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,16 @@ class CommandArgs
}

CommandArgs(const CommandArgs& obj) :
m_path(obj.m_path),
m_applicationPath(obj.m_applicationPath),
m_all(obj.m_all),
m_productsAll(obj.m_productsAll),
m_products(obj.m_products),
m_requires(obj.m_requires),
m_version(obj.m_version),
m_latest(obj.m_latest),
m_sort(obj.m_sort),
m_legacy(obj.m_legacy),
m_path(obj.m_path),
m_sort(obj.m_sort),
m_prerelease(obj.m_prerelease),
m_format(obj.m_format),
m_property(obj.m_property),
Expand All @@ -42,9 +43,9 @@ class CommandArgs
{
}

const std::wstring& get_Path() const noexcept
const std::wstring& get_ApplicationPath() const noexcept
{
return m_path;
return m_applicationPath;
}

const bool get_All() const noexcept
Expand Down Expand Up @@ -82,14 +83,19 @@ class CommandArgs
return m_latest;
}

const bool get_Sort() const noexcept
const bool get_Legacy() const noexcept
{
return m_sort;
return m_legacy;
}

const bool get_Legacy() const noexcept
const std::wstring& get_Path() const noexcept
{
return m_legacy;
return m_path;
}

const bool get_Sort() const noexcept
{
return m_sort;
}

const bool get_Prerelease() const noexcept
Expand Down Expand Up @@ -143,16 +149,17 @@ class CommandArgs

void Parse(_In_ std::vector<CommandParser::Token> args);

std::wstring m_path;
std::wstring m_applicationPath;
bool m_all;
bool m_productsAll;
std::vector<std::wstring> m_products;
std::vector<std::wstring> m_requires;
bool m_requiresAny;
std::wstring m_version;
bool m_latest;
bool m_sort;
bool m_legacy;
std::wstring m_path;
bool m_sort;
bool m_prerelease;
std::wstring m_format;
std::wstring m_property;
Expand Down
Binary file modified src/vswhere.lib/resource.h
Binary file not shown.
Binary file modified src/vswhere.lib/vswhere.lib.rc
Binary file not shown.
51 changes: 47 additions & 4 deletions src/vswhere/Program.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using namespace std;

void GetEnumerator(_In_ const CommandArgs& args, _In_ ISetupConfigurationPtr& query, _In_ IEnumSetupInstancesPtr& e);
wstring GetFullPath(_In_ const wstring& path);
void WriteLogo(_In_ const CommandArgs& args, _In_ Console& console, _In_ Module& module);

int wmain(_In_ int argc, _In_ LPCWSTR argv[])
Expand Down Expand Up @@ -55,11 +56,26 @@ int wmain(_In_ int argc, _In_ LPCWSTR argv[])
helper.Attach(new VersionRange);
}

IEnumSetupInstancesPtr e;
GetEnumerator(args, query, e);
vector<ISetupInstancePtr> instances;
if (args.get_Path().empty())
{
IEnumSetupInstancesPtr e;
GetEnumerator(args, query, e);

InstanceSelector selector(args, helper);
instances = std::move(selector.Select(e));
}
else
{
auto path = GetFullPath(args.get_Path());

InstanceSelector selector(args, helper);
auto instances = selector.Select(e);
ISetupInstancePtr instance;
hr = query->GetInstanceForPath(path.c_str(), &instance);
if (SUCCEEDED(hr))
{
instances.push_back(instance);
}
}

// Create the formatter and optionally show the logo.
auto formatter = Formatter::Create(args.get_Format());
Expand Down Expand Up @@ -146,6 +162,33 @@ void GetEnumerator(_In_ const CommandArgs& args, _In_ ISetupConfigurationPtr& qu
}
}

wstring GetFullPath(_In_ const wstring& path)
{
DWORD ret = 0;
wstring fullPath;

for (;;)
{
ret = ::GetFullPathNameW(path.c_str(), fullPath.capacity(), const_cast<LPWSTR>(fullPath.c_str()), NULL);

if (ret == 0)
{
throw win32_error();
}
// If buffer too small, return value contains required character count including terminating null.
else if (ret >= fullPath.capacity())
{
fullPath.resize(ret, L'\0');
}
else
{
break;
}
}

return fullPath;
}

void WriteLogo(_In_ const CommandArgs& args, _In_ Console& console, _In_ Module& module)
{
if (args.get_Logo())
Expand Down
8 changes: 8 additions & 0 deletions src/vswhere/vswhere.exe.manifest
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings xmlns:ws2="https://schemas.microsoft.com/SMI/2016/WindowsSettings">
<ws2:longPathAware>true</ws2:longPathAware>
</windowsSettings>
</application>
</assembly>
9 changes: 9 additions & 0 deletions src/vswhere/vswhere.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<Manifest>
<AdditionalManifestFiles>vswhere.exe.manifest</AdditionalManifestFiles>
</Manifest>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
Expand All @@ -86,6 +89,9 @@
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<Manifest>
<AdditionalManifestFiles>vswhere.exe.manifest</AdditionalManifestFiles>
</Manifest>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="resource.h" />
Expand All @@ -108,6 +114,9 @@
<None Include="packages.config">
<SubType>Designer</SubType>
</None>
<None Include="vswhere.exe.manifest">
<SubType>Designer</SubType>
</None>
</ItemGroup>
<ItemGroup>
<FilesToSign Include="$(TargetPath)">
Expand Down
5 changes: 4 additions & 1 deletion src/vswhere/vswhere.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;manifest</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
Expand All @@ -35,5 +35,8 @@
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
<None Include="vswhere.exe.manifest">
<Filter>Resource Files</Filter>
</None>
</ItemGroup>
</Project>
Loading

0 comments on commit 180c706

Please sign in to comment.