Why doesn't dfrgui exe work in x86 target platform - c#

static void Main(string[] args)
{
string fileName = #"C:\windows\SysWOW64\dfrgui.exe";
ExecuteAsAdmin(fileName);
}
public static void ExecuteAsAdmin(string fileName)
{
Process proc = new Process();
proc.StartInfo.FileName = fileName;
proc.StartInfo.UseShellExecute = true;
proc.StartInfo.Verb = "runas";
try
{
proc.Start();
}
catch (Exception e)
{
}
}
I am trying to run dfrgui.exe from process.start(). I am using Visual Studio 2008 as my source code is compatible only with this. When I run this code nothing happens and dfrgUI doesn't show up. My target platform is x86 and I should work on it. Is there way I can call this dfrgui.exe from my code using x86 as target platform? I don't want to change this to either anycpu or x64 because my application is 32bit.

Related

open restore point dialog c#

I am trying to open the restore point dialog from C# like
I'm using the following code:
Process.Start("SystemPropertiesProtection");
and from cmd:
public static string ExecuteCMD(IEnumerable<string> commands,
bool inBackground,
bool runAsAdministrator ,
bool WaitProcessForExit)
{
try
{
Process p = new Process();
p.StartInfo.FileName = "cmd.exe";
if (commands.Any())
{
p.StartInfo.Arguments = #" /C " + string.Join("&&", commands);
}
if (runAsAdministrator)
{
p.StartInfo.Verb = "runas";
}
if (inBackground)
{
p.StartInfo.CreateNoWindow = true;
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
}
else
{
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.UseShellExecute = false;
}
p.OutputDataReceived += (sender, e) => { MessageBox.Show(e.Data); };
p.ErrorDataReceived += (sender, e) => { MessageBox.Show(e.Data); };
p.Start();
if (WaitProcessForExit)
{
p.WaitForExit();
}
return "";// p.StandardOutput.ReadToEnd();
}
catch (Exception ex)
{
FRM_MSG f = new FRM_MSG();
f.ShowDLG(" ",
ex.Message + "\n" + ex.StackTrace.ToString(),
FRM_MSG.MSGIcon.Error,
FRM_MSG.BTNS.One,
new string[] { "Ok" });
throw ex;
}
}
Executor.ExecuteCMD(new string[] { "SystemPropertiesProtection" }, true, false, false);
and even create shortcut to create restore point like this:
and open this shortcut with:
Process.Start(RestorePointShortcutFilePath);
but they always open three tabs and don't open the restore point tab
How do I open restore point dialog like shown on first image which has 5 tabs and not 3 tabs, my OS is Windows 7 64 bit? Thanks.
The issue that you're seeing is because of the File System Redirector which is occurring because you're running your program as 32-bit on your 64-bit OS. Therefore, you're executing %windir%\SysWOW64\SystemPropertiesProtection.exe (ex: C:\Windows\SysWOW64\SystemPropertiesProtection.exe).
There are a few ways to avoid this issue. Uncheck "Prefer 32-bit" (Project => <project name> Properties => Build => uncheck 'Prefer 32-bit'). Compile as x64, or check if your application is running as 32-bit on a 64-bit OS. If so, set the appropriate fully-qualified filename.
The documentation states:
32-bit applications can access the native system directory by
substituting %windir%\Sysnative for %windir%\System32. WOW64
recognizes Sysnative as a special alias used to indicate that the file
system should not redirect the access. This mechanism is flexible and
easy to use, therefore, it is the recommended mechanism to bypass file
system redirection. Note that 64-bit applications cannot use the
Sysnative alias as it is a virtual directory not a real one.
Try the following:
Create a new Windows Forms App (.NET Framework)
Add an Application Manifest to your project
Note: This is used to prompt the user to execute the program as Administrator.
In VS menu, click Project
Select Add New Item...
Select Application Manifest File (Windows only)
Click Add
In app.manifest, replace
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
with
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
Add the following using directives:
using System.IO;
using System.Diagnostics;
private void OpenSystemPropertiesProtection()
{
string filename = System.IO.Path.Combine(Environment.GetEnvironmentVariable("windir"), "System32", "SystemPropertiesProtection.exe");
//environment variable windir has the same value as SystemRoot
//use 'Sysnative' to access 64-bit files (in System32) if program is running as 32-bit process
//use 'SysWow64' to access 32-bit files on 64-bit OS
if (Environment.Is64BitOperatingSystem && !Environment.Is64BitProcess)
filename = System.IO.Path.Combine(Environment.GetEnvironmentVariable("windir"), "SysNative", "SystemPropertiesProtection.exe");
Debug.WriteLine($"filename: {filename}");
ProcessStartInfo startInfo = new ProcessStartInfo(filename);
startInfo.UseShellExecute = true;
startInfo.WorkingDirectory = System.IO.Path.GetDirectoryName(filename);
Process.Start(startInfo);
}
Resources:
File System Redirector
Running 32-bit Applications
Use ShellExecute to execute the command.
ProcessStartInfo info = new ProcessStartInfo();
info.FileName = "SystemPropertiesProtection";
info.UseShellExecute = true;
Process.Start(info);
I have tested this on Windows 11, but it will probably also work on Windows 7. Be aware that Windows 7 has reached end-of-life back in 2020. It shouldn't be used anymore.

TeraTerm macro immediately closes when run as a process from c#

I'm currently working on a Winforms program from Visual Studio that acts as a control panel for a whole bunch of TeraTerm macros. I did a dumb and didn't add my first working version to version control, and now it's stopped working and I have no idea why/how to get back to what I had.
The function is question is
using System;
using System.IO.Ports;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using System.Diagnostics;
...
namespace Test
{
public partial class MainWindow : Form
{
...
private void ImagesButton_Click(object sender, EventArgs e)
{
RunMacro("F:\\Users\\Isaac\\Documents\\LED Sign Commands\\Macros\\StartDisplayImages.ttl");
}
....
private void RunMacro(string userArgument)
{
panel1.Enabled = false;
StatusLabel.Visible = true;
Process process = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo()
{
WindowStyle = ProcessWindowStyle.Hidden,
#if DEBUG
FileName = "F:\\Users\\Isaac\\Documents\\LED Sign Commands\\teraterm\\ttpmacro.exe",
#else
FileName = "..\\teraterm\\ttpmacro.exe",
#endif
Arguments = userArgument
};
process.StartInfo = startInfo;
process.Start();
process.WaitForExit();
panel1.Enabled = true;
StatusLabel.Visible = false;
}
...
}
}
When run, I see that ttpmacro.exe does start, and if I omit the Arguments assignment then it will prompt me to select a macro; if I select StartDisplayImages.ttl, it will run as expected. If I include it as an argument as above, however, then ttpmacro still opens but immediately closes. No error comes up (and RedirectStandardOutput/Error produce nothing), it's as if ttpmacro accepts the file but won't do anything with it. I've confirmed both filepaths are valid and correct.
While I didn't add version control, I did extract the main file using ILSpy, and my original functions in the working version were:
private void ImagesButton_Click(object sender, EventArgs e)
{
RunMacro("/V ..\\Macros\\StartDisplayImages.ttl");
}
private void RunMacro(string userArgument)
{
panel1.Enabled = false;
StatusLabel.Visible = true;
Process process = new Process();
ProcessStartInfo startInfo = (process.StartInfo = new ProcessStartInfo
{
WindowStyle = ProcessWindowStyle.Hidden,
FileName = "..\\teraterm\\ttpmacro.exe",
Arguments = userArgument
});
process.Start();
process.WaitForExit();
panel1.Enabled = true;
StatusLabel.Visible = false;
}
Being from the published release, the filepaths are relative to the folder of the application. Other than that, the only difference seems to be minor syntax in how process.StartInfo is assigned, but I tried reverting that with no luck. Target framework is .NET Core 3.1. The /V flag isn't the issue; removing it simply makes the ttpmacro window visible for the fraction of a second it runs before closing. If I use a commandline execution of the same file (eg start "F:/Users/.../ttpmacro.exe" "F:/.../StartDisplayImages.ttl"), it also runs as expected.
It turned out the problem was the spaces in the full macro filepath, and surrounding it with escaped double quotes resolved the issue. TeraTerm just wasn't telling me that it wasn't finding the file. Should have been obvious, but I was sure it had been working previously when I was debugging, without requiring the quotes.

Is there a way to run a program if its path exceeds MAX_PATH?

I need to spawn processes from my C# program, but in some cases full path to an executable can be more then 256 characters.
I have studied several related topics on this site, as well as this article #MSDN. According to that information this should be possible by using \\?\ prefix, but I still couldn't make it work. It looks like system tries to start the process, but fails. I am getting "SmartScreen has stopped working" message instead.
Am I missing something? Here is my code:
private void button2_Click(object sender, EventArgs e)
{
ProcessStartInfo start = new ProcessStartInfo();
start.Arguments = "";
start.FileName = #"\\?\c:\11111111111111111111111111111111111111111111\222222222222222222222222222222222222222222222\3333333333333333333333333333333333333333333333\444444444444444444444444444444444444444444444\5555555555555555555555555555555555555555555555\6666666666666666666666666666666666666666666666\test.exe";
start.WindowStyle = ProcessWindowStyle.Normal;
start.CreateNoWindow = true;
int exitCode;
using (Process proc = Process.Start(start))
{
proc.WaitForExit();
exitCode = proc.ExitCode;
MessageBox.Show(String.Format("Exit code: {0}", exitCode));
}
}
I am running this on Windows 10, version 1703 (OS Build 15063.1387).

Detect 32-bit or 64-bit

I want to launch a program from inside my program, now I can do this relatively easy, and it works using:
protected void butVNC_ItemClick(object sender, EventArgs e)
{
string str = #"C:\Program Files\RealVNC\VNC4\vncviewer.exe";
Process process = new Process();
process.StartInfo.FileName = str;
process.Start();
}
But my problem is, if my program is installed on a 64-bit operating system, that file path is not right, as it is Program Files(x86) so is there a way to detect and run different code or anything.
From .NET 4.0, you can use Environment.Is64BitProcess.
Example:
if (Environment.Is64BitProcess)
{
// Do 64 bit thing
}
else
{
// Do 32 bit thing
}
You can use the %ProgramFiles% enviroment variable to point to the correct Program Files directory. It should point properly to the correct path.
An example : C# - How to get Program Files (x86) on Windows 64 bit
I ended up using this, and works well, and is really simple:
if (IntPtr.Size == 8)
{
string str = #"C:\Program Files(x86)\RealVNC\VNC4\vncviewer.exe";
Process process = new Process();
process.StartInfo.FileName = str;
process.Start();
}
else if (IntPtr.Size == 4)
{
string str = #"C:\Program Files\RealVNC\VNC4\vncviewer.exe";
Process process = new Process();
process.StartInfo.FileName = str;
process.Start();
}
Thank you for your help though :)

C# ProcessStartInfo and Process.Start cannot find programs in System32

I'm trying to run a shell command with elevated permisions in C#. However the following code returns:
The system cannot find the file specified.
string command = System.IO.Path.Combine(Environment.SystemDirectory, "wdsutil.exe");
string args = ""; //Appropriate arguments
ProcessStartInfo psInfo = new ProcessStartInfo(command);
psInfo.Arguments = args;
psInfo.Verb = "runas";
try
{
Process p = Process.Start(psInfo);
p.WaitForExit();
return "Try Done";
}
catch(Exception e)
{
return e.Message;
}
The error exists without the SystemDriectory prefixed as well.
However, the command does not return the error if I execute the command C:\wdsutil (or any other command in C:).
How do I get Process.Start to run these commands in System32
system32 is on newer systems (esp. 64 Bit windows 7 or 2008) not "real"... it is synthezied from some internal directories and when it is accessed it shows different apps (32 vs. 64) different content...
I test ran the code, changing the executable to one that I located in C:\Windows\System32 directory. It runs ok. (I am running Win 7 64 Bit)
Suggestion: Make sure that the exe is present in the
C:\Windows\System32, or wherever you are trying to run it from. Also, make sure it is unblocked if you'd downloaded it from the internet (Right click the exe > Properties > Unblock).
string command = System.IO.Path.Combine(Environment.SystemDirectory, "wscript.exe");
string args1 = ""; //Appropriate arguments
ProcessStartInfo psInfo = new ProcessStartInfo(command);
psInfo.Arguments = args1;
psInfo.Verb = "runas";
try
{
Process p = Process.Start(psInfo);
p.WaitForExit();
//return "Try Done";
}
catch (Exception e)
{
//return e.Message;
}

Categories

Resources