2010-02-22 30 views
6

Sunucu tabanlı olarak değişmesi gereken bir yapılandırma dosyası var, böylece bir sunucu üzerinde kurulu yazılımımız olduğunda, bir istemci yükleyicinin yapılandırma dosyası o sunucunun belirli bir eşleşmesi için ayarlanır. ayarları ve daha sonra dağıtım için web üzerinde bir ortak klasöre kopyalayın.Mage.exe dağıtım sorunları

Yapılandırma dosyasını değiştirdiğim için, * .manifest ve * .application dosyalarını yeniden oluşturmam gerekiyor ve bunu anladığım kadarıyla, bunun tek gerçek seçeneğim Win7 SDK'dan Mage.exe kullanmaktır. . * .manifest dosyasını değiştirilmiş yapılandırma dosyasından uygun karma ile düzeltmek için:

mage -new Application -fd ". \ Application Files \ < appName> _1_0_0_0" -ToFile ". \ Application Files \ _1_0_0_0 \ < appName> .exe.manifest" -Name "< appName>" -Sürüm "1.0.0.0" -CertFile "key.pfx" -password "< şifre>"

sonra, düzeltmek için * modifiye * .Manifest dosyadan uygun karma ile .application dosyası, ben çalıştırın:

büyücü -yeni Dağıtım -I t -t "< appName> .application" -v "1.0.0.0" -appManifest" \. Uygulama Dosyaları \ < appName> _1_0_0_0 \ < appName> .exe.manifest "-pu "http: // < hostaddress>/< yol>/Uygulama Dosyalar/< appName> _1_0_0_0/< appName> .exe.manifest" -CertFile" key.pfx "-password" "

Şimdi, tüm bu işler çalışıyor ve dosyaların başarıyla imzalandığını mesajı alıyorum. Gerçi istemci uygulamayı yüklemeye çalıştığınızda, ben mesajla bir hata günlüğü olsun şeyler ters gitti aşikardır: * .application dosyasında baktığımızda

+ Deployment manifest is not semantically valid. 
+ Deployment manifest requires <deployment> section. 

, bu altında bazı ek bilgiler VS2008 yayımlamak özelliği doğrudan aynı dosya yok "dağıtım" düğüm:

<deployment install="true"> 
    <subscription> 
    <update> 
     <expiration maximumAge="0" unit="days" /> 
    </update> 
    </subscription> 
    <deploymentProvider codebase="http://<hostaddress>/<path>/Application Files/<appName>_1_0_0_0/<appName>.exe.manifest" /> 
</deployment> 

VS2008 sürümünü yayınlamaya basitçe vardır:

<deployment install="true" /> 

zaman Ek bilgileri kaldırıyorum ve dağıtım düğümünü kendi kendini sonlandıran bir düğüme ayarlıyorum, ardından dosyayı yeniden imzalarım, her şey beklendiği gibi çalışır.

Bu bilinen bir sorundur ve Mage dosyasını, dağıtım düğümünde ek bilgi olmadan dosyayı oluşturması için düzgün bir şekilde çalışacak şekilde bir yol var mı?

DÜZENLEME: Geçici bir çözüm olarak, dosyaları bir XmlDocument içine yüklüyorum ve bunları uygun şekilde yeniden düzenleyerek dosyaları yeniden imzalarım. Ayrıca, şimdi, dağıtıma nasıl bir simge ekleyeceğimizi henüz belirleyememe sorunuyla karşı karşıyayım, bu nedenle Başlat menüsü öğesi genel simgeden başka bir simge alır.

+0

bul web bir gün :)

kaybolur olduğunu var. Bir çözüm bulursam cevap vereceğim. –

+0

sadece mage –

+0

Nathan'daki -appc bayrağını kullanın, cevabımı kontrol edin ve size yardımcı olup olmadığını görün. Mage.exe'yi kullanmanız sizin için iyi çalışmalıdır. "Wretched" için –

cevap

2

İşte benim uygulamam. Bu küçük kod üzerinde çok fazla zaman harcadım ve hala Mage'ın tüm nesnesini .application dosyasını müdahale etmeden ele geçirmesi için doğru seçenekleri bulamadım. Bu kodda yapılabilecek pek çok optimizasyon olduğunu söyleyebilirim. Ancak, bu hala birine yardım etmek için bir sıçrama tahtası olarak kullanılabilir.

Aşağıdaki yöntemin çalışması için, VS'deki ClickOnce uygulamasından en az bir kez dağıtmanız ve ardından .application dosyasını bu dağıtımdan tutmanız gerekir. Dağıtım klasöründeki .application ve .manifest öğelerini SİLMELİSİNİZ.Ben Config.Instance.ServerSettings.ClientLocation + "<AppName>_<version>" tüm uygulama dosyalarını taşıdıktan sonra

:

DirectoryInfo filedir = new DirectoryInfo(Config.Instance.ServerSettings.ClientLocation); 

if (filedir.Exists) 
{ 
    FileInfo[] files = filedir.GetFiles(); 

    // Find the current .application file. 
    FileInfo appinfo = null; 
    foreach (FileInfo fi in files) 
    { 
     if (fi.Name == "<AppName>.application") 
     { 
      appinfo = fi; 
      break; 
     } 
    } 

    if (appinfo != null) 
    { 
     XmlDocument applocinfo = new XmlDocument(); 
     applocinfo.Load(appinfo.FullName); 

     // Get the location of the files from the .application file. 
     string codebase = applocinfo["asmv1:assembly"]["dependency"]["dependentAssembly"].Attributes["codebase"].Value.Replace("AppName.exe.manifest", ""); 

     XmlDocument xDoc = new XmlDocument(); 
     xDoc.Load(Path.Combine(Path.Combine(filedir.FullName, codebase), "AppName.exe.config")); 

     foreach (XmlNode xn in xDoc["configuration"]["appSettings"].ChildNodes) 
     { 
      if (xn.Attributes != null && xn.Attributes["key"] != null && xn.Attributes["key"].Value == "Clnt_Host") 
      { 
       // Here is where I'm modifying my config file, the whole purpose in this wretched deployment process. 
       xn.Attributes["value"].Value = Config.Instance.ClientSettings.Host; 
       break; 
      } 
     } 

     xDoc.Save(Path.Combine(Path.Combine(filedir.FullName, codebase), "<AppName>.exe.config")); 

     Process p = new Process(); 
     p.StartInfo = new ProcessStartInfo(Path.Combine(filedir.FullName, "Mage.exe")); 
     p.StartInfo.WorkingDirectory = filedir.FullName; 

     FileInfo fi = new FileInfo(Path.Combine(Path.Combine(filedir.FullName, codebase.TrimStart('.')), "<AppName>.exe.manifest")); 
     if (fi.Exists) 
      fi.Delete(); 

     // Write a new .manifest file as an Application file. (-new Application -ToFile ".\codebase\<AppName.exe.manifest") 
     // Include the files from the codebase directory in the manifest (-fd ".\codebase\") 
     // Give the application a name to use in the start menu (-name "<AppName>") 
     // Assign a version number to the deployment (-Version "<version>") 
     // Give the application an icon to use in the start menu (-IconFile "64x64.ico") 
     // Sign the manifest (-CertFile "<KeyName>.pfx -Password <password>) 
     p.StartInfo.Arguments = "-new Application -fd \".\\" + codebase.TrimEnd('\\') + "\" -ToFile \".\\" + Path.Combine(codebase, "<AppName>.exe.manifest") + "\" -Name \"<AppName>\" -Version \"" + codebase.Substring(codebase.IndexOf('_') + 1, codebase.Length - (codebase.IndexOf('_') + 1)).Replace('_', '.').TrimEnd('\\') + "\" -CertFile \"<KeyName>.pfx\" -Password <Password> -IconFile \"64x64.ico\""; 

     while (p.StartInfo.Arguments.Contains(".\\.\\")) 
      p.StartInfo.Arguments = p.StartInfo.Arguments.Replace(".\\.\\", ".\\"); 

     Logger.Instance.LogInfo("Starting application: " + p.StartInfo.FileName + "\n\tWith arguments: " + p.StartInfo.Arguments, Logger.InfoType.Information); 

     p.Start(); 

     while (!p.HasExited) 
     { 
      Thread.Sleep(100); 
     } 

     // Make a new deployment manifest (-new Deployment -t "<AppName>.application") 
     // Make the application available offline (-I t) 
     // Use the files from the .manifest we just made (-AppManifest ".\codebase\<AppName>.exe.manifest") 
     p.StartInfo.Arguments = "-new Deployment -I t -t \"<AppName>.application\" -v \"" + codebase.Substring(codebase.IndexOf('_') + 1, codebase.Length - (codebase.IndexOf('_') + 1)).Replace('_', '.').TrimEnd('\\') + "\" -AppManifest \".\\" + codebase + "<AppName>.exe.manifest\" -pu \"http://" + Config.Instance.ClientSettings.Host + "/client/" + codebase.Replace('\\', '/') + "<AppName>.exe.manifest\""; 

        while (p.StartInfo.Arguments.Contains(".\\.\\")) 
      p.StartInfo.Arguments = p.StartInfo.Arguments.Replace(".\\.\\", ".\\"); 

     Logger.Instance.LogInfo("Starting application: " + p.StartInfo.FileName + "\n\tWith arguments: " + p.StartInfo.Arguments, Logger.InfoType.Information); 

     p.Start(); 

     while (!p.HasExited) 
     { 
      Thread.Sleep(100); 
     } 

     xDoc = new XmlDocument(); 
     xDoc.Load(Path.Combine(filedir.FullName, "<AppName>.application")); 

     // Add to the Deployment manifest (.application) to make the application 
     // have a minimum required version of the current version,and makes a 
     // subscription so that the application will always check for updates before 
     // running. 
     if (xDoc["asmv1:assembly"]["deployment"]["subscription"] != null) 
     { 
      xDoc["asmv1:assembly"]["deployment"].RemoveChild(xDoc["asmv1:assembly"]["deployment"]["subscription"]); 
      xDoc["asmv1:assembly"]["deployment"].RemoveChild(xDoc["asmv1:assembly"]["deployment"]["deploymentProvider"]); 
      XmlAttribute node = xDoc.CreateAttribute("minimumRequiredVersion"); 
      node.Value = codebase.Substring(codebase.IndexOf('_') + 1, codebase.Length - (codebase.IndexOf('_') + 1)).Replace('_', '.').TrimEnd('\\'); 
      xDoc["asmv1:assembly"]["deployment"].Attributes.Append(node); 

      xDoc["asmv1:assembly"]["deployment"].InnerXml = "<subscription><update><beforeApplicationStartup /></update></subscription>"; 
     } 

     xDoc.Save(Path.Combine(filedir.FullName, "<AppName>.application")); 

     // Sign the deployment manifest (.application) (-Sign "\<AppName>.application" -CertFile "<AppName>.key" -Password <password> 
     p.StartInfo.Arguments = "-Sign \"<AppName>.application\" -CertFile \"<AppName>.pfx\" -Password <password>"; 

     while (p.StartInfo.Arguments.Contains(".\\.\\")) 
      p.StartInfo.Arguments = p.StartInfo.Arguments.Replace(".\\.\\", ".\\"); 

     Logger.Instance.LogInfo("Starting application: " + p.StartInfo.FileName + "\n\tWith arguments: " + p.StartInfo.Arguments, Logger.InfoType.Information); 

     p.Start(); 

     while (!p.HasExited) 
     { 
      Thread.Sleep(100); 
     } 
    } 
} 
+0

