2013-12-14 3 views
4

Моя конкретная проблема заключается в том, как я могу автоматизировать «добавление-перенос» в процессе сборки для Entity Framework. В исследовании это, кажется, в основном, вероятно, подход что-то вдоль линий автоматизации этих шаговКак автоматизировать консоль диспетчера пакетов в Visual Studio 2013

  1. Открыть решение в Visual Studio 2013
  2. Выполнить «Add-Migration blahblah» в Package Manager Console (скорее всего, с помощью дополнения в vsextention)
  3. Закрыть решение

Этот первоначальный подход основан на моих собственных исследованиях и this question, тем PowerShell сценарий в конечном счете, за надстройку миграция требует совсем немного настройки для запуска. Visual Studio автоматически выполняет эту настройку при создании консоли диспетчера пакетов и создании объекта DTE. Я бы предпочел не пытаться дублировать эту настройку вне Visual Studio.

Один возможный путь к решению это без ответа переполнение стека question

В исследовании API NuGet, он не появляется, чтобы иметь «послать этот текст, и он будет работать, как он был напечатан в консоли» , Я не понимаю, что такое Visual Studio vs NuGet, поэтому я не уверен, что это то, что было бы там.

Я могу с легкостью найти «Консоль менеджера Pacakage» через команду «$ dte.Windows» в консоли диспетчера пакетов, но в окне VS 2013 эта коллекция дает мне объекты, которые являются «Microsoft.VisualStudio.Platform .WindowManagement.DTE.WindowBase». Если в нем есть текст материала, я думаю, мне нужно, чтобы это было NuGetConsole.Implementation.PowerConsoleToolWindow ", просмотрев source code. Я не понимаю, как текст будет набит, но я совсем не знаком с тем, что я видя.

в худшем случае, я буду падать обратно к попытке ключей Наполните его вдоль линий this question но предпочел бы не так, что существенно усложняет автоматизацию окружающего процесса сборки.

Всего этих существ

  1. Возможно ли передавать команды через код в Packag e Консоль менеджера в Visual Studio, которая полностью инициализирована и может поддерживать команду «добавить-перенаправить» в Entity Framework?

Спасибо за любые предложения, советы, помощь, не-злоупотреблений заранее,

Джон

+0

Вы пытались использовать SendKeys, чтобы просто нажимать нажатия клавиш на WindowBase? http://msdn.microsoft.com/en-us/library/system.windows.forms.sendkeys(v=vs.110).aspx – jessehouwing

+0

Я/не пробовал SendKeys. Я рассматривал это как мое последнее решение канавы. Сначала я придумал подход ниже. –

+0

Чтобы получить окно PMC, вы можете вызвать 'DTE.ExecuteCommand (« View.PackageManagerConsole »), а затем« DTE.ActiveWindow »будет окном PMC. Я до сих пор не понял, как отправить текст на него. – Jonathan

ответ

5

Подход, который работал для меня было проследить в Entity Framework код, начинающийся в с AddMigrationCommand. cs в проекте EntityFramework.Powershell и найдите крючки в проекте EntityFramework, а затем сделайте эти перехватчики, чтобы не было зависимости от Powershell.

Вы можете получить что-то вроде ...

public static void RunIt(EnvDTE.Project project, Type dbContext, Assembly migrationAssembly, string migrationDirectory, 
     string migrationsNamespace, string contextKey, string migrationName) 
    { 
     DbMigrationsConfiguration migrationsConfiguration = new DbMigrationsConfiguration(); 
     migrationsConfiguration.AutomaticMigrationDataLossAllowed = false; 
     migrationsConfiguration.AutomaticMigrationsEnabled = false; 
     migrationsConfiguration.CodeGenerator = new CSharpMigrationCodeGenerator(); //same as default 
     migrationsConfiguration.ContextType = dbContext; //data 
     migrationsConfiguration.ContextKey = contextKey; 
     migrationsConfiguration.MigrationsAssembly = migrationAssembly; 
     migrationsConfiguration.MigrationsDirectory = migrationDirectory; 
     migrationsConfiguration.MigrationsNamespace = migrationsNamespace; 

     System.Data.Entity.Infrastructure.DbConnectionInfo dbi = new System.Data.Entity.Infrastructure.DbConnectionInfo("DataContext"); 
     migrationsConfiguration.TargetDatabase = dbi; 

     MigrationScaffolder ms = new MigrationScaffolder(migrationsConfiguration); 

     ScaffoldedMigration sf = ms.Scaffold(migrationName, false); 

    } 

