Cara mendapatkan jalur folder untuk aplikasi ClickOnce

160

Saya perlu menulis file di folder yang sama di mana konsol ClickOnce .application (file yang dapat dieksekusi) berada. Folder tempat peluncurannya.

Saya mencoba menggunakan Application.StartupPath& Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) tetapi path menunjuk ke subfolder di bawah c:\Documents & Settings. Bagaimana cara mendapatkan jalur tempat .applicationtinggal?

Tony_Henrich
sumber

Jawaban:

253

Untuk menemukan lokasi folder, Anda cukup menjalankan aplikasi, buka task manager (CTRL-SHIFT-ESC), pilih aplikasi dan klik kanan | Buka lokasi file.

Erik Vullings
sumber
3
hai, tip pro! tapi itu tidak tersedia di mesin XP jelek tua. :)
Jalal
5
@Jalal untuk "mesin jelek lama" buka www.SysInternals.com dan unduh Process Explorer. Saya menduga perubahan dalam TaskManager dari Win7 dan kemudian Win8 baru saja disalin dari itu.
Arioch 'The
1
Bagaimana Anda mencapai ini dalam aplikasi Anda yang berjalan di komputer pelanggan?
user3285954
2
Bagaimana jika saya tidak dapat menjalankan aplikasi karena itu akan menghapus file log yang sangat saya butuhkan?
Tomáš Zato - Reinstate Monica
2
@ Tony_Henrich Anda harus menandai ini sebagai jawaban yang benar
sparkyShorts
120

path menunjuk ke subfolder di bawah c: \ Documents & Settings

Betul sekali. ClickOnce applicationsdipasang di bawah profil pengguna yang menginstalnya. Apakah Anda mengambil jalur yang mengambil informasi dari majelis pelaksana memberi Anda, dan pergi memeriksanya?

Di windows Vista dan Windows 7, Anda akan menemukan cache ClickOnce di sini:

c:\users\username\AppData\Local\Apps\2.0\obfuscatedfoldername\obfuscatedfoldername

Pada Windows XP, Anda akan menemukannya di sini:

C:\Documents and Settings\username\LocalSettings\Apps\2.0\obfuscatedfoldername\obfuscatedfoldername
RobinDotNet
sumber
1
Saya mengerti semua ini. Saya ingin folder tempat saya mengklik aplikasi. Saya tidak memiliki akses ke C: \ Documents and Settings karena itu saya tidak akan memiliki akses ke file log jika saya akan menggunakan jalur folder yang dikembalikan oleh fungsi itu dan saya tidak ingin menggunakan nilai jalur kode keras. .
Tony_Henrich
25

ApplicationDeployment.CurrentDeployment.ActivationUri mungkin berfungsi

"String nol-panjang jika properti TrustUrlParameters dalam manifes penyebaran salah, atau jika pengguna telah memasok UNC untuk membuka penyebaran atau telah membukanya secara lokal. Jika tidak, nilai kembali adalah URL lengkap yang digunakan untuk meluncurkan aplikasi, termasuk parameter apa pun. "


TETAPI yang saya pikir Anda inginkan adalah ApplicationDeployment.CurrentDeployment.DataDirectory yang memberi Anda folder tempat Anda dapat menulis data. Saat Anda memperbarui aplikasi, Anda akan kehilangan apa yang ada di folder .exe asli, tetapi Anda dapat memindahkan direktori data ke versi aplikasi yang baru. Aplikasi Anda dapat menulis ke folder ini dengan file log apa pun yang dimilikinya - dan saya cukup yakin aplikasi ini dijamin dapat ditulis.

Simon_Weaver
sumber
Saya tidak melakukan apa-apa, tetapi file dari DataDirectory lama secara otomatis disalin ke DataDirectory baru setelah penyebaran. Tidak ada direktori .pre juga. (.NET Framework 3.5 dan 4.5)
Der_Meister
15

Saya menggunakan Assembly.GetExecutingAssembly().Locationuntuk mendapatkan path ke ClickOnceaplikasi yang digunakan di .Net 4.5.1.

Namun, Anda tidak boleh menulis ke folder mana pun di mana aplikasi Anda digunakan, terlepas dari metode penyebaran (xcopy, ClickOnce, InstallShield, apa pun) karena itu biasanya hanya dibaca untuk aplikasi, terutama di versi Windows yang lebih baru dan lingkungan server.

Aplikasi harus selalu menulis ke folder yang disediakan untuk tujuan tersebut. Anda bisa mendapatkan folder yang Anda butuhkan mulai dari Enumeration Environment.SpecialFolder Khusus. Halaman MSDN menjelaskan untuk setiap folder: http://msdn.microsoft.com/en-us/library/system.environment.specialfolder.aspx

Yaitu untuk data, log dan file lain yang dapat digunakan ApplicationData(roaming), LocalApplicationData(lokal) atau CommonApplicationData. Untuk file sementara gunakan Path.GetTempPathatau Path.GetTempFileName.

Pekerjaan di atas juga pada server dan desktop.

EDIT: Assembly.GetExecutingAssembly()dipanggil dalam executable utama.

pengguna3285954
sumber
Ini telah bekerja untuk saya untuk aplikasi ClickOnce, dan juga bekerja di lingkungan dev VS saat men-debug aplikasi yang sama.
Developer63
3

Aplikasi ClickOnce DO tinggal di sebuah subdirektori dari C: \ Documents & Settings. Mereka tidak memiliki direktori instalasi "bersih" karena file-file lokal pada dasarnya "sementara" diunduh untuk memungkinkan aplikasi berjalan pada PC lokal dan eksekusi aplikasi dikendalikan dari server ClickOnce tempat mereka digunakan tergantung pada pengaturan penerbitan (Memeriksa pembaruan, persyaratan versi, dll).

NebuSoft
sumber
Saya tidak memiliki akses ke folder C: \ Documents & Settings di server yang berarti saya tidak memiliki akses ke file yang dibuat aplikasi. Saya menjalankan aplikasi dari folder tertentu. Ini folder tempat aplikasi diterbitkan. Bagaimana cara mendapatkan jalur folder itu?
Tony_Henrich
Oh, Anda menginginkan URL penempatan. Maaf, saya tidak mengerti sama sekali. Apakah Anda mencoba mendapatkannya dari dalam aplikasi ClickOnce, atau dari aplikasi eksternal?
RobinDotNet
1

Inilah yang saya temukan yang berfungsi untuk bisa mendapatkan lokasi folder yang digunakan dari aplikasi clickonce saya dan yang belum disebutkan di mana pun saya lihat dalam pencarian saya, untuk skenario yang mirip dan spesifik:

  • Aplikasi clickonce digunakan untuk folder jaringan LAN perusahaan.
  • Aplikasi clickonce diatur untuk tersedia secara online atau offline.
  • URL instalasi clickonce saya dan Perbarui URL di properti proyek saya tidak ada yang ditentukan. Artinya, tidak ada lokasi terpisah untuk instalasi atau pembaruan.
  • Dalam opsi penerbitan saya, saya memiliki pintasan desktop yang dibuat untuk aplikasi clickonce.
  • Folder yang ingin saya dapatkan path saat startup adalah folder yang ingin saya akses oleh DEV, INT, dan versi PROD aplikasi, tanpa hardcoding path.

Berikut ini adalah visual dari use case saya:

masukkan deskripsi gambar di sini

  • Folder kotak biru adalah lokasi direktori saya untuk aplikasi masing-masing lingkungan.
  • Folder kotak merah adalah direktori yang saya ingin dapatkan jalurnya (yang mengharuskan lokasi folder yang digunakan aplikasi "MyClickOnceGreatApp_1_0_0_37" yang sama dengan OP).

