On 24.01.2010 21:57, Michael Hutchinson wrote:


Yes, native applications with access to main's argv[0] can achieve
it easily under Linux, but managed apps simply cannot access this
location. There is also no way that I know of to get a ptr to
this memory location from a native library, so p/invoke won't
help either.

You may want to file an enhancement request with Mono's bugzilla
stating that you wish a facility for *dynamically* changing
the process name.

I guess it's *possible* right now with Mono too. Instead of using the
"mono" executable to run the app, create a tiny native app that uses
libmono and the embedding interfaces to load and run the managed exe.
This native shim can capture argv[0] and expose it via a P/Invokeable
function.

Well, most people are moving towards managed languages because they
are already sick of C :)

Anyway, here is what's possible, modulo bugs due to the aforementioned
C sickness. The tricky part was how to expand argv[0].
Build instructions are on top of the C file.

Robert
/*
 *
 * gcc -Wall -o mymono mymono.c -Wl,--export-dynamic `pkg-config --libs mono`
 * gmcs test.cs
 * ./mymono test.exe
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

/* import from mono */
int mono_main (int argc, char** argv);

const int MAX_ARGV0 = 1024;
static char* original_argv0 = NULL;

void
set_process_command_line (char* line)
{
	if (!(line && original_argv0))
		return;

	strncpy (original_argv0, line, MAX_ARGV0 - 1);
}

char*
get_process_command_line ()
{
	return strdup (original_argv0);
}

static void
expand_command_line (char** argv)
{
	char new_arg0[MAX_ARGV0];
	char *file = argv [0];
	char proc_file[4096];
	int len;

	memset (new_arg0, 'a', MAX_ARGV0);
	new_arg0 [MAX_ARGV0 - 1] = 0;
	argv [0] = new_arg0;

	len = readlink ("/proc/self/exe", proc_file, sizeof (proc_file) - 1);
	if (len != -1) {
		proc_file [len] = 0;
		file = proc_file;
	}

	/* export argv[0] (which is now /proc/self/exe) to the new process */
	setenv ("MYMONO_ORIGINAL_ARGV0", file, 1);
	execv (file, argv);

	/* not reached */
	perror("exec");
	exit (1);
}

int
main (int argc, char** argv)
{
	if (strlen (argv [0]) < MAX_ARGV0 - 1)
		expand_command_line (argv);

	original_argv0 = argv [0];
	set_process_command_line (getenv ("MYMONO_ORIGINAL_ARGV0"));

	/* pass control to mono */
	return mono_main (argc, argv);
}
using System;
using System.Runtime.InteropServices;

class Programm
{
        static void Main ()
        {
                Console.WriteLine (get_process_command_line ());
                set_process_command_line ("rootkit");
                Console.WriteLine (get_process_command_line ());

                set_process_command_line ("rootkit rootkit");
                Console.WriteLine (get_process_command_line ());
        }

        [DllImport("__Internal")]
        static extern void set_process_command_line (string line);

        [DllImport("__Internal")]
        static extern string get_process_command_line ();
}
_______________________________________________
Mono-list maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-list

Reply via email to