2013-03-19 25 views
17

W programie Visual Studio można wykonać Add ->Existing Item, a następnie Add as Link z przycisku rozwijanego Add.Pliki połączone programu Visual Studio nie istnieją.

To jest świetne. To pozwala ci dodać plik z innego projektu, a edycja pliku również edytuje go w oryginalnym projekcie.

Chciałbym użyć tej funkcji, aby plik konfiguracyjny (o nazwie Shared.config) był obecny we wszystkich projektach w ramach jednego rozwiązania. I niech ten plik zawsze będzie taki sam.

rozwiązanie
|
| - projekt 1
| - Shared.config [fizyczny]
| - projekt 2
| - Shared.config [połączony]

Po opublikowaniu plik rzeczywiście trafia do wszystkich opublikowanych projektów, więc nie ma problemu.

Ale PRZED opublikowaniem (w trakcie prac nad kompilacją) połączony plik tak naprawdę nie istnieje. Próba wyświetlenia pliku w Eksploratorze Windows dowodzi, że plik nie znajduje się w katalogu projektu. Visual Studio tylko sprawia, że ​​wygląda tak, jakby istniał tam w eksploratorze rozwiązań. (Choć na budowie, połączone elementy są prawdopodobnie skopiowane do katalogu bin; Ale ja nie chcę używać plików/dostępu z katalogu bin.)

Teraz to daje problemy z kursu. Próba wydrukowania System.IO.File.ReadAllText(HttpContext.Current.Server.MapPath("Shared.config")) zakończy się niepowodzeniem przed opublikowaniem projektu, ze względu na fakt, że Shared.config nie istnieje jeszcze w katalogu głównym projektu.

Co chciałbym zrobić, i gdzie ja potrzebuję twojej pomocy to:

  • Chciałbym Nadmierne kopią wszystkie pliki związane z ich pierwotnej lokalizacji do ich miejsca docelowego.

Spowoduje to, że studio graficzne ma powiązany plik i kopię oryginału, który istnieje zarówno w tym samym katalogu o tej samej nazwie.

Zazwyczaj usługa VS nie zezwala na tworzenie połączonych elementów w katalogu, jeśli katalog ten zawiera już plik o tej samej nazwie.

Ale testowałem, najpierw tworząc połączony element; następnie za pomocą Eksploratora Windows, aby skopiować oryginalny plik do katalogu docelowego i zobaczyć, jak działa Visual Studio. Eksplorator rozwiązań po prostu ukrywa fizyczny plik i pokazuje połączony element zamiast tego. (Nawet jeśli klikniesz Show all files w eksploratorze rozwiązań.)

rozwiązanie
|
| - projekt 1
| - Shared.config [fizyczny]
| - projekt 2
| - Współdzielone.config [link]
| - Shared.config [fizyczny, skopiowany tutaj podczas kompilacji, niewidoczny dla eksploratora rozwiązań]

Dokładnie tego chcę! Podczas próby edycji pliku Visual Studio otworzy "linkowany element". W przypadku kompilacji plik fizyczny zostanie skopiowany do katalogu docelowego, więc istnieje dla kodu, który próbuje uzyskać do niego dostęp.

Jak to zrobić? Czy należy to zrobić z wydarzeniami Build? Jeśli tak, to jak mam powiedzieć "skopiuj oryginały wszystkich połączonych plików do ich katalogu docelowego?

+0

Twoje "rozwiązanie" brzmi niewiarygodnie zagmatwane i koszmar dla kontroli źródła. –

+0

@ 280Z28 W jaki sposób udostępniane pliki są koszmarem dla kontroli źródła? Są one kopiowane podczas kompilacji do katalogu wyjściowego, który nie jest przechowywany w sterowaniu źródłowym. –

+0

"Mylenie" jest subiektywne. Nie ma to jednak wpływu na kontrolę źródła, ponieważ OP nie próbuje sprawdzić kopii fizycznego pliku. Są artefaktem budowy, która po prostu znajduje się w katalogu projektu. – dss539

Odpowiedz

15

Powinieneś prawdopodobnie użyć funkcji MSBuild do zaimplementowania tego.

