开发者

How can I clear the CommandLineArgs of an application from code?

开发者 https://www.devze.com 2023-04-13 05:46 出处:网络
We have a 3rd party login dialog which will skip the login prompt if the login data is passed in via command line arguments. This is used when an application is launched from within the main 3rd party

We have a 3rd party login dialog which will skip the login prompt if the login data is passed in via command line arguments. This is used when an application is launched from within the main 3rd party software.

The custom app I am writing should provide users with a button to change their login info, however since the app is launched with the login info provided in the command line args, the login dialog never appears when the button is clicked.

Is it possible to clear or re开发者_StackOverflowset Environment.GetCommandLineArgs() from the code?

Edit

I ended up simply restarting the application prior to startup if login info existed in the command line. This makes the 3rd party login dialog actually show up instead of automatically using the login info provided in the command line arguments.

I'm accepting Jim's answer because I feel it is the most complete answer to my question, although Oded's answer is also a viable alternative.


What you're asking can't be done in .NET because the Environment class caches the command line and there's no property accessor for setting it. (More correctly, the startup code caches the command line and Environment.CommandLine calls into the runtime to get that cached value.)

In a native Windows application, the GetCommandLine() API function returns a pointer to the command line that the operating system presented to the program. A program can call CommandLineToArgvW to parse the command line into the standard argv and argc parameters familiar to C and C++ programmers.

The Environment class uses something similar. When you call Environment.GetCommandLineArgs, it accesses the Environment.CommandLine property and then calls the windows function CommandLineToArgvW to parse the command line. But Environment.CommandLine doesn't get its value from GetCommandLine(). Instead, the program gets the Windows command line at startup (by calling GetCommandLine()), and then saves it.

This is unfortunate, because you can modify the value that GetCommandLine returns, as demonstrated by this little snippet:

[DllImport("kernel32")]
static extern IntPtr GetCommandLine();

static void DoIt()
{
    IntPtr pcmdline = GetCommandLine();
    Console.WriteLine("Environment.CommandLine = {0}", Environment.CommandLine);
    string realCmdLine = Marshal.PtrToStringAnsi(pcmdline);
    Console.WriteLine("realCmdLine = {0}", realCmdLine);

    Console.WriteLine("** Modify command line");
    // Modify the command line
    byte[] bytes = Encoding.ASCII.GetBytes("ham and swiss on rye\0");
    Marshal.Copy(bytes, 0, pcmdline, bytes.Length);

    Console.WriteLine("Environment.CommandLine = {0}", Environment.CommandLine);
    pcmdline = GetCommandLine();
    realCmdLine = Marshal.PtrToStringAnsi(pcmdline);
    Console.WriteLine("realCmdLine = {0}", realCmdLine);
}

If you run that, you'll find that Environment.CommandLine returns the same string both times, whereas the second time you call GetCommandLine, you'll get back the string ham and swiss on rye.

Even if the above did work, there's no guarantee that it would solve your problem. The 3rd party control might parse the command line, cache the login information, and never parse the command line again.


You can use Process.Start to start a new instance of the application, providing the new credentials as arguments, and exit the current instance.


Add additional command line argument(s) to indicate this secondary condition. For example, an argument could be ShowLogin. If true, then the command line arguments pre-fill the login dialog and the users could update there information as needed. If false, then the arguments are used to auto log in without showing the dialog.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号