diff --git a/src/Orchard.Web/Orchard.Web.csproj b/src/Orchard.Web/Orchard.Web.csproj
index f163cd1fa..1fae8dd81 100644
--- a/src/Orchard.Web/Orchard.Web.csproj
+++ b/src/Orchard.Web/Orchard.Web.csproj
@@ -118,6 +118,10 @@
{2D1D92BB-4555-4CBE-8D0E-63563D6CE4C6}
Orchard.Framework
+
+ {71A006E0-85BD-4CC4-ADF9-B548D5CA72A7}
+ OrchardCLI
+
{33B1BC8D-E292-4972-A363-22056B207156}
Orchard
diff --git a/src/Orchard.sln b/src/Orchard.sln
index 5513613d2..b38424da6 100644
--- a/src/Orchard.sln
+++ b/src/Orchard.sln
@@ -73,6 +73,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lucene", "Orchard.Web\Modul
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Orchard.Packaging", "Orchard.Web\Modules\Orchard.Packaging\Orchard.Packaging.csproj", "{DFD137A2-DDB5-4D22-BE0D-FA9AD4C8B059}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OrchardCLI", "Tools\OrchardCli\OrchardCLI.csproj", "{71A006E0-85BD-4CC4-ADF9-B548D5CA72A7}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -207,6 +209,10 @@ Global
{DFD137A2-DDB5-4D22-BE0D-FA9AD4C8B059}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DFD137A2-DDB5-4D22-BE0D-FA9AD4C8B059}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DFD137A2-DDB5-4D22-BE0D-FA9AD4C8B059}.Release|Any CPU.Build.0 = Release|Any CPU
+ {71A006E0-85BD-4CC4-ADF9-B548D5CA72A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {71A006E0-85BD-4CC4-ADF9-B548D5CA72A7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {71A006E0-85BD-4CC4-ADF9-B548D5CA72A7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {71A006E0-85BD-4CC4-ADF9-B548D5CA72A7}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -240,6 +246,7 @@ Global
{4AB4B5B6-277E-4FF6-B69B-7AE9E16D2A56} = {383DBA32-4A3E-48D1-AAC3-75377A694452}
{33B1BC8D-E292-4972-A363-22056B207156} = {383DBA32-4A3E-48D1-AAC3-75377A694452}
{8A4E42CE-79F8-4BE2-8B1E-A6B83432123B} = {383DBA32-4A3E-48D1-AAC3-75377A694452}
+ {71A006E0-85BD-4CC4-ADF9-B548D5CA72A7} = {383DBA32-4A3E-48D1-AAC3-75377A694452}
{E65E5633-C0FF-453C-A906-481C14F969D6} = {E75A4CE4-CAA6-41E4-B951-33ACC60DC77C}
EndGlobalSection
EndGlobal
diff --git a/src/Tools/Orchard/ApplicationObject.cs b/src/Tools/Orchard/ApplicationObject.cs
index d1755945c..f73b5bdf0 100644
--- a/src/Tools/Orchard/ApplicationObject.cs
+++ b/src/Tools/Orchard/ApplicationObject.cs
@@ -1,9 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace Orchard {
+namespace Orchard {
public class ApplicationObject {
public string ApplicationId { get; set; }
public object ObjectInstance { get; set; }
diff --git a/src/Tools/Orchard/Host/CommandHost.cs b/src/Tools/Orchard/Host/CommandHost.cs
index 1620ffe7a..ac3735f1d 100644
--- a/src/Tools/Orchard/Host/CommandHost.cs
+++ b/src/Tools/Orchard/Host/CommandHost.cs
@@ -7,7 +7,14 @@ using Orchard.Parameters;
using Orchard.ResponseFiles;
namespace Orchard.Host {
- class CommandHost : MarshalByRefObject, IRegisteredObject {
+ ///
+ /// The CommandHost runs inside the ASP.NET AppDomain and serves as an intermediate
+ /// between the command line and the CommandHostAgent, which is known to the Orchard
+ /// Framework and has the ability to execute commands.
+ ///
+ public class CommandHost : MarshalByRefObject, IRegisteredObject {
+ private object _agent;
+
public CommandHost() {
HostingEnvironment.RegisterObject(this);
}
@@ -17,12 +24,24 @@ namespace Orchard.Host {
return null;
}
- public void Stop(bool immediate) {
+ void IRegisteredObject.Stop(bool immediate) {
HostingEnvironment.UnregisterObject(this);
}
+ public void StartSession(TextReader input, TextWriter output) {
+ _agent = CreateAgent();
+ StartHost(_agent, input, output);
+ }
+
+ public void StopSession(TextReader input, TextWriter output) {
+ if (_agent != null) {
+ StopHost(_agent, input, output);
+ _agent = null;
+ }
+ }
+
public int RunCommand(TextReader input, TextWriter output, Logger logger, OrchardParameters args) {
- var agent = Activator.CreateInstance("Orchard.Framework", "Orchard.Commands.CommandHostAgent").Unwrap();
+ var agent = CreateAgent();
int result = (int)agent.GetType().GetMethod("RunSingleCommand").Invoke(agent, new object[] {
input,
output,
@@ -33,10 +52,21 @@ namespace Orchard.Host {
return result;
}
- public int RunCommands(TextReader input, TextWriter output, Logger logger, IEnumerable responseLines) {
- var agent = Activator.CreateInstance("Orchard.Framework", "Orchard.Commands.CommandHostAgent").Unwrap();
+ public int RunCommandInSession(TextReader input, TextWriter output, Logger logger, OrchardParameters args) {
+ int result = (int)_agent.GetType().GetMethod("RunCommand").Invoke(_agent, new object[] {
+ input,
+ output,
+ args.Tenant,
+ args.Arguments.ToArray(),
+ args.Switches});
- int result = (int)agent.GetType().GetMethod("StartHost").Invoke(agent, new object[] { input, output });
+ return result;
+ }
+
+ public int RunCommands(TextReader input, TextWriter output, Logger logger, IEnumerable responseLines) {
+ var agent = CreateAgent();
+
+ int result = StartHost(agent, input, output);
if (result != 0)
return result;
@@ -58,8 +88,20 @@ namespace Orchard.Host {
}
}
- result = (int)agent.GetType().GetMethod("StopHost").Invoke(agent, new object[] { input, output });
+ result = StopHost(agent, input, output);
return result;
}
+
+ private object CreateAgent() {
+ return Activator.CreateInstance("Orchard.Framework", "Orchard.Commands.CommandHostAgent").Unwrap();
+ }
+
+ private int StopHost(object agent, TextReader input, TextWriter output) {
+ return (int)agent.GetType().GetMethod("StopHost").Invoke(agent, new object[] { input, output });
+ }
+
+ private int StartHost(object agent, TextReader input, TextWriter output) {
+ return (int)agent.GetType().GetMethod("StartHost").Invoke(agent, new object[] { input, output });
+ }
}
}
diff --git a/src/Tools/Orchard/ResponseFiles/ResponseFileReader.cs b/src/Tools/Orchard/ResponseFiles/ResponseFileReader.cs
index 4209e065e..037039c41 100644
--- a/src/Tools/Orchard/ResponseFiles/ResponseFileReader.cs
+++ b/src/Tools/Orchard/ResponseFiles/ResponseFileReader.cs
@@ -30,7 +30,7 @@ namespace Orchard.ResponseFiles {
}
}
- private IEnumerable SplitArgs(string text) {
+ public static IEnumerable SplitArgs(string text) {
var sb = new StringBuilder();
bool inString = false;
foreach (char ch in text) {
diff --git a/src/Tools/OrchardCli/CLIHost.cs b/src/Tools/OrchardCli/CLIHost.cs
new file mode 100644
index 000000000..eed4be53a
--- /dev/null
+++ b/src/Tools/OrchardCli/CLIHost.cs
@@ -0,0 +1,63 @@
+using System;
+using System.IO;
+using Orchard;
+using Orchard.Parameters;
+using Orchard.ResponseFiles;
+
+namespace OrchardCLI {
+ class CLIHost {
+ private readonly TextWriter _output;
+ private readonly TextReader _input;
+ private readonly ICommandHostContextProvider _commandHostContextProvider;
+
+ public CLIHost(string[] args) {
+ _input = Console.In;
+ _output = Console.Out;
+ _commandHostContextProvider = new CommandHostContextProvider(args);
+ }
+
+ public int Run() {
+ var context = _commandHostContextProvider.CreateContext();
+
+ while (true) {
+ var command = ReadCommand(context);
+ switch (command.ToLowerInvariant()) {
+ case "quit":
+ case "q":
+ case "exit":
+ case "e":
+ _commandHostContextProvider.Shutdown(context);
+ return 0;
+ default:
+ context = RunCommand(context, command);
+ break;
+ }
+ }
+ }
+
+ private string ReadCommand(CommandHostContext context) {
+ Console.WriteLine();
+ Console.Write("orchard> ");
+ return Console.ReadLine();
+ }
+
+ private CommandHostContext RunCommand(CommandHostContext context, string command) {
+ int result = RunCommandInSession(context, command);
+ if(result == 240) {
+ if (result == 240/*special return code for "Retry"*/) {
+ _commandHostContextProvider.Shutdown(context);
+ context = _commandHostContextProvider.CreateContext();
+ result = RunCommandInSession(context, command);
+ if (result != 0)
+ Console.WriteLine("Command returned non-zero result: {0}", result);
+ }
+ }
+ return context;
+ }
+
+ private int RunCommandInSession(CommandHostContext context, string command) {
+ var args = new OrchardParametersParser().Parse(new CommandParametersParser().Parse(ResponseFileReader.SplitArgs(command)));
+ return context.CommandHost.RunCommandInSession(_input, _output, context.Logger, args);
+ }
+ }
+}
diff --git a/src/Tools/OrchardCli/CommandHostContext.cs b/src/Tools/OrchardCli/CommandHostContext.cs
new file mode 100644
index 000000000..b716caf73
--- /dev/null
+++ b/src/Tools/OrchardCli/CommandHostContext.cs
@@ -0,0 +1,16 @@
+using System;
+using System.IO;
+using System.Web.Hosting;
+using Orchard;
+using Orchard.Host;
+
+namespace OrchardCLI {
+ public class CommandHostContext {
+ public OrchardParameters Arguments { get; set; }
+ public DirectoryInfo OrchardDirectory { get; set; }
+ public ApplicationManager AppManager { get; set; }
+ public ApplicationObject AppObject { get; set; }
+ public CommandHost CommandHost { get; set; }
+ public Logger Logger { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/Tools/OrchardCli/CommandHostContextProvider.cs b/src/Tools/OrchardCli/CommandHostContextProvider.cs
new file mode 100644
index 000000000..038ccd973
--- /dev/null
+++ b/src/Tools/OrchardCli/CommandHostContextProvider.cs
@@ -0,0 +1,200 @@
+using System;
+using System.Globalization;
+using System.IO;
+using System.Reflection;
+using System.Web;
+using System.Web.Hosting;
+using Orchard;
+using Orchard.Host;
+using Orchard.Parameters;
+
+namespace OrchardCLI {
+ public class CommandHostContextProvider : ICommandHostContextProvider{
+ private readonly string[] _args;
+ private TextWriter _output;
+ private TextReader _input;
+
+ public CommandHostContextProvider(string[] args) {
+ _input = Console.In;
+ _output = Console.Out;
+ _args = args;
+ }
+
+ public CommandHostContext CreateContext() {
+ var context = new CommandHostContext();
+ Initialize(context);
+ return context;
+ }
+
+ public void Shutdown(CommandHostContext context) {
+ ShutdownHost(context);
+ }
+
+ private void Initialize(CommandHostContext context) {
+ context.Arguments = new OrchardParametersParser().Parse(new CommandParametersParser().Parse(_args));
+ context.Logger = new Logger(context.Arguments.Verbose, _output);
+
+ // Perform some argument validation and display usage if something is incorrect
+ bool showHelp = context.Arguments.Switches.ContainsKey("?");
+ if (!showHelp) {
+ //showHelp = (!_arguments.Arguments.Any() && !_arguments.ResponseFiles.Any());
+ }
+
+ if (!showHelp) {
+ //showHelp = (_arguments.Arguments.Any() && _arguments.ResponseFiles.Any());
+ //if (showHelp) {
+ // _output.WriteLine("Incorrect syntax: Response files cannot be used in conjunction with commands");
+ //}
+ }
+
+ if (showHelp) {
+ GeneralHelp();
+ return;
+ }
+
+ if (string.IsNullOrEmpty(context.Arguments.VirtualPath))
+ context.Arguments.VirtualPath = "/";
+ LogInfo(context, "Virtual path: \"{0}\"", context.Arguments.VirtualPath);
+
+ if (string.IsNullOrEmpty(context.Arguments.WorkingDirectory))
+ context.Arguments.WorkingDirectory = Environment.CurrentDirectory;
+ LogInfo(context, "Working directory: \"{0}\"", context.Arguments.WorkingDirectory);
+
+ LogInfo(context, "Detecting orchard installation root directory...");
+ context.OrchardDirectory = GetOrchardDirectory(context.Arguments.WorkingDirectory);
+ LogInfo(context, "Orchard root directory: \"{0}\"", context.OrchardDirectory.FullName);
+
+ CreateHost(context);
+ context.CommandHost.StartSession(_input, _output);
+ }
+
+ private void CreateHost(CommandHostContext context) {
+ context.AppManager = ApplicationManager.GetApplicationManager();
+
+ LogInfo(context, "Creating ASP.NET AppDomain for command agent...");
+ context.AppObject = CreateWorkerAppDomainWithHost(context.AppManager, context.Arguments.VirtualPath, context.OrchardDirectory.FullName, typeof(CommandHost));
+ context.CommandHost = (CommandHost)context.AppObject.ObjectInstance;
+ }
+
+ private void ShutdownHost(CommandHostContext context) {
+ if (context.CommandHost != null) {
+ context.CommandHost.StopSession(_input, _output);
+ }
+
+ if (context.AppObject != null) {
+ LogInfo(context, "Shutting down ASP.NET AppDomain...");
+ context.AppManager.ShutdownApplication(context.AppObject.ApplicationId);
+ }
+ }
+
+ private int GeneralHelp() {
+ _output.WriteLine("Executes Orchard commands from a Orchard installation directory.");
+ _output.WriteLine("");
+ _output.WriteLine("Usage:");
+ _output.WriteLine(" orchard.exe command [arg1] ... [argn] [/switch1[:value1]] ... [/switchn[:valuen]]");
+ _output.WriteLine(" orchard.exe @response-file1 ... [@response-filen] [/switch1[:value1]] ... [/switchn[:valuen]]");
+ _output.WriteLine("");
+ _output.WriteLine(" command");
+ _output.WriteLine(" Specify the command to execute");
+ _output.WriteLine("");
+ _output.WriteLine(" [arg1] ... [argn]");
+ _output.WriteLine(" Specify additional arguments for the command");
+ _output.WriteLine("");
+ _output.WriteLine(" [/switch1[:value1]] ... [/switchn[:valuen]]");
+ _output.WriteLine(" Specify switches to apply to the command. Available switches generally ");
+ _output.WriteLine(" depend on the command executed, with the exception of a few built-in ones.");
+ _output.WriteLine("");
+ _output.WriteLine(" [@response-file1] ... [@response-filen]");
+ _output.WriteLine(" Specify one or more response files to be used for reading commands and switches.");
+ _output.WriteLine(" A response file is a text file that contains one line per command to execute.");
+ _output.WriteLine("");
+ _output.WriteLine(" Built-in commands");
+ _output.WriteLine(" =================");
+ _output.WriteLine("");
+ _output.WriteLine(" help commands");
+ _output.WriteLine(" Display the list of available commands.");
+ _output.WriteLine("");
+ _output.WriteLine(" help ");
+ _output.WriteLine(" Display help for a given command.");
+ _output.WriteLine("");
+ _output.WriteLine(" Built-in switches");
+ _output.WriteLine(" =================");
+ _output.WriteLine("");
+ _output.WriteLine(" /WorkingDirectory:");
+ _output.WriteLine(" /wd:");
+ _output.WriteLine(" Specifies the orchard installation directory. The current directory is the default.");
+ _output.WriteLine("");
+ _output.WriteLine(" /Verbose");
+ _output.WriteLine(" /v");
+ _output.WriteLine(" Turn on verbose output");
+ _output.WriteLine("");
+ _output.WriteLine(" /VirtualPath:");
+ _output.WriteLine(" /vp:");
+ _output.WriteLine(" Virtual path to pass to the WebHost. Empty (i.e. root path) by default.");
+ _output.WriteLine("");
+ _output.WriteLine(" /Tenant:tenant-name");
+ _output.WriteLine(" /t:tenant-name");
+ _output.WriteLine(" Specifies which tenant to run the command into. \"Default\" tenant by default.");
+ _output.WriteLine("");
+ return 1;
+ }
+
+ private void LogInfo(CommandHostContext context, string format, params object[] args) {
+ if (context.Logger != null)
+ context.Logger.LogInfo(format, args);
+ }
+
+ private DirectoryInfo GetOrchardDirectory(string directory) {
+ for (var directoryInfo = new DirectoryInfo(directory); directoryInfo != null; directoryInfo = directoryInfo.Parent) {
+ if (!directoryInfo.Exists) {
+ throw new ApplicationException(string.Format("Directory \"{0}\" does not exist", directoryInfo.FullName));
+ }
+
+ // We look for
+ // 1) .\web.config
+ // 2) .\bin\Orchard.Framework.dll
+ var webConfigFileInfo = new FileInfo(Path.Combine(directoryInfo.FullName, "web.config"));
+ if (!webConfigFileInfo.Exists)
+ continue;
+
+ var binDirectoryInfo = new DirectoryInfo(Path.Combine(directoryInfo.FullName, "bin"));
+ if (!binDirectoryInfo.Exists)
+ continue;
+
+ var orchardFrameworkFileInfo = new FileInfo(Path.Combine(binDirectoryInfo.FullName, "Orchard.Framework.dll"));
+ if (!orchardFrameworkFileInfo.Exists)
+ continue;
+
+ return directoryInfo;
+ }
+
+ throw new ApplicationException(
+ string.Format("Directory \"{0}\" doesn't seem to contain an Orchard installation", new DirectoryInfo(directory).FullName));
+ }
+
+ private static ApplicationObject CreateWorkerAppDomainWithHost(ApplicationManager appManager, string virtualPath, string physicalPath, Type hostType) {
+ // this creates worker app domain in a way that host doesn't need to be in GAC or bin
+ // using BuildManagerHost via private reflection
+ string uniqueAppString = string.Concat(virtualPath, physicalPath).ToLowerInvariant();
+ string appId = (uniqueAppString.GetHashCode()).ToString("x", CultureInfo.InvariantCulture);
+
+ // create BuildManagerHost in the worker app domain
+ var buildManagerHostType = typeof(HttpRuntime).Assembly.GetType("System.Web.Compilation.BuildManagerHost");
+ var buildManagerHost = appManager.CreateObject(appId, buildManagerHostType, virtualPath, physicalPath, false);
+
+ // call BuildManagerHost.RegisterAssembly to make Host type loadable in the worker app domain
+ buildManagerHostType.InvokeMember(
+ "RegisterAssembly",
+ BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.NonPublic,
+ null,
+ buildManagerHost,
+ new object[] { hostType.Assembly.FullName, hostType.Assembly.Location });
+
+ // create Host in the worker app domain
+ return new ApplicationObject {
+ ApplicationId = appId,
+ ObjectInstance = appManager.CreateObject(appId, hostType, virtualPath, physicalPath, false)
+ };
+ }
+ }
+}
diff --git a/src/Tools/OrchardCli/ICommandHostContextProvider.cs b/src/Tools/OrchardCli/ICommandHostContextProvider.cs
new file mode 100644
index 000000000..8a75c4309
--- /dev/null
+++ b/src/Tools/OrchardCli/ICommandHostContextProvider.cs
@@ -0,0 +1,6 @@
+namespace OrchardCLI {
+ public interface ICommandHostContextProvider {
+ CommandHostContext CreateContext();
+ void Shutdown(CommandHostContext context);
+ }
+}
\ No newline at end of file
diff --git a/src/Tools/OrchardCli/OrchardCLI.csproj b/src/Tools/OrchardCli/OrchardCLI.csproj
new file mode 100644
index 000000000..400875631
--- /dev/null
+++ b/src/Tools/OrchardCli/OrchardCLI.csproj
@@ -0,0 +1,147 @@
+
+
+
+ Debug
+ AnyCPU
+ 9.0.30729
+ 2.0
+ {71A006E0-85BD-4CC4-ADF9-B548D5CA72A7}
+ Exe
+ Properties
+ OrchardCLI
+ OrchardCLI
+ v4.0
+ 512
+
+
+ 3.5
+
+ false
+
+ publish\
+ true
+ Disk
+ false
+ Foreground
+ 7
+ Days
+ false
+ false
+ true
+ 0
+ 1.0.0.%2a
+ false
+ true
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ true
+ AnyCPU
+ AllRules.ruleset
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ AnyCPU
+ AllRules.ruleset
+
+
+
+
+ 3.5
+
+
+
+ 3.5
+
+
+ 3.5
+
+
+
+
+
+
+ ApplicationObject.cs
+
+
+ Host\CommandHost.cs
+
+
+ IOrchardParametersParser.cs
+
+
+ Logger.cs
+
+
+ OrchardParameters.cs
+
+
+ OrchardParametersParser.cs
+
+
+ Parameters\CommandParameters.cs
+
+
+ Parameters\CommandParametersParser.cs
+
+
+ Parameters\CommandSwitch.cs
+
+
+ Parameters\ICommandParametersParser.cs
+
+
+ ResponseFiles\ResponseFileReader.cs
+
+
+ ResponseFiles\ResponseFiles.cs
+
+
+
+
+
+
+
+
+
+
+ False
+ .NET Framework 3.5 SP1 Client Profile
+ false
+
+
+ False
+ .NET Framework 3.5 SP1
+ true
+
+
+ False
+ Windows Installer 3.1
+ true
+
+
+
+
+ Designer
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Tools/OrchardCli/Program.cs b/src/Tools/OrchardCli/Program.cs
new file mode 100644
index 000000000..4f4eb0588
--- /dev/null
+++ b/src/Tools/OrchardCli/Program.cs
@@ -0,0 +1,7 @@
+namespace OrchardCLI {
+ public class Program {
+ public static int Main(string[] args) {
+ return new CLIHost(args).Run();
+ }
+ }
+}
diff --git a/src/Tools/OrchardCli/Properties/AssemblyInfo.cs b/src/Tools/OrchardCli/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..2e620e743
--- /dev/null
+++ b/src/Tools/OrchardCli/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+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("OrchardCLI")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Orchard")]
+[assembly: AssemblyCopyright("Copyright © CodePlex Foundation 2009")]
+[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)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("5ee627dd-b767-441e-b8d0-ec7d26faac49")]
+
+// 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.5.0")]
+[assembly: AssemblyFileVersion("0.5.0")]
diff --git a/src/Tools/OrchardCli/app.config b/src/Tools/OrchardCli/app.config
new file mode 100644
index 000000000..21ac8f3ab
--- /dev/null
+++ b/src/Tools/OrchardCli/app.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+