Edytuj plik csproj (w Visual Studio, kliknij prawym przyciskiem myszy projekt i rozładować go. Następnie kliknij prawym przyciskiem myszy i Edit)

przewiń do dołu i trzeba znaleźć tę linię.

<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

Natychmiast po tej linii, dodać te linie.

<ItemGroup> 
    <LinkedItem Include="@(None)" Condition="'%Link' != ''" /> 
    </ItemGroup> 
    <Target Name="CopyLinkedFiles" BeforeTargets="Build" Inputs="@(LinkedItem)" Outputs="@(LinkedItem->'%(Filename)%(Extension)')"> 
    <Copy SourceFiles="@(LinkedItem)" DestinationFolder="$(MSBuildProjectDirectory)" /> 
    </Target> 

Teraz za każdym razem, gdy budujesz, tuż przed wykonaniem akcji kompilacji, MSBuild skopiuje wszystkie połączone pliki.

Wyjaśnienie

ItemGroup zawiera moje "wachlarz" o nazwie "LinkedItem". Generuję tę tablicę, dodając tylko elementy "None", które zawierają właściwość link.

Target to koncepcja MSBuild. Możesz myśleć o tym jako o konkretnej fazie budowy. Nazwałam tę fazę "CopyLinkedFiles", ale możesz nadać jej dowolną nazwę.

BeforeTargets to dyrektywa nakazująca MSBuildowi wykonanie akcji przed określoną fazą. Tutaj wybrałem uruchamianie "CopyLinkedFiles" przed fazą "Build".

Inputs to parametr optymalizacji.Służy do przyspieszenia budowania, pomijając kopię, jeśli nie jest to konieczne. Możesz zignorować ten parametr, jeśli nie obchodzi cię to. MSBuild porównuje Inputs z oczekiwanym znacznikiem czasu Outputs, aby sprawdzić, czy musi on zostać wykonany.

Copy to zadanie MSBuild, które akceptuje plik do skopiowania i przekazuje do określonego folderu.

redukcji redundancji

Można wkleić do każdego pliku .csproj, czy można umieścić go w centralnej .proj i osadzić że w plikach csproj. Niestety, bez względu na to, co robisz, będziesz musiał edytować każdy .csproj co najmniej 1 raz. :(

Utwórz plik w wspólnej rozmowy projektu WhateverNameYouLike.proj Put tych treści w pliku

<?xml version="1.0" encoding="utf-8"?> 
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 
    <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> 
    <!-- paste the previously shown code here --> 

    <!-- you can save yourself some hassle by linking the config file here, but if you really enjoy adding the file as a link to every project, you can skip this line --> 
    <None Include="..\Common\Shared.config"> 
    <Link>Shared.config</Link> 
    </None> 
</Project> 

Teraz irytujące część. w każdym .csproj, trzeba będzie dodać linię jak <Import Project="..\Common\WhateverNameYouLike.proj" /> prawdopodobnie na końcu tuż przed znacznikiem </Project> zamknięcia.

+0

3 pytania: (1) Nie interesują mnie znaczniki czasu lub o których jest nowsza. Cieszę się, że oryginał połączonego elementu do skopiowania do katalogu projektu na każdej kompilacji. Czy mogę po prostu pominąć wejścia i wyjścia? (2) @ (None) wydaje się być dziwną tablicą połączonych elementów. Czy to naprawdę służy tylko do powiązanych elementów? A może ta tablica może zawierać również inne pliki? (3) Oryginał połączonych plików znajduje się w projekcie DLL o nazwie "common", do którego odwołują się wszystkie inne projekty. Jak zmniejszyć redundancję, tak jak w swojej notatce? –

+0

Odpowiedzi 1) tak można pominąć Wejścia/Wyjścia, to tylko optymalizacja 2) "Brak" to nazwa, ponieważ uruchomione na nich narzędzie to "Brak" ... pliki csharp są dodawane jako "Kompilacja", ponieważ kompilator działa na nich. Możesz zobaczyć element "Brak" w swoim pliku csproj, jeśli go szukasz. 3) Zmienię moją odpowiedź, aby wyjaśnić, jak to zrobić. – dss539