Saya tidak menemukan saran dalam pertanyaan ini atau komentar mereka untuk mengembalikan folder tempat aplikasi clickonce digunakan (bahwa saya kemudian akan bergerak relatif ke folder ini untuk menemukan folder yang menarik). Tidak ada pencarian internet lain atau pertanyaan SO terkait yang menghasilkan jawaban.

Semua properti yang disarankan gagal karena objek (misalnya ActivationUri) menjadi nol, atau menunjuk ke folder aplikasi yang diinstal dalam cache PC lokal. Ya, saya dapat menangani objek null dengan anggun dengan memeriksa IsNetworkDeployed - itu bukan masalah - tetapi anehnya IsNetworkDeployed mengembalikan false walaupun saya sebenarnya memiliki lokasi folder yang dikerahkan jaringan untuk aplikasi clickonce. Ini karena aplikasi dijalankan dari bit cache lokal.

Solusinya adalah dengan melihat:

  • AppDomain.CurrentDomain.BaseDirectory ketika aplikasi sedang dijalankan di dalam studio visual seperti yang saya kembangkan dan
  • System.Deployment.Application.ApplicationDeployment.CurrentDeployment.UpdateLocation ketika dijalankan secara normal.

System.Deployment.Application.ApplicationDeployment.CurrentDeployment.UpdateLocationdengan benar mengembalikan direktori jaringan tempat aplikasi clickonce saya digunakan, dalam semua kasus. Yaitu, ketika diluncurkan melalui:

  • setup.exe
  • Aplikasi MyClickOnceGreatApp.
  • Pintasan desktop dibuat saat pertama kali menginstal dan meluncurkan aplikasi.

Berikut kode yang saya gunakan saat startup aplikasi untuk mendapatkan path dari folder WorkAccounts. Mendapatkan folder aplikasi yang dikerahkan itu sederhana dengan tidak berbaris ke direktori induk:

string directoryOfInterest = "";
if (System.Diagnostics.Debugger.IsAttached)
{
    directoryOfInterest = Directory.GetParent(Directory.GetParent(Directory.GetParent(AppDomain.CurrentDomain.BaseDirectory).FullName).FullName).FullName;
}
else
{
    try
    {
        string path = System.Deployment.Application.ApplicationDeployment.CurrentDeployment.UpdateLocation.ToString();
        path = path.Replace("file:", "");
        path = path.Replace("/", "\\");
        directoryOfInterest = Directory.GetParent(Directory.GetParent(path).FullName).FullName;
    }
    catch (Exception ex)
    {
        directoryOfInterest = "Error getting update directory needed for relative base for finding WorkAccounts directory.\n" + ex.Message + "\n\nUpdate location directory is: " + System.Deployment.Application.ApplicationDeployment.CurrentDeployment.UpdateLocation.ToString();
    }
}
Kent Kruckeberg
sumber
0

Dengan asumsi pertanyaannya adalah tentang mengakses file di folder aplikasi setelah ClickOnce (true == System.Deployment.ApplicationDeploy.IsNetworkDeployed) aplikasi diinstal pada PC pengguna, mereka adalah tiga cara untuk mendapatkan folder ini oleh aplikasi itu sendiri:

String path1 = System.AppDomain.CurrentDomain.BaseDirectory;
String path2 = System.IO.Directory.GetCurrentDirectory();    
String path3 = System.Reflection.Assembly.GetExecutingAssembly().CodeBase; //Remove the last path component, the executing assembly itself.

Ini bekerja dari VS IDE dan dari aplikasi ClickedOnce yang digunakan / diinstal, tidak ada "true == System.Deployment.ApplicationDeploy.IsNetworkDeployed" yang diperlukan. ClickOnce mengambil semua file yang termasuk dalam proyek Visual Studio 2017 sehingga aplikasi dapat mengakses semua dan semua file yang dikerahkan menggunakan jalur relatif dari dalam aplikasi.

Ini didasarkan pada Windows 10 dan Visual Studio 2017

BoiseBaked
sumber