Это абсолютное требование, чтобы процесс должен отображаться как сам по себе в окне Процессы вкладки диспетчера задач? Или он может работать внутри другого хост-процесса?
В последнем случае вы можете создать проект заглушки, содержащий следующий Main
метод, а затем скомпилировать две версии исполняемого файла: один, как 32-бит (LaunchX86.exe), а другие 64-разрядная (LaunchX64. exe).
static int Main(string[] args)
{
try
{
foreach (var t in Assembly.LoadFile(args[0]).GetTypes())
{
var methodInfo = t.GetMethod(
"Main",
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
if (methodInfo != null)
{
int? retVal = 0;
// See http://stackoverflow.com/questions/2378016/how-to-run-something-in-the-sta-thread#2378077
var thread = new Thread(() =>
{
try
{
// Main() methods may have zero or one parameters
var methodParams = methodInfo.GetParameters().Length == 0
? null
: new object[] {args.Skip(1).ToArray()};
retVal = methodInfo.Invoke(t, methodParams) as int?;
}
catch (Exception e)
{
retVal = 99; // Error 99: The executable itself threw an exception
}
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
thread.Join();
return retVal ?? 0;
}
}
return 98; // Error 98: unable to launch exe because no method "Main" found
}
catch (Exception e)
{
// Can identify exception type here and return appropriate result, e.g.:
// ArgumentNullException - no EXE name provided in first param
// BadImageFormatException - specified file was not a suitable EXE
return 97; // Error 97: unable to load executable for analysis
}
}
Примечание: чтобы держать вещи простыми, выше было очень грубым отлов исключений и карты тех несколько фиксированных значений возврата.
Также обратите внимание, что в методе Invoke()
мы не передаем какие-либо параметры методу Main()
для приложений WPF, потому что приложение WPF автоматически получает те же параметры, что и у запуска. Это не идеально, но возможны различные обходные пути, такие как установка переменной среды с использованием Environment.SetEnvironmentVariable()
перед запуском, проверка этой переменной в целевом приложении с использованием Environment.GetEnvironmentVariable()
и (если она есть) с использованием ее содержимого вместо обычного метода.
Тогда из основного приложения запуска соответствующего хоста исполняемым в зависимости от разрядности вашего текущего процесса в:
new Process
{
StartInfo = new ProcessStartInfo(
Environment.Is64BitProcess ? "LaunchX64.exe" : "LaunchX86.exe",
"application_to_be_hosted.exe param1 param2 etc."
)
}.Start();
«Вызовы нашего ехе» имеет мало смысла. Плагин неизменно загружается как DLL, что файл с расширением .exe-файла не имеет значения в .NET. Любая DLL должна соответствовать битности, выбранной исполняемым файлом запуска. Хост-процесс в сценарии плагина. Очень легко сделать на C#, выбрав «AnyCPU» в качестве цели и * не * проверив флажок «Предпочтительно 32-бит». Вы действительно пробовали это? –
Извините, если я объяснил это неправильно. В этом случае программное обеспечение явно запускает нашappapp.exe (это его собственный процесс не как плагин), поэтому есть два независимых процесса: software.exe и ourapp.exe Да, мы попробовали AnyCPU, прежде чем задавать вопрос и в этих случаях наш процесс основывался на его битте в окнах, которые он выполнял (логически, как задокументировано), но мы хотим, чтобы какой-то параметр основывал его битту на процессе, вызывающем наш exe (стиль начальной загрузки?) – VSP
Есть ли у вас контроль над программным обеспечением .exe? Можете ли вы создать 32bitWrapper и 64BitWrapper нашегоapp.exe и позволить software.exe начинать в зависимости от того, что он хочет? –