Вы можете использовать this question, чтобы добраться до объекта DTE и оттуда, чтобы найти объект проекта передать в вызов.

0

Это сообщение для ответа Джона, которого я должен поблагодарить за «трудную часть», но вот полный пример, который создает перенос, и добавляет, что переход к поставляемому проекту (проект должен быть построен до этого) способ, как Add-Migration InitialBase -IgnoreChanges бы:

public void ScaffoldedMigration(EnvDTE.Project project) 
{ 
    var migrationsNamespace = project.Properties.Cast<Property>() 
     .First(p => p.Name == "RootNamespace").Value.ToString() + ".Migrations"; 

    var assemblyName = project.Properties.Cast<Property>() 
          .First(p => p.Name == "AssemblyName").Value.ToString(); 
    var rootPath = Path.GetDirectoryName(project.FullName); 
    var assemblyPath = Path.Combine(rootPath, "bin", assemblyName + ".dll"); 
    var migrationAssembly = Assembly.Load(File.ReadAllBytes(assemblyPath)); 
    Type dbContext = null; 
    foreach(var type in migrationAssembly.GetTypes()) 
    { 
     if(type.IsSubclassOf(typeof(DbContext))) 
     { 
      dbContext = type; 
      break; 
     } 
    } 

    var migrationsConfiguration = new DbMigrationsConfiguration() 
     { 
      AutomaticMigrationDataLossAllowed = false, 
      AutomaticMigrationsEnabled = false, 
      CodeGenerator = new CSharpMigrationCodeGenerator(), 
      ContextType = dbContext, 
      ContextKey = migrationsNamespace + ".Configuration", 
      MigrationsAssembly = migrationAssembly, 
      MigrationsDirectory = "Migrations", 
      MigrationsNamespace = migrationsNamespace 
     }; 

    var dbi = new System.Data.Entity.Infrastructure 
        .DbConnectionInfo("ConnectionString", "System.Data.SqlClient"); 
    migrationsConfiguration.TargetDatabase = dbi; 

    var scaffolder = new MigrationScaffolder(migrationsConfiguration); 
    ScaffoldedMigration migration = scaffolder.Scaffold("InitialBase", true); 

    var migrationFile = Path.Combine(rootPath, migration.Directory, 
          migration.MigrationId + ".cs"); 
    File.WriteAllText(migrationFile, migration.UserCode); 
    var migrationItem = project.ProjectItems.AddFromFile(migrationFile); 

    var designerFile = Path.Combine(rootPath, migration.Directory, 
          migration.MigrationId + ".Designer.cs"); 
    File.WriteAllText(designerFile, migration.DesignerCode); 
    var designerItem = project.ProjectItems.AddFromFile(migrationFile); 
    foreach(Property prop in designerItem.Properties) 
    { 
     if (prop.Name == "DependentUpon") 
      prop.Value = Path.GetFileName(migrationFile); 
    } 

    var resxFile = Path.Combine(rootPath, migration.Directory, 
         migration.MigrationId + ".resx"); 
    using (ResXResourceWriter resx = new ResXResourceWriter(resxFile)) 
    { 
     foreach (var kvp in migration.Resources) 
      resx.AddResource(kvp.Key, kvp.Value); 
    } 
    var resxItem = project.ProjectItems.AddFromFile(resxFile); 
    foreach (Property prop in resxItem.Properties) 
    { 
     if (prop.Name == "DependentUpon") 
      prop.Value = Path.GetFileName(migrationFile); 
    } 
} 

я исполню это в IWizard реализации моего шаблона проекта, где я управляю миграцией с IgnoreChanges, из-за общее entites с базовым проектом. Измените scaffolder.Scaffold("InitialBase", true) на scaffolder.Scaffold("InitialBase", false), если вы хотите включить изменения.

Смежные вопросы