diff --git a/src/CodeIndex.Server/Controllers/LuceneController.cs b/src/CodeIndex.Server/Controllers/LuceneController.cs
index e89164d..2a10899 100644
--- a/src/CodeIndex.Server/Controllers/LuceneController.cs
+++ b/src/CodeIndex.Server/Controllers/LuceneController.cs
@@ -40,7 +40,7 @@ public FetchResult<IEnumerable<CodeSource>> GetCodeSources(string searchQuery, b
             {
                 searchQuery.RequireNotNullOrEmpty(nameof(searchQuery));
 
-                var showResultsValue = showResults.HasValue && showResults.Value <= 100 && showResults.Value > 0 ? showResults.Value : 100;
+                var showResultsValue = showResults.HasValue && showResults.Value <= 100 && showResults.Value > 0 ? showResults.Value : 1000;
 
                 result = new FetchResult<IEnumerable<CodeSource>>
                 {
diff --git a/src/CodeIndex.VisualStudioExtension/CodeIndex.VisualStudioExtension.csproj b/src/CodeIndex.VisualStudioExtension/CodeIndex.VisualStudioExtension.csproj
new file mode 100644
index 0000000..2052cd7
--- /dev/null
+++ b/src/CodeIndex.VisualStudioExtension/CodeIndex.VisualStudioExtension.csproj
@@ -0,0 +1,146 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <MinimumVisualStudioVersion>16.0</MinimumVisualStudioVersion>
+    <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
+    <TargetFrameworkProfile />
+  </PropertyGroup>
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectTypeGuids>{82b43b9b-a64c-4715-b499-d71e9ca2bd60};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <ProjectGuid>{ED1D3026-8695-4B9B-9FA9-2D68E28EE850}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>CodeIndex.VisualStudioExtension</RootNamespace>
+    <AssemblyName>CodeIndex.VisualStudioExtension</AssemblyName>
+    <TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
+    <GeneratePkgDefFile>true</GeneratePkgDefFile>
+    <UseCodebase>true</UseCodebase>
+    <IncludeAssemblyInVSIXContainer>true</IncludeAssemblyInVSIXContainer>
+    <IncludeDebugSymbolsInVSIXContainer>false</IncludeDebugSymbolsInVSIXContainer>
+    <IncludeDebugSymbolsInLocalVSIXDeployment>false</IncludeDebugSymbolsInLocalVSIXDeployment>
+    <CopyBuildOutputToOutputDirectory>true</CopyBuildOutputToOutputDirectory>
+    <CopyOutputSymbolsToOutputDirectory>true</CopyOutputSymbolsToOutputDirectory>
+    <StartAction>Program</StartAction>
+    <StartProgram Condition="'$(DevEnvDir)' != ''">$(DevEnvDir)devenv.exe</StartProgram>
+    <StartArguments>/rootsuffix Exp</StartArguments>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Compile Include="..\CodeIndex.Common\CodeSource.cs">
+      <Link>Models\CodeSource.cs</Link>
+    </Compile>
+    <Compile Include="..\CodeIndex.Common\FetchResult.cs">
+      <Link>Models\FetchResult.cs</Link>
+    </Compile>
+    <Compile Include="..\CodeIndex.Common\Status.cs">
+      <Link>Models\Status.cs</Link>
+    </Compile>
+    <Compile Include="Controls\CodeIndexSearchControl.xaml.cs">
+      <DependentUpon>CodeIndexSearchControl.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="CodeIndexSearchWindow.cs" />
+    <Compile Include="CodeIndexSearchWindowCommand.cs" />
+    <Compile Include="CodeIndexSearchWindowControl.xaml.cs">
+      <DependentUpon>CodeIndexSearchWindowControl.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="Models\BaseViewModel.cs" />
+    <Compile Include="Models\CodeIndexSearchViewModel.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="CodeIndex.VisualStudioExtensionPackage.cs" />
+    <Compile Include="Properties\CodeIndexSettings.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DesignTimeSharedInput>True</DesignTimeSharedInput>
+      <DependentUpon>CodeIndexSettings.settings</DependentUpon>
+    </Compile>
+    <Compile Include="ProvideToolboxControlAttribute.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="app.config" />
+    <None Include="Properties\CodeIndexSettings.settings">
+      <Generator>SettingsSingleFileGenerator</Generator>
+      <LastGenOutput>CodeIndexSettings.Designer.cs</LastGenOutput>
+    </None>
+    <None Include="source.extension.vsixmanifest">
+      <SubType>Designer</SubType>
+    </None>
+  </ItemGroup>
+  <ItemGroup>
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="PresentationCore" />
+    <Reference Include="PresentationFramework" />
+    <Reference Include="PresentationFramework.Aero2" />
+    <Reference Include="System" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="System.Design" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Web" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Xaml" />
+    <Reference Include="System.Xml" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="WindowsBase" />
+  </ItemGroup>
+  <ItemGroup>
+    <PackageReference Include="Microsoft.AspNet.WebApi.Client">
+      <Version>5.2.7</Version>
+    </PackageReference>
+    <PackageReference Include="Microsoft.VisualStudio.SDK" Version="16.0.204" ExcludeAssets="runtime" />
+    <PackageReference Include="Microsoft.VSSDK.BuildTools" Version="16.6.2031">
+      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
+      <PrivateAssets>all</PrivateAssets>
+    </PackageReference>
+  </ItemGroup>
+  <ItemGroup>
+    <VSCTCompile Include="VisualStudioExtensionPackage.vsct">
+      <ResourceName>Menus.ctmenu</ResourceName>
+    </VSCTCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="Resources\CodeIndexSearchWindowCommand.png" />
+  </ItemGroup>
+  <ItemGroup>
+    <Page Include="Controls\CodeIndexSearchControl.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
+    <Page Include="CodeIndexSearchWindowControl.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
+    <Page Include="Resources\Style.xaml">
+      <Generator>MSBuild:Compile</Generator>
+      <SubType>Designer</SubType>
+    </Page>
+  </ItemGroup>
+  <ItemGroup />
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <Import Project="$(VSToolsPath)\VSSDK\Microsoft.VsSDK.targets" Condition="'$(VSToolsPath)' != ''" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
\ No newline at end of file
diff --git a/src/CodeIndex.VisualStudioExtension/CodeIndex.VisualStudioExtensionPackage.cs b/src/CodeIndex.VisualStudioExtension/CodeIndex.VisualStudioExtensionPackage.cs
new file mode 100644
index 0000000..53f4c7b
--- /dev/null
+++ b/src/CodeIndex.VisualStudioExtension/CodeIndex.VisualStudioExtensionPackage.cs
@@ -0,0 +1,56 @@
+using System;
+using System.Runtime.InteropServices;
+using System.Threading;
+using Microsoft.VisualStudio.Shell;
+using Task = System.Threading.Tasks.Task;
+
+namespace CodeIndex.VisualStudioExtension
+{
+    /// <summary>
+    /// This is the class that implements the package exposed by this assembly.
+    /// </summary>
+    /// <remarks>
+    /// <para>
+    /// The minimum requirement for a class to be considered a valid package for Visual Studio
+    /// is to implement the IVsPackage interface and register itself with the shell.
+    /// This package uses the helper classes defined inside the Managed Package Framework (MPF)
+    /// to do it: it derives from the Package class that provides the implementation of the
+    /// IVsPackage interface and uses the registration attributes defined in the framework to
+    /// register itself and its components with the shell. These attributes tell the pkgdef creation
+    /// utility what data to put into .pkgdef file.
+    /// </para>
+    /// <para>
+    /// To get loaded into VS, the package must be referred by &lt;Asset Type="Microsoft.VisualStudio.VsPackage" ...&gt; in .vsixmanifest file.
+    /// </para>
+    /// </remarks>
+    [PackageRegistration(UseManagedResourcesOnly = true, AllowsBackgroundLoading = true)]
+    [Guid(PackageGuidString)]
+    [ProvideMenuResource("Menus.ctmenu", 1)]
+    [ProvideToolWindow(typeof(CodeIndex.VisualStudioExtension.CodeIndexSearchWindow))]
+    public sealed class VisualStudioExtensionPackage : AsyncPackage
+    {
+        /// <summary>
+        /// CodeIndex.VisualStudioExtensionPackage GUID string.
+        /// </summary>
+        public const string PackageGuidString = "1eaddb39-c1f2-42e2-807d-234d73e8ef2a";
+
+        #region Package Members
+
+        /// <summary>
+        /// Initialization of the package; this method is called right after the package is sited, so this is the place
+        /// where you can put all the initialization code that rely on services provided by VisualStudio.
+        /// </summary>
+        /// <param name="cancellationToken">A cancellation token to monitor for initialization cancellation, which can occur when VS is shutting down.</param>
+        /// <param name="progress">A provider for progress updates.</param>
+        /// <returns>A task representing the async work of package initialization, or an already completed task if there is none. Do not return null from this method.</returns>
+        protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress<ServiceProgressData> progress)
+        {
+            // When initialized asynchronously, the current thread may be a background thread at this point.
+            // Do any initialization that requires the UI thread after switching to the UI thread.
+            await this.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
+            await CodeIndex.VisualStudioExtension.CodeIndexSearchWindowCommand.InitializeAsync(this);
+        }
+
+        #endregion
+    }
+}
diff --git a/src/CodeIndex.VisualStudioExtension/CodeIndexSearchWindow.cs b/src/CodeIndex.VisualStudioExtension/CodeIndexSearchWindow.cs
new file mode 100644
index 0000000..edbd64d
--- /dev/null
+++ b/src/CodeIndex.VisualStudioExtension/CodeIndexSearchWindow.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Runtime.InteropServices;
+using Microsoft.VisualStudio.Shell;
+
+namespace CodeIndex.VisualStudioExtension
+{
+    /// <summary>
+    /// This class implements the tool window exposed by this package and hosts a user control.
+    /// </summary>
+    /// <remarks>
+    /// In Visual Studio tool windows are composed of a frame (implemented by the shell) and a pane,
+    /// usually implemented by the package implementer.
+    /// <para>
+    /// This class derives from the ToolWindowPane class provided from the MPF in order to use its
+    /// implementation of the IVsUIElementPane interface.
+    /// </para>
+    /// </remarks>
+    [Guid("6d5fde57-9331-4f68-8c3e-2945d8049f40")]
+    public class CodeIndexSearchWindow : ToolWindowPane
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="CodeIndexSearchWindow"/> class.
+        /// </summary>
+        public CodeIndexSearchWindow() : base(null)
+        {
+            this.Caption = "Code Index Search";
+
+            // This is the user control hosted by the tool window; Note that, even if this class implements IDisposable,
+            // we are not calling Dispose on this object. This is because ToolWindowPane calls Dispose on
+            // the object returned by the Content property.
+            this.Content = new CodeIndexSearchWindowControl();
+        }
+    }
+}
diff --git a/src/CodeIndex.VisualStudioExtension/CodeIndexSearchWindowCommand.cs b/src/CodeIndex.VisualStudioExtension/CodeIndexSearchWindowCommand.cs
new file mode 100644
index 0000000..9ddfb49
--- /dev/null
+++ b/src/CodeIndex.VisualStudioExtension/CodeIndexSearchWindowCommand.cs
@@ -0,0 +1,99 @@
+using System;
+using System.ComponentModel.Design;
+using System.Globalization;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.VisualStudio.Shell;
+using Microsoft.VisualStudio.Shell.Interop;
+using Task = System.Threading.Tasks.Task;
+
+namespace CodeIndex.VisualStudioExtension
+{
+    /// <summary>
+    /// Command handler
+    /// </summary>
+    internal sealed class CodeIndexSearchWindowCommand
+    {
+        /// <summary>
+        /// Command ID.
+        /// </summary>
+        public const int CommandId = 4129;
+
+        /// <summary>
+        /// Command menu group (command set GUID).
+        /// </summary>
+        public static readonly Guid CommandSet = new Guid("c025b4ef-e6ed-42b4-9c22-2d6835421d25");
+
+        /// <summary>
+        /// VS Package that provides this command, not null.
+        /// </summary>
+        private readonly AsyncPackage package;
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="CodeIndexSearchWindowCommand"/> class.
+        /// Adds our command handlers for menu (commands must exist in the command table file)
+        /// </summary>
+        /// <param name="package">Owner package, not null.</param>
+        /// <param name="commandService">Command service to add command to, not null.</param>
+        private CodeIndexSearchWindowCommand(AsyncPackage package, OleMenuCommandService commandService)
+        {
+            this.package = package ?? throw new ArgumentNullException(nameof(package));
+            commandService = commandService ?? throw new ArgumentNullException(nameof(commandService));
+
+            var menuCommandID = new CommandID(CommandSet, CommandId);
+            var menuItem = new MenuCommand(this.Execute, menuCommandID);
+            commandService.AddCommand(menuItem);
+        }
+
+        /// <summary>
+        /// Gets the instance of the command.
+        /// </summary>
+        public static CodeIndexSearchWindowCommand Instance
+        {
+            get;
+            private set;
+        }
+
+        /// <summary>
+        /// Gets the service provider from the owner package.
+        /// </summary>
+        private Microsoft.VisualStudio.Shell.IAsyncServiceProvider ServiceProvider
+        {
+            get
+            {
+                return this.package;
+            }
+        }
+
+        /// <summary>
+        /// Initializes the singleton instance of the command.
+        /// </summary>
+        /// <param name="package">Owner package, not null.</param>
+        public static async Task InitializeAsync(AsyncPackage package)
+        {
+            // Switch to the main thread - the call to AddCommand in CodeIndexSearchWindowCommand's constructor requires
+            // the UI thread.
+            await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(package.DisposalToken);
+
+            OleMenuCommandService commandService = await package.GetServiceAsync((typeof(IMenuCommandService))) as OleMenuCommandService;
+            Instance = new CodeIndexSearchWindowCommand(package, commandService);
+        }
+
+        /// <summary>
+        /// Shows the tool window when the menu item is clicked.
+        /// </summary>
+        /// <param name="sender">The event sender.</param>
+        /// <param name="e">The event args.</param>
+        private void Execute(object sender, EventArgs e)
+        {
+            this.package.JoinableTaskFactory.RunAsync(async delegate
+            {
+                ToolWindowPane window = await this.package.ShowToolWindowAsync(typeof(CodeIndexSearchWindow), 0, true, this.package.DisposalToken);
+                if ((null == window) || (null == window.Frame))
+                {
+                    throw new NotSupportedException("Cannot create tool window");
+                }
+            });
+        }
+    }
+}
diff --git a/src/CodeIndex.VisualStudioExtension/CodeIndexSearchWindowControl.xaml b/src/CodeIndex.VisualStudioExtension/CodeIndexSearchWindowControl.xaml
new file mode 100644
index 0000000..2936f7f
--- /dev/null
+++ b/src/CodeIndex.VisualStudioExtension/CodeIndexSearchWindowControl.xaml
@@ -0,0 +1,17 @@
+<UserControl x:Class="CodeIndex.VisualStudioExtension.CodeIndexSearchWindowControl"
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+             xmlns:vsshell="clr-namespace:Microsoft.VisualStudio.Shell;assembly=Microsoft.VisualStudio.Shell.15.0" xmlns:visualstudioextension="clr-namespace:CodeIndex.VisualStudioExtension"
+             Background="{DynamicResource {x:Static vsshell:VsBrushes.WindowKey}}"
+             Foreground="{DynamicResource {x:Static vsshell:VsBrushes.WindowTextKey}}"
+             mc:Ignorable="d"
+             d:DesignHeight="225.889" d:DesignWidth="783.068"
+             Name="MyToolWindow">
+    <Grid>
+        <DockPanel LastChildFill="True">
+            <visualstudioextension:CodeIndexSearchControl x:Name="SearchControl"></visualstudioextension:CodeIndexSearchControl>
+        </DockPanel>
+    </Grid>
+</UserControl>
diff --git a/src/CodeIndex.VisualStudioExtension/CodeIndexSearchWindowControl.xaml.cs b/src/CodeIndex.VisualStudioExtension/CodeIndexSearchWindowControl.xaml.cs
new file mode 100644
index 0000000..01cc3f8
--- /dev/null
+++ b/src/CodeIndex.VisualStudioExtension/CodeIndexSearchWindowControl.xaml.cs
@@ -0,0 +1,20 @@
+using System.Windows.Controls;
+
+namespace CodeIndex.VisualStudioExtension
+{
+    /// <summary>
+    /// Interaction logic for CodeIndexSearchWindowControl.
+    /// </summary>
+    public partial class CodeIndexSearchWindowControl : UserControl
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="CodeIndexSearchWindowControl"/> class.
+        /// </summary>
+        public CodeIndexSearchWindowControl()
+        {
+            InitializeComponent();
+
+            SearchControl.DataContext = new CodeIndexSearchViewModel();
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/CodeIndex.VisualStudioExtension/Controls/CodeIndexSearchControl.xaml b/src/CodeIndex.VisualStudioExtension/Controls/CodeIndexSearchControl.xaml
new file mode 100644
index 0000000..d028be4
--- /dev/null
+++ b/src/CodeIndex.VisualStudioExtension/Controls/CodeIndexSearchControl.xaml
@@ -0,0 +1,137 @@
+<UserControl x:Class="CodeIndex.VisualStudioExtension.CodeIndexSearchControl"
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+             mc:Ignorable="d" 
+             d:DesignHeight="281.2" d:DesignWidth="987.2" Foreground="Black" Background="#FF2D2D30">
+    <Grid>
+        <DockPanel LastChildFill="True" Margin="6">
+            <WrapPanel HorizontalAlignment="Left" DockPanel.Dock="Top">
+                <Label Content="Content:"/>
+                <TextBox Height="23" TextWrapping="Wrap" Text="{Binding Content, UpdateSourceTrigger=PropertyChanged}" Width="240" KeyDown="TextBox_KeyDown"/>
+                <Label Content="File Name:"/>
+                <TextBox Height="23" TextWrapping="Wrap" Text="{Binding FileName, UpdateSourceTrigger=PropertyChanged}" Width="120" KeyDown="TextBox_KeyDown"/>
+                <Label Content="File Extension:"/>
+                <TextBox Height="23" TextWrapping="Wrap" Text="{Binding FileExtension, UpdateSourceTrigger=PropertyChanged}" Width="120" KeyDown="TextBox_KeyDown"/>
+                <Label Content="File Location:"/>
+                <TextBox Height="23" TextWrapping="Wrap" Text="{Binding FileLocation, UpdateSourceTrigger=PropertyChanged}" Width="120" KeyDown="TextBox_KeyDown"/>
+                <Label Content="Show Results: "/>
+                <ComboBox SelectedValue="{Binding ShowResultsNumber}" ItemsSource="{Binding Options}" DisplayMemberPath="Name" SelectedValuePath="Value" Width="100" VerticalAlignment="Center"/>
+                <Button x:Name="SearchButton" Margin="10 0 0 0" Content="Search" Command="{Binding SearchIndexCommand}" Style="{DynamicResource InfoButton}"/>
+                <Button Margin="10 0 0 0" Content="Stop Search" Command="{Binding StopSearchCommand}" Style="{DynamicResource WarnButton}"/>
+            </WrapPanel>
+            <WrapPanel DockPanel.Dock="Top">
+                <Label Content="Service Url:"/>
+                <TextBox Height="23" TextWrapping="NoWrap" Text="{Binding ServiceUrl}" Width="200"/>
+                <Label Content="Result Info:"/>
+                <ScrollViewer VerticalScrollBarVisibility="Auto" MaxHeight="60">
+                    <Label Content="{Binding ResultInfo}" Foreground="Yellow"/>
+                </ScrollViewer>
+            </WrapPanel>
+            <DataGrid Background="#FF2D2D30" Margin="0 6 0 0" ItemsSource="{Binding SearchResult}" AutoGenerateColumns="True" IsReadOnly="True" HeadersVisibility="Column"/>
+        </DockPanel>
+    </Grid>
+    <UserControl.Resources>
+        <Style TargetType="{x:Type Label}">
+            <Setter Property="Foreground" Value="White"/>
+            <Setter Property="Margin" Value="2"/>
+        </Style>
+        <Style TargetType="{x:Type TextBox}">
+            <Setter Property="Background" Value="#FF434343"/>
+            <Setter Property="Foreground" Value="White"/>
+        </Style>
+        <Style TargetType="{x:Type DataGridRow}">
+            <Setter Property="Foreground" Value="White"/>
+            <Setter Property="Background" Value="#FF2D2D30"/>
+        </Style>
+        <Style TargetType="{x:Type DataGridColumnHeader}">
+            <Setter Property="Foreground" Value="White"/>
+            <Setter Property="Background" Value="#FF434343"/>
+        </Style>
+        <Style TargetType="{x:Type DataGridCell}">
+            <Setter Property="Background" Value="Transparent"/>
+            <Setter Property="BorderBrush" Value="Transparent"/>
+            <Setter Property="BorderThickness" Value="1"/>
+            <Setter Property="Template">
+                <Setter.Value>
+                    <ControlTemplate TargetType="{x:Type DataGridCell}">
+                        <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
+                            <ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
+                        </Border>
+                    </ControlTemplate>
+                </Setter.Value>
+            </Setter>
+            <Style.Triggers>
+                <Trigger Property="IsSelected" Value="True">
+                    <Setter Property="Background" Value="#FF0078D7"/>
+                    <Setter Property="Foreground" Value="White"/>
+                    <Setter Property="BorderBrush" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
+                </Trigger>
+                <Trigger Property="IsKeyboardFocusWithin" Value="True">
+                    <Setter Property="BorderBrush" Value="{DynamicResource {x:Static DataGrid.FocusBorderBrushKey}}"/>
+                </Trigger>
+                <MultiTrigger>
+                    <MultiTrigger.Conditions>
+                        <Condition Property="IsSelected" Value="true"/>
+                        <Condition Property="Selector.IsSelectionActive" Value="false"/>
+                    </MultiTrigger.Conditions>
+                    <Setter Property="Background" Value="#FF0078D7"/>
+                    <Setter Property="Foreground" Value="White"/>
+                    <Setter Property="BorderBrush" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/>
+                </MultiTrigger>
+                <Trigger Property="IsEnabled" Value="false">
+                    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
+                </Trigger>
+            </Style.Triggers>
+        </Style>
+        <Style TargetType="{x:Type Button}" x:Key="InfoButton">
+            <Setter Property="Width" Value="70"/>
+            <Setter Property="Height" Value="25"/>
+            <Setter Property="Foreground" Value="White"/>
+            <Setter Property="BorderThickness" Value="0"/>
+            <Setter Property="Background" Value="#43a9c7"/>
+            <Setter Property="Template">
+                <Setter.Value>
+                    <ControlTemplate TargetType="Button">
+                        <Border x:Name="border" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="True">
+                            <TextBlock Text="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
+                        </Border>
+                        <ControlTemplate.Triggers>
+                            <Trigger Property="IsMouseOver" Value="True">
+                                <Setter TargetName="border" Property="Background" Value="#2f96b4"/>
+                            </Trigger>
+                            <Trigger Property="IsPressed" Value="True">
+                                <Setter TargetName="border" Property="Background" Value="#2a89a4"/>
+                            </Trigger>
+                        </ControlTemplate.Triggers>
+                    </ControlTemplate>
+                </Setter.Value>
+            </Setter>
+        </Style>
+        <Style TargetType="{x:Type Button}" x:Key="WarnButton">
+            <Setter Property="Width" Value="80"/>
+            <Setter Property="Height" Value="25"/>
+            <Setter Property="Foreground" Value="White"/>
+            <Setter Property="BorderThickness" Value="0"/>
+            <Setter Property="Background" Value="#FFFF3A18"/>
+            <Setter Property="Template">
+                <Setter.Value>
+                    <ControlTemplate TargetType="Button">
+                        <Border x:Name="border" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="True">
+                            <TextBlock Text="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
+                        </Border>
+                        <ControlTemplate.Triggers>
+                            <Trigger Property="IsMouseOver" Value="True">
+                                <Setter TargetName="border" Property="Background" Value="#FFFF6E54"/>
+                            </Trigger>
+                            <Trigger Property="IsPressed" Value="True">
+                                <Setter TargetName="border" Property="Background" Value="#FFFF9887"/>
+                            </Trigger>
+                        </ControlTemplate.Triggers>
+                    </ControlTemplate>
+                </Setter.Value>
+            </Setter>
+        </Style>
+    </UserControl.Resources>
+</UserControl>
diff --git a/src/CodeIndex.VisualStudioExtension/Controls/CodeIndexSearchControl.xaml.cs b/src/CodeIndex.VisualStudioExtension/Controls/CodeIndexSearchControl.xaml.cs
new file mode 100644
index 0000000..bf61000
--- /dev/null
+++ b/src/CodeIndex.VisualStudioExtension/Controls/CodeIndexSearchControl.xaml.cs
@@ -0,0 +1,28 @@
+using System.Windows.Controls;
+using System.Windows.Input;
+
+namespace CodeIndex.VisualStudioExtension
+{
+    /// <summary>
+    /// Interaction logic for CodeIndexSearchControl.xaml.
+    /// </summary>
+    [ProvideToolboxControl("CodeIndex.VisualStudioExtension.CodeIndexSearchControl", true)]
+    public partial class CodeIndexSearchControl : UserControl
+    {
+        public CodeIndexSearchControl()
+        {
+            InitializeComponent();
+        }
+
+        void TextBox_KeyDown(object sender, KeyEventArgs e)
+        {
+            if (e.Key == Key.Enter)
+            {
+                if(e.KeyboardDevice.Modifiers != ModifierKeys.Control)
+                {
+                    SearchButton.Command?.Execute(null);
+                }
+            }
+        }
+    }
+}
diff --git a/src/CodeIndex.VisualStudioExtension/Models/BaseViewModel.cs b/src/CodeIndex.VisualStudioExtension/Models/BaseViewModel.cs
new file mode 100644
index 0000000..1d143a6
--- /dev/null
+++ b/src/CodeIndex.VisualStudioExtension/Models/BaseViewModel.cs
@@ -0,0 +1,27 @@
+using System;
+using System.ComponentModel;
+using System.Runtime.CompilerServices;
+using System.Windows.Threading;
+
+namespace CodeIndex.VisualStudioExtension
+{
+    public class BaseViewModel : INotifyPropertyChanged
+    {
+        public event PropertyChangedEventHandler PropertyChanged;
+
+        public void NotifyPropertyChange([CallerMemberName]string memberName = null)
+        {
+            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(memberName));
+        }
+
+        public void NotifyPropertyChange(Func<string> propertyName)
+        {
+            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName.Invoke()));
+        }
+
+        public static void InvokeDispatcher(Action action, Dispatcher dispatcher, DispatcherPriority dispatcherPriority = DispatcherPriority.Normal)
+        {
+            dispatcher?.BeginInvoke(dispatcherPriority, action);
+        }
+    }
+}
diff --git a/src/CodeIndex.VisualStudioExtension/Models/CodeIndexSearchViewModel.cs b/src/CodeIndex.VisualStudioExtension/Models/CodeIndexSearchViewModel.cs
new file mode 100644
index 0000000..4acfa45
--- /dev/null
+++ b/src/CodeIndex.VisualStudioExtension/Models/CodeIndexSearchViewModel.cs
@@ -0,0 +1,257 @@
+using CodeIndex.Common;
+using CodeIndex.VisualStudioExtension.Properties;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Net.Http;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Windows.Input;
+
+namespace CodeIndex.VisualStudioExtension
+{
+    public class CodeIndexSearchViewModel : BaseViewModel
+    {
+        public CodeIndexSearchViewModel()
+        {
+            ServiceUrl = CodeIndexSettings.Default.ServiceUrl;
+        }
+
+        public string FileName { get; set; }
+        public string Content { get; set; }
+        public string FileExtension { get; set; }
+        public string FileLocation { get; set; }
+        public int ShowResultsNumber { get; set; } = 50;
+        public string ServiceUrl
+        {
+            get => serviceUrl;
+            set
+            {
+                if (value != null && value.EndsWith("/"))
+                {
+                    value = value.Substring(0, value.Length - 1);
+                }
+
+                CodeIndexSettings.Default.ServiceUrl = value;
+                serviceUrl = value;
+            }
+        }
+        public string ResultInfo
+        {
+            get => resultInfo;
+            set
+            {
+                resultInfo = value;
+                NotifyPropertyChange();
+            }
+        }
+        public Item<int>[] Options { get; } = new[]
+        {
+            new Item<int>("Top 10", 10),
+            new Item<int>("Top 20", 20),
+            new Item<int>("Top 50", 50),
+            new Item<int>("Top 100", 100),
+            new Item<int>("Top 1000", 1000)
+        };
+
+        public List<CodeSource> SearchResult
+        {
+            get => searchResult;
+            set
+            {
+                searchResult = value;
+                NotifyPropertyChange();
+            }
+        }
+
+        public class Item<T>
+        {
+            public Item(string name, T value)
+            {
+                Name = name;
+                Value = value;
+            }
+
+            public string Name { get; }
+            public T Value { get; }
+        }
+
+
+        ICommand searchIndexCommand;
+        ICommand stopSearchCommand;
+        string serviceUrl;
+        List<CodeSource> searchResult = new List<CodeSource>();
+        string resultInfo;
+        CancellationTokenSource tokenSource;
+
+        public ICommand SearchIndexCommand
+        {
+            get
+            {
+                if (searchIndexCommand == null)
+                {
+                    searchIndexCommand = new CommonCommand(
+                        param => SearchCodeIndexAsync(),
+                        param => true
+                    );
+                }
+                return searchIndexCommand;
+            }
+        }
+
+
+        public ICommand StopSearchCommand
+        {
+            get
+            {
+                if (stopSearchCommand == null)
+                {
+                    stopSearchCommand = new CommonCommand(
+                        param => tokenSource?.Cancel(),
+                        param => true
+                    );
+                }
+                return stopSearchCommand;
+            }
+        }
+
+        #region SearchCodeIndex
+
+        bool IsSearching { get; set; }
+
+        async Task SearchCodeIndexAsync()
+        {
+            if (!IsSearching)
+            {
+                try
+                {
+                    IsSearching = true;
+                    tokenSource?.Dispose();
+                    tokenSource = new CancellationTokenSource();
+                    ResultInfo = "Searching...";
+
+                    await SearchCodeIndexCoreAsync();
+                }
+                catch (TaskCanceledException)
+                {
+                    ResultInfo = "Search cancelled.";
+                }
+                catch (Exception ex)
+                {
+                    ResultInfo = "Exception Occur: " + ex;
+                }
+                finally
+                {
+                    IsSearching = false;
+                }
+            }
+        }
+
+        async Task SearchCodeIndexCoreAsync()
+        {
+            if (IsValidate())
+            {
+                var url = $"{ServiceUrl}/api/lucene/GetCodeSources?searchQuery=" + System.Web.HttpUtility.UrlEncode(GetSearchStr()) + "&showResults=" + ShowResultsNumber + "&preview=true" + "&contentQuery=" + System.Web.HttpUtility.UrlEncode(Content ?? string.Empty);
+
+                var client = new HttpClient();
+                var response = await client.GetAsync(url, tokenSource.Token);
+                var result = await response.Content.ReadAsAsync<FetchResult<List<CodeSource>>>();
+
+                if (result.Status.Success)
+                {
+                    SearchResult = result.Result;
+                }
+                else
+                {
+                    SearchResult.Clear();
+                }
+
+                ResultInfo = $"Successful: {result.Status.Success}, Desc: {result.Status.StatusDesc}, Fetch Count: {SearchResult.Count}.";
+            }
+            else
+            {
+                ResultInfo = "Search query can't be empty.";
+            }
+        }
+
+        string GetSearchStr()
+        {
+            var searchQueries = new List<string>();
+
+            if (!string.IsNullOrWhiteSpace(FileName))
+            {
+                searchQueries.Add($"{nameof(CodeSource.FileName)}:{FileName}");
+            }
+
+            if (!string.IsNullOrWhiteSpace(Content))
+            {
+                searchQueries.Add($"{nameof(CodeSource.Content)}:{Content}");
+            }
+
+            if (!string.IsNullOrWhiteSpace(FileExtension))
+            {
+                searchQueries.Add($"{nameof(CodeSource.FileExtension)}:{FileExtension}");
+            }
+
+            if (!string.IsNullOrWhiteSpace(FileLocation))
+            {
+                if (SurroundWithQuotation(FileLocation))
+                {
+                    FileLocation = FileLocation.Replace("\\", "\\\\");
+                }
+
+                searchQueries.Add($"{nameof(CodeSource.FilePath)}:{FileLocation}");
+            }
+
+            return string.Join(" AND ", searchQueries);
+        }
+
+        static bool SurroundWithQuotation(string content)
+        {
+            return !string.IsNullOrWhiteSpace(content) && content.StartsWith("\"") && content.EndsWith("\"");
+        }
+
+        bool IsValidate()
+        {
+            return !string.IsNullOrEmpty(GetSearchStr());
+        }
+
+        #endregion
+
+        public class CommonCommand : ICommand
+        {
+            readonly Action<object> execute;
+            readonly Predicate<object> canExecute;
+
+            public CommonCommand(Action<object> execute) : this(execute, null)
+            {
+            }
+
+            public CommonCommand(Action<object> execute, Predicate<object> canExecute)
+            {
+                if (execute == null)
+                    throw new ArgumentNullException("execute");
+
+                this.execute = execute;
+                this.canExecute = canExecute;
+            }
+
+            [DebuggerStepThrough]
+            public bool CanExecute(object parameters)
+            {
+                return canExecute == null ? true : canExecute(parameters);
+            }
+
+            public event EventHandler CanExecuteChanged
+            {
+                add { CommandManager.RequerySuggested += value; }
+                remove { CommandManager.RequerySuggested -= value; }
+            }
+
+            public void Execute(object parameters)
+            {
+                execute(parameters);
+            }
+        }
+    }
+}
diff --git a/src/CodeIndex.VisualStudioExtension/Properties/AssemblyInfo.cs b/src/CodeIndex.VisualStudioExtension/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..639a0e6
--- /dev/null
+++ b/src/CodeIndex.VisualStudioExtension/Properties/AssemblyInfo.cs
@@ -0,0 +1,34 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Code Index Search")]
+[assembly: AssemblyDescription("Code Index Search Extension For Visual Studio")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("CodeIndex.VisualStudioExtension")]
+[assembly: AssemblyCopyright("https://github.com/qiuhaotc/CodeIndex")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("0.1.0.0")]
+[assembly: AssemblyFileVersion("0.1.0.0")]
+[assembly: Guid("8F594ABC-BDED-431E-BF88-23AFE38F9032")]
diff --git a/src/CodeIndex.VisualStudioExtension/Properties/CodeIndexSettings.Designer.cs b/src/CodeIndex.VisualStudioExtension/Properties/CodeIndexSettings.Designer.cs
new file mode 100644
index 0000000..c5842e2
--- /dev/null
+++ b/src/CodeIndex.VisualStudioExtension/Properties/CodeIndexSettings.Designer.cs
@@ -0,0 +1,38 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     此代码由工具生成。
+//     运行时版本:4.0.30319.42000
+//
+//     对此文件的更改可能会导致不正确的行为,并且如果
+//     重新生成代码,这些更改将会丢失。
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace CodeIndex.VisualStudioExtension.Properties {
+    
+    
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.5.0.0")]
+    internal sealed partial class CodeIndexSettings : global::System.Configuration.ApplicationSettingsBase {
+        
+        private static CodeIndexSettings defaultInstance = ((CodeIndexSettings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new CodeIndexSettings())));
+        
+        public static CodeIndexSettings Default {
+            get {
+                return defaultInstance;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("https://codeindex.qhnetdisk.tk/")]
+        public string ServiceUrl {
+            get {
+                return ((string)(this["ServiceUrl"]));
+            }
+            set {
+                this["ServiceUrl"] = value;
+            }
+        }
+    }
+}
diff --git a/src/CodeIndex.VisualStudioExtension/Properties/CodeIndexSettings.settings b/src/CodeIndex.VisualStudioExtension/Properties/CodeIndexSettings.settings
new file mode 100644
index 0000000..9c15cb7
--- /dev/null
+++ b/src/CodeIndex.VisualStudioExtension/Properties/CodeIndexSettings.settings
@@ -0,0 +1,9 @@
+<?xml version='1.0' encoding='utf-8'?>
+<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="CodeIndex.VisualStudioExtension.Properties" GeneratedClassName="CodeIndexSettings">
+  <Profiles />
+  <Settings>
+    <Setting Name="ServiceUrl" Type="System.String" Scope="User">
+      <Value Profile="(Default)">https://codeindex.qhnetdisk.tk/</Value>
+    </Setting>
+  </Settings>
+</SettingsFile>
\ No newline at end of file
diff --git a/src/CodeIndex.VisualStudioExtension/ProvideToolboxControlAttribute.cs b/src/CodeIndex.VisualStudioExtension/ProvideToolboxControlAttribute.cs
new file mode 100644
index 0000000..775f936
--- /dev/null
+++ b/src/CodeIndex.VisualStudioExtension/ProvideToolboxControlAttribute.cs
@@ -0,0 +1,83 @@
+using Microsoft.VisualStudio.Shell;
+using System;
+using System.Globalization;
+using System.Runtime.InteropServices;
+
+namespace CodeIndex.VisualStudioExtension
+{
+    /// <summary>
+    /// This attribute adds a ToolboxControlsInstaller key for the assembly to install toolbox controls from the assembly.
+    /// </summary>
+    /// <remarks>
+    /// For example
+    ///     [$(Rootkey)\ToolboxControlsInstaller\$FullAssemblyName$]
+    ///         "Codebase"="$path$"
+    ///         "WpfControls"="1"
+    /// </remarks>
+    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
+    [ComVisible(false)]
+    public sealed class ProvideToolboxControlAttribute : RegistrationAttribute
+    {
+        private const string ToolboxControlsInstallerPath = "ToolboxControlsInstaller";
+        private readonly string name;
+        private readonly bool areWPFControls;
+
+        /// <summary>
+        /// Creates a new ProvideToolboxControl attribute to register the assembly for toolbox controls installer.
+        /// </summary>
+        /// <param name="name">The name of the toolbox controls.</param>
+        /// <param name="areWPFControls">Indicates whether the toolbox controls are WPF controls.</param>
+        public ProvideToolboxControlAttribute(string name, bool areWPFControls)
+        {
+            if (name == null)
+            {
+                throw new ArgumentNullException(nameof(name));
+            }
+
+            this.name = name;
+            this.areWPFControls = areWPFControls;
+        }
+
+        /// <summary>
+        /// Called to register this attribute with the given context. The context
+        /// contains the location where the registration information should be placed.
+        /// It also contains other information such as the type being registered and path information.
+        /// </summary>
+        /// <param name="context">Given context to register in.</param>
+        public override void Register(RegistrationContext context)
+        {
+            if (context == null)
+            {
+                throw new ArgumentNullException(nameof(context));
+            }
+
+            using (Key key = context.CreateKey(string.Format(CultureInfo.InvariantCulture, "{0}\\{1}",
+                                                             ToolboxControlsInstallerPath,
+                                                             context.ComponentType.Assembly.FullName)))
+            {
+                key.SetValue(string.Empty, this.name);
+                key.SetValue("Codebase", context.CodeBase);
+                if (this.areWPFControls)
+                {
+                    key.SetValue("WPFControls", "1");
+                }
+            }
+        }
+
+        /// <summary>
+        /// Called to unregister this attribute with the given context.
+        /// </summary>
+        /// <param name="context">A registration context provided by an external registration tool. 
+        /// The context can be used to remove registry keys, log registration activity, and obtain information
+        /// about the component being registered.</param>
+        public override void Unregister(RegistrationContext context)
+        {
+            if (context != null)
+            {
+                context.RemoveKey(string.Format(CultureInfo.InvariantCulture, "{0}\\{1}",
+                                                             ToolboxControlsInstallerPath,
+                                                             context.ComponentType.Assembly.FullName));
+            }
+        }
+    }
+}
diff --git a/src/CodeIndex.VisualStudioExtension/Resources/CodeIndexSearchWindowCommand.png b/src/CodeIndex.VisualStudioExtension/Resources/CodeIndexSearchWindowCommand.png
new file mode 100644
index 0000000..b22d975
Binary files /dev/null and b/src/CodeIndex.VisualStudioExtension/Resources/CodeIndexSearchWindowCommand.png differ
diff --git a/src/CodeIndex.VisualStudioExtension/Resources/Style.xaml b/src/CodeIndex.VisualStudioExtension/Resources/Style.xaml
new file mode 100644
index 0000000..4f44c3d
--- /dev/null
+++ b/src/CodeIndex.VisualStudioExtension/Resources/Style.xaml
@@ -0,0 +1,3 @@
+<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
+    
+</ResourceDictionary>
\ No newline at end of file
diff --git a/src/CodeIndex.VisualStudioExtension/VisualStudioExtensionPackage.vsct b/src/CodeIndex.VisualStudioExtension/VisualStudioExtensionPackage.vsct
new file mode 100644
index 0000000..55d5c59
--- /dev/null
+++ b/src/CodeIndex.VisualStudioExtension/VisualStudioExtensionPackage.vsct
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="utf-8"?>
+<CommandTable xmlns="http://schemas.microsoft.com/VisualStudio/2005-10-18/CommandTable" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+  <!--  This is the file that defines the actual layout and type of the commands.
+        It is divided in different sections (e.g. command definition, command
+        placement, ...), with each defining a specific set of properties.
+        See the comment before each section for more details about how to
+        use it. -->
+
+  <!--  The VSCT compiler (the tool that translates this file into the binary
+        format that VisualStudio will consume) has the ability to run a preprocessor
+        on the vsct file; this preprocessor is (usually) the C++ preprocessor, so
+        it is possible to define includes and macros with the same syntax used
+        in C++ files. Using this ability of the compiler here, we include some files
+        defining some of the constants that we will use inside the file. -->
+
+  <!--This is the file that defines the IDs for all the commands exposed by VisualStudio. -->
+  <Extern href="stdidcmd.h" />
+
+  <!--This header contains the command ids for the menus provided by the shell. -->
+  <Extern href="vsshlids.h" />
+
+  <!--The Commands section is where commands, menus, and menu groups are defined.
+      This section uses a Guid to identify the package that provides the command defined inside it. -->
+  <Commands package="guidVisualStudioExtensionPackage">
+    <!-- Inside this section we have different sub-sections: one for the menus, another
+    for the menu groups, one for the buttons (the actual commands), one for the combos
+    and the last one for the bitmaps used. Each element is identified by a command id that
+    is a unique pair of guid and numeric identifier; the guid part of the identifier is usually
+    called "command set" and is used to group different command inside a logically related
+    group; your package should define its own command set in order to avoid collisions
+    with command ids defined by other packages. -->
+
+    <!--Buttons section. -->
+    <!--This section defines the elements the user can interact with, like a menu command or a button
+        or combo box in a toolbar. -->
+    <Buttons>
+      <!--To define a menu group you have to specify its ID, the parent menu and its display priority.
+          The command is visible and enabled by default. If you need to change the visibility, status, etc, you can use
+          the CommandFlag node.
+          You can add more than one CommandFlag node e.g.:
+              <CommandFlag>DefaultInvisible</CommandFlag>
+              <CommandFlag>DynamicVisibility</CommandFlag>
+          If you do not want an image next to your command, remove the Icon node /> -->
+      <Button guid="guidVisualStudioExtensionPackageCmdSet" id="cmdidCodeIndexSearchWindowCommand" priority="0x0100" type="Button">
+        <Parent guid="guidSHLMainMenu" id="IDG_VS_WNDO_OTRWNDWS1" />
+        <Icon guid="guidImages1" id="bmpPicSearch" />
+        <Strings>
+          <ButtonText>Code Index Search</ButtonText>
+        </Strings>
+      </Button>
+    </Buttons>
+
+    <!--The bitmaps section is used to define the bitmaps that are used for the commands.-->
+    <Bitmaps>
+      <!--  The bitmap id is defined in a way that is a little bit different from the others:
+            the declaration starts with a guid for the bitmap strip, then there is the resource id of the
+            bitmap strip containing the bitmaps and then there are the numeric ids of the elements used
+            inside a button definition. An important aspect of this declaration is that the element id
+            must be the actual index (1-based) of the bitmap inside the bitmap strip. -->
+      <Bitmap guid="guidImages1" href="Resources\CodeIndexSearchWindowCommand.png" usedList="bmpPic1, bmpPic2, bmpPicSearch, bmpPicX, bmpPicArrows, bmpPicStrikethrough" />
+    </Bitmaps>
+  </Commands>
+
+  <Symbols>
+    <!-- This is the package guid. -->
+    <GuidSymbol name="guidVisualStudioExtensionPackage" value="{1eaddb39-c1f2-42e2-807d-234d73e8ef2a}" />
+
+    <!-- This is the guid used to group the menu commands together -->
+    <GuidSymbol name="guidVisualStudioExtensionPackageCmdSet" value="{c025b4ef-e6ed-42b4-9c22-2d6835421d25}">
+      <IDSymbol value="4129" name="cmdidCodeIndexSearchWindowCommand" />
+    </GuidSymbol>
+
+    <GuidSymbol name="guidImages" value="{8f96059a-9439-496a-91a0-b937e25c4e41}">
+      <IDSymbol name="bmpPic1" value="1" />
+      <IDSymbol name="bmpPic2" value="2" />
+      <IDSymbol name="bmpPicSearch" value="3" />
+      <IDSymbol name="bmpPicX" value="4" />
+      <IDSymbol name="bmpPicArrows" value="5" />
+      <IDSymbol name="bmpPicStrikethrough" value="6" />
+    </GuidSymbol>
+  
+    <GuidSymbol value="{3e596c47-5e3e-4915-aff5-dd8a8b1394a9}" name="guidImages1">
+      <IDSymbol name="bmpPic1" value="1" />
+      <IDSymbol name="bmpPic2" value="2" />
+      <IDSymbol name="bmpPicSearch" value="3" />
+      <IDSymbol name="bmpPicX" value="4" />
+      <IDSymbol name="bmpPicArrows" value="5" />
+      <IDSymbol name="bmpPicStrikethrough" value="6" />
+    </GuidSymbol>
+  </Symbols>
+</CommandTable>
diff --git a/src/CodeIndex.VisualStudioExtension/app.config b/src/CodeIndex.VisualStudioExtension/app.config
new file mode 100644
index 0000000..6902a91
--- /dev/null
+++ b/src/CodeIndex.VisualStudioExtension/app.config
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<configuration>
+    <configSections>
+        <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
+            <section name="CodeIndex.VisualStudioExtension.Properties.CodeIndexSettings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
+        </sectionGroup>
+    </configSections>
+    <userSettings>
+        <CodeIndex.VisualStudioExtension.Properties.CodeIndexSettings>
+            <setting name="ServiceUrl" serializeAs="String">
+                <value>https://codeindex.qhnetdisk.tk/</value>
+            </setting>
+        </CodeIndex.VisualStudioExtension.Properties.CodeIndexSettings>
+    </userSettings>
+</configuration>
\ No newline at end of file
diff --git a/src/CodeIndex.VisualStudioExtension/source.extension.vsixmanifest b/src/CodeIndex.VisualStudioExtension/source.extension.vsixmanifest
new file mode 100644
index 0000000..81ee373
--- /dev/null
+++ b/src/CodeIndex.VisualStudioExtension/source.extension.vsixmanifest
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<PackageManifest Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011" xmlns:d="http://schemas.microsoft.com/developer/vsx-schema-design/2011">
+    <Metadata>
+        <Identity Id="CodeIndex.VisualStudioExtension.3fee47f7-831c-4577-8b21-f6505d9699f5" Version="1.0" Language="en-US" Publisher="笑问苍天" />
+        <DisplayName>CodeIndex.VisualStudioExtension</DisplayName>
+        <Description xml:space="preserve">Code Index Search Extension For Visual Studio</Description>
+        <MoreInfo>https://github.com/qiuhaotc/CodeIndex</MoreInfo>
+        <Tags>Code full-text search</Tags>
+        <Preview>true</Preview>
+    </Metadata>
+    <Installation>
+        <InstallationTarget Id="Microsoft.VisualStudio.Community" Version="[16.0, 17.0)" />
+    </Installation>
+    <Dependencies>
+        <Dependency Id="Microsoft.Framework.NDP" DisplayName="Microsoft .NET Framework" d:Source="Manual" Version="[4.5,)" />
+    </Dependencies>
+    <Prerequisites>
+        <Prerequisite Id="Microsoft.VisualStudio.Component.CoreEditor" Version="[16.0,17.0)" DisplayName="Visual Studio core editor" />
+    </Prerequisites>
+    <Assets>
+        <Asset Type="Microsoft.VisualStudio.VsPackage" d:Source="Project" d:ProjectName="%CurrentProject%" Path="|%CurrentProject%;PkgdefProjectOutputGroup|" />
+        <Asset Type="Microsoft.VisualStudio.ToolboxControl" d:Source="Project" d:ProjectName="%CurrentProject%" Path="|%CurrentProject%;PkgdefProjectOutputGroup|" />
+    </Assets>
+</PackageManifest>
diff --git a/src/CodeIndex.sln b/src/CodeIndex.sln
index 9cea751..6d8f411 100644
--- a/src/CodeIndex.sln
+++ b/src/CodeIndex.sln
@@ -26,6 +26,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "doc", "doc", "{B0519424-9D6
 		..\doc\WebServer.png = ..\doc\WebServer.png
 	EndProjectSection
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeIndex.VisualStudioExtension", "CodeIndex.VisualStudioExtension\CodeIndex.VisualStudioExtension.csproj", "{ED1D3026-8695-4B9B-9FA9-2D68E28EE850}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -64,6 +66,10 @@ Global
 		{BE1F4C0F-F4FF-43B0-B8F2-2C1F9B446059}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{BE1F4C0F-F4FF-43B0-B8F2-2C1F9B446059}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{BE1F4C0F-F4FF-43B0-B8F2-2C1F9B446059}.Release|Any CPU.Build.0 = Release|Any CPU
+		{ED1D3026-8695-4B9B-9FA9-2D68E28EE850}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{ED1D3026-8695-4B9B-9FA9-2D68E28EE850}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{ED1D3026-8695-4B9B-9FA9-2D68E28EE850}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{ED1D3026-8695-4B9B-9FA9-2D68E28EE850}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE