Cannot run a .exe file from windows form - Visual Studio - visual-studio

I have build a simple windows form where when i press a button run a process indicated in a TextBox
I have tried with this code
Try
System.Diagnostics.Process.Start(TextBox1.Text)
Catch ex As Exception
MsgBox("Error")
End Try
Code works, but I don't understand why I canno't run a .exe genereted from a compiled c project using gcc (which is my goal).
I have tried to execute as Administrator too.
Someone can explain me?

(Converting my comment to an answer)
Code works, but I don't understand why I canno't run a .exe genereted from a compiled c project using gcc (which is my goal).
I suspect the problem is that your gcc-compiled executable has runtime dependencies on files located in the same filesystem directory as your gcc-compiled executable and it references those files only by their short-names (e.g. "someFile.txt") instead of by their absolute-path filenames (e.g. "C:\my-gcc-program\bin\someFile.txt") then the OS looks inside that process' Working Directory (aka Current Directory).
Note that when your program uses Process.Start(String fileName) then the newly created (child) OS process inherits your process's Working Directory rather than it being reset to the new process' executable's filename's parent directory!
So if your child process expects "someFile.txt" to be in its working-directory then you need to launch the child-process with the correct working-directory instead of it inheriting it from your process.
You can do this in 2 different ways, both of which require you to use ProcessStartInfo instead of any of the Process.Start overloads that accept String fileName.
Option 1: Set ProcessStartInfo.WorkingDirectory directly:
ProcessStartInfo psi = new ProcessStartInfo()
{
FileName = #"C:\my-gcc-program\bin\program.exe",
WorkingDirectory = #"C:\my-gcc-program\bin",
}
using( Process p = Process.Start( psi ) )
{
p.WaitForExit();
}
Option 2: Use ProcessStartInfo.UseShellExecute;
The UseShellExecute option creates the new process as though the user started it through their OS shell, such as cmd.exe or Explorer.exe rather than as a child process of your process. (One of the many) effects of this option is that the OS handles setting the Working-directory of this new process automatically for you.
Note that in .NET Framework, this is true by default - but false in .NET Core (and will cause errors if used in UWP). Because it's not true by default in .NET Core you should set it explicitly if you're depending on it to work on all platforms besides UWP.
Note that when using UseShellExecute == true, you still must provide a valid WorkingDirectory path, however its purposes changes:
The WorkingDirectory property behaves differently when UseShellExecute is true than when UseShellExecute is false.
When UseShellExecute is true, the WorkingDirectory property specifies the location of the executable.
If WorkingDirectory is an empty string, the current directory is understood to contain the executable.
When UseShellExecute is true, the working directory of the application that starts the executable is also the working directory of the executable.
When UseShellExecute is false, the WorkingDirectory property is not used to find the executable. Instead, its value applies to the process that is started and only has meaning within the context of the new process.
ProcessStartInfo psi = new ProcessStartInfo()
{
FileName = #"program.exe",
WorkingDirectory = #"C:\my-gcc-program\bin",
UseShellExecute = true
}
using( Process p = Process.Start( psi ) )
{
p.WaitForExit();
}

I post here the code who I have written in Button click event. Maybe can be useful for someone
Try
Dim startInfo As New ProcessStartInfo
startInfo.UseShellExecute = True
startInfo.WorkingDirectory = "C:\workDirectory"
startInfo.FileName = TextBox1.Text
System.Diagnostics.Process.Start(startInfo)
Catch ex As Exception
MsgBox("Error")
End Try
Thanks #Dai for help

Related

How to test if a folder can be deleted

