我有两个应该一起运行的.exe文件,否则我的应用程序将无法运行。所以我创建了一个批处理脚本,它可以运行两个exe,最终它的批处理窗口文件不是窗口安装程序。
我查看了其他打包工具Inno,但他们没有执行两项并行操作。
无论如何,我可以从窗口运行两个带有单个快捷图标的exe文件吗?如果你能提供一点帮助,我将不胜感激。 提前谢谢。
答案 0 :(得分:2)
如果我不误解你......
这是一个生成.Net
exe的批处理文件,可以根据需要启动任意数量的进程。保存为(即 build.bat )运行它,您将获得一个myNetExe.exe
文件,该文件将启动两个notepad
。
//>nul 2>nul||@goto :batch_code
/*
:batch_code
@echo off
setlocal
rem place desired exe name
set "theExeFile=myNetExe.exe"
rem if not exist "%theExeFile%" call :build_the_exe || exit/B
call :build_the_exe || exit/B
endlocal
exit /b 0
:build_the_exe
:: find csc.exe
set "frm=%SystemRoot%\Microsoft.NET\Framework\"
for /f "tokens=* delims=" %%v in ('dir /b /a:d /o:-n "%SystemRoot%\Microsoft.NET\Framework\v*"') do (
set netver=%%v
goto :break_loop
)
:break_loop
set "csc=%frm%%netver%\csc.exe"
:: csc not found
if "%csc%" == "\csc.exe" echo/&echo/Warning: Net Framework Not Found&exit/B 1
::csc found
call %csc% /nologo /out:"%theExeFile%" "%~dpsfnx0"
exit/B 0
*/
//begin c# code
using System;
using System.Security; // get secure string
using System.Diagnostics; // processes
namespace ElZooilogico
{
public class Procesos
{
private static SecureString GetSecureString(string str)
{
SecureString secureString = new SecureString();
foreach (char ch in str)
{
secureString.AppendChar(ch);
}
secureString.MakeReadOnly();
return secureString;
}
//public static bool CreateProceso(string processName, string processArgs, string user, string pass, out uint processID, bool bShowWindow = true)
public static bool CreateProceso(string processName, string processArgs, out uint processID, bool bShowWindow = true)
{
bool result = false;
processID = 0;
try
{
ProcessStartInfo procStartInfo = new ProcessStartInfo()
{
RedirectStandardOutput = false,
UseShellExecute = false,
CreateNoWindow = bShowWindow,
//UserName = user,
//Password = GetSecureString(pass),
FileName = processName,
Arguments = processArgs
};
Process p = new Process();
p.StartInfo = procStartInfo;
if ( (result = p.Start()) )
processID = (uint)p.Id;
} catch {}
return result;
}
public static void Main()
{
uint processID = 0;
try {
CreateProceso("notepad", @"C:\Windows\win.ini", out processID, true);
CreateProceso("notepad", @"C:\Windows\system.ini", out processID, true);
//use following line to start process under other user account (remove comments from UserName/Password above)
//CreateProceso("notepad", @"C:\Windows\win.ini", "some_user_name", "user_password", out processID, true);
} catch {}
}
} // class Procesos
}
使用notepad
和path\exe
将C:\Windows\win.ini
更改为您的参数并将其更改为
此外,您可以更改main
函数以从命令行运行程序,但是您必须确保始终为每个程序设置一对program + prog_params
。另外,如果path
或params
包含空格,请加上引号。另一种方法是添加检查,但不在此范围内。
即。 myNetExe "C:\Program Files (x86)\some_folder\some.exe" "param1 param2" "C:\Program Files (x86)\some_other_folder\other.exe" ""
。在后面,没有参数,但必须发送空字符串。
public static void Main(string[] args)
{
uint processID = 0;
try {
for ( int i = 0; i < args.Length; i+=2 )
{
CreateProceso(args[i], args[i+1], out processID, true);
}
} catch {}
}
编辑仅作为概念验证,添加了用于创建快捷方式的开关。
//>nul 2>nul||@goto :batch_code
/*
:batch_code
@echo off
setlocal
rem place desired exe name
set "theExeFile=myNetExe.exe"
rem if not exist "%theExeFile%" call :build_the_exe || exit/B
call :build_the_exe || exit/B
endlocal
exit /b 0
:build_the_exe
:: find csc.exe
set "frm=%SystemRoot%\Microsoft.NET\Framework\"
for /f "tokens=* delims=" %%v in ('dir /b /a:d /o:-n "%SystemRoot%\Microsoft.NET\Framework\v*"') do (
set netver=%%v
goto :break_loop
)
:break_loop
rem set "netver=v3.5" & rem for version build testing purposes
cls&echo/&echo/Framework version is [%netver:~1%]&echo/
set "csc=%frm%%netver%\csc.exe"
:: csc not found
if "%csc%" == "\csc.exe" echo/&echo/Warning: Net Framework Not Found&exit/B 1
::csc found
if /I "%netver%" EQU "v3.5" (
call %csc% /nologo /define:NET35 /out:"%theExeFile%" "%~dpsfnx0" && (echo Done^!) || (echo Failed^!)
) else (
call %csc% /nologo /define:NET40 /out:"%theExeFile%" "%~dpsfnx0" && (echo Done^!) || (echo Failed^!)
)
exit/B 0
*/
//begin c# code
using System;
using System.IO; // file, path
using System.Security; // get secure string
using System.Reflection; // Shortcut
using System.Diagnostics; // processes
using System.Windows.Forms; // Application
using System.Runtime.InteropServices; // Com
namespace ElZooilogico
{
public static class Shortcut
{
private const string DEFAULT_EXTENSION = ".lnk";
#if (NET35)
public static string Create(string linkFileName, string targetPath, string description, string arguments, int iconNumber)
#else
public static string Create(string linkFileName, string targetPath, string description = "", string arguments = "", int iconNumber = 0)
#endif
{
if ( linkFileName.Contains(DEFAULT_EXTENSION) == false )
linkFileName = string.Format("{0}{1}", linkFileName, DEFAULT_EXTENSION);
if ( File.Exists(targetPath) == false )
throw new Exception(targetPath);
string iconLocation = string.Format("{0},{1}", targetPath, iconNumber);
Type t = Type.GetTypeFromCLSID(new Guid("72C24DD5-D70A-438B-8A42-98424B88AFB8")); //Windows Script Host Shell Object
#if (NET35)
object shell = Activator.CreateInstance(t);
try {
object shortcut = t.InvokeMember("CreateShortcut", BindingFlags.InvokeMethod, null, shell, new object[]{linkFileName});
try {
t.InvokeMember("TargetPath", BindingFlags.SetProperty, null, shortcut, new object[]{targetPath});
t.InvokeMember("WorkingDirectory", BindingFlags.SetProperty, null, shortcut, new object[]{Path.GetDirectoryName(targetPath)});
t.InvokeMember("Arguments", BindingFlags.SetProperty, null, shortcut, new object[]{arguments});
t.InvokeMember("WindowStyle", BindingFlags.SetProperty, null, shortcut, new object[]{1});
t.InvokeMember("Description", BindingFlags.SetProperty, null, shortcut, new object[]{description});
t.InvokeMember("IconLocation", BindingFlags.SetProperty, null, shortcut, new object[]{"shell32.dll, 5"});
t.InvokeMember("Save", BindingFlags.InvokeMethod, null, shortcut, null);
} finally { Marshal.FinalReleaseComObject(shortcut); }
} finally { Marshal.FinalReleaseComObject(shell); }
#else
dynamic shell = Activator.CreateInstance(t);
try {
var shortcut = shell.CreateShortcut(linkFileName);
try {
shortcut.TargetPath = targetPath;
shortcut.WorkingDirectory = Path.GetDirectoryName(targetPath);
shortcut.Arguments = arguments;
shortcut.WindowStyle = 1;
shortcut.Description = description;
shortcut.IconLocation = "shell32.dll, 1"; //iconLocation; // "shell32.dll, 1";
shortcut.Save();
} finally { Marshal.FinalReleaseComObject(shortcut); }
} finally { Marshal.FinalReleaseComObject(shell); }
#endif
return Path.Combine(System.Windows.Forms.Application.StartupPath, linkFileName);
}
} // class Shortcut
public class Procesos
{
private static string own = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\My Shortcut";
#if (NET35)
private static string all = Path.GetPathRoot(Environment.SystemDirectory) + @"Users\Public\Desktop\All Shortcut";
#else
private static string all = Environment.GetFolderPath(Environment.SpecialFolder.CommonDesktopDirectory) + "\\All Shortcut";
#endif
private static SecureString GetSecureString(string str)
{
SecureString secureString = new SecureString();
foreach (char ch in str)
{
secureString.AppendChar(ch);
}
secureString.MakeReadOnly();
return secureString;
}
//public static bool CreateProceso(string processName, string processArgs, string user, string pass, out uint processID, bool bShowWindow = true)
#if (NET35)
public static bool CreateProceso(string processName, string processArgs, out uint processID, bool bShowWindow)
#else
public static bool CreateProceso(string processName, string processArgs, out uint processID, bool bShowWindow = true)
#endif
{
bool result = false;
processID = 0;
try
{
ProcessStartInfo procStartInfo = new ProcessStartInfo()
{
RedirectStandardOutput = false,
UseShellExecute = false,
CreateNoWindow = bShowWindow,
//UserName = user,
//Password = GetSecureString(pass),
FileName = processName,
Arguments = processArgs
};
Process p = new Process();
p.StartInfo = procStartInfo;
if ( (result = p.Start()) )
processID = (uint)p.Id;
} catch {}
return result;
}
public static void Main(string[] args)
{
uint processID = 0;
if ( args.Length > 0 )
{
try {
for ( int i = 0; i < args.Length; i+=2 )
{
if ( args[i].Equals("/LO", StringComparison.OrdinalIgnoreCase) ) { try { Shortcut.Create(own, Application.ExecutablePath, "This is a shortcut for current user", string.Empty, 0); } catch (Exception e) { MessageBox.Show(e.Message); return; } return; }
if ( args[i].Equals("/LA", StringComparison.OrdinalIgnoreCase) ) { try { Shortcut.Create(all, Application.ExecutablePath, "This is a shortcut for all users", string.Empty, 0); } catch (Exception e) { MessageBox.Show(e.Message); return; } return; }
try
{
CreateProceso(args[i], args[i+1], out processID, true);
} catch {}
}
} catch {}
}
else
{
try {
CreateProceso("notepad", @"C:\Windows\win.ini", out processID, true);
CreateProceso("notepad", @"C:\Windows\system.ini", out processID, true);
//use following line to start process under other user account (remove comments from UserName/Password above)
//CreateProceso("notepad", @"C:\Windows\win.ini", "some_user_name", "user_password", out processID, true);
} catch {}
}
}
} // class Procesos
} // namespace ElZooilogico
答案 1 :(得分:0)
Inno Setup解决了这个问题,我经历了几个自己的脚本,它根据它的命令行事。这是 setup.iss 有效的解决方案:
; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
[Setup]
AppName=Electron
AppVersion=1.5
DefaultDirName={pf}\MySetup
DefaultGroupName=MySetup
UninstallDisplayIcon={app}\MySetup.exe
Compression=lzma2
SolidCompression=yes
OutputDir=userdocs:Inno Setup Examples Output
[Files]
Source: "D:\FirstExeFolder\*"; DestDir: "{app}\App"; Flags: ignoreversion recursesubdirs
Source: "D:\test\SecondExeFolder\*"; DestDir: "{app}\server"; Flags: ignoreversion recursesubdirs
Source: "D:\test\batinstaller.bat"; DestDir: "{app}"
[Icons]
Name: "{group}\MySetup"; Filename: "{app}\batinstaller.bat"; WorkingDir: "{app}"; IconFilename: "{app}\icon.ico"
[Run]
Filename: "{app}\batinstaller.bat"
它会将脚本编译成窗口安装程序,可以在任何窗口机器中支持。