+1. – Tim

1

hedef ben yenisini oluştururken neden emin değilim ortamlar arasında uygulama bildirimi değiştirmek ise. Sadece mevcut olanı değiştir. İhtiyacınız olanı ve daha fazlasını yapmak için bir powershell komut dosyası gönderiyorum. Benim durumumda bir kurulum bootstrapper'ım var, ama ihtiyacınız olan kod aşağıya doğru.

Kurulum önyükleyici için imzalı bir önyükleyiciyi istifa edemezsiniz, böylece imzalı bir üçüncü şahıs dll bulmam gerekiyordu. (Delcert) http://forum.xda-developers.com/showthread.php?t=416175 Ben kaynak denetiminde anne durumda o bölüm Ben benzer konularla çok benzer bir kullanım durum var #Begin Resigning various Manifests

$root = "$PSScriptRoot" 
$ToolsPath = "C:\Tools" 
$CertFile = $ToolsPath + "\my cert.pfx" 
$CertPassword = "wouldn't you like to know" 

#Update the setup.exe bootstrappers update url 
Start-Process "$PSScriptRoot\setup.exe" -ArgumentList "-url=`"$ClickOnceUpdateUrl`"" -Wait 

#The bootstrappers signature is now invalid since we updated the url 
#We need to remove the old signature 
Start-Process 'C:\Tools\delcert.exe' -ArgumentList "`"$root\setup.exe`"" -Wait 

