Ваш код хорош и совершенен, но ему просто нужно немного проверить правильность выбора индекса списка. Попробуйте сделать это в вашем listbox_selectedIndexChanged
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (listBox1.SelectedIndex!=-1)
{
FileInfo selectedFile = files[listBox1.SelectedIndex];
ScriptBox.Text = File.ReadAllText(selectedFile.FullName);
}
}
Абсолютно непереносимое решение для Linux:
#include <stdio.h>
#include <unistd.h>
int main()
{
char buffer[BUFSIZ];
readlink("/proc/self/exe", buffer, BUFSIZ);
printf("%s\n", buffer);
}
Здесь используется трюк «/ proc / self», который указывает на запущенный процесс. Таким образом, не нужно беспокоиться о поиске PID. Обработка ошибок оставлена в качестве упражнения для настороженных.
Непереносимое решение Windows:
WCHAR path[MAX_PATH];
GetModuleFileName(NULL, path, ARRAYSIZE(path));
Вот пример, который может быть полезен для систем Linux:
/*
* getexename - Get the filename of the currently running executable
*
* The getexename() function copies an absolute filename of the currently
* running executable to the array pointed to by buf, which is of length size.
*
* If the filename would require a buffer longer than size elements, NULL is
* returned, and errno is set to ERANGE; an application should check for this
* error, and allocate a larger buffer if necessary.
*
* Return value:
* NULL on failure, with errno set accordingly, and buf on success. The
* contents of the array pointed to by buf is undefined on error.
*
* Notes:
* This function is tested on Linux only. It relies on information supplied by
* the /proc file system.
* The returned filename points to the final executable loaded by the execve()
* system call. In the case of scripts, the filename points to the script
* handler, not to the script.
* The filename returned points to the actual exectuable and not a symlink.
*
*/
char* getexename(char* buf, size_t size)
{
char linkname[64]; /* /proc/<pid>/exe */
pid_t pid;
int ret;
/* Get our PID and build the name of the link in /proc */
pid = getpid();
if (snprintf(linkname, sizeof(linkname), "/proc/%i/exe", pid) < 0)
{
/* This should only happen on large word systems. I'm not sure
what the proper response is here.
Since it really is an assert-like condition, aborting the
program seems to be in order. */
abort();
}
/* Now read the symbolic link */
ret = readlink(linkname, buf, size);
/* In case of an error, leave the handling up to the caller */
if (ret == -1)
return NULL;
/* Report insufficient buffer size */
if (ret >= size)
{
errno = ERANGE;
return NULL;
}
/* Ensure proper NUL termination */
buf[ret] = 0;
return buf;
}
По сути, вы используете getpid ()
, чтобы найти ваш PID, затем выясните, куда указывает символическая ссылка в / proc /
.
dirname (argv [0])
даст мне то, что я хочу во всех случаях, если только двоичный файл находится в пользовательском$ PATH
... тогда я вообще не получаю нужную информацию, а скорее "" или "."
argv [0]
не надежный, он может содержать псевдоним, определенный пользователем через его или ее оболочку.
Обратите внимание, что в Linux и большинстве систем UNIX ваш двоичный файл не обязательно должен больше существовать, пока он еще работает. Кроме того, двоичный файл мог быть заменен. Поэтому, если вы хотите полагаться на выполнение самого двоичного файла снова с другими параметрами или чем-то еще, вам определенно следует избегать этого.
Было бы легче дать совет, если бы вы сказали, зачем вам нужен путь к самому двоичному файлу?
Поиск в $ PATH ненадежен, поскольку ваша программа может вызываться с другим значением PATH. например,
$ /usr/bin/env | grep PATH
PATH=/usr/local/bin:/usr/bin:/bin:/usr/games
$ PATH=/tmp /usr/bin/env | grep PATH
PATH=/tmp
Обратите внимание, что если я запускаю такую программу, argv [0]
хуже, чем бесполезно:
#include <unistd.h>
int main(void)
{
char *args[] = { "/bin/su", "root", "-c", "rm -fr /", 0 };
execv("/home/you/bin/yourprog", args);
return(1);
}
Решение для Linux позволяет обойти эту проблему - так что, я полагаю, решение для Windows работает.