Cách nhận đường dẫn thư mục cho ứng dụng ClickOnce


160

Tôi cần phải viết một tệp trong cùng một thư mục có bảng điều khiển ClickOnce .application(tệp thực thi). Thư mục nơi nó khởi chạy.

Tôi đã thử sử dụng Application.StartupPath& Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) nhưng đường dẫn trỏ đến thư mục con bên dưới c:\Documents & Settings. Làm thế nào để tôi có được con đường nơi .applicationcư trú?

Câu trả lời:


253

Để tìm vị trí thư mục, bạn chỉ cần chạy ứng dụng, mở trình quản lý tác vụ (CTRL-SHIFT-ESC), chọn ứng dụng và nhấp chuột phải vào | Mở vị trí tệp.


3
này, mẹo chuyên nghiệp! nhưng nó không có sẵn trên các máy XP cũ. :)
Jalal

5
@Jalal cho "máy cũ crappy" truy cập www.SysI INTERNals.com và tải xuống Process Explorer. Tôi nghi ngờ những thay đổi trong Trình quản lý tác vụ của Win7 và sau đó Win8 chỉ được sao chép từ nó.
Arioch '

1
Làm thế nào để bạn đạt được điều này trong ứng dụng của bạn chạy trên máy tính của khách hàng?
dùng3285954

2
Điều gì xảy ra nếu tôi không thể chạy ứng dụng vì nó sẽ xóa một tệp nhật ký mà tôi rất cần?
Tomáš Zato - Phục hồi Monica

2
@Tony_Henrich bạn nên đánh dấu đây là câu trả lời đúng
sparkyShorts

120

đường dẫn đang trỏ đến thư mục con trong c: \ Documents & Settings

Đúng rồi. ClickOnce applicationsđược cài đặt theo hồ sơ của người dùng đã cài đặt chúng. Bạn đã đi theo con đường lấy thông tin từ hội đồng thi hành đã đưa cho bạn, và đi kiểm tra nó?

Trên windows Vista và Windows 7, bạn sẽ tìm thấy bộ đệm ClickOnce tại đây:

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

Trên Windows XP, bạn sẽ tìm thấy nó ở đây:

C:\Documents and Settings\username\LocalSettings\Apps\2.0\obfuscatedfoldername\obfuscatedfoldername

1
Tôi hiểu tất cả điều này. Tôi muốn thư mục từ nơi tôi nhấp vào ứng dụng. Tôi không có quyền truy cập vào C: \ Documents and Settings do đó tôi sẽ không có quyền truy cập vào tệp nhật ký nếu tôi sẽ sử dụng đường dẫn thư mục được trả về bởi chức năng đó và tôi không muốn sử dụng các giá trị đường dẫn được mã hóa cứng .
Tony_Henrich

25

ApplicationDeployment.C HiệnDeployment.ActivationUri có thể hoạt động

"Chuỗi có độ dài bằng không nếu thuộc tính TrustUrlParameter trong bảng kê khai triển khai là sai hoặc nếu người dùng đã cung cấp UNC để mở triển khai hoặc đã mở cục bộ. Nếu không, giá trị trả về là URL đầy đủ được sử dụng để khởi chạy ứng dụng, bao gồm mọi thông số. "


NHƯNG điều tôi nghĩ bạn thực sự muốn là ApplicationDeployment.C HiệnDeployment.DataDirectory cung cấp cho bạn một thư mục mà bạn có thể ghi dữ liệu. Khi bạn cập nhật ứng dụng, bạn sẽ mất những gì có trong thư mục .exe gốc, nhưng bạn có thể di chuyển thư mục dữ liệu sang phiên bản mới của ứng dụng. Ứng dụng của bạn có thể ghi vào thư mục này với bất kỳ tệp nhật ký nào mà nó có - và tôi khá chắc chắn rằng nó được đảm bảo có thể ghi được.


Tôi không làm gì cả, nhưng các tệp từ DataDirectory cũ sẽ tự động được sao chép sang DataDirectory mới sau khi triển khai. Không có thư mục .pre cũng có. (.NET Framework 3.5 và 4.5)
Der_Meister

15

Tôi đang sử dụng Assembly.GetExecutingAssembly().Locationđể có được đường dẫn đến một ClickOnceứng dụng đã triển khai trong .Net 4.5.1.

Tuy nhiên, bạn không nên ghi vào bất kỳ thư mục nào mà ứng dụng của bạn được triển khai đến mọi lúc, bất kể phương thức triển khai (xcopy, ClickOnce, InstallShield, bất cứ điều gì) vì chúng thường chỉ đọc cho các ứng dụng, đặc biệt là trong các phiên bản Windows và môi trường máy chủ mới hơn.

Một ứng dụng phải luôn luôn ghi vào các thư mục dành riêng cho các mục đích đó. Bạn có thể nhận được các thư mục bạn cần bắt đầu từ Môi trường. Đặc biệt. Trang MSDN giải thích mỗi thư mục dùng để làm gì: http://msdn.microsoft.com/en-us/l Library / system.en môi.specialfolder.aspx

Tức là cho dữ liệu, nhật ký và các tệp khác người ta có thể sử dụng ApplicationData(chuyển vùng), LocalApplicationData(cục bộ) hoặc CommonApplicationData. Đối với các tập tin tạm thời sử dụng Path.GetTempPathhoặc Path.GetTempFileName.

Các công việc trên trên máy chủ và máy tính để bàn quá.

EDIT: Assembly.GetExecutingAssembly()được gọi trong thực thi chính.


Điều này đã làm việc cho tôi cho một ứng dụng ClickOnce, cũng như làm việc trong môi trường nhà phát triển VS trong khi gỡ lỗi cùng ứng dụng đó.
Nhà phát

3

Các ứng dụng ClickOnce DO nằm trong thư mục con của C: \ Documents & Settings. Họ không có thư mục cài đặt "sạch" vì các tệp cục bộ về cơ bản được "tải xuống" tạm thời để cho phép ứng dụng chạy trên PC cục bộ và việc thực thi ứng dụng được kiểm soát từ máy chủ ClickOnce mà chúng được triển khai tùy thuộc vào cài đặt xuất bản (Kiểm tra cập nhật, yêu cầu phiên bản, v.v.).


Tôi không có quyền truy cập vào thư mục C: \ Documents & Settings trên máy chủ, điều đó có nghĩa là tôi không có quyền truy cập vào tệp mà ứng dụng tạo. Tôi chạy ứng dụng từ một thư mục nhất định. Đó là thư mục nơi ứng dụng được xuất bản. Làm thế nào để tôi có được đường dẫn của thư mục đó?
Tony_Henrich

Ồ, bạn muốn URL triển khai. Xin lỗi, tôi đã không nhận được điều đó cả. Bạn đang cố gắng lấy nó từ bên trong ứng dụng ClickOnce hoặc từ một ứng dụng bên ngoài?
RobinDotNet

1

Đây là những gì tôi thấy rằng đã hoạt động để có thể có được vị trí thư mục đã triển khai của ứng dụng clickonce của tôi và điều đó đã không được đề cập ở bất cứ đâu tôi thấy trong các tìm kiếm của mình, cho kịch bản tương tự, cụ thể của tôi:

  • Ứng dụng clickonce được triển khai vào thư mục mạng LAN của công ty.
  • Ứng dụng clickonce được đặt thành trực tuyến hoặc ngoại tuyến.
  • URL cài đặt clickonce và URL cập nhật trong thuộc tính dự án của tôi không có gì được chỉ định. Đó là, không có vị trí riêng để cài đặt hoặc cập nhật.
  • Trong các tùy chọn xuất bản của mình, tôi có một lối tắt trên màn hình được tạo cho ứng dụng clickonce.
  • Thư mục tôi muốn nhận đường dẫn khi khởi động là thư mục mà tôi muốn được truy cập bởi các phiên bản DEV, INT và PROD của ứng dụng mà không cần mã hóa đường dẫn.

Dưới đây là hình ảnh về trường hợp sử dụng của tôi:

nhập mô tả hình ảnh ở đây

  • Các thư mục được đóng hộp màu xanh là vị trí thư mục của tôi cho từng ứng dụng của môi trường.
  • Thư mục được đóng hộp màu đỏ là thư mục tôi muốn nhận đường dẫn (trước tiên yêu cầu vị trí thư mục được triển khai của ứng dụng "MyClickOnceGreatApp_1_0_0_37" giống với OP).

Tôi không tìm thấy bất kỳ đề xuất nào trong câu hỏi này hoặc nhận xét của họ để trả về thư mục mà ứng dụng clickonce đã được triển khai (sau đó tôi sẽ chuyển liên quan đến thư mục này để tìm thư mục quan tâm). Không có câu hỏi tìm kiếm trên internet hoặc các câu hỏi SO liên quan nào cũng đưa ra câu trả lời.

Tất cả các thuộc tính được đề xuất đều bị lỗi do đối tượng (ví dụ ActivationUri) là null hoặc đang trỏ đến thư mục ứng dụng được cài đặt trong bộ nhớ cache của PC cục bộ. Có, tôi có thể xử lý các đối tượng null một cách duyên dáng bằng cách kiểm tra IsNetworkDeployed - đó không phải là vấn đề - nhưng đáng ngạc nhiên là IsNetworkDeployed trả về sai mặc dù trên thực tế tôi có một vị trí thư mục được triển khai mạng cho ứng dụng clickonce. Điều này là do ứng dụng đang chạy từ các bit cục bộ, được lưu trong bộ nhớ cache.

Giải pháp là xem xét:

  • AppDomain.CurrentDomain.BaseDirectory khi ứng dụng đang được chạy trong studio hình ảnh khi tôi phát triển và
  • System.Deployment.Application.ApplicationDeployment.CurrentDeployment.UpdateLocation khi nó đang thực thi bình thường.

System.Deployment.Application.ApplicationDeployment.CurrentDeployment.UpdateLocationtrả về chính xác thư mục mạng mà ứng dụng clickonce của tôi được triển khai, trong mọi trường hợp. Đó là, khi nó được khởi chạy thông qua:

  • setup.exe
  • MyClickOnceGreatApp.application
  • Phím tắt trên máy tính để bàn được tạo khi cài đặt và khởi chạy ứng dụng đầu tiên.

Đây là mã tôi sử dụng khi khởi động ứng dụng để lấy đường dẫn của thư mục WorkAccounts. Bắt thư mục ứng dụng đã triển khai rất đơn giản chỉ bằng cách không di chuyển đến thư mục mẹ:

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();
    }
}

0

Giả sử câu hỏi là về việc truy cập các tệp trong thư mục ứng dụng sau khi ứng dụng ClickOnce (true == System.Deployment.ApplicationDeploy.IsNetworkDeployed) được cài đặt trên PC của người dùng, đây là ba cách để có được thư mục này bởi chính ứng dụng:

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.

Các công việc này từ VS IDE và từ ứng dụng ClickedOnce được triển khai / cài đặt, không yêu cầu kiểm tra "true == System.Deployment.ApplicationDeploy.IsNetworkDeployed". ClickOnce chọn bất kỳ tệp nào có trong dự án Visual Studio 2017 để ứng dụng thực sự có thể truy cập bất kỳ và tất cả các tệp được triển khai bằng các đường dẫn tương đối từ trong ứng dụng.

Điều này dựa trên Windows 10 và Visual Studio 2017

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.