ฉันจะรับชื่อของไฟล์เรียกทำงานปัจจุบันใน C # ได้อย่างไร


355

ฉันต้องการรับชื่อของโปรแกรมที่กำลังทำงานอยู่นั่นคือชื่อที่ปฏิบัติการได้ของโปรแกรม ใน C / C ++ args[0]คุณได้รับมันจาก


ปฏิบัติการเป็นไฟล์ EXE (Windows Forms, WPF applications)? โปรแกรมสามารถเป็นแอปเดสก์ท็อป (WinForms, WPF และ WinRT-Windows Phone?), เว็บแอปพลิเคชัน, แอปพลิเคชันบริการ Wcf, Visual Studio Addin, โปรแกรม Add-in ของ Outlook-Word, การทดสอบหน่วยใน VS (MSTest) หรือ
Kiquenet

คำตอบ:


405
System.AppDomain.CurrentDomain.FriendlyName

61
ระวังคำตอบที่ยอมรับ เรามีปัญหากับการใช้งานSystem.AppDomain.CurrentDomain.FriendlyNameภายใต้แอปพลิเคชันที่คลิกได้เมื่อปรับใช้ สำหรับเรานี่เป็นการส่งคืน " DefaultDomain " ไม่ใช่ชื่อ exe ดั้งเดิม
Gaspode

40
เราใช้สิ่งนี้ในท้ายที่สุด:string file = object_of_type_in_application_assembly.GetType().Assembly.Location; string app = System.IO.Path.GetFileNameWithoutExtension( file );
Gaspode

4
FriendlyName สามารถตั้งค่าเป็นอะไรก็ได้ การรับตำแหน่งแอสเซมบลีอาจไม่เพียงพอหากคุณมี exe ที่มีหลายไฟล์ นอกจากนี้หากคุณใช้ AppDomain หลายชุด Assembly.GetCallingAssembly () จะส่งคืนค่า null
276648

2
@Gaspode: มันจะง่ายกว่าที่จะบอกว่า Path.GetFileNameWithoutExtension (GetType (). Assembly.Location) - คุณไม่จำเป็นต้องระบุวัตถุประเภทในชุดประกอบปัจจุบัน คุณสามารถใช้ GetType ได้จากนั้นคุณไม่จำเป็นต้องพูดว่า "นี่"
vbullinger

4
สิ่งนี้มีประโยชน์ แต่ไม่ควรเป็นคำตอบที่ยอมรับได้: มันแตกต่างอย่างมากจากสิ่งที่ถูกขอ - มันจะบังเอิญเป็นสิ่งเดียวกันในบางสถานการณ์ แต่นี่เป็นสิ่งอื่นโดยสิ้นเชิง หากคุณไม่ได้เขียนแอปพลิเคชันด้วยตัวเองคุณสามารถส่งคืน "ฉันชอบมันฝรั่ง!" หรืออะไรก็ตามที่เพื่อนร่วมงานที่มีอารมณ์ขันของคุณเขียนลงในที่พักนี้เมื่อพวกเขาสร้างแอปพลิเคชัน!
AnorZaken

237

System.AppDomain.CurrentDomain.FriendlyName - ส่งคืนชื่อไฟล์ที่มีนามสกุล (เช่น MyApp.exe)

System.Diagnostics.Process.GetCurrentProcess().ProcessName- ส่งคืนชื่อไฟล์โดยไม่มีนามสกุล (เช่น MyApp)

System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName- ส่งคืนพา ธ เต็มและชื่อไฟล์ (เช่น C: \ ตัวอย่าง \ Processes \ MyApp.exe) จากนั้นคุณสามารถส่งผ่านสิ่งนี้เข้าSystem.IO.Path.GetFileName()หรือSystem.IO.Path.GetFileNameWithoutExtension()เพื่อให้ได้ผลลัพธ์เดียวกันกับข้างบน


