Как выполнить команду DOS SET из С# и сохранить переменную после закрытия exe?

У меня есть исполняемый файл консоли С#, запущенный в командном процессе DOS.

Мне нужно иметь возможность выполнять команды DOS из исполняемого файла C # (в частности, мне нужно иметь возможность устанавливать переменные) и сохранять переменные, чтобы остальная часть процесса DOS могла ссылаться на них.

ie:

Запуск процесса DOS -> C# выполняет команду SET для установки UserVariable -> процесс DOS может ECHO %UserVariable%

Из-за соображений производительности я не могу записать команду set в сценарий dos. На самом деле, у меня вообще не может быть файлового ввода-вывода.

Кто-нибудь может помочь?


person Mohammed    schedule 14.06.2012    source источник


Ответы (6)


Если вы запускаете приложение С# из сценария dos и хотите использовать переменные, установленные в приложении после этого из сценария, я не знаю, как это сделать только для контекста этого сценария из С#, другие ответы здесь показывают вам за саму машину, но я понимаю, что вам нужно что-то с менее постоянным объемом.

Обходной путь метапрограммирования может заключаться в следующем:

  • Вызовите приложение C# из цикла DOS FOR
  • Из приложения C# вывод в консольные команды SET
  • Используйте цикл for для выполнения вывода приложения

Вызывающий DOS-скрипт будет выглядеть так:

FOR /F "tokens=* delims=" %%A IN ('MyApp.exe') DO ( 
   %%A
)

Выход консоли из MyApp.exe должен быть в форме:

SET UserVariable1=UserValue1
SET UserVariable2=UserValue2

И тогда каждая из выходных строк будет выполняться вызывающим циклом FOR, и тогда переменные будут существовать в контексте вызывающего скрипта.

person Don Vince    schedule 21.06.2012
comment
Это идеально :) Как раз то, что мне нужно. - person Mohammed; 21.06.2012

SETX сохраняет переменные среды. Проверьте это: http://technet.microsoft.com/es-es/library/cc755104%28v=ws.10%29.aspx

person Ignacio Soler Garcia    schedule 14.06.2012
comment
Спасибо за ответ. - Как мне потом получить значение? Потребность заключается в следующем: на протяжении всего срока службы одного командного окна нам нужно иметь возможность устанавливать переменные DOS из C#, вызываемые в этом командном окне, для доступа в том же командном окне. В идеале эти значения не должны сохраняться после закрытия окна. - person Mohammed; 15.06.2012
comment
Я думаю, что использование SETX yourvar= удалит его. - person Ignacio Soler Garcia; 15.06.2012
comment
Нас беспокоит не удаление. Он извлекает его для использования (например, ECHO %SomeVariable%) в коде DOS после C#. На данный момент, если не будет найдено работающее решение, нам придется использовать один файл ввода-вывода в процессе, чтобы написать небольшой пакетный файл с установленными командами. - person Mohammed; 15.06.2012
comment
Если вы вызовете SETX, переменная останется навсегда, пока не будет удалена. Таким образом, после выполнения команды SETX вы можете получить доступ к переменной из любого места с помощью %var%. Вы открываете cmd, выполняете SETX test=jj, закрываете cmd, открываете другой cmd, пишете %test% и получаете jj - person Ignacio Soler Garcia; 15.06.2012
comment
Спасибо за четкий и полезный ответ. Да, это сработает, но нарушит ограничения, с которыми я работаю, поэтому я, к сожалению, не могу его использовать. - person Mohammed; 18.06.2012

Проблема не в том, что вы вызываете SET из приложения C#. Даже если вы откроете приглашение Windows и вызовете SET для установки пользовательской переменной, она не будет сохраняться в течение сеансов.

Отображение, установка или удаление переменных среды CMD. Изменения, сделанные с помощью SET, останутся только на время текущего сеанса CMD.

Источник.

Советую все-таки задавать переменные напрямую через .Net. Для этого можно использовать Environment.SetEnvironmentVariable.

person Bruno Brant    schedule 14.06.2012
comment
Конечно, если у вас есть веская причина сделать это из подсказки, пост @SoMoS — это то, что вам нужно. Хотя я не краду его ответ. :) - person Bruno Brant; 14.06.2012

Вместо этого используйте следующий метод .NET:

Environment.SetEnvironmentVariable

person Mr. TA    schedule 14.06.2012
comment
К сожалению, это не сработало. Использование: Environment.SetEnvironmentVariable(MoTest, We are Sorted...); в моем коде C# мне не удалось получить значение в сценарии DOS после кода C#. - person Mohammed; 15.06.2012
comment
Что вы передали за 3-й параметр? - person Mr. TA; 15.06.2012
comment
Упс, не заметил перегрузки. Только что попробовал с Environment.SetEnvironmentVariable(MoTest, We are Sorted..., EnvironmentVariableTarget.Process); но получил тот же результат. Я с осторожностью отношусь к использованию USER или MACHINE, так как оба они записывают в реестр. - person Mohammed; 15.06.2012
comment
Подумайте об этом на секунду. Вы проходите в Process и задаетесь вопросом, почему он недоступен за пределами вашего процесса. Тем не менее, вы с подозрением относитесь к Пользователю и Машине, потому что они пишут в реестр. Вам не приходило в голову, что для того, чтобы он был доступен вне вашего процесса, он должен быть прописан ГДЕ-НИБУДЬ и именно им является реестр? - person Mr. TA; 15.06.2012
comment
Спасибо за исправление моей орфографии, и да, я знаю, что это нужно будет где-то написать, но надеялся, что кто-нибудь знает способ установить значение без файлового ввода-вывода и без использования реестра. В нашей системе будет выполняться множество параллельных сценариев, поэтому мы не будем использовать реестр для хранения значений, которые должны существовать только в течение времени существования одного сценария. Еще раз спасибо за все ваше время и усилия, но я думаю, что мы пойдем на компромисс с записью одного файла для каждого выполнения скрипта и посмотрим, как это повлияет на производительность. - person Mohammed; 15.06.2012
comment
—1 потому что я не вижу причин быть педантом с ОП. - person Bruno Brant; 17.06.2012

Это ни в коем случае не ответ, но по характеру проблемы этот «компромисс» является тем путем, который мы избрали на данный момент.

Мы будем использовать пакетный сценарий, созданный приложением C#, в котором будут все необходимые простые команды set, которые затем будут выполняться процессом CMD, вызвавшим приложение C#.

Пожалуйста, не стесняйтесь добавлять любые дополнительные идеи и комментарии, так как это не идеальное решение.

person Mohammed    schedule 15.06.2012

К сожалению, насколько я могу судить, это «решение», которое доступно, по крайней мере, через Windows 7. Я экспериментировал с различными способами установки и последующего использования переменных среды, и суть моего исследования заключается в том, что , если вы хотите использовать переменную, она должна быть либо заранее установлена ​​в ключе USER или MACHINE, либо это должна быть локальная переменная, установленная командой сценария, а затем протестированная далее в том же сценарии.

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

person David Gray    schedule 24.08.2012