I am writing a Lua function to delete a folder using Luacom in Windows (version 7 onwards and I can't dictate the version). The folder path is specified in UTF-8 and will contain non-ASCII characters, so os.remove, io.whatever, Penlight and lfs will not work. So far I have (using Luacom to access the Windows com model):
function delFolder(sPath, bForce)
--sPath is a fully specified folder path
--bForce is a Boolean indicating whether the folder should be
--deleted even if it contains read-only files
require('luacom')
fso = luacom.CreateObject("Scripting.FileSystemObject")
--code in here to test that the folder exists,
--and return an error if it does not
fso:DeleteFolder(sPath, bForce)
end
My problem is that, if bForce = false, and the folder is effectively read-only, the operation errors out. I need to be able to test for this situation and return an error instead of attempting the operation.
One possibility is to manipulate the Luacom error handling not to abort on error, and test the last error after the operation:
luacom.config.abort_on_error = false
luacom.config.last_error = nil
fso:DeleteFolder(sPath, bForce)
if luacom.config.last_error then
--return error indicating that the folder cannot be deleted
end
but is there a simpler way, using the com model or some other alternative available in Lua?
Reference for FileSystemObject

Xamarin Windows cannot access the specified device, path, or file

I have a Xamarin application running on Windows, and I have a method which includes an opening of a pdf file like this:
var psi = new ProcessStartInfo
{
FileName = "cmd",
WindowStyle = ProcessWindowStyle.Hidden,
UseShellExecute = false,
CreateNoWindow = true,
Arguments = $"/c start {filename}"
};
Process.Start(psi);
When this executes, the windows opens a dialog with the following message:
Windows cannot access the specified device, path, or file. You may not have the appropriate permissions to access the item.
The filename is a pdf file located in the LocalApplicationData, and I also have a database there, and the application is normally creating a database there and manipulates with it, so it should have a permission to access that folder. Also, when I run that pdf with double-click outside the application, the pdf opens normally with Chrome. How to solve this?
Unless you have a file there called "cmd" this won't work, as you have declared your filename as a string with the value "cmd".

QFileDialog: how to set default filename in "Save as..." dialog

I try to create "Save as..." dialog in Mac OS X. But I don't want to use QFileDialog::getSaveFileName() function, because dialog that created by this function is NOT truly-native in Mac OS X Lion. So I decide to create dialog as QFileDialog object:
auto export_dialog( new QFileDialog( main_window ) );
export_dialog->setWindowModality( Qt::WindowModal );
export_dialog->setFileMode( QFileDialog::AnyFile );
export_dialog->setAcceptMode( QFileDialog::AcceptSave );
All works fine, except one problem. I cannot set default name for saved file, so user must type this name manually every time. I know that function QFileDialog::getSaveFileName() allows to set default filename via third argument, dir (http://qt-project.org/doc/qt-4.8/qfiledialog.html#getSaveFileName). But how to set this default name without this function?
I can set default suffix for saved file via QFileDialog::setDefaultSuffix() function, but I need to set whole default name, not only default suffix.
I've tried to use QFileDialog::setDirectory() function, but it sets only directory where to save, without name of saved file.
I use Qt 4.8.1 on Mac OS X Lion.
I have found that using selectFile("myFileName"); only works if the file actually exists. In my case, the intent is to create a new file with the option of overwriting an existing file.
The solution that worked for me (Qt 5.3.2) was as follows:
QFileDialog svDlg;
QString saveFileName = svDlg.getSaveFileName(this, caption, preferredName, filter);
In the above example, preferredName is a QString that contains "C:/pre-selected-name.txt"
Restating what was in the comments for future visitors, the following line puts "myFileName" as the default name in the QFileDialog:
export_dialog->selectFile("myFileName");
Discussion: http://www.qtcentre.org/threads/49434-QFileDialog-set-default-name?highlight=QFileDialog
Not-so-helpful docs: http://qt-project.org/doc/qt-4.8/qfiledialog.html#selectFile
QString dir = QDir::homePath();
QString name = "test.txt";
QFileDialog::getSaveFileName(nullptr, tr("save file"), dir + "/" + name, tr("TXT (*.txt)"));
If you set "dir" argument, and dir is "file"(exist or not), in windows you will have default name.
With the current QT-version (5.x) you can set your preferred file-name with the argument directory in the QFileDialog.getSaveFileName() function call:
QFileDialog.getSaveFileName( directory = 'preferredFileName.txt' )
docs: http://doc.qt.io/qt-5/qfiledialog.html#getSaveFileName

Receiving the path of a VS2010 extension?

I've written a small Extension for VS2010 (vsix file), within the vsix is a binary file, which gets called by the extension.
I try to open the file like this:
ProcessStartInfo startInfo = new ProcessStartInfo
{
FileName = #".\Binaries\TFPT.exe"}
Which works fine if I debug everything. But if I install it, I get a "file not found" error. The Binaries are installed correctly.
So I thought I try to get the complete path to the binaries. But how can I get the path? All Application.Path infos are not pointing to the correct path. Is there a way to get the path of the extension directory?
The path is something like:
C:\Users[username.domain]\AppData\Local\Microsoft\VisualStudio\10.0\Extensions[Company][ExtensionName]\1.0
Any idea without putting it together by hand?
How about retrieving the path from the current executing assembly and use Path.Combine() with your the remaining relative path segment ?
Note: This piece of code comes from a SO answer.
private static string RetrieveAssemblyDirectory()
{
string codeBase = Assembly.GetExecutingAssembly().CodeBase;
var uri = new UriBuilder(codeBase);
string path = Uri.UnescapeDataString(uri.Path);
return Path.GetDirectoryName(path);
}
You can get this path asking for your extension installation path to Visual Studio:
var serviceProvider = [YourPackageObject] as IServiceProvider;
var manager = serviceProvider.GetService(typeof(SVsExtensionManager)) as IVsExtensionManager;
foreach (IInstalledExtension extension in manager.GetInstalledExtensions())
if(extension.Header.Name == [MyExtensionName])
return extension.InstallPath;

How can I run a windows batch file but hide the command window?

How can I run a windows batch file but hiding the command window? I dont want cmd.exe to be visible on screen when the file is being executed. Is this possible?
If you write an unmanaged program and use CreateProcess API then you should initialize lpStartupInfo parameter of the type STARTUPINFO so that wShowWindow field of the struct is SW_HIDE and not forget to use STARTF_USESHOWWINDOW flag in the dwFlags field of STARTUPINFO. Another method is to use CREATE_NO_WINDOW flag of dwCreationFlags parameter. The same trick work also with ShellExecute and ShellExecuteEx functions.
If you write a managed application you should follows advices from http://blogs.msdn.com/b/jmstall/archive/2006/09/28/createnowindow.aspx: initialize ProcessStartInfo with CreateNoWindow = true and UseShellExecute = false and then use as a parameter of . Exactly like in case of you can set property WindowStyle of ProcessStartInfo to ProcessWindowStyle.Hidden instead or together with CreateNoWindow = true.
You can use a VBS script which you start with wcsript.exe. Inside the script you can use CreateObject("WScript.Shell") and then Run with 0 as the second (intWindowStyle) parameter. See http://www.robvanderwoude.com/files/runnhide_vbs.txt as an example. I can continue with Kix, PowerShell and so on.
If you don't want to write any program you can use any existing utility like CMDOW /RUN /HID "c:\SomeDir\MyBatch.cmd", hstart /NOWINDOW /D=c:\scripts "c:\scripts\mybatch.bat", hstart /NOCONSOLE "batch_file_1.bat" which do exactly the same. I am sure that you will find much more such kind of free utilities.
In some scenario (for example starting from UNC path) it is important to set also a working directory to some local path (%SystemRoot%\system32 work always). This can be important for usage any from above listed variants of starting hidden batch.
Using C# it's very easy to start a batch command without having a window open.
Have a look at the following code example:
Process process = new Process();
process.StartInfo.CreateNoWindow = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.UseShellExecute = false;
process.StartInfo.FileName = "doSomeBatch.bat";
process.Start();
For any executable file, you can run your program using cmd with "c" parameter:
cmd /c "your program address"\"YourFileName".bat
(->if it's a batch file!) As a final solution, I suggest that you create a .cmd file and put this command in it:
cmd /c "your program address"\"YourFileName".bat
exit
Now just run this .cmd file.
Native C++ codified version of Oleg's answer -- this is copy/pasted from a project I work on under the Boost Software License.
BOOL noError;
STARTUPINFO startupInfo;
PROCESS_INFORMATION processInformation;
ZeroMemory(&startupInfo, sizeof(startupInfo));
startupInfo.cb = sizeof(startupInfo);
startupInfo.dwFlags = STARTF_USESHOWWINDOW;
startupInfo.wShowWindow = SW_HIDE;
noError = CreateProcess(
NULL, //lpApplicationName
//Okay the const_cast is bad -- this code was written a while ago.
//should probably be &commandLine[0] instead. Oh, and commandLine is
//a std::wstring
const_cast<LPWSTR>(commandLine.c_str()), //lpCommandLine
NULL, //lpProcessAttributes
NULL, //lpThreadAttributes
FALSE, //bInheritHandles
CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT, //dwCreationFlags
//This is for passing in a custom environment block -- you can probably
//just use NULL here.
options.e ? environment : NULL, //lpEnvironment
NULL, //lpCurrentDirectory
&startupInfo, //lpStartupInfo
&processInformation //lpProcessInformation
);
if(!noError)
{
return GetLastError();
}
DWORD exitCode = 0;
if (options.w) //Wait
{
WaitForSingleObject(processInformation.hProcess, INFINITE);
if (GetExitCodeProcess(processInformation.hProcess, &exitCode) == 0)
{
exitCode = (DWORD)-1;
}
}
CloseHandle( processInformation.hProcess );
CloseHandle( processInformation.hThread );
To self-hide already running script you'll need getCmdPid.bat and windowoMode.bat
#echo off
echo self minimizing
call getCmdPid.bat
call windowMode.bat -pid %errorlevel% -mode hidden
echo --other commands--
pause
Here I've compiled all ways that I know to start a hidden process with batch without external tools.With a ready to use scripts (some of them rich on options) , and all of them form command line.Where is possible also the PID is returned .Used tools are IEXPRESS,SCHTASKS,WScript.Shell,Win32_Process and JScript.Net - but all of them wrapped in a .bat files.
This little VBScript from technet does the trick:
Const HIDDEN_WINDOW = 12
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set objStartup = objWMIService.Get("Win32_ProcessStartup")
Set objConfig = objStartup.SpawnInstance_
objConfig.ShowWindow = HIDDEN_WINDOW
Set objProcess = GetObject("winmgmts:root\cimv2:Win32_Process")
errReturn = objProcess.Create("mybatch.bat", null, objConfig, intProcessID)
Edit mybatch.bat to your bat file name, save as a vbs, run it.
Doc says it's not tested in Win7, but I just tested it, it works fine. Won't show any window for whatever process you run
You could write a windows service that does nothing but execute your batch file. Since services run in their own desktop session, the command window won't be visible by the user.
Create a shortcut to your bat file by using the right-click and selecting Create shortcut.
Right-click on the shortcut you created and click on properties.
Click on the Run drop-down box and select Minimized.
Use Bat To Exe Converter and compile the Bat file as an executable.
Steps:
Open Bat to Exe Converter
Select your Bat file
In the options select "Invisible Application"
Finish by pressing the compile button
1,Download the bat to exe converter and install it
2,Run the bat to exe application
3,Download .pco images if you want to make good looking exe
4,specify the bat file location(c:\my.bat)
5,Specify the location for saving the exe(ex:c:/my.exe)
6,Select Version Information Tab
7,Choose the icon file (downloaded .pco image)
8,if you want fill the information like version,comapny name etc
9,change the tab to option
10,Select the invisible application(This will hide the command prompt while running the application)
11,Choose 32 bit(if you select 64 bit exe will work only in 32 bit OS)
12,Compile
13,Copy the exe to the location where bat file executed properly
14,Run the exe

Resources