3
AppDomain สามารถเป็นแอปพลิเคชัน EXE, เว็บแอปพลิเคชัน, แอปพลิเคชันทดสอบหน่วย, Addin Visual Studio และ "Silverlight App" (?) อาจเป็นโซลูชันที่น่าสนใจสำหรับทุกกรณี ตัวอย่างเช่นสำหรับการทดสอบหน่วย VS2012 - ProcessName: vstest.executionengine.x86 MainModule.FileName: C: \ PROGRAM FILES (X86) \ MICROSOFT VISUAL STUDIO 11.0 \ COMMON7 \ IDE \ COMMONEXTENSIONS \ MICROSOFT \ TESTWINDOW \ vstest.exengine.exe MainModule.ModuleName: vstest.executionengine.x86.exe FriendlyName: UnitTestAdapter: กำลังรันการทดสอบ ApplicationName:
Kiquenet

"โปรแกรม" สามารถเป็นแอปเดสก์ท็อป (WinForms, WPF; และ WinRT-Windows Phone?), เว็บแอปพลิเคชัน, แอปพลิเคชันบริการ Wcf, Visual Studio Addin, โปรแกรม Add-in ของ Outlook, Word Test Unit ใน VS (MSTest) หรือ . ตัวอย่างเช่นรับบริการโฮสต์แอสเซมบลีสำหรับแอปพลิเคชันบริการ Wcf ที่โฮสต์ใน IIS ไม่ใช่ IISExpress หรือ WebDevServer
Kiquenet

6
+1 ฉันจะไปกับคำตอบนี้เพราะมันมีทั้งสามรูปแบบที่คุณอาจต้องการในวิธีที่สะอาดและเรียบง่าย การใช้ชื่อโปรแกรมเปล่าโดยไม่ใช้พา ธ หรือส่วนขยายมีประโยชน์อย่างมากสำหรับข้อความช่วยเหลือในโปรแกรม ( /?สวิตช์) เนื่องจากการใช้ส่วนขยายและพา ธ จะทำให้มันยุ่งเหยิงโดยไม่จำเป็น
Synetech

2
อย่าลืมกำจัดผลลัพธ์ของGetCurrentProcess()
Mahmoud Al-Qudsi

Process.GetCurrentProcess().ProcessName()ส่งกลับMyApp.vshostสำหรับฉัน
Jonathan Wood

106

System.Diagnostics.Process.GetCurrentProcess()รับกระบวนการที่กำลังทำงานอยู่ คุณสามารถใช้ProcessNameคุณสมบัตินี้เพื่อค้นหาชื่อ ด้านล่างเป็นแอปคอนโซลตัวอย่าง

using System;
using System.Diagnostics;

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(Process.GetCurrentProcess().ProcessName);
        Console.ReadLine();
    }
}

36
ใช้ Process.GetCurrentProcess () ได้ดีขึ้น MainModule.FileName
KindDragon

Process.GetCurrentProcess () MainModule.FileName ทำงานได้อย่างสมบูรณ์จากภายใน Excel Addin (ExcelDNA)
earcam

10
วิธีการนี้จะล้มเหลวเมื่อใช้กับ Mono runtime ชื่อกระบวนการสำหรับแอปพลิเคชันที่ทำงานบน Mono จะเป็นตัวแปรบางตัว.../bin/monoใน * nixes หรือ.../mono.exeบน Windows
cdhowie

1
นี่ควรเป็นคำตอบที่ยอมรับได้ ชื่อ AppDomain ปัจจุบันอาจไม่มีส่วนเกี่ยวข้องกับชื่อกระบวนการที่สามารถปฏิบัติการได้โดยเฉพาะอย่างยิ่งเมื่อมีหลายแอปโดเมนแสดงอยู่
Ivan Krivyakov

วิธีนี้อาจช้ากว่าการเล่นกับแอสเซมบลีคลาสอย่างมาก
เออร์วินเมเยอร์

99

สิ่งนี้น่าจะพอเพียง:

Environment.GetCommandLineArgs()[0];

3
อืมสิ่งนี้จะส่งคืน (เมื่อเรียกใช้จาก vs.net และใช้สิ่งที่โฮสต์การดีบัก) ตำแหน่งและชื่อของ filename.vshost.exe ... ซึ่งแน่นอนว่าเป็นไฟล์ที่ใช้งานในเวลานี้)
Frederik Gheysels

13
นี่เป็นคำตอบที่ดีที่สุดสำหรับฉันเพราะEnvironment.GetCommandLineArgs()มันเป็นอะนาล็อก C # ที่แน่นอนargvจาก C / C ++
Frederick The Fool