+0

(1) ok. (2) uh, więc czy powinienem się także obawiać, że inne pliki niż pliki Linked są również kopiowane? Przepraszam, że wciąż nie rozumiem w pełni. (3) Cool! Dzięki! –

1

Kliknij prawym przyciskiem myszy połączony plik konfiguracyjny, wybierz właściwości, zmień Copy to Output Directory z Never na Copy always.

+1

Nie sądzę, że to naprawdę odpowiada na jego pytanie, ponieważ OP nie chce pliku w katalogu wyjściowym, ale raczej w katalogu projektu. – dss539

+1

To naprawdę po prostu umieszcza plik w katalogu bin. Nie tego chcę. Kod nadal jest uszkodzony podczas debugowania podczas programowania, ponieważ plik nie istnieje, gdy eksplorator rozwiązań pokazuje plik, który istnieje. –

+0

Przepraszamy. Całkowicie niezrozumiany. –

0

Można tworzyć zdarzenia poprzedzające i następujące po utworzeniu w programie Visual Studio.

Wybierz projekt, kliknij prawym przyciskiem myszy, właściwości, buduj zdarzenia.

Dla prebuild -

copy /y "$(LocationOfShared.Config)Shared.config\" "$(TargetDir)" 

Na stanowisko budować

cd $(TargetDir) 
del shared.config 

Oczywiście trzeba się bawić z rzeczywistych miejscach, które będą zwracane, ale masz pomysł.

Edytuj - powyższe odpowiedzi są łatwiejsze i bardziej proste, ale powinno to działać jak runda na temat sposobu.

+0

Inne odpowiedzi nie pomagają mi. Spójrzmy więc na to, co robisz. Po pierwsze widzę, że wyraźnie nazywasz "Shared.config". Chciałbym tego uniknąć.Moje pytanie było/jest "jak powiedzieć" skopiuj oryginały wszystkich połączonych plików do ich katalogu docelowego " –

+0

@ nl-x Możesz rzucić okiem na moją odpowiedź. Jestem prawie pewien, że robi dokładnie to, co chcesz. ;) – dss539

+0

@Alexander Ow, i btw, możesz pominąć część budowania postu, ponieważ chcę, aby plik fizyczny nadal istniał podczas debugowania (który rozpoczyna się po zakończeniu kompilacji postu); W rzeczywistości nie chcę, aby ten fizyczny plik został w ogóle usunięty. –

23

miałem pewne problemy z dss539's answer (testowane w VS2010). po pierwsze, duplikaty pojawił się w oknie Solution Explorer dopasowane do każdego pliku s. econd, '%link' nie jest akcesorem właściwości, jest ciągiem znaków i zawsze nie jest równy pustemu ciągowi '', więc każdy plik z działaniem kompilacji None został dopasowany, zduplikowany i skopiowany podczas kompilacji. Po trzecie, połączone pliki są kopiowane do katalogu głównego projektu, ale potrzebowałem plików do skopiowania tam, gdzie są umieszczone łącza. Więc zrobiłem pewne modyfikacje:

<Target Name="CopyLinkedFiles" BeforeTargets="Build"> 
    <ItemGroup> 
    <LinkedItem Include="@(Content)" Condition="%(Content.Link) != ''" /> 
    </ItemGroup> 
    <Copy SourceFiles="@(LinkedItem)" DestinationFiles="%(LinkedItem.Link)"/> 
</Target> 

LinkedItem nie jest już duplikaty pozycji w Solution Explorer. Aby utworzyć link do skopiowania, musisz ustawić akcję budowania Content.

+1

brzmi dobrze. +1 – dss539

+1

VS 2013 z aktualizacją 4 przetestowany –

+0

Wydaje się, że działa całkiem dobrze. Jedna uwaga: jeśli używasz tego do udostępniania widoków MVC, twój projekt "współdzielony" powinien być projektem MVC, a nie rzeczywistym typem "Shared Project", stracisz wsparcie dla intelliSense. – user2880616

Powiązane problemy