Applicazione ClickOnce non si avvia attraverso il Processo.Start(“x.abc”) con *.abc associato all'applicazione ClickOnce

StackOverflow https://stackoverflow.com/questions/1890634

Domanda

Ho sviluppato e implementato un'applicazione ClickOnce che registra un file associato, estensione, per esempio *.abc.Quando faccio clic su un file di nome x.abc o se di tipo x.abc dal prompt dei comandi, l'applicazione ClickOnce inizia, e riesco a recuperare il file tramite l'API dedicate.Posso anche lanciare l'applicazione a livello di programmazione con il codice riportato di seguito:

System.Diagnostics.Process.Start ("x.abc");

Tutto funziona bene sul mio Windows Vista a 64 bit, box.

Tuttavia, se cerco di fare esattamente la stessa cosa su Windows 7 (anche a 64 bit ), ho uno strano problema.Ecco cosa vedo:

  1. Avvio manuale di x.abc facendo doppio clic su di esso da una finestra di Explorer funziona.
  2. Avvio manuale di x.abc dal prompt dei comandi funziona.
  3. Process.Start("x.abc") non avviare l'applicazione;tuttavia, il processo oggetto restituito mostra che non c'era errore e che l'applicazione ClickOnce in qualche modo è uscito subito.Ma anche un Trace all'inizio di applicazione ClickOnce non viene mai raggiunto.
  4. Straniero di sicurezza, Process.Start("x.bat") con un file x.bat contenente la riga x.abc non si avvia l'applicazione ClickOnce sia!Stesso x.bat iniziato da Explorer funziona (naturalmente).

Cercando di analizzare quello che succede con ProcMon non è stato molto utile, come ClickOnce processo di avvio di un'applicazione è molto difficile da seguire, dal mio punto di vista.Osservo rundll32 arrivare al lavoro, ma nessuna prova di guasto.

Il programma che sta facendo il Process.Start è una piena fiducia applicazione console con davvero niente di speciale.

Io non riesco a vedere cosa è cambiato rispetto a come le applicazioni ClickOnce sono gestiti su Windows 7 e perché Process.Start non farei esattamente la stessa di lanciare il file da Esplora risorse.Vale la pena ricordare che l'utilizzo di più versioni avanzate del Start con il metodo di ProcessStartInfo e impostazione UseShellExecute per true non aiutano.

A partire cmd con Process.Start e poi cercando di lancio x.abc mostra esattamente lo stesso problema.Se metto a confronto le impostazioni di ambiente con un cmd avviato manualmente, vedo differenze nel modo in cui ProgramFiles è definito (il primo dei punti di C:\Program Files (x86) mentre il secondo punta a C:\Program Files).Le applicazioni avviate dal mio .NET applicazione sono iniziato il 32-bit livello di emulazione (SysWoW64).

Sono stato in grado di riprodurre il mancato avvio di x.abc a partire da una versione a 32 bit del prompt dei comandi (che è, %windir%\SysWoW64\cmd.exe) e poi con il comando x.abc al prompt dei comandi.Ho anche trovato una brutta soluzione, che è quella di avviare un 64-bit prompt dei comandi da un ambiente a 32 bit con il lancio di %windir%\Sysnative\cmd.exe /C x.abc invece di x.abc.

Ma io preferirei usare un modo pulito di fare (o di avere un rappresentante di Microsoft mi dicono che questo è effettivamente un problema con Windows 7 e/o ClickOncce e che sarà risolto al più presto).

È stato utile?

Soluzione 3

Mi è venuta in mente una .PIPISTRELLO a base di soluzione, che è facile da implementare.Dire che si desidera avviare l'applicazione ClickOnce associati *.abc file, quindi è sufficiente mettere un file con lo stesso nome, ma con il *.bat estensione nella stessa cartella, e quindi eseguire il file batch, invece.Ecco lo script batch:

if exist "%windir%\sysnative\cmd.exe" goto :mode64bit

rem For a file named "C:\foo\xyz.bat", this will generate the corresponding
rem "C:\foo\xyz.abc" file, built as the concatenation of the drive (%~d0),
rem the folder (%~p0) and the file name (%~n0), plus ".abc":

