C# calling batch file failed to copy dll files to System32 folder - c#

I have created a batch file that copies some dll files into System32 folder.
I ran this batch from my program written in C# code:
string path = #"ABC\install.bat";
ProcessStartInfo procStartInfo = new ProcessStartInfo()
{
UseShellExecute = true,
CreateNoWindow = false,
FileName = "\"" + path + "\"",
//Arguments = "\"" + path + "\""
Verb = "runas"
};
using (Process proc = new Process())
{
proc.StartInfo = procStartInfo;
proc.Start();
}
Everything has worked fine. I got the popup message to confirm the change from Windows 7. The console also proved that the file had been copied:
C:\Program Files\XXX>copy commpro.dll C:\Windows\system32\
1 file(s) copied.
But when I look in System32 folder I couldn't find my dlls there.
It's so strange!
Does anybody occur this issue?
Edit: My question is different with this question: How to write files in C:\Windows\System32 with full permissions
Here I got the popup that allow me to grant permission to write to System32 folder. And the output of "copy" command didn't show "Access Denied" but "Copied".
The problem is why it doesn't contain my dlls while it said "copied" ?

If your app is a 32-bit application, then the file will end up in the %windir%\SysWOW64 folder. See this page on Msdn for more details.
Your 32-bit application should be able to see this file.
I should point out that copying dlls to your system folder is usually a bad idea and should be avoided if at all possible.

Related

Installing a program with setup.exe including multiple msi-files using C# process from a subfolder

In my C# WPF application I want to install an other program. The other program consists of a setup.exe, multiple msi files and a vcredist.exe. I need to start the setup.exe because it hands over some parameters and information to the msi files and uses an update functionality for the existing version of the program. So I can't start the msi files directly.
programPath = programPath + #"\setup.exe";
Process programsetup = Process.Start(programPath);
programsetup.WaitForExit();
Files are stored in root directory of my C# app. My problem is that I can't move the files to an subfolder because the msi files are always searched in the root directory and not in the subfolder.
now:
..\myApp\setup.exe
..\myApp\client.msi
..\myApp\host.msi
..\myApp\manager.msi
..\myApp\vcredist.exe
My question: How can I move setup.exe and msi files in a subfolder and start it from there?
What I want:
..\myApp\toolkit\setup.exe
..\myApp\toolkit\client.msi
..\myApp\toolkit\host.msi
..\myApp\toolkit\manager.msi
..\myApp\toolkit\vcredist.exe
Error I get during setup when I do it this way: ..\myApp\client.msi not found.
This code will directly launch setup.exe.
Properties -> right click Open to Resources.resx -> Top Left Add Existing File -> select the file.
byte[] resourceFile = Properties.Resources.setup;
string destination = Path.Combine(Path.GetTempPath(), "setup.exe");
System.IO.File.WriteAllBytes(destination, resourceFile);
Process.Start(destination);
I've solved it with ProcessStartInfo.WorkingDirectory.
Problem/Solution: If you start a setup file with Process which loads during installation some msi files from same directory you need to set WorkingDirectory.
Code example:
string ToolkitExe = myAppPath + #"\myApp\toolkit\setup.exe";
string ToolkitPath = myAppPath + #"\myApp\toolkit\";
ProcessStartInfo startInfo = new ProcessStartInfo(myAppPath + #"\myApp\toolkit\");
startInfo.WorkingDirectory = myAppPath;
Process p = Process.Start(startInfo);
p.WaitForExit();
RunAll();

How to reference an exe file stored in visual studio project resource when running cmd.exe using process.start()

I am developing a C# windows form application project. The form contains a button and after the button click event cmd.exe is started using Process.Start() method. The StartInfo.Arguments() contains path to an exe file stored in the project resources folder (I have created a new folder called Resources and another subfolder called SW1. The exe file is inside SW1 folder)
Right now, the exe file is stored in a different location in local computer and I use the full path to refernce the exe file in StartInfo.Argument(). However, when i publish the C# application, I want the exe file will be bundled as a resource. How can I reference the exe file in this case?
private async void button1_Click(object sender, EventArgs e)
{
await RunCMDAsync();
}
private async static Task RunCMDAsync()
{
try
{
using (Process myProcess = new Process())
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = "cmd.exe";
startInfo.Arguments = #"/C cd <path to the exe file on my local computer here> & <name of exe --additional arguments>";
startInfo.UseShellExecute = false;
startInfo.RedirectStandardInput = true;
myProcess.StartInfo = startInfo;
myProcess.Start();
myProcess.WaitForExit();
}
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
In the above code, Whenever the cmd.exe process is started, I want to pass two arguments using StartInfo.Arguments()
startInfo.Arguments = #"/C cd <path to the exe file on my local computer here> & <name of exe --additional arguments>";
The first argument is to cd into the folder which contains the exe file
(/C cd <path to the exe file on my local computer here>)
The second argument runs the exe file with some parameters (<name of exe --additional arguments>)
How can I reference the exe file in Resources > SW1 folder after I publish this as a standalone application? Do I need to extract the exe file to a location on the target computer during installing the C# application and use the same code as above or is there a way to directly reference resources folder?
If what you need is to find the directory where your program is running (I'm not sure I understood your problem) then use System.AppDomain.CurrentDomain.BaseDirectory.
string exePath = System.AppDomain.CurrentDomain.BaseDirectory +
"Resources\\SW1\\" + exefilenameWithExtension;

LPR command to print pcl-file from windows service not working(Now a tray application)

I've been looking around for a while for a possible solution and explanation, but I can't find anything really.
The following command is being run from a windows service. The same command does function if used directly in cmd.
It does not return any errors or anything else for that matter.
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
startInfo.FileName = "cmd.exe";
startInfo.Arguments = "/C lpr.exe –S " + printerIP + " –P " + deviceName + " –o l " + fInfo.DirectoryName + #"\" + fInfo.Name;
process.StartInfo = startInfo;
process.Start();
It might just be some minor thing I'm missing, but I just can't see it. If it's possible to go around using the lpr-command with an easy alternative I'd love that, but I havent seen anything yet.
Edit:
Forgot to add that the file I'm trying to send to the printer is a pcl file.
Edit2:
When I run the command without the Hidden windowstyle and WaitForExit(5000) applied to the process then I can't seem to see any commandline written - all that appears is the empty command prompt.
Edit 3:
Been toying a bit around with this now and I've come up with the following:
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
startInfo.FileName = "lpr";
startInfo.Arguments = " –S " + printerIP + " –P " + deviceName + " –o l " + fInfo.DirectoryName + #"\" + fInfo.Name;
process.StartInfo = startInfo;
process.Start();
The above code works if it is executed by a user clicking a button in a form. So I decided to change my code into running as a tray application, seeing as I thought this might solve the issues - yet it still seems to refuse being run. Could it be some sort of issue with it being run by a triggered timer or another thread? Or perhaps something to do with the rights of those methods?
Change your code to this:
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
startInfo.FileName = "cmd.exe";
startInfo.Arguments = "/C C:\windows\Sysnative\lpr.exe –S " + printerIP + " –P " + deviceName + " –o l " + fInfo.DirectoryName + #"\" + fInfo.Name;
process.StartInfo = startInfo;
process.Start();
The issue is that you are trying to access a 64 bit application (lpr) from a 32 bit cmd.exe application. The simple solution is to use the sysnative directory.
http://www.samlogic.net/articles/sysnative-folder-64-bit-windows.htm
The 'Sysnative' folder is invisible in Windows Explorer If you
start Windows Explorer and open the Windows folder on your hard disk,
you may notice that the Sysnative folder is not shown. The main reason
to this is that Windows Explorer is a 64-bit program (when run in a
64-bit Windows), and the Sysnative folder is only visible and
accessible from 32-bit software. If 64-bit software need access to the
64-bit system folder in Windows, the only option is to use the
System32 folder name (for example: C:\Windows\System32).
Using the 'Sysnative' folder will help you access 64-bit tools from
32-bit code Some tools in a 64-bit Windows only exist in a 64-bit
version; there is no 32-bit version available. And some of these tools
are located in the 64-bit System32 folder. One example is the nbtstat
tool that is used to help troubleshoot NetBIOS name resolution
problems. If you try to run the nbtstat tool from 32-bit code (for
example from an application or from script) and use a path like
C:\Windows\System32, you will get a "File not found" error. The file
can not be found; although Windows Explorer shows that the nbtstat
program file actually is located in the C:\Windows\System32 folder.
The solution to this (somewhat confusing) problem is to include the
virtual Sysnative folder in the folder path when you want to run the
tool. For example like this: C:\Windows\Sysnative\nbtstat.exe The
file path above will give you access to the 64-bit nbtstat tool from a
32-bit application or from a 32-bit script. We recommend you to read
this article / blog post (at Scottie’s Tech.Info) to get more details
about this.

Executing a batch file from Windows Forms application

I have written a small batch file that copies an exe from solution to the system32 folder.
copy "blah.exe" "%systemroot%/System32"
The batch file works fine and copies the exe if ran from the desktop by double clikcing (placed exe on the desktop as well)
However, I tried doing that from Windows Application by:
Process.Start("sample.bat");
(EXE file and batfile -> Properties -> Output to Copy Always)
The cmd window does come up, but the .exe file is not there in the destination directory. What am I missing here?
in your batch file change path to that particular folder where you have blah.exe, change to the particular drive and then to particular folderlets say your source folder is C:\test then type cd\test in the batch file, it should be something like:
C:
cd\test
copy "blah.exe" "%systemroot%/System32"
or use copy with complete path e.g
copy "C:\test\blah.exe" "%systemroot%/System32"
EDIT:
To copy using CMD try:
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
startInfo.FileName = "cmd.exe";
startInfo.Arguments = "/C copy /b blah.exe %systemroot%/System32";
process.StartInfo = startInfo;
process.Start();
Edit 2: Or for batch file
System.Diagnostics.Process.Start("cmd", "/c sample.bat");

Starting program in C# including all files

I'm having problems running a process from my program.
When I start the process it says "Cannot find Tibia.dat!" ( it thinks the exe file is located in project directory, when it isn't ).
So when I start the process in my program ( from: C:\program\Tibia\Tibia.exe ) it says "Cannot find C:\user\marcus\my documents\visual studio 2009\blablalba\Tibia.dat".
Here's the code I'm using:
Process.Start(addressToFirstTibia + "\\Tibia.exe");
Grateful for help !!
You need to set the working directory. Tibia.exe probably expects it to be the same as the executable's directory, so try:
Process.Start(new ProcessStartInfo {
FileName = Path.Combine(addressToFirstTibia, "Tibia.exe"),
WorkingDirectory = addressToFirstTibia
});
Is Tibia.exe looking for Tibia.dat internally? It may be detecting somehow that the "current working directory" is the project directory, not its own executable directory.
There's a property called WorkingDirectory on ProcessStartInfo that may solve this issue for you. Info can be found here.

Categories