ตกลงกัน! คำตอบที่ดีที่สุด ฉันต้องการรับ Environment.GetCommandLineArgs () [1];
Jerry Liang

1
เพื่อหลีกเลี่ยงเส้นทางที่สมบูรณ์:Path.GetFileNameWithoutExtension(Environment.GetCommandLineArgs()[0])
นาธาน

1
สิ่งนี้ทำงานได้ดีเมื่อพยายามติดตามบริการ WCF ชื่อกระบวนการกลับมาพร้อมกับ iisexpress ในกรณีของฉัน แต่คำสั่งนี้ให้ชื่อแอสเซมบลีของบริการ WCF ที่แท้จริง
P.Brian.Mackey

19

นี่คือรหัสที่ใช้งานได้สำหรับฉัน:

string fullName = Assembly.GetEntryAssembly().Location;
string myName = Path.GetFileNameWithoutExtension(fullName);

ตัวอย่างทั้งหมดข้างต้นให้ฉันชื่อ processsheet กับ vshost หรือชื่อ dll ที่กำลังทำงานอยู่


4
สำหรับผู้ที่ไม่ทราบหรือไม่ได้รับคำตอบอื่นเนมสเปซสำหรับแอสเซมบลีคือ System.Reflection และเนมสเปซสำหรับ Path คือ System.IO
รวม

4
GetEntryAssembly จะส่งคืนค่า null ถ้าจุดเข้าใช้งานของแอปพลิเคชันนั้นเป็นรหัสเนทีฟแทนที่จะเป็นแอสเซมบลี
Emdot

18

ลองสิ่งนี้:

System.Reflection.Assembly.GetExecutingAssembly()

นี่จะส่งคืนSystem.Reflection.Assemblyอินสแตนซ์ที่มีข้อมูลทั้งหมดที่คุณอาจต้องการทราบเกี่ยวกับแอปพลิเคชันปัจจุบัน ฉันคิดว่าLocationทรัพย์สินอาจได้รับสิ่งที่คุณเป็นโดยเฉพาะ


6
อาจปลอดภัยกว่าที่จะใช้CodeBaseแทนLocationในกรณีที่คุณสมบัติ shadow copy ของ. NET เปิดใช้งานอยู่ ดูblogs.msdn.com/suzcook/archive/2003/06/26/…
Dirk Vollmar

18
ระวัง GetExecutingAssembly (): ถ้าคุณเรียกสิ่งนี้จากแอสเซมบลีไลบรารีมันจะส่งคืนชื่อของแอสเซมบลีไลบรารีซึ่งแตกต่างจากชื่อของรายการแอสเซมบลี (เช่นไฟล์เรียกทำงานดั้งเดิม) หากคุณใช้ GetEntryAssembly () จะส่งคืนชื่อของปฏิบัติการจริง แต่จะส่งข้อยกเว้นหากกระบวนการทำงานภายใต้ WCF (ยอมรับสถานการณ์ที่ไม่ค่อยเกิดขึ้น) สำหรับรหัสที่มีเสถียรภาพมากที่สุดใช้ Process.GetCurrentProcess (). ProcessName
Contango

@ Gravitas: ไม่แน่นอนไฟล์ปฏิบัติการใด ๆ ที่รัน "ตีความ" เช่นกับ / usr / bin / mono จะมีชื่อกระบวนการที่ไม่ถูกต้อง ProcessName จะไม่ทำงานกับบริการ windows หากคุณใช้ในห้องสมุดให้ใช้ GetCallingAssembly
Stefan Steiger

1
ทำงานให้ฉัน ชื่อคุณสมบัติของการเรียกอินสแตนซ์แอสเซมบลีที่ส่งคืน GetName () คือสิ่งที่คุณต้องการและไม่รวมส่วน ".exe" ทดสอบบน Mono / Linux พร้อมกับผลลัพธ์ที่คาดหวัง Assembly.GetName (). ชื่อ
Hatoru Hansou