Write-Host "$root [writeline]" 
#Resign with signtool 
Invoke-Expression 'C:\Tools\signtool.exe sign /d "My Company" /f "$CertFile" /p "$CertPassword" "$root\setup.exe"' 

#update config properties 
$CodeBasePath = Convert-Path "$PSScriptRoot\Application Files\MyProduct_*" 
$ConfigPath = $CodeBasePath + "\MyProduct.dll.config.deploy" 
[xml] $xml = Get-Content $ConfigPath 

$Endpoint = $xml.SelectSingleNode('/configuration/appSettings/add[@key="MailCheckerEndpoint"]') 
$Endpoint.value = $MailCheckerEndpoint 

$ApiEndpoint = $xml.SelectSingleNode('/configuration/appSettings/add[@key="MyApi:ApiBaseUrl"]') 
$ApiEndpoint.value = $MyProductApiEndpoint 
$xml.Save($ConfigPath) 

#Begin Resigning various Manifests 
$AppManifestPath = Convert-Path "Application Files\MyCompany_*\MyCompany.dll.manifest" 

#Need to resign the application manifest, but before we do we need to rename all the files back to their original names (remove .deploy) 
Get-ChildItem "$CodeBasePath\*.deploy" -Recurse | Rename-Item -NewName { $_.Name -replace '\.deploy','' } 

#Resign application manifest 
Invoke-Expression 'C:\Tools\mage.exe -update "$CodeBasePath\MyCompany.dll.manifest" -certFile "$CertFile" -password "$CertPassword" -if "Application Files\MyCompany_1_2_35_0\Resources\ID.ico"' 

#Regisn deployment manifests in root and versioned folder 
Invoke-Expression 'C:\Tools\mage.exe -update "$CodeBasePath\MyCompany.vsto" -certFile "$CertFile" -password "$CertPassword" -appManifest "$AppManifestPath" -pub "My Company" -ti "http://timestamp.globalsign.com/scripts/timstamp.dll"' 
Invoke-Expression 'C:\Tools\mage.exe -update "$root\MyComapny.vsto" -certFile "$CertFile" -password "$CertPassword" -appManifest "$AppManifestPath" -pub "My company" -ti "http://timestamp.globalsign.com/scripts/timstamp.dll"' 

#Rename files back to the .deploy extension, skipping the files that shouldn't be renamed 
Get-ChildItem -Path "Application Files\*" -Recurse | Where-Object {!$_.PSIsContainer -and $_.Name -notlike "*.manifest" -and $_.Name -notlike "*.vsto"} | Rename-Item -NewName {$_.Name + ".deploy"}