I have two Unity3D applications - one launched by the other, with a -batchmode argument on the launched one so it has no graphics.
On Mac OSX the launched process still gets a dock icon that sits there bouncing forever; clicking it does nothing since it's non-graphical, and I'd really like to remove it.
I've tried modifying the Info.plist with a LSUIElement entry to get rid of the dock icon. That works perfectly if I launch the application myself, but it still gets a dock icon when I launch it as a process.
My process launching code is a little unusual which mightn't be helping. This works on Windows and Linux but not OSX and I'm not sure why (C#, mono):
ProcessStartInfo proc = new ProcessStartInfo();
proc.FileName = path + filename;
proc.WorkingDirectory = path;
proc.Arguments = commandlineFlags;
process = Process.Start(proc);
I've only got it to launch on OSX with this specific setup:
ProcessStartInfo startInfo = new ProcessStartInfo("open", "-a '" + path + filename + "' -n --args " + commandlineFlags);
startInfo.UseShellExecute = false;
process = Process.Start(startInfo);
You will need MonoMac for this if you are not already using it, either the older open-source version or the commercial version (Xamarin.Mac).
In the Unity app that you are launching as a 'sub-process' from the first app add a project reference to MonoMac and add a using clause for MonoMac:
using MonoMac;
Then in your static Main function:
MonoMac.AppKit.NSApplication.Init ();
MonoMac.AppKit.NSApplication.SharedApplication.ActivationPolicy = MonoMac.AppKit.NSApplicationActivationPolicy.Accessory;
That will hide the application/process from dock and task switcher... Of course you can conditional skip that code if you are running on Windows/Linux.
Answering my own question, but adding these to the ProcessStartInfo removed the dock icon:
startInfo.CreateNoWindow = true;
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
I'm not sure if both of those is actually needed, but there doesn't seem to be any harm.
A PList edit seems to be needed as well. Specifically I'm adding:
<key>LSBackgroundOnly</key>
<string>1</string>
As found here.
Related
I am running processes from C# using the following code;
private static void ExecuteShellCMD(string workingDir, string commandWithArgs, bool bWait = true)
{
ProcessStartInfo info = new ProcessStartInfo();
info.Verb = "runas";
info.FileName = "cmd.exe";
info.WorkingDirectory = workingDir;
info.Arguments = "/C " + commandWithArgs;
info.UseShellExecute = false;
using (Process myProcess = Process.Start(info))
{
if (bWait)
{
myProcess.WaitForExit();
}
int ExitCode = myProcess.ExitCode;
//Log exit code here.
}
}
It loads an elevated command window and executes the code/bat file I pass it, but without logging anything to the console. This doesn't appear to be consistent on other machines, and has worked in the past on my machine, and I wondered if anyone had any ideas about how I can consistently make this Process just print logs into the command window the process makes.
I can see logs if I set UseShellExecute = true but then can't use Verb without accepting the elevation prompt which is undesirable.
I have tried looking for solutions around the web, and I am aware that I can redirect the output using other settings. Most of the questions and tutorials on this subject seem to deal with redirecting the ouput to somewhere else but I want to be able to keep track of the progress in the command window itself.
Perhaps I have missed an command line argument or similar?
Turns out this was actually a bug in Unity Hub. The process and output were working fine, however when ran from a Unity instance that was launched from Unity Hub it took control of the output and didn't release it. This was solved by just launching Unity directly and a bug report has been filed against Unity hub.
I've been looking around the internet for this, but I couldn't find it.
Is there a way to trigger an uninstaller (from the Programs and Features screen) via C#? Or is this blocked by Windows for security purposes?
You can use msiexec.exe. You can simply uninstall an application with its product code. Using command you can set whether to show UI during the uninstallation or make it a silent uninstallation,
string UninstallCommandString = "/x {0} /qn";
/qn: Set user interface level: None
/qb: Set user interface level: Basic UI
/qr: Set user interface level: Reduced UI
/qf: Set user interface level: Full UI (default)
C# code
string UninstallCommandString = "/x {0} /qn";
Process process = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
process.StartInfo = startInfo;
startInfo.UseShellExecute = false;
startInfo.RedirectStandardError = true;
startInfo.FileName = "msiexec.exe";
startInfo.Arguments = string.Format(UninstallCommandString, "Product Code");
process.Start();
Have a look at C# - Installing and uninstalling software and Programmatically Uninstall Programs With C#
You could invoke the executable file for the uninstaller using system.diagnostics.
Something like the following should do the trick:
System.Diagnostics.Process.Start("/path/to/uninstall.exe", "arguments for uninstaller if needed, else don't bother with this arg");
It's quick and dirty and /should/ work. Hope that helps.
edit- Just realised you want to do this from the add remove software screen. I'll leave this here anyway but my mistake.
We changed the logo-icon of our WPF application, and then the icon of the main executable. On my PC with Win 7, there is a problem with the refresh of the icon cache: the desktop shortcut to the main executable, and the preview of the icon of the executable, in Windows Explorer still shows the old icon.
Even restarting the system the problem persists.
I found that running this command solves the problem:
ie4uinit.exe-ClearIconCache
My problem is that I can't run it from code. I made two attempts.
First:
Dim si As New ProcessStartInfo()
si.CreateNoWindow = False
si.UseShellExecute = False
si.FileName = "ie4uinit.exe"
si.WindowStyle = ProcessWindowStyle.Hidden
si.Arguments = "-ClearIconCache"
Dim p As Process = Process.Start(si)
error: "Could not find the specified file" - I tried to input the full path but it still doesn't find the file
Second:
I put the command in a batch file
Dim si As New ProcessStartInfo("C:\test.bat")
si.UseShellExecute = False
si.RedirectStandardError = True
si.RedirectStandardInput = True
si.RedirectStandardOutput = True
si.CreateNoWindow = True
si.ErrorDialog = False
si.WindowStyle = ProcessWindowStyle.Hidden
Dim p As Process = Process.Start(si)
This time I get no errors, but not even the desired effect. If I double-click on the batch file instead, everything is working fine.
I'd like to adjust one of these procedure otherwise finding a new one to clear the windows icon cache. C# or Visual Basic is not important...
Pileggi
maybe it doesn't search for it in the path try using:
as the path "%WINDIR%\System32\ie4uinit.exe",
if this doesnt work try "C:\Windows\System32\ie4uinit.exe"
I found the solution: I had to build the executable that runs the batch file for "Any CPU", otherwise it has not sufficient permissions to run ie4unit.
Before I was trying building for "x86" and I was running the process on a Win7 64 bit...
I had a similar issue, trying to call ie4uinit from an Inno installer. The PATH did include the right system directories; however, doing a "dir" did not show that the file exists. In fact, there were over 100 *.exe files that could not be found from whatever shell was executing the command. Opening Explorer or a command window reveals the file is there (which of course we know). I think it is a permissions or access issue. I didn't have the patience to trace it further, but just copied ie4uinit.exe to a local directory and had my installer execute it there.
Enables or disables file system redirection for the calling thread.
[DllImport("Kernel32.dll")]
private static extern bool Wow64EnableWow64FsRedirection(bool Wow64FsEnableRedirection);
//.....
Wow64EnableWow64FsRedirection(false);
Dim p As Process = Process.Start(si)
Wow64EnableWow64FsRedirection(true);
You can try this:
Dim objProcess As System.Diagnostics.Process
objProcess = New System.Diagnostics.Process()
objProcess.StartInfo.FileName = "ie4uinit.exe"
objProcess.StartInfo.Arguments = "-ClearIconCache"
objProcess.StartInfo.WindowStyle = ProcessWindowStyle.Normal
objProcess.Start()
objProcess.WaitForExit()
objProcess.Close()
I have searched everywhere to find out how to make a custom minecraft launcher. I managed to create this code, which should work, but sadly it does not. I login but it never starts, however for a second I get the loading ring next to my mouse. This is my code:
ProcessStartInfo start = new ProcessStartInfo();
// Enter in the command line arguments, everything you would enter after the executable name itself
start.Arguments = #"-Xmx1G -Djava.library.path=%APPDATA%\.minecraft\versions\1.6.2\1.6.2-natives -cp %APPDATA%\.minecraft\libraries\net\sf\jopt-simple\jopt-simple\4.5\jopt-simple-4.5.jar;%APPDATA%\.minecraft\libraries\com\paulscode\codecjorbis\20101023\codecjorbis-20101023.jar;%APPDATA%\.minecraft\libraries\com\paulscode\codecwav\20101023\codecwav-20101023.jar;%APPDATA%\.minecraft\libraries\com\paulscode\libraryjavasound\20101123\libraryjavasound-20101123.jar;%APPDATA%\.minecraft\libraries\com\paulscode\librarylwjglopenal\20100824\librarylwjglopenal-20100824.jar;%APPDATA%\.minecraft\libraries\com\paulscode\soundsystem\20120107\soundsystem-20120107.jar;%APPDATA%\.minecraft\libraries\argo\argo\2.25_fixed\argo-2.25_fixed.jar;%APPDATA%\.minecraft\libraries\org\bouncycastle\bcprov-jdk15on\1.47\bcprov-jdk15on-1.47.jar;%APPDATA%\.minecraft\libraries\com\google\guava\guava\14.0\guava-14.0.jar;%APPDATA%\.minecraft\libraries\org\apache\commons\commons-lang3\3.1\commons-lang3-3.1.jar;%APPDATA%\.minecraft\libraries\commons-io\commons-io\2.4\commons-io-2.4.jar;%APPDATA%\.minecraft\libraries\net\java\jinput\jinput\2.0.5\jinput-2.0.5.jar;%APPDATA%\.minecraft\libraries\net\java\jutils\jutils\1.0.0\jutils-1.0.0.jar;%APPDATA%\.minecraft\libraries\com\google\code\gson\gson\2.2.2\gson-2.2.2.jar;%APPDATA%\.minecraft\libraries\org\lwjgl\lwjgl\lwjgl\2.9.0\lwjgl-2.9.0.jar;%APPDATA%\.minecraft\libraries\org\lwjgl\lwjgl\lwjgl_util\2.9.0\lwjgl_util-2.9.0.jar;%APPDATA%\.minecraft\versions\1.6.2\1.6.2.jar net.minecraft.client.main.Main --username playername --session token:"+ words[3] + #":" + words[4]+ #" --version 1.6.2 --gameDir %APPDATA%\.minecraft --assetsDir %APPDATA%\.minecraft\assets";
start.FileName = #"c:\Program Files (x86)\java\jre7\bin\javaw.exe";
// Do you want to show a console window?
start.CreateNoWindow = true;
System.Diagnostics.Process.Start(start);
This just does the loading ring by my mouse for a second, then nothing opens. No logs, crashes, errors, nothing wrong. This is Visual c# compiled on Visual Studio 2012.
The arguments you are giving have an environment variable in them - %APPDATA%.
The command line will expand this by default, but the .net library won't.
See How do I ensure c# Process.Start will expand environment variables?
As Pete Kirkham mentioned you need to set up environment variable.
You can set it before starting the Process like:
var appDataPath = "your path";
start.EnvironmentVariables.Add("APPDATA", appDataPath);
I'm trying to launch an executable with Process.Start(). When the exe has no DLL dependencies, it works fine. However, when I need to include 2 DLLs, it doesn't work. I've tried setting the WorkingDirectory, and have verified that the 2 required DLLs are present there. Any ideas?
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = false;
startInfo.UseShellExecute = false;
startInfo.FileName = "memcached.exe";
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.Arguments = arguments; //not shown
startInfo.WorkingDirectory = Environment.CurrentDirectory;
try
{
using (Process exeProcess = Process.Start(startInfo))
{
exeProcess.WaitForExit();
}
}
catch (Exception ex)
{
Trace.TraceError(ex.Message); // never gets here
}
This is code based on the Windows Azure Memcached Solution Accelerator. When memcached can't launch, a dialog box is displayed. Unfortunately you can't see this when the code is running remotely in the cloud.
I had similar problem trying to start another process that needed a DLL and couldn't find it. The solution was pretty simple in my case, a missing '\'.
procInfo.WorkingDirectory = #"C:\filedir"; //won't work
procInfo.WorkingDirectory = #"C:\filedir\" ; //would do the trick
procInfo.WorkingDirectory = Enviroment.CurrentDirectory; //== "C:\filedir", that won't work either
procInfo.WorkingDirectory = Enviroment.CurrentDirectory + '\\'; // would work.
Hope that helps you.
The problem might be that you are setting the WorkingDirectory to the current directory of the current process (which could be anywhere, not necessarily the directory containing your program). Try setting the working directory to the directory containing the exe you want to start.
Also, have you verified that the DLLs are with memcached.exe (or in the place required by the memcached.exe)?
Try to place your .EXE file and that referenced assemblies in same place, and to define your WorkingDirectory.WorkingDirectory to that folder. This probably will work fine.
One extreme alternative is to strong name that references assemblies (DLL) and to register them into GAC.
You should exhaust all other alternatives before think about this option.