1
อืมโปรดทราบว่าสตริงที่ส่งคืนจะไม่เปลี่ยนแปลงแม้ว่าคุณจะเปลี่ยนชื่อไฟล์ที่เรียกทำงานด้วยมือโดยใช้ file explorer ในขณะที่ Environment.GetCommandLineArgs () [0] การเปลี่ยนแปลงพร้อมกับชื่อไฟล์ปฏิบัติการจริง (แน่นอน) บังเอิญวิธีที่สองมีผลดีกว่าสำหรับสถานการณ์เฉพาะของฉันเนื่องจากฉันต้องการให้มีการตั้งชื่อโฟลเดอร์ข้อมูลเป็นชื่อแฟ้มที่ปฏิบัติการจริง
Hatoru Hansou


11

ทำไมไม่มีใครแนะนำสิ่งนี้มันเรียบง่าย

Path.GetFileName(Application.ExecutablePath)

3
แอปพลิเคชันใดที่มีเนมสเปซอยู่
Jeetendra

6
สิ่งนี้มีประโยชน์เมื่ออยู่ในแอพ Windows Forms แต่ไม่ใช่อย่างอื่น
NineBerry

@NineBerry คุณอาจจะสนใจในApplication.ExecutablePath's รหัสที่มา
Spooky

@Nberryberry ดูโพสต์ของฉัน สิ่งนี้ใช้ได้ภายในแอปคอนโซลหากคุณเพิ่มการอ้างอิงไปยัง System.Windows.Forms
John


9

หากคุณต้องการชื่อโปรแกรมเพื่อตั้งค่ากฎไฟร์วอลล์ให้ใช้:

System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName

สิ่งนี้จะช่วยให้แน่ใจว่าชื่อนั้นถูกต้องทั้งเมื่อทำการดีบั๊กใน VisualStudio และเมื่อเรียกใช้แอพใน windows


2
สำหรับวัตถุประสงค์ของฉัน (การสร้างชื่อไฟล์บันทึก) นี่คือคำตอบที่ดีที่สุด หากใช้กระบวนการโฮสต์ (พูดบริการหรือเว็บแอปพลิเคชัน), System.AppDomain.CurrentDomain.FriendlyName สามารถส่งคืนชื่อ GUID-y ที่น่าเกลียดด้วยเครื่องหมายสแลชที่ฝังตัว
ห้วน

8

เมื่อไม่แน่ใจหรือมีข้อสงสัยให้วิ่งเป็นวงกลมกรีดร้องและตะโกน

class Ourself
{
    public static string OurFileName() {
        System.Reflection.Assembly _objParentAssembly;

        if (System.Reflection.Assembly.GetEntryAssembly() == null)
            _objParentAssembly = System.Reflection.Assembly.GetCallingAssembly();
        else
            _objParentAssembly = System.Reflection.Assembly.GetEntryAssembly();

        if (_objParentAssembly.CodeBase.StartsWith("http://"))
            throw new System.IO.IOException("Deployed from URL");

        if (System.IO.File.Exists(_objParentAssembly.Location))
            return _objParentAssembly.Location;
        if (System.IO.File.Exists(System.AppDomain.CurrentDomain.BaseDirectory + System.AppDomain.CurrentDomain.FriendlyName))
            return System.AppDomain.CurrentDomain.BaseDirectory + System.AppDomain.CurrentDomain.FriendlyName;
        if (System.IO.File.Exists(System.Reflection.Assembly.GetExecutingAssembly().Location))
            return System.Reflection.Assembly.GetExecutingAssembly().Location;

        throw new System.IO.IOException("Assembly not found");
    }
}

ฉันไม่สามารถอ้างว่าได้ทำการทดสอบแต่ละตัวเลือก แต่มันไม่ได้ทำอะไรโง่ ๆ เช่นคืน vhost ระหว่างการดีบักเซสชัน


2
+1 เพื่อความสนุก :-) ฉันแทบจะไม่ใช้โค้ดนี้ยกเว้นว่าฉันจะเขียนไลบรารี่ทั่วไปที่ไม่มีความคิดเกี่ยวกับสภาพแวดล้อมของมัน (และจากนั้นอาจเป็นความคิดที่ดีที่จะรักษาสภาพของโลกที่คุณจะใช้ ชื่อสำหรับ)
Andrey Tarantsov

@Orwellophile A "โปรแกรม" สามารถเป็นแอปเดสก์ท็อป (WinForms, WPF; และ WinRT-Windows Phone?), เว็บแอปพลิเคชัน, แอปพลิเคชันบริการ Wcf, Visual Studio Addin, Add-Studio Outlook, Word Test Unit ใน VS (MSTest) หรือ แอปพลิเคชัน Silverlight ตัวอย่างเช่นรับบริการโฮสต์แอสเซมบลีสำหรับแอปพลิเคชันบริการ Wcf ที่โฮสต์ใน IIS ไม่ใช่ IISExpress หรือ WebDevServer รหัสเต็มรูปแบบใด ๆ ที่ใช้ได้สำหรับ A WinForms, WPF, เว็บแอปพลิเคชัน, แอปพลิเคชันบริการ Wcf, Visual Studio Addin, Outlook-Word Addin, การทดสอบหน่วยในแอปพลิเคชัน VS (MSTest)
Kiquenet

8
  • System.Reflection.Assembly.GetEntryAssembly().Location ส่งคืนตำแหน่งของชื่อ exe หากแอสเซมบลีไม่ได้โหลดจากหน่วยความจำ
  • System.Reflection.Assembly.GetEntryAssembly().CodeBase ส่งคืนตำแหน่งเป็น URL

ผ่านการทดสอบแล้วใช้งานได้ 100% แม้ว่าจะถูกเรียกจากภายในไลบรารี C #
Contango

1
GetEntryAssembly () ส่งคืนค่า null หากคุณไม่ได้อยู่ใน AppDomain หลัก
276648

4

หากคุณกำลังมองหาข้อมูลเส้นทางแบบเต็มของปฏิบัติการของคุณวิธีที่เชื่อถือได้คือการใช้ต่อไปนี้:

   var executable = System.Diagnostics.Process.GetCurrentProcess().MainModule
                       .FileName.Replace(".vshost", "");

สิ่งนี้จะช่วยลดปัญหาใด ๆ กับตัวกลางที่กำลัง, vshost, ฯลฯ


ฉันลองใช้วิธีที่เชื่อถือได้ของคุณใน Ubuntu Linux 15.10 C ++ โดยใช้ realpath ตามด้วยสตริงแทนที่ STL C ++ และมันทำให้ Point และ Click ล้มเหลว อาจเกิดจากข้อผิดพลาดในรูปแบบโมโนในฐานะผู้อำนวยการด้านซอฟต์แวร์ของเราในวันนี้ ขอบคุณ
Frank

ฉันไม่ได้เขียนโปรแกรมบนโมโนแม้ว่ามันอาจจะสนุกที่จะลอง
theMayer

Gasponde เขียนไว้ด้านบนว่า "เรามีปัญหาในการใช้ System.AppDomain.CurrentDomain.FriendlyName ภายใต้แอปพลิเคชันที่คลิกได้เมื่อใช้งาน" คุณช่วยเดาได้ไหมว่าปัญหาอะไรบ้างที่เกิดขึ้นกับแอพพลิเคชั่นที่ติดตั้งในคลิกของ NET ขอบคุณ
Frank

ส่งคืน C: \ Program Files \ dotnet \ dotnet.exe สำหรับโปรแกรมตัวอย่างของฉันใน VS2017
jwdonahue

3

คุณสามารถใช้Environment.GetCommandLineArgs()เพื่อรับอาร์กิวเมนต์และEnvironment.CommandLineรับบรรทัดคำสั่งจริงตามที่ป้อน

นอกจากนี้คุณยังสามารถใช้หรือAssembly.GetEntryAssembly()Process.GetCurrentProcess()

อย่างไรก็ตามเมื่อทำการดีบั๊กคุณควรระวังเนื่องจากตัวอย่างสุดท้ายนี้อาจให้ชื่อปฏิบัติการของดีบักเกอร์ (ขึ้นอยู่กับวิธีที่คุณแนบตัวดีบั๊ก) แทนการปฏิบัติการของคุณเช่นเดียวกับตัวอย่างอื่น ๆ


4
ระวัง GetExecutingAssembly (): ถ้าคุณเรียกสิ่งนี้จากแอสเซมบลีไลบรารีมันจะส่งคืนชื่อของแอสเซมบลีไลบรารีซึ่งแตกต่างจากชื่อของแอสเซมบลีรายการ (เช่นปฏิบัติการดั้งเดิม) หากคุณใช้ GetEntryAssembly () จะส่งคืนชื่อของปฏิบัติการจริง แต่จะส่งข้อยกเว้นหากกระบวนการทำงานภายใต้ WCF (ยอมรับสถานการณ์ที่ไม่ค่อยเกิดขึ้น) สำหรับรหัสที่มีเสถียรภาพมากที่สุดใช้ Process.GetCurrentProcess (). ProcessName
Contango

@ Gravitas: จุดดี - ว้าวมันเป็นเวลานานแล้วที่ข้าเขียนมันออกมา! : D ฉันจะแก้ไขตามนั้น
Jeff Yates

Environment.CommandLineให้พา ธ สัมบูรณ์ไม่ใช่บรรทัดคำสั่งที่ป้อนอย่างน้อยใน Mono / Linux
หอยทากเครื่องกล

@ Mechanicalsnail: ฟังดูเหมือน Mono ไม่ค่อยเป็นไปตามเอกสาร น่าสนใจ
Jeff Yates

1

นี่คือสิ่งที่คุณต้องการ:

Assembly.GetExecutingAssembly ().Location

4
ระวัง GetExecutingAssembly (): ถ้าคุณเรียกสิ่งนี้จากแอสเซมบลีไลบรารีมันจะส่งคืนชื่อของแอสเซมบลีไลบรารีซึ่งแตกต่างจากชื่อของแอสเซมบลีรายการ (เช่นปฏิบัติการดั้งเดิม) หากคุณใช้ GetEntryAssembly () จะส่งคืนชื่อของปฏิบัติการจริง แต่จะส่งข้อยกเว้นหากกระบวนการทำงานภายใต้ WCF (ยอมรับสถานการณ์ที่ไม่ค่อยเกิดขึ้น) สำหรับรหัสที่มีเสถียรภาพมากที่สุดใช้ Process.GetCurrentProcess (). ProcessName
Contango

คำตอบไม่ควรเป็นคำถาม นั่นคือสิ่งที่ OP ต้องการหรือไม่
jwdonahue

1

บน. Net Core (หรือ Mono) คำตอบส่วนใหญ่จะไม่นำมาใช้เมื่อไบนารีกำหนดกระบวนการเป็นไบนารีรันไทม์ของ Mono หรือ. Net Core (dotnet) ไม่ใช่แอปพลิเคชันจริงของคุณที่คุณสนใจในกรณีนี้ ใช้สิ่งนี้:

var myName = Path.GetFileNameWithoutExtension(System.Reflection.Assembly.GetEntryAssembly().Location);

1
GetEntryAssembly()สามารถส่งคืน null
2864740

1

สำหรับแอพ windows (แบบฟอร์มและคอนโซล) ฉันใช้สิ่งนี้:

เพิ่มการอ้างอิงถึง System.Windows.Forms ใน VS แล้ว:

using System.Windows.Forms;
namespace whatever
{
    class Program
    {
        static string ApplicationName = Application.ProductName.ToString();
        static void Main(string[] args)
        {
            ........
        }
    }
}

สิ่งนี้ทำงานได้อย่างถูกต้องสำหรับฉันไม่ว่าฉันจะเรียกใช้ปฏิบัติการจริงหรือการดีบักภายใน VS

โปรดทราบว่ามันจะส่งคืนชื่อแอปพลิเคชันโดยไม่มีนามสกุล

จอห์น


1

ง่ายสุด ๆ ที่นี่:

Environment.CurrentDirectory + "\\" + Process.GetCurrentProcess().ProcessName

1
สำหรับ. NET Core Process.GetCurrentProcess (). ProcessName ส่งคืน "dotnet"
Evgeni Nabokov

1
ไดเรกทอรีปัจจุบันชั่วคราวชั่วคราวและไม่สามารถเชื่อถือได้ว่าเป็นที่ตั้งของการชุมนุม / ปฏิบัติการ
jwdonahue

1

ใช้งานได้หากคุณต้องการชื่อแอปพลิเคชันที่ไม่มีส่วนขยายเท่านั้น:

Path.GetFileNameWithoutExtension(AppDomain.CurrentDomain.FriendlyName);

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.