Контекст:
В настоящее время я пишу приложение, которое позволяет пользователю открывать решение Visual Studio (файл .sln). Затем они смогут редактировать определенные аспекты открытого проекта через пользовательский интерфейс моего приложения, вместо того, чтобы редактировать код самостоятельно. Во избежание путаницы я говорю о Visual Studio, хотя технически файл будет использоваться и открываться TwinCatXAEShell, что по сути одно и то же.
Проблема:
Чтобы открыть файл решения, я использую System.Diagnostics.Process.Start(). Однако для отправки команд работающему проекту мне нужна ссылка на интерфейс EnvDTE.DTE этого проекта.
Вот код, который я использую для открытия файла:// get TwinCAT application
string applicationPath = getTwinCatInstallPath();
if (!File.Exists(applicationPath)) return;
// start TwinCAT with provided file
System.Diagnostics.Process fileopener = new System.Diagnostics.Process();
fileopener.StartInfo = new ProcessStartInfo()
{
FileName = applicationPath,
Arguments = $"\"{solutionPath}\"",
WindowStyle = ProcessWindowStyle.Minimized
};
fileopener.Start();
Некоторые «решения»:
Вариант 1:
То, что я делаю до сих пор, это для поиска в таблице запущенных объектов Windows и поиска идентификатора процесса в именах запущенных объектов. Но я продолжаю думать, что должна быть возможность напрямую получить доступ к экземпляру System.Diagnostics.Process...
Вот код для поиска в таблице запущенных объектов Windows:
(очевидно, не полностью мое ^^)
static DTE ProcessToDte(System.Diagnostics.Process process)
{
// get list of windows processes
IRunningObjectTable runningObjectTable;
GetRunningObjectTable(0, out runningObjectTable);
// get enumerator for the list
runningObjectTable.EnumRunning(out IEnumMoniker monikerEnumerator);
monikerEnumerator.Reset();
// iterate over list and crate a subset with fitting processes
IMoniker[] monikers = new IMoniker[1];
while (monikerEnumerator.Next(1, monikers, IntPtr.Zero) == 0)
{
CreateBindCtx(0, out IBindCtx ctx);
monikers[0].GetDisplayName(ctx, null, out string runningObjectName);
if (!runningObjectName.Contains("TcXaeShell")) continue;
if (runningObjectName.Contains(process.Id.ToString()))
{
runningObjectTable.GetObject(monikers[0], out object runningObjectData);
DTE ide;
try { ide = runningObjectData as DTE; } catch { continue; }
return ide;
}
}
return null;
}
[DllImport("ole32.dll")]
static extern int GetRunningObjectTable(int reserved, out IRunningObjectTable rot); // needed for ProcessToDte()
[DllImport("ole32.dll")]
static extern int CreateBindCtx(uint reserved, out IBindCtx ppbc); // needed for ProcessToDte()
Вариант 2:
Я обнаружил, что другой способ обойти эту проблему — никогда даже не использовать System.Diagnostics.Process и вместо этого откройте файл решения, как показано ниже, но процесс.Start() кажется гораздо более удобным и понятным для будущих проверок кода.
Type t = Type.GetTypeFromProgID("TcXaeShell.DTE.15.0");
if (t == null) return;
DTE dte;
dte = (DTE)Activator.CreateInstance(t);
dte.SuppressUI = false;
dte.MainWindow.Visible = true;
dte.MainWindow.WindowState = vsWindowState.vsWindowStateMinimize;
dte.UserControl = true;
Подробнее здесь: https://stackoverflow.com/questions/785 ... tance-of-s
C# получает интерфейс EnvDTE.DTE решения Visual Studio через экземпляр System.Diagnostics.Process ⇐ C#
Место общения программистов C#
1716994838
Anonymous
Контекст:
В настоящее время я пишу приложение, которое позволяет пользователю открывать решение Visual Studio (файл .sln). Затем они смогут редактировать определенные аспекты открытого проекта через пользовательский интерфейс моего приложения, вместо того, чтобы редактировать код самостоятельно. Во избежание путаницы я говорю о Visual Studio, хотя технически файл будет использоваться и открываться TwinCatXAEShell, что по сути одно и то же.
Проблема:
Чтобы открыть файл решения, я использую System.Diagnostics.Process.Start(). Однако для отправки команд работающему проекту мне нужна ссылка на интерфейс EnvDTE.DTE этого проекта.
Вот код, который я использую для открытия файла:// get TwinCAT application
string applicationPath = getTwinCatInstallPath();
if (!File.Exists(applicationPath)) return;
// start TwinCAT with provided file
System.Diagnostics.Process fileopener = new System.Diagnostics.Process();
fileopener.StartInfo = new ProcessStartInfo()
{
FileName = applicationPath,
Arguments = $"\"{solutionPath}\"",
WindowStyle = ProcessWindowStyle.Minimized
};
fileopener.Start();
Некоторые «решения»:
[b]Вариант 1:[/b]
То, что я делаю до сих пор, это для поиска в таблице запущенных объектов Windows и поиска идентификатора процесса в именах запущенных объектов. Но я продолжаю думать, что должна быть возможность напрямую получить доступ к экземпляру System.Diagnostics.Process...
Вот код для поиска в таблице запущенных объектов Windows:
(очевидно, не полностью мое ^^)
static DTE ProcessToDte(System.Diagnostics.Process process)
{
// get list of windows processes
IRunningObjectTable runningObjectTable;
GetRunningObjectTable(0, out runningObjectTable);
// get enumerator for the list
runningObjectTable.EnumRunning(out IEnumMoniker monikerEnumerator);
monikerEnumerator.Reset();
// iterate over list and crate a subset with fitting processes
IMoniker[] monikers = new IMoniker[1];
while (monikerEnumerator.Next(1, monikers, IntPtr.Zero) == 0)
{
CreateBindCtx(0, out IBindCtx ctx);
monikers[0].GetDisplayName(ctx, null, out string runningObjectName);
if (!runningObjectName.Contains("TcXaeShell")) continue;
if (runningObjectName.Contains(process.Id.ToString()))
{
runningObjectTable.GetObject(monikers[0], out object runningObjectData);
DTE ide;
try { ide = runningObjectData as DTE; } catch { continue; }
return ide;
}
}
return null;
}
[DllImport("ole32.dll")]
static extern int GetRunningObjectTable(int reserved, out IRunningObjectTable rot); // needed for ProcessToDte()
[DllImport("ole32.dll")]
static extern int CreateBindCtx(uint reserved, out IBindCtx ppbc); // needed for ProcessToDte()
[b]Вариант 2:[/b]
Я обнаружил, что другой способ обойти эту проблему — никогда даже не использовать System.Diagnostics.Process и вместо этого откройте файл решения, как показано ниже, но процесс.Start() кажется гораздо более удобным и понятным для будущих проверок кода.
Type t = Type.GetTypeFromProgID("TcXaeShell.DTE.15.0");
if (t == null) return;
DTE dte;
dte = (DTE)Activator.CreateInstance(t);
dte.SuppressUI = false;
dte.MainWindow.Visible = true;
dte.MainWindow.WindowState = vsWindowState.vsWindowStateMinimize;
dte.UserControl = true;
Подробнее здесь: [url]https://stackoverflow.com/questions/78550420/c-sharp-get-envdte-dte-interface-of-visual-studio-solution-through-instance-of-s[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия