python win32 使用 Windows 安装程序 API 失败但 perl 工作正常 - 我在 python 中做错了什么?
python win32 fails using Windows Installer API fine but perl works fine - what am I doing wrong in python?
我正在尝试使用 python 的 win32 COM API 编辑 Windows 安装程序 MSI,但无法正常工作。
我的 perl 应用程序工作正常,但尽管我的 python 运行没有错误,但 MSI 没有更新。我是 python 的新手,所以可能做了一些愚蠢的事情。我的新工作使用 python 而不是 perl,所以我非常感谢任何更正(尤其是在错误检测和处理方面)。谢谢!
下面是 python 的 perl
use Win32::OLE;
my $msifile = "ws.msi";
my($Installer, $database, $query, $view);
$Installer = undef;
Win32::OLE::CreateObject("WindowsInstaller.Installer", $Installer) ||
die "CreateObject installer failed: $!";
$database = $Installer->OpenDatabase($msifile, 1) ||
die "cannot open msi file $msifile (OpenDatabase failed): $!";
my $qry = "UPDATE `InstallExecuteSequence` SET `InstallExecuteSequence`.`Condition`='1' WHERE `InstallExecuteSequence`.`Action`='CheckAllUserLegacy'";
$view = $database->OpenView($qry);
check_error();
$view->Execute;
check_error();
$database->Commit();
check_error();
print "\t$msifile updated \n";
$record = undef;
$view = undef;
$database = undef;
$Installer = undef;
exit 0;
sub check_error {
if ( Win32::OLE->LastError() ) {
printf "SQL ERROR, the following query:\n\t'==$query==\ngets\n\t(%-s)\n", Win32::OLE->LastError();
exit(1);
}
}
============================================= ============================
import pdb;
import win32com.client
msifile = "e:\ws.msi"
MSIDBOPEN_TRANSACT = 1
MSIDBOPEN_DIRECT = 2
openMode = MSIDBOPEN_TRANSACT
print "about to open DB"
#pdb.set_trace()
try:
wi = win32com.client.DispatchEx ( "WindowsInstaller.Installer" )
db = wi.OpenDatabase( msifile, openMode )
except:
print "Oops"
else:
print ("opened OK")
sql = "UPDATE `InstallExecuteSequence` SET `InstallExecuteSequence`.`Condition`='0' WHERE `InstallExecuteSequence`.`Action`='CheckAllUserLegacy'"
#print(sql)
try:
view = db.OpenView(sql)
except:
error = wi.LastErrorRecord()
for field_num in range(1, error.FieldCount + 1):
print error.StringData(field_num)
else:
print ("after open view, didn't get exception")
try:
view.Execute
except:
error = wi.LastErrorRecord()
for field_num in range(1, error.FieldCount + 1):
print error.StringData(field_num)
else:
print ("view.executed didn't get exception")
try:
db.Commit
except:
error = wi.LastErrorRecord()
for field_num in range(1, error.FieldCount + 1):
print error.StringData(field_num)
else:
print ("after commit, didn't get exception")
print "end"
在 运行 perl 之后 MSI 被正确更改,但是在 运行 之后 python 它没有改变。我是 python 新手,但使用 perl 多年(这些是精简的片段,不是很好的编程示例)
Python 函数名称后需要括号,否则它只会计算它们的地址而不调用它们。在 view.Execute
和 db.Commit
之后你错过了它们。
我正在尝试使用 python 的 win32 COM API 编辑 Windows 安装程序 MSI,但无法正常工作。 我的 perl 应用程序工作正常,但尽管我的 python 运行没有错误,但 MSI 没有更新。我是 python 的新手,所以可能做了一些愚蠢的事情。我的新工作使用 python 而不是 perl,所以我非常感谢任何更正(尤其是在错误检测和处理方面)。谢谢!
下面是 python 的 perl
use Win32::OLE;
my $msifile = "ws.msi";
my($Installer, $database, $query, $view);
$Installer = undef;
Win32::OLE::CreateObject("WindowsInstaller.Installer", $Installer) ||
die "CreateObject installer failed: $!";
$database = $Installer->OpenDatabase($msifile, 1) ||
die "cannot open msi file $msifile (OpenDatabase failed): $!";
my $qry = "UPDATE `InstallExecuteSequence` SET `InstallExecuteSequence`.`Condition`='1' WHERE `InstallExecuteSequence`.`Action`='CheckAllUserLegacy'";
$view = $database->OpenView($qry);
check_error();
$view->Execute;
check_error();
$database->Commit();
check_error();
print "\t$msifile updated \n";
$record = undef;
$view = undef;
$database = undef;
$Installer = undef;
exit 0;
sub check_error {
if ( Win32::OLE->LastError() ) {
printf "SQL ERROR, the following query:\n\t'==$query==\ngets\n\t(%-s)\n", Win32::OLE->LastError();
exit(1);
}
}
============================================= ============================
import pdb;
import win32com.client
msifile = "e:\ws.msi"
MSIDBOPEN_TRANSACT = 1
MSIDBOPEN_DIRECT = 2
openMode = MSIDBOPEN_TRANSACT
print "about to open DB"
#pdb.set_trace()
try:
wi = win32com.client.DispatchEx ( "WindowsInstaller.Installer" )
db = wi.OpenDatabase( msifile, openMode )
except:
print "Oops"
else:
print ("opened OK")
sql = "UPDATE `InstallExecuteSequence` SET `InstallExecuteSequence`.`Condition`='0' WHERE `InstallExecuteSequence`.`Action`='CheckAllUserLegacy'"
#print(sql)
try:
view = db.OpenView(sql)
except:
error = wi.LastErrorRecord()
for field_num in range(1, error.FieldCount + 1):
print error.StringData(field_num)
else:
print ("after open view, didn't get exception")
try:
view.Execute
except:
error = wi.LastErrorRecord()
for field_num in range(1, error.FieldCount + 1):
print error.StringData(field_num)
else:
print ("view.executed didn't get exception")
try:
db.Commit
except:
error = wi.LastErrorRecord()
for field_num in range(1, error.FieldCount + 1):
print error.StringData(field_num)
else:
print ("after commit, didn't get exception")
print "end"
在 运行 perl 之后 MSI 被正确更改,但是在 运行 之后 python 它没有改变。我是 python 新手,但使用 perl 多年(这些是精简的片段,不是很好的编程示例)
Python 函数名称后需要括号,否则它只会计算它们的地址而不调用它们。在 view.Execute
和 db.Commit
之后你错过了它们。