"%~d0%~p0%~n0.abc"
goto :end

:mode64bit

rem When running in a 32-bit emulation environment on a real 64-bit system,
rem start the 64-bit version of CMD.EXE, and make if start the ".abc" file
rem for us:

C:\Windows\sysnative\cmd.exe /c "%~d0%~p0%~n0.xgen"

:end

Questo potrebbe essere implementato direttamente nel chiamante del *.abc i file, ma a volte un file batch aiuta nella transizione...

Altri suggerimenti

Sembra che costruire la vostra applicazione utilizzando 'x32' come la piattaforma di destinazione, il che rende Process.Start la generazione di un x32 bit.E come credo di Windows 7 contiene le associazioni dei file per la versione a 32-bit e 64-bit separatamente le applicazioni.

Se non si dispone di COM o non gestiti a 32-bit dipendenze si potrebbe provare a costruire la propria applicazione per 'Qualsiasi' piattaforma di destinazione, invece di 'x32'.

Ho studiato alcuni ulteriori e trovato che il programma di installazione ClickOnce crea il seguente verbo open per qualsiasi file associato estensione (GUID è unico per ogni applicazione):

rundll32.exe dfshim.dll, ShOpenVerbExtension {dce01888-35e8-4df3-af35-cd971f520d8d} %1

Utilizzando Process Monitor, Ho trovato che la versione a 32 bit non riesce ad aprire HKCU\Software\Classes\Wow6432Node\CLSID\{dce01888-35e8-4df3-af35-cd971f520d8d} chiave del registro di sistema.(la versione a 64 bit con successo la apre a HKCU\Software\Classes\CLSID\{dce01888-35e8-4df3-af35-cd971f520d8d}.)

Quindi per me è davvero un ClickOnce bug.Se fossi in te, vorrei utilizzare sporca %WinDir%\system32\cmd.exe /C test.abc per risolvere il problema.(Che sembra funzionare tentato da x32 Task Manager.

Ho aggiunto questo problema per il Microsoft Connect (aggiornamento 2013-02-13:quel link è marcio).

Avete provato a usare ShellExecute();API?

        [DllImport("Shell32.dll",CharSet=CharSet.Auto)]
    public static extern IntPtr ShellExecute(
        IntPtr hwnd, 
        string lpVerb,
        string lpFile, 
        string lpParameters, 
        string lpDirectory,
        int nShowCmd );

ShellExecute(this.Handle,"open","x.abc","","",3);

Si potrebbe anche provare il Shell(); la funzione di una parte del quadro

Che solo potrebbe iniziare a livello di sistema di estensioni come .bat o anche .txt, ma non si può sempre lanciare programmi corretti attraverso le estensioni.

Invece di provare questa API o una simile alternativa .NET:

FindExecutable : shell32.dll Alias : "FindExecutableA" / "FindExecutableW" tipo restituito : int parametri : · lpFile Puntatore a una stringa con terminazione null che specifica un il nome del file.Questo può essere un documento o file eseguibile. · lpDirectory Puntatore a una stringa con terminazione null che specifica il directory predefinita. · lpResult Puntatore a un buffer di ricevere il nome del file quando il la funzione restituisce.Il nome del file è un stringa con terminazione null che specifica il il file eseguibile è iniziato quando un “open” associazione file specificato nel lpFile parametro.

Questo restituisce un numero intero maggiore di zero se il successo e il valore char contiene un stringa con terminazione null che punti al file eseguibile che lancia questo file extension quindi si può usare come questa

System.Diagnostics.Process.Start ("program.exe $:\path\x.abc");

Invece di program.exe, dovrai utilizzare il risultato della funzione API, e potrete utilizzare il percorso per il file separati con uno spazio proprio come una riga di comando.

Come per la mancata applicazione, potrebbe indicare che il programma ha bisogno di diritti amministrativi per eseguire correttamente. cmd già ho i diritti di amministratore, in modo che possa fare le applicazioni figlio eredita, ma non API di windows. createprocess consente di utilizzare LPSECURITY gli attributi che possono aiutare nel lancio di questo programma con i privilegi corretti.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top