Delphi ShellExecute不在IDE中工作,但在其他情况下工作
我想使用ShellExecute命令创建并打开一个txt文件 我已经在Delphi 7中使用此代码多年了,它很有效:Delphi ShellExecute不在IDE中工作,但在其他情况下工作,delphi,Delphi,我想使用ShellExecute命令创建并打开一个txt文件 我已经在Delphi 7中使用此代码多年了,它很有效: function Executa(CONST ExeName, Parameters: string): Boolean; begin if Parameters= '' then Result:= ShellExecute(0, 'open', PChar(ExeName), NIL , nil, SW_SHOWNORMAL)> 32 el
function Executa(CONST ExeName, Parameters: string): Boolean;
begin
if Parameters= ''
then Result:= ShellExecute(0, 'open', PChar(ExeName), NIL , nil, SW_SHOWNORMAL)> 32
else Result:= ShellExecute(0, 'open', PChar(ExeName), PChar(Parameters), nil, SW_SHOWNORMAL)> 32;
end;
现在,我切换到Windows7,当它从IDE运行时,代码不再工作。Delphi显示CPU窗口,标题为“CPU进程未知(2352)”。我关闭CU窗口,一切正常,直到我关闭应用程序,当Delphi再次显示CPU窗口时。
如果我从IDE外部运行应用程序,它可以正常工作
看起来调试器有话要对我说,但我不知道是什么。我昨天遇到了一个问题,调试器使我的应用程序崩溃,但是在IDE之外运行它可以正常运行。我在开发中使用了包 我曾经验证我发现我从另一个位置加载了一份副本,超出了预期。我有两份同一份BPL的副本。一旦我删除了我没有编译的那个,我就没事了
将此应用于此问题,我将检查以确保您没有任何编译代码的副本,其中包括:.DCU、.DCP、.BPL、.EXE。然后我还要确保您可以按住ctrl键并单击“ShellExecute”来查看声明。您的库路径设置可能无法找到源。听起来您好像打开了“”选项。启用该选项后,调试器会尽早中断新进程。按下“运行”按钮,使其继续运行
您可以在下次调试程序时确认此假设。将流程ID(示例中为2352)与Task Manager显示的流程列表进行比较。该列表中的哪个进程与调试器报告的进程ID相匹配?此处是暗中拍摄的,但请尝试以管理员身份运行IDE,然后不以管理员身份运行。这可能是一个因素。一些用户设置了管理员选项,以使自动更新成功运行。因此,如果您已经这样做了,那么您可能正在以管理员的身份运行IDE。这不是您问题的答案(我投票支持Rob Kennedy和Chris Thornton),但您可以以更简洁的方式编写例程:
function Executa(const ExeName, Parameters: string): Boolean;
begin
Result :=
(ShellExecute(0, 'open', PChar(ExeName), Pointer(Parameters), nil, SW_SHOWNORMAL) > 32);
end;
注意第四个参数的指针()而不是PChar()。这是一个记录在案的PChar/指针强制转换行为(请参阅帮助)。我也是这么做的,我将ShellExecute替换为以下内容来解决它:
function TformMain.CreateProcessSimple(
sExecutableFilePath : string )
: string;
function GetExeByExtension(sExt : string) : string;
var
sExtDesc:string;
begin
with TRegistry.Create do
begin
try
RootKey:=HKEY_CLASSES_ROOT;
if OpenKeyReadOnly(sExt) then
begin
sExtDesc:=ReadString('') ;
CloseKey;
end;
if sExtDesc <>'' then
begin
if OpenKeyReadOnly(sExtDesc + '\Shell\Open\Command') then
begin
Result:= ReadString('') ;
end
end;
finally
Free;
end;
end;
end;
var
pi: TProcessInformation;
si: TStartupInfo;
fapp: string;
begin
fapp:=GetExeByExtension(ExtractFileExt(sExecutableFilePath));
FillMemory( @si, sizeof( si ), 0 );
si.cb := sizeof( si );
if Pos('%1',fApp)>0 then begin
sExecutableFilePath:=StringReplace(fapp,'%1',sExecutableFilePath,[rfReplaceAll]);
end else begin
sExecutableFilePath:=fApp+' "'+sExecutableFilePath+'"';
end;
CreateProcess(
Nil,
// path to the executable file:
PChar( sExecutableFilePath ),
Nil, Nil, False,
NORMAL_PRIORITY_CLASS, Nil, Nil,
si, pi );
// "after calling code" such as
// the code to wait until the
// process is done should go here
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
end;
函数TformMain.CreateProcessSimple(
sExecutableFilePath:string)
:字符串;
函数GetExeByExtension(sExt:string):string;
变量
sExtDesc:字符串;
开始
使用TRegistry。创建do
开始
尝试
RootKey:=HKEY_CLASSES_ROOT;
如果OpenKeyReadOnly(sExt),则
开始
sExtDesc:=读取字符串(“”);
闭合键;
结束;
如果sExtDesc“”则
开始
如果OpenKeyReadOnly(sExtDesc+'\Shell\Open\Command'),则
开始
结果:=读取字符串(“”);
结束
结束;
最后
自由的
结束;
结束;
结束;
变量
pi:t过程信息;
si:TStartupInfo;
fapp:字符串;
开始
fapp:=GetExeByExtension(ExtractFileExt(sExecutableFilePath));
填充内存(@si,sizeof(si),0);
si.cb:=sizeof(si);
如果Pos(“%1”,fApp)>0,则开始
sExecutableFilePath:=StringReplace(fapp,'%1',sExecutableFilePath,[rfReplaceAll]);
结束,否则开始
sExecutableFilePath:=fApp+''“'+sExecutableFilePath+''”;
结束;
创建进程(
无
//可执行文件的路径:
PChar(sExecutableFilePath),
零,零,假,
正常优先级等级,无,无,
si,pi);
//“调用代码后”如
//要等到
//流程完成后,请转到此处
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
结束;
ShellExecuteW在关闭“调试衍生进程”选项的情况下解决我的问题(XE2/Win7/32位)
:)
mybe,因为字符串和pchar是2010年的宽指针这可能是我的情况。我查一下。谢谢谢谢我想这样做,但我不确定它是否会起作用。因为时间不够,我选择了安全的方式。再次感谢!!1+就是这样!但我已经检查了好几年了!与Win 98和Win XP一起工作!开着这个不是更好吗?1+并标记为“已接受”。非常感谢。显然,如果您要调试生成的进程,最好不要关闭它。这就是你想做的吗?如果您没有源代码或任何调试信息,那么您可能无法执行太多操作,因此您最好将其关闭,这样您就不会被每个新进程打断。