2015-03-04 3 views
1

У меня мало опыта на C#, но я очень хочу учиться. Я пытаюсь создать приложение с кнопкой, которая запускает исполняемый файл. Приложение запускается с USB-накопителя. Допустим, у флеш-накопителя есть расписание (e :) на моем компьютере. Я хочу запустить программу rkill.exe из каталога bin.C# Открытие программы из локального каталога

private void opschonen_RKill_Click(object sender, EventArgs e) 
    { 
     var process_RKill = new Process 
     { 
      StartInfo = new ProcessStartInfo 
      { 
       FileName = "/bin/rkill.exe" 
      } 
     }; 
     process_RKill.Start(); 
     process_RKill.WaitForExit(); 
    } 

Однако это не работает. Если я запускаю приложение из корня, он работает. Я не могу указать на информационный бюллетень, потому что не каждый компьютер присваивает букву E:

Что я делаю неправильно? Полагаю, это просто, потому что я просто новичок.

+0

Упоминание полный путь 'exe' может решить эту проблему. –

+0

Спасибо, но у меня нет полного пути, потому что я не могу предоставить буклет. –

+0

Проверить http://stackoverflow.com/questions/123927/how-to-find-usb-drive-letter –

ответ

5
const string relativePath = "bin/rkill.exe"; 

//Check for idle, removable drives 
var drives = DriveInfo.GetDrives() 
         .Where(drive => drive.IsReady 
          && drive.DriveType == DriveType.Removable); 

foreach (var drive in drives) 
{ 
    //Get the full filename for the application 
    var rootDir = drive.RootDirectory.FullName; 
    var fileName = Path.Combine(rootDir, relativePath); 

    //If it does not exist, skip this drive 
    if (!File.Exists(fileName)) continue; 

    //Execute the application and wait for it to exit 
    var process = new Process 
    { 
     StartInfo = new ProcessStartInfo 
     { 
      FileName = fileName 
     } 
    }; 

    process.Start(); 
    process.WaitForExit(); 
} 
0

EDIT решение Эмиля PELs' кажется гораздо более оптимизированы. Предполагая, что это работает, я предлагаю выбрать это по моему быстрому и грязному исправлению :)

Учитывая, что он работает от корня (как вы сказали), проблема в том, что вы используете относительный путь. Он работает только тогда, когда относительный путь действительно разрешается, т. Е. Когда ваше приложение находится в корне.

Чтобы работать в других местах, вам необходимо использовать абсолютный путь. Это означает, что вам понадобится буква диска (запрет на использование переменных среды, которые кажутся невозможными).

Я могу придумать обходные пути, чтобы найти правильный привод.

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

using System.IO; 

public static string LookForDrive(string filepath) //filepath = "\\bin\\myApp.exe") 
{ 
    List<string> possibleLetters = new List<string>() { "A", "B", "C" }; //and so on... 

    foreach(string driveLetter in possibleLetters) 
    { 
     var testPath = String.Format("{0}:\\{1}", driveLetter, filepath); 

     if(File.Exists(testPath)) 
     { 
      return testPath, 
     } 
    } 

    //If you get here, no drive letter was valid. 

    throw new Exception("Could not find the specified file on any possible drive."); 
} 

Вышесказанное - это просто то, что я бросил вместе. Вероятно, он может быть оптимизирован, но я надеюсь, что это намерение ясно.

0

Вы можете проверить, что является адресом съемного диска. Затем используйте адрес для построения полного пути. Обратите внимание, что это возможно, чтобы иметь больше чем один съемный диск, поэтому перед запуском проверки процесса, если ваш ех присутствует на диске:

 var myExe = "/bin/rkill.exe"; 
     // Find removable drives 
     var driveDirectories = 
      DriveInfo.GetDrives() 
      .Where(d => d.DriveType == DriveType.Removable) 
      .Select(d => d.RootDirectory.FullName); 

     foreach (var directory in driveDirectories) 
     { 
      // create full path 
      var fullPath = Path.Combine(directory, myExe); 

      // check if path exists 
      if (File.Exists(fullPath)) 
      { 
       // execute 
       var process_RKill = new Process 
       { 
        StartInfo = new ProcessStartInfo 
        { 
         FileName = fullPath; 
        } 
       }; 
       process_RKill.Start(); 
       process_RKill.WaitForExit(); 
       // don't try other drives after successful execution 
       return; 
      } 
     } 
0

Как вы будете запускать приложение с самого диска, вы можете просто вернуться методом буква диска:

private static string GetCurrentDriveLetter() 
{ 
    return Path.GetPathRoot(Environment.CurrentDirectory); // Alternatively, if you believe the working directory may be different 
    // return Path.GetPathRoot(Assembly.GetExecutingAssembly().Location); 
} 

Затем примените текущую логику, хотя переписан для использования(), чтобы убедиться, что он расположен:

using (Process p = new Process()) 
      { 
       string executable = Path.Combine(GetCurrentDriveLetter(), "/bin/rkill.exe"); // This is preferable to simple string concatenation because it helps prevent some possible issues that may arise otherwise 
       p.StartInfo = new ProcessStartInfo(executable); 
       //p.StartInfo.UseShellExecute = false; // < Uncomment these two if you see a pop up CLI window 
       //p.StartInfo.CreateNoWindow = true; // < 
       p.Start(); 
       p.WaitForExit(); 
      } 
Смежные вопросы