text:
I'm not the language you're looking for!
Isn't it annoying when you find a piece of code and you don't know what language it was written in? This challenge attempts to somewhat solve this.
Challenge
You will have to write a program that when run in two different languages, will output the string:
This program wasn't written in <language program compiled/interpreted in>, it was built for <other language the program can be run in>!

In the output, language names should have official capitalization. eg: CJam, C++
Neither program should take any input from the user.
When run in both languages, output should be to stdout or equivalent.
There should be no output to stderr in either program.
You may use comments in either language.
Two different versions of the same language count as different languages.

If this is done, the program should output the major version number, and if running on two different minor versions, should report the minor version also.
You should not use prebuilt version functions (this includes variables that have already been evaluated at runtime).

Example output:
Perl and Ruby:

Perl: This program wasn't written in Perl, it was built for Ruby!
Ruby: This program wasn't written in Ruby, it was built for Perl!

Python and C:

Python: This program wasn't written in Python, it was built for C!
C: This program wasn't written in C, it was built for Python!

Python 2 and Python 3:

Python 2: This program wasn't written in Python 2, it was built for Python 3!
Python 3: This program wasn't written in Python 3, it was built for Python 2!

Python 2.4 and Python 2.7:

Python 2.4: This program wasn't written in Python 2.4, it was built for Python 2.7!
Python 2.7: This program wasn't written in Python 2.7, it was built for Python 2.4!

This is code golf so the shortest code in bytes wins.

"Two different versions of the same language count as different languages." So tricking like with C pre and past 99 comments is valid? easy ^^

Added it, it feels paradoxical but fits to your rules.

No one's doing a Whitespace/Python polyglot?

nevermind.  Saw the 23 implementation

Does relying on the program to be run with a certain interpreter count as input? that is, switching on argv[0]?

@cat You should not use prebuilt version functions. looking at argv[0] counts as that I guess

What that thing is for, at all?

For the fun of the person answering

Can one language output with a trailing new line and the other not?

Foo/CJam, 70 bytes
"This program wasn't written in ""Foo"", it was built for ""CJam"\@"!"

In Foo, as many have found out, it just prints everything in the double quotes, and ignores most other character or does something that doesn't affect the output in most cases. In short, \@ does nothing and the strings are all printed as-is.
In CJam, \ swaps the top two items, and @ moves the 3rd item to the top, which arrange the strings into the right order. And after the program ends, everything left in the stack is automatically printed.

And just for the fun of it, there's a similar 75-byte solution for Fission/CJam: R"This program wasn't written in ""Fission"", it was built for ""CJam"\@'!O

Nice. I had "This program wasn't written in Clip, it was built for CJam!"3{4-_36+e\}/ for Clip/CJam.

I came into this thread to post a Foo solution, should've realized everybody knows by now how easy it is to write a Foo polyglot.

Is there a link to the Foo programming language spec?

@justhalf http://esolangs.org/wiki/Foo

How does this work?

@ErikE Added some explanation.

C89/C99, 171 152 136 114 111 107 105 bytes
Thanks at @Hurkyls, @Qwertiys, @jimmy23013 and @MD XF for your hints.
golfed version:
c;main(){c=-4.5//**/
-4.5;printf("This program wasn't written in C%d, it was built for C%d!",90-c,98+c);}

ungolfed version:
c;

main()
{
    c = -4.5//**/
    -4.5;
    printf("This program wasn't written in C%d, it was built for C%d!",90-c,98+c);
}

Little description:
C versions previous C99 just had the multiline comment like this:
/*foo*/

with C99 the single line comment was introduced. like this:
//foo

so if you compile a line like this:
c =-4.5//**/
-4.5;

the for the c99 compiler compiling-related code would be:
c = -4.5 -4.5;

while the for a c89 compiler relevant code would be:
(as the first / isn't part of a comment and therfor treat as operator)
c = -4.5 / -4.5;

+1 for a marvellous answer. A little bit of explanation for those unfamiliar with C would be nice though.

@ace I believe this relies on C99-style comments. In the fourth line, notice the //**/. In C89, that's the division operator followed by an empty comment. In C99, // starts a single-line comment, so the rest of the line is blank. Therefore, in C89, it becomes (90-(-4.5/-4.5)), which is 89, while in C99, it becomes (90-(-4.5-4.5)), which is 99.

To save a few bytes, use 188-c instead of c==99?89:99.

@kirbyfan64sos I know how this works, just saying that OP can make this a better answer.

Do you really need include in C?

@Qwertiy: include is neccesarry for avoiding implicite declaration of printf. probabbly I could leave it away but that would be undefined or unspecified behaving (not sure what of both) And I'm not sure how this is treat for pcg. But here http://goo.gl/20CvGY it works without include aswell.

As I know, C didn't require porotope declaration at all, but it was recommended to have them to allow compiler to make type casts on calling. And prototypes for printf and other such functions are not required still, not sure about custon functions. I didn't use include in my answer - there are no warnings when compiling it.

And I think you don't need int due to default int declaration. It was in initial version of C, not sure if it's still in there.

@Qwertiy: the int thing on main is your point the other thing I asked on emta about:http://meta.codegolf.stackexchange.com/q/6888/31033 lets see. thanks for your feedback in any case.

Ok, let's see the answer here too: http://stackoverflow.com/q/32398402/4928642

Seems like the answer: http://stackoverflow.com/a/32399720/4928642.

@Qwertiy Calling undeclared functions is technically invalid in C99, as is leaving off the return type.

Yep. http://stackoverflow.com/q/26189962/4928642, but "After issuing the diagnostic, an implementation may choose to assume an implicit int and continue to translate the program in order to support existing source code that exploits this feature."

I don't think you need the space and the outer parenthesis with the assignment.

You can use 90-c,98+c to remove the parens. And does it work if you move c to the parameters to remove int?

@jimmy23013: I'm not sure I'm getting you right. If I understand you correct, that would work BUT would increase the amount of cahracters required. Otherwise I don't get what you mean.

@jimmy23013: But then I had it 2 times so 3 more bytes in the count. So what would I win through?

@jimmy23013: I guess I'm missunderstanding you, and not getting the point. Would you mind just commenting the golfed snippet as you mean it? I really want to understand.

http://pastebin.com/wmnzRqQR

105 bytes

Shaving: can you get a few characters more by using 8/-2 = -4 while 8-2=6? Or does it have to be floating point to not print to stderr? (The constants need to be adjusted, 93+-4=89, 93+6=99 on the one side, 95-(-4)=99, 95-6=89 on the other... But that shouldn't cost any extra chars.)

JavaScript/Ruby, 170 bytes
Might be 2.0 only, doesn't appear to work in at least 2.1.5... Edit: Updates as per advice from @Jordan hopefully it works in a few more versions now!
a='1';c=console=console||eval('def c.log s;$><<s end;c');c.log("This program wasn't written in "+(d=['JavaScript','Ruby'])[b= ~(a=~/1/)]+', it was built for '+d[b+1]+'!')

Abuses the ~ operator in that Ruby will treat =~ as a regex match returning the position of the first match in the string (0), but JavaScript will treat it as = ~/1/ which is -1 (since /1/ is converted to NaN for numeric operations, which has 0 value).

This answer does not work for me in Ruby 2.1.5. I get: NoMethodError: undefined method \log' for :log:Symbol`

@EMBLEM My testing was carried out on Ruby 2.0 built into OS X, I haven't tested anything beyond that, but I'll certainly add a comment indicating it might well be broken in other version!

In more recent versions of Ruby, a method definition returns the name of the method as a symbol, so your eval is returning :log. I think you could fix it by putting ;c after end. The =~/= ~ trick is great, though!

You could also save. A few bytes by using $><<s instead of puts s and using double-quotes so you can drop the backslash in wasn\'t.

@Jordan Thanks! Not sure how I didn't spot the removal of the \' with double quotes though, and $><< means I can apply the fix you mentioned and keep the same byte count!

You can write JavaScript by JS to save bytes.

@Oliver Indeed, I think if I'd thought about that at first I'd have gone with it, but since this has been around a while now, I'll keep as-is. I'll remember that though for sure, as I'm sure it'll come in handy at some point! Thanks!

Python 2/Python 3, 92
Uses the "standard" Python version check (integer vs. float division).
print("This program wasn't written in Python %d, it was built for Python %d!"%(3/2*2,4-3/2))

This was talked about in the sandbox and the consensus was to allow this sort of thing

@flawr Would Python and Cobra be allowed? ;)

@flawr Python is actually named after the comedy ~~group~~ gods, Monty Python.

@Mutantoe It may appear to you that "Monty" not being a name of an animal, the pun wouldn't work.

Fishing/><> 233 217 bytes
v++C-CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC+CCCCCCC-CCCCCCCCCCCCCCCCCCC+CCCCCC
\   "This program wasn't written in ""><>"  ", it was built for Fishing!"
>r!`ol?!;32.                         Fishing                     ><>!`N

Fishing is a language based on a fisherman walking around catching fish. To make a program in this language who first have to define a dock on which he walks around. The dock only provides control flow to a program. The dock in this program is:
v++C-CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC+CCCCCCC-CCCCCCCCCCCCCCCCCCC+CCCCCC

Whenever the C command is found, the fisherman throws out his line to catch an instruction. The + and - instructions decrease and increase the length of his line respectively. v changes his throw direction to downwards. The fish that he catches in this program are:
`This program wasn't written in Fishing, it was built for ><>!`N

><> is a language based on a fish moving through the water. The v command starts the fish moving downwards, where it is then reflected to the right with the \ command. Everything between quotes is pushed onto the stack. After the string is pushed onto the stack, the fish wraps around to the other side where it is reflected downwards by \. It then prints out the contents of the stack with:
>r!`ol?!;32.

You can reduce your code by 13 bytes by putting your print loop for ><> in the whitespace on the third line (which I don't think will interfere with the fishing part, although I don't know that language). I'm not sure how this comment will handle the whole code, so here's a hastebin link: http://hastebin.com/quqinozizi (I may have messed up the spacing on the third line but I think that everything is aligned properly).

@Cole It does work. In fact your suggestion actually removes 16 characters.

Fish and fishing polyglot...  possibly the first of its kind!

this is so funny what!

23/Malbolge, 5688 bytes
                    bCBA@?>=<;:987
                                                                                6543210/.-,+*)
                                                                                ('&%$#"!~}|{zy
                                                                                xwvutsrqponmlk
                                                                                jihgfedcba`_^]
                                                                                \[ZYXWVUTSRQPO
                                                                                NMLKJIHGFEDCBA
                                                                                @?>=<;:9y76543
                                                                210/(L,l*)(!E}
                   |B"!~}|{zyxwvu
                                                                                tsrqponmlkjiha
                                                                                fed]#a`_^]?zZY
                                                                                XWVUTSRQ3ONMLK
                   JIHGFEDCBA:^>=
                                                                                <;:98705.R21q/
                                                                                .-,+*#G'&%${"!
                                                                                x>|{zyxwYutm3k
                                                                                ponmlkjihg`&^c
                                                                                ba`_^]\[ZYXWVO
                   sSRQPONMLEi,HG
                                                                                FEDCBA@?>=6Z:9
                                                                                y76543210/.-,+
                                                                                *)('&%$#"y?w|u
                   ;sxwvutm3qSonm
                                                                                fkjiha'edcba`_
                                                                                ^]\[ZYXWVUTSRQ
                   PONM/EiIHGFEDC
                               BA@?>7[;:987w5
                                      432+O/o-,%I)('
                                     &}$#z@~}|{zsxw
                   vutsrqponmlkji
                                                                                ha'&dFba`_^]\U
                                                                                yYXWVUTMRQPONM
                   LKDhH*F?DCBA@?
                                                                                8\<;:98765432r
                                                                                0/.-&J*)('&f$#
                                                                                "!~}|{zyxwvuts
                                                                                rqj0nmOkjihaf_
                                                                                %cE[!_^]\[=SwW
                                                                                VU7SLpPONMLEJI
                                                                                HAeEDC%A@?>=<;
                   :9876543210/.-
                                                                                ,+$H('&}${A!xw
                          ={]yxwvutsrk1o
                                                                                nmOejib(fedcE"
                                                                                `_^]?[ZYRvVUT6
                                                                                RKo2HMLKJIHAe
                                                                                EDCBA@?>=<;:9
                    87w5432+O/.-,
                                                                                +*)('&%e#"y?w
                                                                                |{zs9wvun4rqp
                                                                                onmlNjib(fedc
                                                                                ba`_^]\[ZYXWV
                                                                                8TMqKPONMLKDh
                                                                                +GFEDCB;_?>=<
                                                                                ;:9y7654321*N
                    .-,+*)('&f|{A
                                                                                !~}|{]yxwvo5s
                                                                                rqpinmlkjihg`
                                                                                &dcbD`_^]\[Tx
                                                                        ;WVUTMRQJnN0F
                                                 KDhH*FEDC<A@?
     >=<5Y92765.R?

Note that the program requires a trailing linefeed. No line contains trailing whitespace, so copy/paste should work just fine.
Verification
To test the Malbolge code in this online interpreter, paste it in the Malbolge code area and click Load/Reset, then Execute.
To test the 23 code in this online interpreter, paste it in the Source area, press Enter to insert the trailing linefeed, type 23 in the Console area (to switch from the default 23.dezsy notation to auto-detection) and click Run Interpreter!.

Dude... it looks like a bomb went off in your code!

o_0 how did you write Malbolge code

Outgolfed! https://codegolf.stackexchange.com/questions/55960/im-not-the-language-youre-looking-for/191063#191063

Lua/C - 182 164 bytes
#if 0
print"This program wasn't written in Lua, it was built for C!"--[[
#endif
main(){printf("This program wasn't written in C, it was built for Lua!\n");}/*]]--*/

Takes advantage of the feature where Lua treats a hash mark on the first line as a comment to allow for Unix shebangs.  Otherwise wraps the other language's comments in its own comments.
To shave bytes, I rely on implicit behavior that only emits warnings in GCC and Clang: implicit declaration of int for main and implicit definition of printf.

Very cleverly done!

If removing "include<stdio.h>" is too extreme, I'll revert the answer.

Why not use the // comment in the C part? Saves 2 bytes.

JavaScript/Haskell, 158 bytes 147 bytes
General idea: sneak each one's comment syntax into the other.
In one line:
u="This program wasn't written in ";v=", it was built for ";j="JavaScript";h="Haskell";{-console.log(u+j+v+h+"!")}//-}main=putStrLn$u++h++v++j++"!"

What this looks like to Haskell:
-- some variable definitions
u = "This program wasn't written in "
v = ", it was built for "
j = "JavaScript"
h = "Haskell"

-- a comment
{-console.log(u+j+v+h+"!")}//-}

-- the main method that does the dirty deed
main = putStrLn $ u ++ h ++ v ++ j ++ "!"

What this looks like to JavaScript:
/* variables can be declared without `var` */
u = "This program wasn't written in ";
v = ", it was built for ";
j = "JavaScript";
h = "Haskell";

/* hey look, an anonymous block! */
{
  /* we negate the `undefined` that comes out of console.log */
  -console.log(u+j+v+h+"!")
}
/* there are two automatic semicolon insertions here:
   one before `}` and one before EOF. */

/* a one-line comment. */
//-}main=putStrLn$u++h++v++j++"!"

alert is golfier.

Brainfuck/Foo, 769 bytes
-[--->+<]>-.[---->+++++<]>-.+.++++++++++.+[---->+<]>+++.[-->+++++++<]>.++.---.--------.+++++++++++.+++[->+++<]>++.++++++++++++.[->+++++<]>-.--[->++++<]>-.-[->+++<]>-.--[--->+<]>--.-----.[++>---<]>++.[->+++<]>-.[---->+<]>+++.--[->++++<]>-.-----.---------.+++++++++++..+++[->+++<]>.+++++++++.-[->+++++<]>-.-[--->++<]>-.+++++.-[->+++++<]>-.+[->++<]>.---[----->+<]>-.+++[->+++<]>++.++++++++.+++++.--------.-[--->+<]>--.+[->+++<]>+.++++++++.+++[----->++<]>.------------.-[--->++<]>-.+++++++++++.[---->+<]>+++.--[->++++<]>-.-[->+++<]>-.--[--->+<]>--.+[---->+<]>+++.[->+++<]>++.[--->+<]>-.------------.+++.++++++++.[---->+<]>+++.++[->+++<]>.+++++++++.+++.[-->+++++<]>+++.+++[->++<]>.+[--->+<]>++..[--->+<]>----."This program wasn't written in Foo, it was built for Brainfuck!"

An extremely intricate and complex answer... or not.

Dammit, not you again Foo :D

I like how you think.

When running this in Brainfuck, Brainfuck will wait for input because of the , in the text at the end. I believe that goes against the assignment rules.

@SimonForsberg it is a long time, but in an interpreter like try it online, and most others I think, , just sets cell to 0, for EOF

C / Python, 238 chars
This doesn't print 100% exactly what's requested, but quite close.
A reboot of my valentine's day card.
#define def main(){0?
#define print printf(
#define return 0)));}
#define pass 0);

def main():
    print "This program wasn't written in ",
    pass
    print "Python",
    print ", it was built for ",
    print "C",
    return

main();

What does it print if it isn't exact?

@BetaDecay, it prints some whitespace and no !.

@Fatalize, it's exactly right, thanks.

The question doesn't mention whitespace so the only thing preventing this being a valid answer is the lack of !.

That nested printf thing is brilliant...

How does C interpret the def keyword? It doesn't seem to be replaced anywhere.

This is not valid C. Clang complains about def and the : after def main(), and you don't actually open a function body for main. Did you actually try compiling your answer in C?

The line #define def main(){0? is missing

@Kay, You got it right - I omitted this exact line. I'll fix it.

@C0deH4cker, It's a copy&paste error - a line is missing. I did try to compile it, but copied the working program wrong.

@ugoren Okay, I see. Changed my downvote to an upvote :)

Why do you need the hashes in pri##ntf?

@Kay, For stupid reasons I can't post the word printf. If you could edit it and remove the ## it would be nice.

@ugoren, sorry, I can neither: "Edits must be at least 6 characters; is there something else to improve in this post?" :)

@Kay, thanks for trying, I'll try to deal with it.

@ugoren Edited.

#define return makes me cry a little...

C/C++, 136
#include<stdio.h>
int main(){
char*a="++",z=sizeof'c'/2;
printf("This program wasn't written in C%s, it was built for C%s!\n",a+z,a+2-z);
}

Newlines added for formatting. Try it in C or C++.

What if I'm on a platform where int is 2 bytes? Where can I get a C+ compiler?

@immibis haha :P but on a serious note the empty struct trick might work: struct{}s;z=2*sizeof s

Befunge/><>, 141 138 134 133 130 bytes
3 bytes saved thanks to @Cole.
To be exact, I'm using Befunge-98.
\"!><> rof tliub saw ti ,egnufeB"   >" rof nettirw t'nsaw margorp sih"'T>:#,_@'~~~~~~
>l?v"!egnufeB rof tliub saw ti ,><>"^
?!;>ol

Using the facts that:

\ is a mirror in ><> and swap in Befunge
'string' is a string in ><> and 'c is a char in Befunge

Unless you need it for the Befunge code (which I don't think you do), you can shave off 3 bytes by replacing the bottom line with ?!;>ol

PHP/MySQL, 147 bytes
-- $argc;die("This program wasn't written in PHP, it was built for MySQL!");
SELECT("This program wasn't written in MySQL, it was built for PHP!");

Finally, one I kinda understand.

You should be able to get rid of the second line's parentheses, for two bytes fewer: SELECT"This program wasn't written in MySQL, it was built for PHP!";

But that will no longer work in PHP - it will cause a parse error. SELECT"..." is not a valid PHP expression.

Python 3/><>, 177 173 172 167 Bytes
Thanks to @mathmandan for shaving 5 bytes off!
Well this was an experience, and a trying one, too. Any golf suggestions are welcome, since this is pretty long. I tried my best to reuse text, but it was quite difficult.
Technically, it would be Python 3 that this program should output (and I could change that if I didn't meet the specs -- but in the example Python/C output Python was listed).
aa=" ni nettirw t'nsaw margorp sihT\"\""
v="><>!"                 #v   "><>"r~/
a=", it was built for "+v#\a
print(aa[-3::-1]+"Pytho" +"n"+a)
#  .4b;!?lor"!nohtyP r"~/

Try it on an online ><> interpreter and a Python 3 interpreter (the ><> interpreter requires you to input the code manually)
Returns
This program wasn't written in ><>, it was built for Python!

in ><> and
This program wasn't written in Python, it was built for ><>!

in Python.
Explanation (Python)
For the Python side of things, it's pretty simple. Here's the code that we care about (basically the code without comments, which are denoted by a # in Python). Note that in Python \ is an escape character when used in strings, so \" evaluates to " in the string.
aa=" ni nettirw t'nsaw margorp sihT\"\""
v="><>!"
a=", it was built for "+v
print(aa[-3::-1]+"Pytho" +"n"+a)

What we care most about here is the operations performed on the variable aa:
aa[-3::-1]: reverses the string and chops off the quotation marks (thanks to @mathmandan)

The print statement thus evaluates to
"This program wasn't written in " + "Pytho" + "n" + ", it was built for ><>!"

Explanation (><>)
Now we get to the more difficult part. Once again, here's the code with the unnecessary bits removed.
aa=" ni nettirw t'nsaw margorp sihT\"\
                          v   "><>"r~/
a=", it was built for "+v \a

   .4b;!?lor"!nohtyP r"~/

Line 1:
aa=" ni nettirw t'nsaw margorp sihT\"\

aa=         pushes 1 onto the stack (evaluates 10==10, basically)
" ni ... \" pushes the first part plus a \ onto the stack.
\           deflects the pointer downwards

The stack right now (if printed): \This program wasn't written in
Line 2:
Note that line 2 begins at the / because of the position of the pointer from line 1, and moves right to left.
v   "><>"r~/

/     deflects the pointer leftwards
~r    pops the / off the stack and then reverses it
"><>" pushes ><> onto the stack
v     deflects the pointer downwards

The stack right now: ><> ni nettirw t'nsaw margorp sihT
Line 3:
Like the previous line, this one begins at the \, which is where line 2 sends the pointer. Note that because the pointer wraps around the line when it reaches the first a I'll be writing my explanation in order of where the pointer goes (and thus what is executed)
a=", it was built for "+v \a

\aa=       deflect and push 1 onto the stack
", i ... " push the string onto the stack
+v         sum the last two values pushed and deflect

The stack right now(x is the character formed by the addition of "r" and a space. -- it is not the actual character, just a placeholder from me):
xof tliub saw ti ,><> ni nettirw t'nsaw margorp sihT
Line 4:
The pointer simply continues downwards so this line warrants no further explanation.
Line 5:
Starting at / and going leftwards.
.4b;!?lor"!nohtyP r"~/

~"r Python!" pops x off and adds back r and a space
r            reverses the stack
o            pops and prints a character
l?!;         pushes the length of the stack and stops if it's 0
b4.          pushes 11 then 4 then moves to that location (where o is)

The stack right now (the output reversed):
!nohtyP rof tliub saw ti ,><> ni nettirw t'nsaw margorp sihT
And that should be it for the explanation. Let me know if there is any inconsistency between the explanation/code or if I did anything wrong; I golfed down my code some more while I was in the middle of writing the explanation so I might have mixed bits of old and new code up.

It would be wrong if I said that you had to add the 3 because it isn't python 2. It's fine.

If this were Python only, I believe you could replace aa[:-2][::-1] with aa[-3::-1].  In this case, of course, that may interfere with the ><> formatting, but maybe it's worth considering if you haven't already.  In particular I'm pretty sure you need a space below the v in the previous line, but it looks like print(aa[-3::-1]+"Pytho" would fit into the 24 characters below a=", it was built for "+, and then you could put a space followed by +"n"+a).  I'm not sure if this would break something else, but if it works it will save a few bytes.

@mathmandan Great idea, I'll update my code and credit you.

Nice job! FYI, I think this would work just fine in Python 2, and in Python 2 you can save a byte by dropping parentheses in the print statement: print aa[-3::-1]+"Pytho" +"n"+a. One other question though: in the ><> version, what happens to the 1 that was originally pushed onto the stack?

@mathmandan I think either the interpreter I used doesn't print the character if it's invalid or the printed character doesn't show at all. I'm honestly not 100% sure why printing that character doesn't matter; I discovered it accidentally.

OK, good work! I think you're allowed to specify an interpreter (as long as you didn't write it specifically for this challenge!) so that should be just fine.

Batch .BAT File / Batch .CMD File, 194 185 Bytes
@ECHO OFF
SET a=BAT
SET b=CMD
CALL :F&&GOTO :C||GOTO :O
:C
SET a=CMD
SET b=BAT
:O
ECHO This program wasn't written for %a% File, it was built for %b% File!
GOTO :EOF
:F
md;2>nul
SET v=1

Edit: Saved 9 bytes, and corrected a missing ! thanks to DLosc
Yeah, there's differences between BAT and CMD files. Reference. Essentially, CMD sets the ERRORLEVEL on a SET command, while BAT doesn't, meaning that here the ERRORLEVEL set by the malformed md command gets cleared by the SET v=1 in one version but not the other. This script is based on the example provided by "Ritchie" in that newsgroup thread.
Note that the shortened script above presumes ENABLEEXTENSIONS to be set ON (it is by default on every platform). The expanded script below explicitly sets it, to guarantee correct functionality. Without that, the SET command for CMD doesn't allow all extensions, and (on some systems, maybe) might not set the ERRORLEVEL appropriately.
Expanded and remarked
@ECHO OFF
setlocal ENABLEEXTENSIONS

REM Call the :FUNC subroutine and branch based on the resulting errorlevel
CALL :FUNC&&GOTO :CMD||GOTO :BAT

REM Just in case. If we reach this, though, hoo-boy ...
GOTO :EOF

:BAT
REM We're a BAT file, so set variables and goto output
SET a=BAT
SET b=CMD
GOTO :OUTPUT

:CMD
REM We're a CMD file, so set variables and goto output
SET a=CMD
SET b=BAT
GOTO :OUTPUT

:OUTPUT
REM Print out the result, then go to end of file
ECHO This program wasn't written for %a% File, it was built for %b% File!
GOTO :EOF

:FUNC
REM Simple subroutine to set the ERRORLEVEL appropriately
md;2>nul
REM Right now, ERRORLEVEL on both CMD and BAT is 1
SET v=1
REM Right now, ERRORLEVEL on CMD is 0, but BAT is still 1

...there's a difference between CMD and BAT?

Javascript / C, 148 146 143 chars
//\
alert/*
main(){puts/**/("This program wasn't written in "//\
+"Javascript"+/*
"C"/**/", it was built for "//\
+"C!")/*
"Javascript!");}/**/

C: http://codepad.org/u8UimGLc http://codepad.org/Y80M5jpc http://codepad.org/m4DB2Ndd
Javascript: just copy code to browser console

@ Qwertiy, Brilliant!

Beautiful.

CJam/GolfScript, 81 78 bytes
"This program wasn't written in "o"GolfScript"", it was built for ""CJam"oo"!"

Original 81 byte version:
"This program wasn't written in "["CJam"", it was built for ""GolfScript"]-1a%"!"

BF/SPL, 5342 bytes
I'm pretty sure this is the first Shakespeare Programming Language polyglot on this site.
Probably not going to win any prizes. Works by sneaking BF code into act/scene/program titles. The SPL code uses exclamation points instead of periods except for a few cases. The programs aren't supposed to take input, so the commas in the character declarations are "commented out" by zeroing cells and putting square brackets around the commas. The same procedure applies when hiding the square brackets around the enter/exeunt statements.
[-][.
Ford,.
Page,.
Act I:]+++++++++[>+++++++++<-]>+++.
Scene I:>[.
[Enter Ford and Page]
Ford:
You is sum of bad bad bad bad bad bad day and sum of bad bad bad bad day and bad bad day!Speak thy mind!
Scene II:]<<++[>++++++++++<-]>.
Page:
You is sum of bad bad bad bad bad bad day and sum of bad bad bad bad bad day and bad bad bad day!Speak thy mind!
Scene III:+.
Page:
You is sum of thyself and day!Speak thy mind!
Scene IV:++++++++++.
Page:
You is sum of thyself and sum of bad bad bad day and bad day!Speak thy mind!
Scene V:>++++[>++++++++<-]>.
Ford:
You is fat fat fat fat fat cat!Speak thy mind!
Scene VI:[-<+>]<<---.
Page:
You is sum of thyself and sum of big pig and pig!Speak thy mind!
Scene VII:++.
Page:
You is sum of thyself and fat cat!Speak thy mind!
Scene VIII:---.
Page:
You is sum of thyself and sum of big pig and pig!Speak thy mind!
Scene IX:--------.
Page:
You is sum of thyself and big big big pig!Speak thy mind!
Scene X:+++++++++++.
Page:
You is sum of thyself and sum of fat fat fat cat and sum of fat cat and cat!Speak thy mind!
Scene XI:<++++[->----<]>-.
Page:
You is sum of thyself and sum of big big big big pig and pig!Speak thy mind!
Scene XII:++++++++++++.
Page:
You is sum of thyself and sum of fat fat fat fat cat and big big pig!Speak thy mind!
Scene XIII:>.
Ford:
Speak thy mind!
Scene XIV:<++++++++++.
Page:
You is sum of thyself and sum of fat fat fat cat and fat cat!Speak thy mind!
Scene XV:<++++[->-----<]>--.
Page:
You is sum of thyself and sum of big big big big big pig and sum of fat fat fat cat and fat cat!Speak thy mind!
Scene XVI:<++++[>++++<-]>++.
Page:
You is sum of thyself and sum of fat fat fat fat cat and fat cat!Speak thy mind!
Scene XVII:-----.
Page:
You is sum of thyself and sum of big big pig and pig!Speak thy mind!
Scene XVIII:>+++++++.
Ford:
You is sum of thyself and sum of fat fat fat cat and pig!Speak thy mind!
Scene XIX:<++++++.
Page:
You is sum of thyself and sum of fat fat cat and fat cat!Speak thy mind!
Scene XX:>-------.
Ford:
You is sum of thyself and sum of big big big pig and cat!Speak thy mind!
Scene XXI:<+++.
Page:
You is sum of thyself and sum of fat cat and cat!Speak thy mind!
Scene XXII:-----.
Page:
You is sum of thyself and sum of big big pig and pig!Speak thy mind!
Scene XXIII:---------.
Page:
You is sum of thyself and sum of big big big pig and pig!Speak thy mind!
Scene XXIV:+++++++++++.
Page:
You is sum of thyself and sum of cat and sum of fat cat and fat fat fat cat.Speak thy mind!Speak thy mind!
Scene XXV:<+++[>-----<-]>.
Page:
You is sum of thyself and sum of big big big big pig and cat!Speak thy mind!
Scene XXVI:+++++++++.
Page:
You is sum of thyself and sum of fat fat fat cat and cat!Speak thy mind!
Scene XXVII:>.
Ford:
Speak thy mind!
Scene XXVIII:<-----.
Page:
You is sum of thyself and sum of big big pig and pig!Speak thy mind!
Scene XXIX:+++++.
Page:
You is sum of thyself and sum of fat fat cat and cat!Speak thy mind!
Scene XXX:>.
Ford:
Speak thy mind!
Scene XXXI:[->++<]>++.
Page:
You is sum of thyself and sum of big big big big big pig and sum of fat fat cat and cat!Speak thy mind!You is sum of thyself and sum of big pig and pig!Speak thy mind!
Scene XXXII:++++.
Page:
You is sum of thyself and big red hog!Speak thy mind!
Scene XXXIII:<+++++[>-----<-]>-.
Page:
You is sum of thyself and big big big big big pig!Speak thy mind!
Scene XXXIV:[-<+>]<------------.
Ford:
Speak thy mind!
Scene XXXV:<-----.
Page:
You is sum of thyself and sum of fat fat fat fat fat fat cat and sum of big pig and pig!Speak thy mind!
Scene XXXVI:+++++++++++.
Page:
You is sum of thyself and sum of fat fat fat cat and sum of fat cat and cat!Speak thy mind!
Scene XXXVII:>.
Ford:
Speak thy mind!
Scene XXXVIII:<+++.
Page:
You is sum of thyself and sum of fat cat and cat!Speak thy mind!
Scene XXXIX:<++++[->-----<]>--.
Page:
You is sum of thyself and sum of big big big big big pig and sum of fat fat fat cat and fat cat!Speak thy mind!
Scene XL:<++++[>++++<-]>++.
Page:
You is sum of thyself and sum of fat fat fat fat cat and fat cat!Speak thy mind!
Scene XLI:>.
Ford:
Speak thy mind!
Scene XLII:<<++++[>----<-]>-.
Page:
You is sum of thyself and sum of big big big big pig and pig!Speak thy mind!
Scene XLIII:<+++++[>++++<-]>-.
Page:
You is sum of thyself and sum of fat fat fat fat cat and sum of fat cat and cat!Speak thy mind!
Scene XLIV:------------.
Page:
You is sum of thyself and sum of big big big big pig and fat fat cat!Speak thy mind!
Scene XLV:+++.
Page:
You is sum of thyself and sum of fat cat and cat!Speak thy mind!
Scene XLVI:++++++++.
Page:
You is sum of thyself and fat fat fat cat!Speak thy mind!
Scene XLVII:>.
Ford:
Speak thy mind!
Scene XLVIII:<--------------.
Page:
You is sum of thyself and sum of big big big big pig and fat cat!Speak thy mind!
Scene XLIX:+++++++++.
Page:
You is sum of thyself and sum of fat fat fat cat and cat!Speak thy mind!
Scene L:+++.
Page:
You is sum of thyself and sum of fat cat and cat!Speak thy mind!
Scene LI:>.
Ford:
Speak thy mind!
Scene LII:>+++++++[<+++++++>-]<++.
Page:
You is sum of thyself and sum of big big big big big pig and big big big big pig!Speak thy mind!
Scene LIII:---.
Page:
You is sum of thyself and fat fat cat!Speak thy mind!
Scene LIV:----.
Ford:
You is sum of thyself and cat!Speak thy mind!
Scene LV:>+++++++[<------>-]<-.
Ford:
You is cat!
Scene LVI:>[.
[Exeunt]

Test out BF at https://repl.it/E8Hh/23.
SPL code was tested at the compiler found here: https://github.com/drsam94/Spl/.

JavaScript 1.8/JavaScript 1.7, 89 bytes
a=![].reduce;`This program wasn't written in JS 1.${8-a}, it was built for JS 1.${7+a}!`

Because Array.prototype.reduce is new in 1.8
EDIT:
Golfed out 7 bytes by directly initializing a instead of using reverse()
EDIT:
JavaScript can be written as JS, saving 8 bytes
EDIT:
Thanks Hedi for pointing out that I can save 3 more bytes if I don't use the variable b any more
EDIT: Golfed out 6 bytes by computing 7+a and 8-a, where a=1 if reduce is defined (JS 1.8) and a=0 if it is not defined (JS 1.7)
EDIT: Hedi golfed out 6 more bytes suggesting the use of template string
EDIT: ETHproductions golfed out 2 bytes suggesting a=!![].reduce; instead of a=[].reduce?1:0;
EDIT: no1xsyzy golfed out one more byte suggesting to revers the boolean check

With "JS" instead of "JavaScript", using twice " JS 1." in your string is shorter than using the variable b.

You can use template string to make it shorter :
`This program wasn't written in JS 1.${7+a}, it was built for JS 1.${8+a}!`

I think you can save two bytes by changing a=[].reduce?1:0; to a=!![].reduce;.

@ETHproductions Thanks, but I don't think it'd work. I need a to hold the value 1 or 0, not true or false

@ETHproductions sorry, you're right, I tried and it works. Thanks!

a=![].reduce and exchange 7+a and 8-a may -1 byte

PHP/Perl, 98 96 bytes
$a="HP";$b="erl";
//;$a=$b;$b=HP;
print"This code wasn't written in P$a, it was built for P$b!";

Dunno if this is cheating or not, since as far as I can tell the only way to run PHP without an opening <? tag is something like php -r $(cat codefile.php). But assuming that's legal... // is a PHP comment, but in Perl it's a regex (which, in a statement by itself, doesn't do anything). The rest should be pretty self-explanatory.
Edit: Now using a bareword in the Perl-only part. I wanted to use those in the first place for both languages, but PHP displays a warning when you do that, contrary to "There should be no output to stderr."

<?'>#'; is valid syntax in both languages.

Ruby/Python, 105 chars
a=["Ruby","Python"];a.sort();print("This program wasn't written in "+a[0]+", it was built for "+a[1]+"!")

This is really good! I especially like that there are no comments used.

Python 2.7.9/Python 2.7.10, 127 bytes
We've had a couple posts that used minor versions, but none that have gone to the next level down...
import types
n=len(dir(types))
print"This program wasn't written in Python 2.7.%d, it was made for Python 2.7.%d!"%(n%33,-n%52)

Try it on Ideone (Python 2.7.10) and repl.it (technically Python 2.7.2, but should give the same result as 2.7.9).
Python 2.7.10, according to the changelog:

Added an __all__ to the types module.

This pushed len(dir(types)) from 42 to 43, giving a numerical difference we can exploit to generate the desired output.

SWI-Prolog 6/SWI-Prolog 7, 156 bytes
P='SWI-Prolog ',A=6,B=7,(is_list(""),N=A,M=B;N=B,M=A),atomic_list_concat(['This program wasn\'t written in ',P,N,', it was built for ',P,M,'!'],W),write(W).

Uses the fact that double-quotes "" are string codes (i.e. list of character codes) in SWI-Prolog versions older than 7, and are a proper String type in version 7. is_list("") will thus be false in version 7 and true in earlier versions.

Ruby 1.8/Ruby 1.9, 87
puts"This program wasn't written in Ruby 1.#{?9%49}, it was built for Ruby 1.#{?8%47}!"

In Ruby 1.8, ?9 is the ASCII value of "9", which is 8 modulo 49. In Ruby 1.9, it's the string "9", and %49 is a formatting operation that does nothing since "9" doesn't have any format strings in it.

sed / Hexagony 251 Bytes
/$/cThis program wasn't written in sed, it was built for Hexagony!
#...>32;p;r;o;g;r;\+/;a;w;23+;m;a<.;.>s;n;+39;t;+32\s/;n;e;;t;i;r;w;<. |.>+32;i;n;+32;H;e\ ;/4+;y;n;o;g;a;x;< i>4;+32;i;t;+32;\;/u;b;23+;s;a;w<h>;i;l;t;+32;f\;/;s;23+;r;o;< T>e;d;+33;@

sed: Try it Online!
Hexagony: Try it Online!

In sed, it prints the correct string if it matches the empty string at the end (always). The second line is a comment. This does require a string on STDIN, but it can be empty (allowed based on this consensus).
Example:
echo '' | sed -f whatLanguage.sed

In Hexagony, the first / redirects to the bottom left, it follows the left side up to where the sed part starts, then just wraps left to right, down a line, right to left, down a line, and so on. The expanded hex looks like this:
         / $ / c T h i s p r
        o g r a m w a s n ' t
       w r i t t e n i n s e d
      , i t w a s b u i l t f o
     r H e x a g o n y ! # . . .
    > 3 2 ; p ; r ; o ; g ; r ; \
   + / ; a ; w ; 2 3 + ; m ; a < .
  ; . > s ; n ; + 3 9 ; t ; + 3 2 \
 s / ; n ; e ; ; t ; i ; r ; w ; < .
| . > + 3 2 ; i ; n ; + 3 2 ; H ; e \
 ; / 4 + ; y ; n ; o ; g ; a ; x ; <
  i > 4 ; + 3 2 ; i ; t ; + 3 2 ; \
   ; / u ; b ; 2 3 + ; s ; a ; w <
    h > ; i ; l ; t ; + 3 2 ; f \
     ; / ; s ; 2 3 + ; r ; o ; <
      T > e ; d ; @ . . . . . .
       . . . . . . . . . . . .
        . . . . . . . . . . .
         . . . . . . . . . .

I will never understand Hexagony...

@DJgamer98 I don't really understand it either. This is my first time using it.

You can shorten the Hexagony a bit by making use of the fact that ; takes the current cell mod 256 to determine a byte value (e.g. you can print a space with P0; regardless of the current cell value). This CJam script generates all the pairs: http://cjam.tryitonline.net/#code=J1ssX2VsXkEsbSp7X29Tb0FiMjU2JWNvTm99JQ&input=

Python/QBasic, 160 142 bytes
Tested with Python 3 and QBasic 1.1. Won't work in Python 2 without adding from __future__ import print_function to line 4.
1# DEFSTR A-B
a = "QBasic"
b = "Python"
'';a,b=b,a;PRINT=print
PRINT ("This program wasn't written in " + a + ", it was built for " + b + "!")

In Python, 1# is the expression 1 (no-op) followed by a comment. In QBasic, it's a line number (with the type suffix marking it as a DOUBLE). The DEFSTR statement tells QBasic that all variables whose names start with A or B (case-insensitive) are string variables. That way, we can call our variables a and b instead of a$ and b$ (which wouldn't work in Python).
In QBasic, ' begins a comment. In Python, '' is the empty string (no-op). Then we swap the language names and define an alias for the print function (since QBasic keywords are auto-formatted to uppercase).
The parentheses on the final line aren't necessary in QBasic, but don't hurt anything either.

If I'm allowed to turn off the autoformatter (which is an option in QB64, though not in the original QBasic), I can get it down to 114 bytes using Python 2:
1#DEFSTR A-B
a="QBasic"
b="Python"
'';a,b=b,a
print"This program wasn't written in "+a+", it was built for "+b+"!"

-3 bytes: Switch to actual QB64.

Autoformatting.

QB64/Python 2 is 131 bytes! Or Python 3 for 133 bytes.

/// and Retina, 95 + 3 = 98 bytes
/
//

This program wasn't written in \/\/\/, it was built for Retina!
/?./....(.*)(R.*)!
$2$1///!

+3 bytes for the -s flag in Retina.
Explanation for ///
The first instruction is
/
//

removes all newlines from the rest of the code, resulting in
This program wasn't written in \/\/\/, it was built for Retina!/?./....(.*)(R.*)!$2$1///!

Everything up to the ! is just a literal and printed to STDOUT. The next instruction is
/?./....(.*)(R.*)!$2$1/

But the search string ?. cannot be found, so nothing happens. Then the remaining code is //! which is an incomplete instruction so the program terminates, having printed the correct string.
Explanation for Retina
/
//

This tells Retina to replace / with //. But the input is empty, so this doesn't match anything.
<empty>
This program wasn't written in \/\/\/, it was built for Retina!

This replaces the input with the string in the second line.
/?./....(.*)(R.*)!
$2$1///!

This matches the string \/\/\/, it was built for Retina! and replaces it with Retina, it was built for ///! to give the correct result.

You know, I think it would be trivial to do one between Retina and rs... ;)

@kirbyfan64sos Probably, but how short would it be? ;)

Well, so far I've gotten around 85 bytes + 3 for -s, though saying what I did would spoil the fun! :D

@kirbyfan64sos Go ahead and post it, I don't think I'll have time to look into rs any time soon.

Perl/Ruby, 129 bytes
0&&eval('def sort a,b;[b,a] end');printf"This program wasn't written in %s, it was built for %s!",(@a=sort"Perl","Ruby")[0],@a[1]

No regular expression abuse in this one, just making the most of the fact that 0 is truthy in Ruby to eval a definition for sort (which actually reverses) and printfing. Ruby didn't like using the list for the arguments, so I had to do each one individually.

Why does a have to be an instance variable, as opposed to a local one?

@QPaysTaxes the @ sigil on a variable in Perl denotes that it's a list, in Perl storing in, say $a instead, yields no output.

Ah, I see. Thanks for the explanation.

Python / Retina, 133 120 119 117 115 bytes
Now that I know more about Retina and regexes, I've golfed it a bit more. It also actually works now.
#?.*
print"This program wasn't written in Python, it was built for Retina!"
#?.*t"

#?(\w+)(,.* )(.+)!"
#$3$2$1!
#

Python just prints the statement. Retina replaces anything with the Python print statement, then removes the print and any quotes. Then, I swap Python and Retina and remove the #.
Try in Python | Try in Retina

http://retina.tryitonline.net/#code=Iz8uKgpwcmludCJUaGlzIHByb2dyYW0gd2Fzbid0IHdyaXR0ZW4gaW4gUHl0aG9uLCBpdCB3YXMgYnVpbHQgZm9yIFJldGluYSEiCiM2YC4KCiM_KCBcdyspKCwuKikoIFx3KykhIgojJDMkMiQxIQojCg&input=

@jimmy23013 Limits didn't exist at the time this challenge was posted. That's a relatively new feature of Retina.

http://retina.tryitonline.net/#code=Iz8uKgpwcmludCJUaGlzIHByb2dyYW0gd2Fzbid0IHdyaXR0ZW4gaW4gUHl0aG9uLCBpdCB3YXMgYnVpbHQgZm9yIFJldGluYSEiCiM_Lip0IgoKIz8oXHcrKSgsLiogKSguKykhIgojJDMkMiQxIQojCg&input=

JavaScript/CoffeeScript, 125 124 bytes
console.log("This program wasn't written in",(a=['Coffee','Java'])[+(b=0=='0')]+"Script, it was built for",a[b^1]+"Script!")

In CoffeeScript, a==b is compiled down to a===b, which makes the intermediate condition false. I used a bit of magic to convert the boolean value to an integer.
Saved 1 byte thanks to @DomHastings!
125-byte version:
console.log("This program wasn't written in",(a=['Coffee','Java'])[(b=0=='0')+0]+"Script, it was built for",a[b^1]+"Script!")

Nice! I think you can save a byte with +(b=0=='0') instead of +0!

Instead of b^1, I think you can use ~b

@IsmaelMiguel Nope. It says it was built for undefinedScript.

I forgot that ~1 == -2. But (b=0=='0')+0 can be written as +(b=0=='0'). Or b=+(0=='0'). That should cut off 1 byte.

@IsmaelMiguel I already did that in the most recent version...

Would 1&'1' produce 0 on CoffeeScript? If so, you can write b=1&'1'.

@IsmaelMiguel Nope. The only operators CoffeeScript changes are == and !=.

ToffeeScript!!!

VB6 / ES6 – 115 bytes
VB6
l="VB"
o="ES"
'';[l,o,MsgBox]=[o,l,alert]
MsgBox("This program wasn't written in "+l+"6, it was built for "+o+"6!")

ES6
l="VB"
o="ES"
'';[l,o,MsgBox]=[o,l,alert]
MsgBox("This program wasn't written in "+l+"6, it was built for "+o+"6!")

VBScript is not at version 6.  The latest is 5.8.

@peterferrie Thanks, but that's irrelevant. VB6 stands for Visual Basic 6, not VBScript 6.

Whitespace and Malbolge, 1318 1055 bytes
Did I just outgolf Dennis? Yes I outgolfed Dennis.
Although, it happened so that Kevin outgolfed me. Thanks for -263!
  		   			D'`rq
  			">7<Y
  		kW8Ux
   	  54-P>
   			=MLon
  			 %[k5F
   	  h}UeA
  				b?,__
  			 		)(r8Y
  		  	   Xtsl2
   	 	 Sonmf
   			,jLba
  		 f_%cE
 	  		[`Y}@
   		  ?[ZYR
   	  vVUTS
   	RQJIm
   		 	M/KDh
  			 HA)E>
 	  	 	bB$@?
   	 		>=6Z{
  				3810/
   				.R2r0
 	  		/.'&+
   		  $H('&
   	feB"!
 	  	 ~`_{z
  					  s9qvu
  			tsrk1
  		 	ohmlk
  				jc)J`
   	   &GF\a
   	 		ZY^]\
  			UyYXW
   		  9UNrR
   	QJOHM
   Fj-CH
  		   	AF?c=
  		  	   B;:9]
   		 =<|{9
   	2V0v4
 	  	 -QP0/
   		 o-&Jk
  			)"!&}
   		  C#c!x
 }|u;s
    	xwpun
   	 	 4UTpo
   				ng-kj
 	  			ihgfH
   		  %]\[`
  		     	Y^W{[
   		 Z<RvV
   	 		UT65Q
  				JnNG/
   				Ei,HG
 	  		 F?D=B
   	 	A@?8\
  				<54Xy
   	 	 x6/S3
  		210/o
   			-&Jk#
 	  	 (!~%$
   	   {Ab~w
 	  			|u;yx
   	 		qYutm
   	3kpon
   g-kji
  		 	  hgfH%
]\[`_
  ^WVzZ
   		 	   <Rv9O
	   	TMRQP
  ImGLE
 DhHGF
ED=%;
_?>=<;4z2V6/u-,+O/.'&J*j(!~}C#c!x}|u;\xqvotsl2poQPlkd*KJ`ed]\"ZY^W{UZYRWVOsSRKJOHGkKJIHA@dDCBA#">7[;{z870Tu3210).-,%$H"'&%$#"!~w=^]s9Zvo5Vlqpih.leM*u

Try it online! (Malbolge)
Try it online! (Whitespace)

You can golf the Whitespace part of the program from 789 bytes to 526 bytes. So it'll become 1055 bytes in total: try it in Whitespace or try it in Malbolge.

Thanks! I'll update my answer in a second

Are solutions with more than two languages allowed? If so:
Python 3 / JavaScript / jq, 284 bytes
0//1|"\(".__len__();console={'log':lambda x:print(x.replace('JavaScript','Python 3').replace('jq','JavaScript'))}#")"|
"\(";console['log']('This program wasn\u0027t written in JavaScript, it was built for jq!');0//1#"|"This program wasn't written in jq, it was built for Python 3!")"

Highlighted for Python:
0//1|"\(".__len__();console={'log':lambda x:print(x.replace('JavaScript','Python 3').replace('jq','JavaScript'))}#")"|
"\(";console['log']('This program wasn\u0027t written in JavaScript, it was built for jq!');0//1#"|"This program wasn't written in jq, it was built for Python 3!")"

Highlighted for JavaScript:
0//1|"\(".__len__();console={'log':lambda x:print(x.replace('JavaScript','Python 3').replace('jq','JavaScript'))}#")"|
"\(";console['log']('This program wasn\u0027t written in JavaScript, it was built for jq!');0//1#"|"This program wasn't written in jq, it was built for Python 3!")"

No idea how to start explaining the jq part; just know that the string interpolation syntax in jq works as a "string inside string" of sorts: between "\(" and ")", jq is in a string inside a string, while Python and JavaScript consider them individual strings.
Using jq -n -r, python3 and node.

Emotinomicon/Python 2, 168 bytes
#!2 nohtyP rof tliub saw ti ,nocimonitomE ni nettirw t'nsaw margorp sihT⏪⏬⏩
print"This program wasn't written in Python 2, it was built for Emotinomicon!"

or with more languages:
Emotinomicon/Python 2/><>, 267 bytes
v=0
 #!2 nohtyP rof tliub saw ti ,nocimonitomE ni nettirw t'nsaw margorp sihT⏪⏬⏩
for _ in[0]:print"This program wasn't written in Python 2, it was built for ><>!"
"""
"
>v
v>"!nocimonitomE rof tliub saw ti ,><> ni nettirw t'nsaw margorp sihT"
>l?!;o
"""

but I'm bored so let's add another language:
Emotinomicon/Python 2/><>/Gol><>, 358 bytes
v=0
 #!2 nohtyP rof tliub saw ti ,nocimonitomE ni nettirw t'nsaw margorp sihT⏪⏬⏩
for _ in[0]:print"This program wasn't written in Python 2, it was built for ><>!"
"""
`
"
?
>v
v>"!><>loG rof tliub saw ti ,><> ni nettirw t'nsaw margorp sihT"
>l?!;o
"
>!v~~~~~"!nocimonitomE rof tliub saw ti ,><>loG ni nettirw t'nsaw margorp sihT"0q
  >l?!;o
"""

Perl/PHP, 99 bytes
<?$p=erl;">;$p=HP#"
;$o=$p^erl^HP;print"This program wasn't written in P$o, it was built for P$p!";

For PHP, I assume the default interpreter settings, as they are without any ini. If you are uncertain, you may disable your local ini with -n as in php -n script.php.

On Ubuntu 15.04, perl does what's expected, but command-line php 5.6.4-4ubuntu6.2 just returns a verbatim copy of the input, even with -f or -F. Doesn't it work on command line?

@StéphaneGourichon you will need to explicitly enable the short_open_tag in the php config file. Although it is enabled by default, all of the sample config files disable it.

I'd rather not require administrator-level privilege just for this.  I give up here since adding  -d display_errors=Off or =0 does not clean the output.
`php -d short_open_tag=On  polyglot.php
PHP Notice:  Use of undefined constant erl - assumed 'erl' in polyglot.php on line 1
PHP Notice:  Use of undefined constant erl - assumed 'erl' in polyglot.php on line 2
PHP Notice:  Use of undefined constant HP - assumed 'HP' in polyglot.php on line 2
This program wasn't written in PHP, it was built for Perl!`

@StéphaneGourichon "I'd rather not require administrator-level privilege just for this." To be honest, I assumed most people would be running it from their own rig. short_open_tag: default value On. error_reporting: default value E_ALL & ~E_NOTICE.

Ruby/Python 3, 127 122 114 109 bytes
a=["Python","Ruby"];b=(0 and 1);print("This program wasn't written in "+a[b]+", it was built for "+a[~b]+"!")

Explanation: Ruby evaluates 0 to true whereas Python evaluates it to false. The b=(0 and 1) determines whether 0 is truthy, so it represents the array index of the language it's being called from. Python had to come first because it can act oddly when the statement after the and evaluates to false. Also, that link says that it only works in older Python versions but I tried it in Python 3 and it worked fine.
Thanks kirbyfan64sos for removing 5 13 bytes!
Edit: Turns out 0 and 1 instead of 0 and 1 or 0 will also determine whether 1 is truthy in both languages.

Nice! You can shave a 5 bytes off by changing a[(b+1)%2] to a[~b].

@kirbyfan64sos thanks, implemented! I never really knew about that operator before

It's the bitwise complement: 0 becomes -1 (which is the last element of a two-element array, 1), and 1 becomes -2 (which is the first element of a two-element array, 0).

One more thing: is it possible to remove the spaces around the plus signs?

@kirbyfan64sos yes! I'm kinda new to this whole code golfing thing, thanks

TeX / BASH - 192 bytes
echo "This program wasn't written in bash, it was built for TeX!";: "\output{\setbox0\hbox{\box255}\setbox0\vbox{This program wasn't written in \TeX, it was built for bash!}\shipout\box0}\end"

Trick is basically in the : "...." which lets bash do nothing with what comes inside the " ". TeX on the other hand just print it's own stuff onto a white paper.
I know I could save 1 byte by writing "TeX" instead of "\TeX", but I wont, this looks much nicer:

Inspired by http://pts.szit.bme.hu
Bonus:
TeX / many shells - 244 bytes
S=$(ps | grep `echo $$`$5 | awk '{ print $4$6 }');echo "This program wasn't written in $S$6, it was built for TeX!";: "\output{\setbox0\hbox{\box255}\setbox0\vbox{This program wasn't written in \TeX, it was built for shells!}\shipout\box0}\end"

This can in addition be run with dash, sh, ksh, et. al and will produce:
sheß@donald:~$ bash sh.sh
This program wasn't written in bash, it was built for TeX!
sheß@donald:~$ dash sh.sh
This program wasn't written in dash, it was built for TeX!
sheß@donald:~$ sh sh.sh
This program wasn't written in sh, it was built for TeX!

Finally:), I was already worried that no one would appreciate that

Haskell/Python 198 185 Bytes
Haskell
pass#b=b
pass##b=pass++b
p=print#putStrLn where print=p
main=p("This program wasn't written for "##(
 "Python"#"Haskell")##
 ", it was built for "##(
 "Haskell"#"Python")##
 "!")

Python
pass#b=b
pass##b=pass++b
p=print#putStrLn where print=p
main=p("This program wasn't written for "##(
 "Python"#"Haskell")##
 ", it was built for "##(
 "Haskell"#"Python")##
 "!")

Not actually sure if it works with all Pythons. Should work with python 3 at least.
If quotes in the output were valid, we could remove the third line and just use print in main (it'd print quotes around the string in haskell) - I'm assuming this is not valid here.
Explanation: The first 2 lines are no-ops in python (they just consist of pass), in Haskell they define 'select second' and 'concatenate' and concatenate operators respectively. The next line defines a 'variable' both in python and in haskell; In python it's pointing to print, in haskell it's defined as putStrLn (the where part shadows print, without it we would get type instantiation errors because of print there). The part after that is just abusing the fact that consecutive string literals in Python are concatenated like in C, in haskell we use the concatenation operator instead. We swap out "Python" and "Haskell" using our selection operators.
In python, the assignment to main is useless but valid. In Haskell, it's required because we need a main :: IO ().

Java/C, 418 Bytes
It might not have been a wise decision to use Java, nonetheless here's my solution:
//\u000a/*
#include <stdio.h>
#define public
#define static }
#define String int i,char*v
#define args
#define class
#define long g(){int
#define A struct{struct{int(*printf)();}out;}System={printf};f()
#define true 0
//*/
public class A{public static void main(String[]args){int c=true==(0==0)?1:0;System.out.printf("This program wasn't written in %s, it was built for %s!",c==0?"C":"Java",c==0?"Java":"C");}long f;}

Turns out Java and C are quite close. Except java is a lot more verbose and has a lot of keywords C doesn't need. And Java doesn't like the mixture of int's and booleans.
Annotated version

//\u000a/*                  /* \u000a gets replaced by a newline by javac
                               -> single line comment in C, multiline in java */
#include <stdio.h>          /* include needed, so I can use printf as function pointer */
#define public
#define static }
#define String int i,char*v /* make main declaration C compatible */
#define args
#define class
#define long g(){int        /* to remove closing bracket for `class {}` */
#define A struct { \        /* System.out.printf for C */
              struct { \
                  int (*printf)(); \
              } out; \
          } System = { printf }; \
          f()
#define true 0              /* Nothing is true, everything is permitted */
//*/                        /* single line comment in C, ends java multiline comment */
public class A {
    public static void main(String[] args) {
        int c = true == (0 == 0) ? 1 : 0; /* 1 for Java, 0 for C */
        System.out.printf("This program wasn't written in %s, it was built for %s!",
            c == 0 ? "C" : "Java",
            c == 0 ? "Java": "C");
    }
    long f; /* extra member, in java. gets redefined in C to get rid of the last } */
}

There might be some possibilites to cut off a few bytes here and there.

I think you can safely remove the v after #define String int i, char*

Perl/JavaScript ES6, 170 bytes
$a='Perl',$b='JavaScript';/1/&&($a=[$b,$b=$a].shift());$_="This program wasn't written in $a, it was built for $b!";/1/?console.log($_.replace(/\$./g,$r=>eval($r))):print

Again abusing regular expressions, but this time the fact that /1/ is truthy in JavaScript (because it's a RegExp object) and falsy in Perl (because $_ is empty) to switch the variables and run the correct print statement.
Note: This is ES6 JavaScript to work around Perl throwing a syntax error.

QBasic / Javascript, 153 134 bytes
UPDATE: Saw that the text could be de-duplicated:
a$="This program wasn't written in "
b$=", it was built for "
PRINT(a$+"JS"+b$+"QB!")
'';function PRINT(){alert(a$+"QB"+b$+"JS!");}

First post! Anyway, my code is:
PRINT ("This program wasn't written in JS, it was built for QB!")
'';function PRINT(){alert("This program wasn't written in QB, it was built for JS!");}

In QBasic, it prints the first line and doesn't execute the second line because it's believed to be a comment (thank you '). In JS, it calls the function PRINT, which is defined on the second line.

Perl/Tcl 171 bytes
#\
sub set{eval"\$$_[0]=\"$_[1]\""}sub puts{}
set a, "This program wasn't written in";
set b, "l, it was built for";
#\
print"$a Per$b Tcl!\n"||
puts "${a,} Tc${b,} Perl!"

No trailing semicolon or newline.  This exploits Tcl comments being, well, odd!

Python/Pip, 103 bytes
print(#x)O
"This program wasn't written in "#xO"Pip"Y
"Python"#xO
", it was built for "  "Pip!")
#xy.'!

GitHub repository for Pip
The main difficulty with Python and Pip is that they use completely different syntax for output (print vs O/P), for string concatenation (+ vs .), and for assignment (= vs :). At least they have the same syntax for defining strings! This is how Python interprets the program, with comments moved for clarity:
print(                             #x)O
"This program wasn't written in "  #xO"Pip"Y
"Python"                           #xO
", it was built for "  "Pip!")
                                   #xy.'!

Literal strings in Python that are separated only by whitespace are concatenated.
Now here's how the program looks to the Pip interpreter:
p r i n t                           No-ops (all lowercase letters are variables)
(#x)                                Another no-op (# is the unary length operator)
O"This program wasn't written in "  Output without newline
#x                                  No-op
O"Pip"                              Output
Y"Python"                           The yank operator Y assigns its operand to y
#x                                  No-op
O", it was built for "              "Pip!") is a comment since it comes after two spaces
#x                                  No-op
y.'!                                Concatenate ! to the end of y and print (implicit)

Ruby 2.1.5/JavaScript, 189
i
=begin
=9;n=console.log;end='';y
=end
//=~'';def n(x);puts x;end
n("This program wasn't written in "+(f=['JavaScript','Ruby'])[b='k'.match(/[^\W]/i)?0:1]+", it was built for "+f[1-b]+"!")

This does some simple polyglot manipulation to make n a function that prints to stdout.  That's the only polyglot trick.  The real trick is that Ruby has a bug in the Regexp matcher wherein "k" and "s" do not match /[^\W]/i due to case-folding.  It's in the official documentation, too.
Anyway, to Ruby, this looks like:
i       # a pointless variable declaration
=begin
  This is a block comment
=end
//=~''; # just a pointless regex evaluation

# declare a method `n` which puts to stdout
def n(x)
  puts x
end

# call n.  b will equal 1 since this erroneously fails to match.
n("This program wasn't written in "+(f=['JavaScript','Ruby'])[b='k'.match(/[^\W]/i)?0:1]+", it was built for "+f[1-b]+"!")

And to JavaScript, it looks like:
i=begin=9;  // pointless assignment of i and begin to 9
n=console.log; // set up `n` as a function to log to stdout

// more pointless assignments....
end='';
y=end

// comments
//=~'';def n(x);puts x;end

// call n.  b will be 0 because JS does not share Ruby's bug.
n("This program wasn't written in "+(f=['JavaScript','Ruby'])[b='k'.match(/[^\W]/i)?0:1]+", it was built for "+f[1-b]+"!")

I realize that it'd be shorter to use the truthiness of 0 in both languages, but I've been looking for a way to exploit this bug for months.

The polyglottishness was stolen outright from a younger me

That's a great bug! Seems to be fixed in the latest Ruby, too, so you could use it to distinguish between 2.1 and 2.2.

What version of ruby is this meant to run in? I just get undefined local variable or method 'i' for main:Object (NameError) when I try to run it on 2.2.3p173

@Shel v2.1.5.  It should also work in 2.0.0 and maybe even 1.8.7

You can save one byte by doing end=7 instead of end=''

Haskell / C - 225 219 bytes
Probably not optimized very well.
Haskell
int /* x = x -- */ printf(const char*,...); /*
main = putStrLn "This program wasn't written in C, it was built for Haskell!"
-- */ int main () { printf("This program wasn't written in Haskell, it was built for C!"); }

C
int /* x = x -- */ printf(const char*,...); /*
main = putStrLn "This program wasn't written in C, it was built for Haskell!"
-- */ int main () { printf("This program wasn't written in Haskell, it was built for C!"); }

FYI I could cut some whitespace to save bytes, but I don't feel like that'd improve the answer by much.

Got it down to 173

Aren't the Haskell/C strings mixed up? That should be really easy to fix.

@EsolangingFruit this skips the declaration of the output function, which I wanted to include so it compiles without warnings. Could save a couple bytes by using puts instead of printf though.

Haskell / Literate Haskell (195 bytes)
I hope this isn't cheaty, but I fully intended it to be cheeky!
main = putStrLn "This program wasn't written in Haskell, it was built for Literate Haskell!"
{-

> main = putStrLn "This program wasn't written in Literate Haskell, it was built for Haskell!"

-}

Can you remove the spaces around = and putStrLn?

Hugs 98 Haskell/GHC Haskell, 203 bytes
Edit: Please also see this version, which is more interesting, and now shorter as well!
This takes advantage of an accidental change in the strictness of foldl' in the base library that came with GHC 7.10. Said change was noted several years ago, but has not been reverted. The "version names" I've used are a bit bogus, but they mirror the ones on TIO. It would be trivial to use something different.
import Control.Exception
import Data.List
p#q=putStrLn$"This program wasn't written in Haskell"++p++", it was built for Haskell"++q++"!"
main=handle(\ErrorCall{}->""#"98")$foldl'(!)(error"")[1]
_!_="98"#""

Try it online (GHC)
Try it online (Hugs)

You can shorten (ErrorCall _) to ErrorCall{}.

@ØrjanJohansen, heh, I made a similar suggestion to someone else recently! Thanks.

201 bytes

JavaScript/JavaScript ES6, 132 130 bytes
var v=[];v[0]=v[1]=" JavaScript";v[[].fill?0:1]+=" ES6";alert("This program wasn't written in"+v[0]+", it was built for"+v[1]+"!")

You can save 2 bytes by using [].fill or [].find instead of [].values

And I just noticed you can save another byte by using +!![].fill instead of [].fill?0:1

@PatrickRoberts thanks! I didn't notice fill! But, are you sure about the +!![].fill? I make a few tests on online interpreters and firefox and I'm not getting the expected results.

Well the idea is to cast the function to a boolean then a number which is either 0 or 1 based on whether the version is ES6 or not, so that was the idea but maybe it doesn't work in practice

PowerShell 2/PowerShell 3, 144 118 Bytes
$p="PowerShell ";$a,$b=try{$d=[ordered]@{};3,2}catch{2,3}"This program wasn't written in $p$a, it was built for $p$b!"

Saved a bunch of bytes thanks to @Matt
There are probably other ways of doing this, but this is a simple one, and relatively short. The [ordered] keyword was only introduced with PowerShell v3 and later, which means that PowerShell v2 doesn't support it. A simple try/catch to set the appropriate variables, and we're off and running. (Note that the $d= is necessary to suppress setting $a to the hashtable and $b to an array when run on PowerShell 3.)

I would replace the try block with this instead $a,$b=try{$d=[Ordered]@{};3,2}catch{2,3} pretty sure that will work the same and is shorter all around

Selectors Level 4/Selectors Level 3, 148 chars
:has(*){--a:4;--b:3}*{--a:3;--b:4;content:"This program wasn't written in Selectors Level "var(--a)", it was built for Selectors Level "var(--b)"!"}

It works like this:

I assume a HTML document with a root element (<html>) and some child (<body>). Those should be generated automatically by the HTML parser, even if they aren't in the source code.
* will match <html>
I assume support of CSS Custom Properties for Cascading Variables Module Level 1. This will create the variables --a and --b.
In Selectors Level 3, :has(*) in an invalid selector, so it's ignored silently.
In Selectors Level 4, <html> matches :has(*), which has more specificity than *. This will modify the variables.
I assume support of CSS3 Generated and Replaced Content Module. The content property will replace the contents of <html> with the desired string, which uses var() to read the variables.

I think it should work, but I don't have any implementation to test it.
Thankfully, the name of the spec is only "Selectors Level X" instead of "CSS3 Selectors and Foo for Bar Module Level X".

Only Opera 12 supports content for real elements. Not sure, but probably you need to use pseudoelement. What does specification sais about it? And at the moment only Firefox supports css variables.

Just a little note: Selectors Level 4 does not imply support for CSS Custom Properties for Cascading Variables Module Level 1 or CSS3 Generated and Replaced Content Module.

@Qwertiy But html:after is longer than * (I would have to target html explicitly to avoid displaying the string twice: for html and body)

Python/Boo, 102 bytes
v=1//2
n=("Python","Boo");print"This program wasn't written in "+n[v]+", it was built for "+n[1-v]+"!"

Explanation: Boo's syntax is strongly based on Python's, but it uses // as a C-style comment, whereas Python uses it for integer division.

Brainfuck/Bash 4.3, 849 848 843 bytes
#-[--->+<]>-.[---->+++++<]>-.+.++++++++++.+[---->+<]>+++.[-->+++++++<]>.++.---.--------.+++++++++++.+++[->+++<]>++.++++++++++++.[->+++++<]>-.--[->++++<]>-.-[->+++<]>-.--[--->+<]>--.-----.[++>---<]>++.[->+++<]>-.[---->+<]>+++.--[->++++<]>-.-----.---------.+++++++++++..+++[->+++<]>.+++++++++.-[->+++++<]>-.-[--->++<]>-.+++++.-[->+++++<]>-.+[->++<]>.---[----->+<]>-.+++[->+++<]>++.++++++++.+++++.--------.-[--->+<]>--.+[->+++<]>+.++++++++.+++[----->++<]>.------------.-[--->++<]>-.+++++++++++.[---->+<]>+++.--[->++++<]>-.-[->+++<]>-.--[--->+<]>--.+[---->+<]>+++.[->+++<]>++.[--->+<]>-.------------.+++.++++++++.[---->+<]>+++.++[->+++<]>.+++++++++.+++.[-->+++++<]>+++.+[->++<]>.[-->+++<]>--.--[--->+<]>--.-----------.--[--->+<]>--.++[-->+++<]>+.------.+++++.[--->++<]>
echo -e "This program wasn't written in Bash 4.3, it was built for Brainfuck!"

This doesn't have the ! at the end. All you have to do to fix this is change the ending >- on the Brainfuck line to >-..

@Shebang nope. That point is hidden in the bash version :)

..what? That's not what I said. You do not print an exclamation point when executed in Brainfuck, so this answer is not valid.

The ending . you mean is located in Bash 4.3

@Shebang you were right. Instead of adding a ., removing the last - in the first line solved the problem. I forgot about the minus sign in echo -e. Thank you!

Java/Groovy, 190 186 184 181 bytes
class A{public static void main(String[]a){String Groovy=" Java",Java=" Groovy";System.out.print("This program wasn't written in$Java, it was built for$Groovy!".replace('$',' '));}}

Ungolfed:
class NotThatLanguage {
  public static void main(String[] args) {
    String Groovy=" Java", Java=" Groovy";
    System.out.print("This program wasn't written in$Java, it was built for$Groovy!".replace('$', ' '));
  }
}

Commodore 64 Basic/QBasic, 169
In order to get the capitalization right, you'll need to switch your Commodore 64 to character set 2 by pressing <SHIFT> + <C=>.
1 c$ = "QBasic": d$ = "Commodore 64 Basic"
2 if(fre(0) < 0) then e$ = c$:c$ = d$:d$ = e$
3 print "This program wasn't written in "; c$; ", it was built for "; d$; "!"

In Microsoft dialects of Basic, the "fre()" function returns the available free space.  Now, QBasic can run on surprisingly low-memory IBM compatibles, so you can't reliably tell QBasic and Commodore Basic apart just by the amount of free space.  However, the Commodore Basic version returns a signed 16-bit integer where the QBasic version returns a 32-bit one -- and since the Commodore 64 has more than 32767 bytes free with just a small program, while QBasic, as a real-mode program, will never see more than 1048576 bytes, "fre(0)" will always return a negative number on a C64 and a positive number under QBasic.
Commodore Basic's 80-character-per-line limit and QBasic's autoformatter interact in annoying ways here.  For example, I found a neat trick involving an if-then-else statement (invalid in Commodore Basic, but an "end" statement keeps the Commodore interpreter from encountering the invalid bits) -- except that the resulting line is 86 characters long after QBasic's autoformatter gets through adding whitespace.  Likewise, line 1 can't be combined with line 2: the result would be 88 characters long after autoformatting.

Why does QBasic autoformatting matter?

@CatsAreFluffy, QBasic has a combined editor/interpreter.  If you type in or load a program with what it considers improper whitespace, it will insert the whitespace for you.

So? If you paste an improperly formatted program in, it'll be autoformatted. I just don't get why the pasted-in program has to be formatted properly. If people had to care about whitespace added by the IDE, I'd have to fix every single one of my answers. (Well actually, I think 3 of them are fine, but why is ths so long)

I'm pretty sure there's a thing called QB64 which allows disabling autoformatting.

MATLAB / Octave, 118 116 Bytes
x=all(version-82);s={'Octave','MATLAB'};
fprintf('This code wasn''t written in %s, it was built for %s!',s{2-[x ~x]})

This works because version returns something like: 8.4.0.150421 (R2014b), in MATLAB, and 3.6.2 in Octave. version-82 will contain a zero if there is an R in the version name. all(version-82) gives true if there are only non-zero values, and false if one value is zero.

Mathematica 9/Mathematica 10, 115 bytes
Print["This program wasn't written in",a=" Mathematica ",If[b=Now==Now,9,10],", it was built for",a,If[b,10,9],"!"]

A bit late to the party... In Mathematica 9, Now remains unevaluated, and therefore equals itself. In Mma 10, each evaluation has a slight time offset, causing the two Nows to be unequal.

You could replace the print function with ""<>{} with those strings as parameters to shave of a byte since Mathematica prints the evaluation implicitly. <> is shorthand for StringJoin.

@Pavel The Mathematica REPL is not considered to be a full program.

Emoji/Emojicode, 170 bytes
This program wasn't written in Emoji, it was built for Emojicode!➡
This program wasn't written in Emojicode, it was built for Emoji!

Try Emoji online!
Try Emojicode online!

Excel / Google Sheets, 128 126 Bytes
Anonymous worksheet function that takes no input and outputs to the calling cell.
="This program wasn't written in "&IfError(M("Google Sheets, it was built for Excel"),"Excel, it was built for Google Sheets")

Or
="This program wasn't written in "&Substitute(IfError(M("Google Sheets1Excel"),"Excel1Google Sheets"),1,", it was built for ")

C++ (gcc) / R, 163 bytes
#include<cstdio>
#define cat(x)x
#define sprintf(a,b,c)int main(){printf(a,c,b);}
cat(sprintf("This program wasn't written in %s, it was built for %s!","R","C++"))

C++ (gcc) : Try it online!
R : Try it online!
# is the comment character in R, so using preprocessor's magic of C++ we can switch between the two languages

Haskell GHC/Hugs98, 199 bytes
I've already written a different program for these language variants, but I think this one is much more clever. And now, it's also shorter!
Thanks to @ASCII-only for suggesting putStr instead of putStrLn. Thanks to @ØrjanJohansen for suggesting id rather than a custom operator for a related answer, and then shedding a full 30 bytes by realizing the Num instance can be left empty.
instance Eq(a->b)where _==_=0<1
instance Show(a->b)
instance Num(a->b)
p#q=putStr$"This program wasn't written in Haskell"++p++", it was built for Haskell"++q++"!"
main|(0`id`)==1=""#"98"|0<1="98"#""

Try it online (GHC Haskell)
Try it online (Hugs98 Haskell)
Explanation
Hugs 98 used a "relaxed" interpretation of operator sections, where (x!) meant (!) x. In even vaguely recent times, GHC has only used that relaxed interpretation when a certain language extension is enabled. The rest of the time, (x!) means \y -> (!) x y. The latter (more strictly standards-compliant) interpretation can cause the type constraints on (x`id`) to be stronger. In particular, it requires id to be a function of (at least) two arguments.
Haskell has a mechanism for defaulting ambiguous types under certain narrow conditions. The defaulting mechanism is just sensitive enough to the imposed constraints that we can detect the difference in operator section interpretation.
Open questions

Is it possible to cut the code size down? I'm not terribly happy with the way I actually put the strings together.
Is it possible to use Haskell's special rules for pattern matching on numeric literals without increasing the code size? That would make it even golfier, IMO.

Wait, why not putStr

@ASCII-only, fixed.

This is too lazy to ever evaluate a function number literal, so just instance Num(a->b) will do.

Vyxal V, 53 bytes
`λ« ƛ¾ wṠǒ't «ḭ in %, it λ¨ €₇ λ⟑ %!`‛₴ŀ:‛ V+"w1→iR∑%

Try it Online!
`...`                            # String with % in place of the language names
     ‛₴ŀ              # String 'Vyxal'
        :             # Duplicate
         ‛ V+         # Append ' V' to one copy
             "        # Pair with itself
              w       # Wrap in a list
               1→iR   # If flagless, this stores 1 to the variable iR.
                      # If the V flag, this stores 1 to the variable i, and swaps the two
                   ∑  # Unwrap
                    % # Format, replacing the %s

-11 thanks to Aaron Miller.

Now that deserves a +1. You absolute madlad. You’ve inspired me to do something similar.

53 bytes

@AaronMiller Oh that is very nice.

Vyxal, Vyxal r, 62 49 bytes
-13 bytes because I really overcomplicated this :/
‛₴ŀ`₴ŀ r`"`λ« ƛ¾ wṠǒ't «ḭ in %, it λ¨ €₇ λ⟑ %!`$%

Try it Online!
Explanation:
‛₴ŀ                # Push "Vyxal"
   `₴ŀ r`          # Push "Vyxal r"
         "         # Join top two values
          `...`    # Push target string with "%" where the names should go
               $   # Swap top two values (does nothing with "r" flag)
                %  # Insert "Vyxal" and "Vyxal r" in the string where the "%" are

Lua/Python, 150 bytes
Code:
print(1^2==1 and "This program wasn't written in Lua, it was built for Python!" or "This program wasn't written in Python, it was built for Lua!")

Explanation
This program makes use of three things:

Python and Lua both print output with the 'print()' function.
Python interprets the '^' operator as bitwise-xor, while Lua interprets it as an exponent operator.
This was the tricky part. Python and Lua have completely different syntaxes and keywords for conditionals, so I had to find a syntax that means the same thing in both languages. I was able to do this when I stumbled upon the fact that ' and  or ' will return the '' if '' is True, and '' if it is False.

When I first started this challenge, I attempted to make use of the fact that Python zero-indexes lists, while Lua one-indexes them. However, this failed because Lua uses curly brackets instead of Python's straight brackets. At first I thought it might work since curly brackets denote sets in Python, but Python doesn't allow you to access a set element the same way you access a list element since Python sets are by definition 'unordered,' so I gave up that idea and looked for alternatives until I remembered that the '^' operator doesn't mean exponentiation in Python, and I devised a solution based on the fact that the '^' operator means exponentiation in Lua, but not Python.
Try it Online! (Python)
Try it Online! (Lua)

It seems that print with parens does work in Python 2…

Also you can remove the " 3" since you have only one version of Python.

Okay thanks. I just edited my post. I thought that Python 2 only had a print statement. whoops.

Also, if you were wondering, I couldn't shave bytes easily by concatenating strings. Python uses the '+' operator, and Lua uses '..'. If you know a way to get around this, let me know and I'll try to golf the code to a smaller size.

Python 2 only has a print statement, that's right, but it can be called like this because, as usual, you can wrap anything in parens.

This is why I like python so much

PHP/Javascript 178 chars
/*<?php echo "This program wasn't written in PHP, it was built for JavaScript!*"."/";exit;?>*/console.log("/*This program wasn't written in JavaScript, it was built for PHP!*/");
This is not perfect due to the Fact it is in this Format: /*{Message}*/.
It abuses the Comments from Javascript and the exit; function from PHP, which also causes the stupid Format.

PHP/Javascript(ES6), 191 bytes
This one is quite obvious for some people. And I think it is bigger than the existing PHP/JS answer.
$e=($j="\0"=='\0')?[a=>console.log(a.join(''))][0]:function($a){echo(join('',$a));};$L=['PHP','Javascript'];$e(["This program wasn't written in ",$L[+$j],', it was built for ',$L[+!$j],'!']);

You can try it on:

ES6: http://www.es6fiddle.net/ie4ocwmy/
PHP: http://ideone.com/o0JchK

I believe there's a bit more to chop off.

Perl 5 / Perl 6, 113 bytes
$X=5;$Y=6;if ("a".chars>0) {$X++;$Y--}print "This program wasn't written in Perl $X, it was built for Perl $Y!\n"

This proved to be harder than anticipated.
How it works? In perl 6 the "a".chars gives a result of 1.
But in Perl 5 the string "achars" is compared against a number, which results in false.
(** shakes finger at perl 6 for making it harder to golf **)

This doesn't work in Perl 6 unless you add a no strict at the beginning

Perl 5 / Perl 6
perl -e '$x= ~ -2; printf "This program wasn\x27t written in perl\%d, it was built for perl\%d", 4+abs($x), 7-abs($x);'

Explanation, please?

~ is complement in 5; string coercion in 6.

I was going to use $/=5;$_=6;#\(␤$/++;$--;#)␤print "This program wasn't written in Perl $, it was built for Perl $/!\n"`

Perl5 / JavaScript
y= 1, split = function(){return ''; " =; #"}
print ( "This program wasn't written for", split( //, " Perl, it was built for JavaScript!") );
y), "\bJavascript, it was built for Perl!");
x=split();

jq / Python 3, 151
"\("; print('This program wasn\u0027t written in Python 3, it was built for jq!')#" | "This program wasn't written in jq, it was built for Python 3!")"

The problem gets a little bit complicated when one of the languages does not have a comment syntax.
Run with jq -n -r or with python3.

Scala/Groovy, 128 bytes
Adapting my Java/Groovy snippet for Scala instead lets us get rid of a lot of Java boilerplate:
def Scala=" Groovy"
def Groovy=" Scala"
print("This program wasn't written in$Scala, it was built for$Groovy!".replace('$',' '))

Worth pointing out that this isn't scala "proper", but Scala script. A full scala program does still need a main entry point.

JavaScript / JavaScript ES6, 110 bytes
"This program wasn't written in "+((b=[a="JavaScript",c=a+" ES6"].keys)?c:a)+", it was built for "+(b?a:c)+"!"

Checks for the existence of .keys. Most browsers these days are ES6 so I recommend installing a separate engine such as Rhino if you really want to test this.

CoffeeScript+CJam
Uses CoffeeScript's ### and CJam's e#
e###
"This program wasn't written in CJam, it was built for CoffeeScript!"
e### ###
e### alert "This program wasn't written in CoffeeScript, it was built for CJam!"

How CJam sees it
e# comment
push "This program wasn't written in CJam, it was built for CoffeeScript!"
e# comment
e# comment

How Coffee sees it:
e
###
comment
###
###
comment
###
alert("This program wasn't written in CoffeeScript, it was built for CJam!")

Javascript ES6, ES5 131 127 bytes
I just thought I post this for fun
"This program wasn't written in "+((c=eval("try{let a=0}catch(e){1}"))?"ES5":"ES6")+", it was built for "+(c?"ES6":"ES5")+"!"

The main part of the code is this:
try{d.join``;0}catch(e){1}

If the version of javascript is ES5, this returns 1, because d.join`` throws an error.

JavaScript / Python3, 119 bytes
i=1//2
d=['print','console.log']
s=['python','js']
eval(d[i])('this program is not '+s[i]+', it was built for '+s[1-i])

Tested on Node.js v6.x and Python 3.5.1
The trick was to use Python's "floor division" operator which is the same as JavaScript's line comment //. This is how we swap 0 and 1 for i depending on the language.
This won't work on python2 because print was not a function until python3 and therefore cannot be evaluated using eval. It should work for almost any JavaScript VM.
Edit
Golfed 7 bytes by removing j variable and using s[1-i] instead of s[j].

You could remove the j= line and use eval(d[i])('this program is not '+s[i]+', it was built for '+s[1-i]), for a saving of 7 bytes :)

@ETHproductions Thanks! That is clever!

Crystal / Ruby, 117 bytes
c="Crystal";r="Ruby";x='a'!="a";puts "This program wasn't written in "+(x ?c: r)+", it was built for "+(x ?r: c)+"!"

Crystal is heavily inspired by Ruby, so not much trickery is needed here except a way to detect which language is being used. This snippet abuses a key difference in both languages: Crystal has a character type (Char), while Ruby only has a String.
In Crystal, 'a' is a character literal, while "a" is a string literal. In Ruby, both are string literals. The code tests if 'a'=="a" (true in Ruby, false in Crystal) then uses that to decide whether to print Crystal or Ruby.

Common Lisp / C, 208 156 150 119 bytes
;main(){puts(
//(format't"~A~2*~A~2@*~AC!"
"This program wasn't written in ""C"", it was built for ""Common Lisp""!");}

Try it online for C
Try it online for Common Lisp
-52 bytes thanks to @ceilingcat!
-37 bytes thanks to @ASCII-only and his excellent mastering of CL format function

Thanks a lot @ceilingcat, I did'nt know that puts could be used without include!

You appear to have an extra slash in the codeblock

:( smart way is 158

150

Wonder if there's an easier way to concatenate strings, tried format but that doesn't seem to work too well (actually... 147)

124

@ASCII-only, amazing!!!

122 (2@ instead of 2: works too)

@ASCII-only, excellent! You're a very clever person, indeed!

119, forgot i only have one function now >_> (+ the fact it was after a comment...)

I'm not that great at using format lol, I just always refer to this (gigamonkeys' is also pretty good)

Ruby/Crystal, 149 140 bytes
v = 1e10.class == Float ? ["Ruby", "Crystal"] : ["Crystal", "Ruby"]
puts "This program wasn't written in #{v[0]}, it was built for #{v[1]}!"

Crystal is a language similar to Ruby, but it is compiled. In Crystal, the type of the literal 1e10 is Float64, while in Ruby it is Float. Probably can be golfed some.

x86_64/i386 machine code (with libc call), 91 bytes
One last machine code one, this time with actual machine code (and golfed assembly for the lulz). xx xx xx xx represents an unlinked placeholder, to main+23 (printf_str) and printf, respectively.
bf xx xx xx xx 8d 77 38  8d 57 3f 56 52 57 e8 xx
xx xx xx 5f 5a 5e c3 54  68 69 73 20 70 72 6f 67
72 61 6d 20 77 61 73 6e  27 74 20 77 72 69 74 74
65 6e 20 69 6e 20 25 73  2c 20 69 74 20 77 61 73
20 62 75 69 6c 74 20 66  6f 72 20 25 73 21 00 78
38 36 5f 36 34 00 69 33  38 36 00

x86_64: Try it online!
i386: Try it online!
What? You didn't expect me to not golf the demo, did you?
Explanation
It is pretty simple. It abuses the fact that x86_64 and i386 have completely different calling conventions.
x86_64 (on Unix) passes (most) arguments in registers, starting with rdi, rsi, and rdx. It ignores the stack unless you run out of registers. This is called the System V calling convention.
i386 (on Unix and usually on Windows) passes all arguments on the stack in right to left (i.e. backwards from C) order. It ignores the registers. This is called the cdecl calling convention.
So I set up the x86_64 message in the registers, and the i386 message on the stack (with the arguments rearranged), then call printf. It's that simple.
Ungolfed assembly (substitute registers starting with r with e for i386):
        .intel_syntax noprefix
        .globl main
main:
        # First, set up a System V call for x86_64 in the registers.
        # We assume the program is low enough in memory and that PIC is off.
        #     printf(printf_str, "x86_64", "i386");
        mov     edi, offset printf_str
        lea     esi, [rdi + 56] # x86_64_str
        lea     edx, [rdi + 64] # i386_str
        # And then we set up a cdecl call for i386, but swap the arguments.
        # Since the arguments are already in registers, we can just push them.
        #     printf(printf_str, "i386", "x86_64");
        push    rsi # x86_64_str
        push    rdx # i386_str
        push    rdi # printf_str
        # Call printf, using each architecture's calling convention
        call    printf
        # Clean up the stack and return. We can't add to rsp, as the offsets
        # would be different on i386.
        pop     rdi
        pop     rdx
        pop     rsi
        ret
printf_str:
        .asciz "This program wasn't written in %s, it was built for %s!"
x86_64_str:
        .asciz "x86_64"
i386_str:
        .asciz "i386"

Assembly (MIPS, SPIM)/Assembly (GCC, MIPS Linux O32), 319 313 309 305 270 256 255 241 233 bytes
.globl main
main:la $5,p+9
lh $3,-7($5)
li $6,54
jal w
sub $5,5
li $6,5
jal w
xor $3,5
w:move $2,$3
syscall
jr $ra
.data
p:.word 0xf0fa4,0x5350494d
.ascii"!This program wasn't written in "
.word 0x4d495053
.ascii", it was built for "

Try it online!
Since it reuses argc, it must be called with no arguments. This is implied given that "neither program should take any input from the user.".
Outputs This program wasn't written in SPIM, it was built for MIPS! on SPIM (on a little endian machine).
Outputs This program wasn't written in MIPS, it was built for SPIM! on a real MIPS64 machine from the GCC Compiler Farm (specifically gcc22).
Explanation
Two words: Endian memes.
MIPS is big endian, while SPIM is little endian. This is perfect for us.
The first magic number is a "hybrid" encoding of the sys_write syscall. We store the SPIM syscall number in the most significant 16 bits, and the Linux syscall number in the least significant 16 bits.
We then do a halfword load on the address + 2.
On big endian, this would load the least significant bytes, while on little endian, it would load the most significant bytes. That is why you never cast pointers in C if you want your code to be portable.
This is actually what we want: we will load the Linux syscall on big endian, and the SPIM syscall on little endian.
This is also used to obtain the sys_exit syscall number.
On SPIM, the syscall for sys_write is 15, while the syscall for sys_exit is 10.
On Linux, the syscall for sys_write is 4004, while the syscall for sys_exit is 4001.
15 XOR 10 is 4004 XOR 4001 is 5, so sys_write XOR 5 is sys_exit, quick maffs!
Therefore, to magically convert both the SPIM and MIPS syscalls from sys_write to sys_exit, we can simply XOR by 5!
The second two magic numbers are "SPIM" and "MIPS" in big endian packed ASCII, respectively. These are inline with the strings.
"SPIM" being simply "MIPS" backwards means that it will be reversed on little endian. On MIPS, this will be "SPIM" and "MIPS", respectively, while on SPIM, it will be "MIPS" and "SPIM", respectively.
The reason we store the strings backwards is because it is shorter, and more importantly, both GAS and SPIM will insert alignment bytes for .words if they are not 4 byte aligned which mangle our output.
By coincidence, the second half of the string ends one byte after a word boundary, and the first half of the string is one byte off from being aligned, so we just merge them together to remove all padding (and allowing us to merge the last ! into the next .ascii block).
| = word boundary, @ = padding, $ = EOS, W = .word
|   |   |   |   |   |   |   |   | W |   |   |   |   |   | W |
@This program wasn't written in MIPS, it was built for @SPIM!$
| W |   |   |   |   |   |   |   |   | W |   |   |   |   |   |
SPIM!This program wasn't written in MIPS, it was built for $

Note that while it looks like I could save space by writing 0xf0fa4 in base 10, I can't, because for some reason, SPIM doesn't like comma separated numbers unless they are in hex.
Ungolfed version (not compatible with SPIM because SPIM doesn't allow arithmetic in .word):
        .data
hybrid_syscall:
        # sys_write syscall. SPIM is the high 16 bits, MIPS Linux
        # is the low 16 bits.
        # By doing a halfword read, we can automatically read the
        # right syscall number thanks to endianness.
        .word (15 << 16) | 4004     # -9(string_1)

string_2: # "SPIM!"
        # "SPIM" in big endian packed ASCII.
        # SPIM will store this backwards as "MIPS".
        .word ('S' << 24) | ('P' << 16) | ('I' <<  8) | 'M'
        # This "!" also aligns string_1 so the "MIPS" is aligned.
        .ascii "!"

string_1: # "This program wasn't written in MIPS, it was built for "
        .ascii "This program wasn't written in "
        # "MIPS" in big endian packed ASCII.
        # SPIM will store this backwards as "SPIM".
        .word ('M' << 24) | ('I' << 16) | ('P' <<  8) | 'S'
        .ascii ", it was built for "

        .text
        .globl main
main:
        # Pointer to string_1
        la      $a1, string_1
        # Load the Linux sys_write syscall on big endian and the
        # SPIM sys_write syscall on little endian.
        # *(uint16_t *)(hybrid_syscall + 2) == sys_write
        # Uses a relative offset from string_1.
        lh      $v1, -9+2($a1)
        # strlen(string_1)
        li      $a2, 54
        # do_syscall(sys_write, string_1, strlen(string_1))
        jal     do_syscall

        # Pointer to string_2
        # In the golfed version, we subtract five from the last
        # pointer, because a1 is always returned unmodified.
        la      $a1, string_2
        # strlen(string_2)
        li      $a2, 5
        # do_syscall(sys_write, string_2, strlen(string_2))
        jal     do_syscall

        # Do an XOR to magically convert sys_write to sys_exit.
        xor     $v1, 5
        # FALLTHROUGH: do_syscall(sys_exit)

        # Runs a syscall.
        # C equivalent: syscall(v1, ...)
        # v1: syscall number
        # varargs: passed to syscall as-is
do_syscall:
        # Move the syscall number into v0.
        move    $v0, $v1
        # As long as our program is called with no arguments
        # which is implied by the rules, we can reuse argc to pass
        # 1 as the first argument, which corresponds to stdout.
        # li      $a0, 1

        # write(STDOUT_FILENO, string, length)
        # exit(1)
        syscall
        # Return
        jr      $ra

Brainfuck/Javascript 936 chars
/*[-]>[-]>++++[-<++++++++>]<>[-]>++++++[-<++++++++++>]<+++++>[-]>++++++++++[-<++++++++++>]<---<<<>>+++++++++++++++++++.>+++++++.+.++++++++++.<<.>>---.++.---.--------.+++++++++++.-----------------.++++++++++++.<<.>>++++++++++.----------------------.++++++++++++++++++.-----.<<+++++++.>>++++++.<<-------.>>+++.-----.---------.+++++++++++..---------------.+++++++++.<<.>>-----.+++++.<<.>------------------.>++++.-----------------.++++++++.+++++.--------.+++++++++++++++.------------------.++++++++.<<++++++++++++.------------.>>--.+++++++++++.<<.>>+++.----------------------.++++++++++++++++++.<<.>>-----------------.+++++++++++++++++++.------------.+++.++++++++.<<.>>--------------.+++++++++.+++.<<.>++++++++.>-----------------.+++++++++++++++++++++.---------------------.++++++++++++++++++.----------------.+++++++++++++++.---------.+++++++.++++.<<+*/console.log("This program wasn't written in Javascript, it was built for Brainfuck!");

This is just Brainfuck Code in a Comment Javascript will ignore, but Javacript Code that Brainfuck will ignore. So it is perfect. :D

Outputs 'This program wasn't written in Brainfuck, it was built for Javascript!!' when executed in BF. Probably because you have an extra . in console.log.

I think you can get around the issue @muddyfish mentioned by just removing the . before the */, which is a byte shorter anyhow.

I know, I was just waiting for the OP to do it themselves.

fixed the little bug :D

You have another bug, the comma in your JS string will be executed, prompting for input. This probably isn't allowed, so you should use a hex escape sequence.

Already noticed it, but doesn't change this fact it outputs it, WHICH is the target...

Brainfuck/PHP 812 chars
<?php/*[-]>[-]>++++[-<++++++++>]<>[-]>++++++[-<++++++++++>]<+++++>[-]>++++++++++[-<++++++++++>]<---<<<>>+++++++++++++++++++.>+++++++.+.++++++++++.<<.>>---.++.---.--------.+++++++++++.-----------------.++++++++++++.<<.>>++++++++++.----------------------.++++++++++++++++++.-----.<<+++++++.>>++++++.<<-------.>>+++.-----.---------.+++++++++++..---------------.+++++++++.<<.>>-----.+++++.<<.>------------------.>++++.-----------------.++++++++.+++++.--------.+++++++++++++++.------------------.++++++++.<<++++++++++++.------------.>>--.+++++++++++.<<.>>+++.----------------------.++++++++++++++++++.<<.>>-----------------.+++++++++++++++++++.------------.+++.++++++++.<<.>>--------------.+++++++++.+++.<<.>++++++++++++++.--------.++++++++.<+.*/echo "This program wasn't written in PHP, it was built for Brainfuck!";

This is just Brainfuck Code in a PHP Comment that is getting ignored, while Brainfuck will ignore the PHP.

Brainf***/Thue, 829 bytes
a::=~This program wasn't written in Thue, it was built for Brainf***!
::=
a++++++++[>+>++>+++>++++>+++++>++++++>+++++++>++++++++>+++++++++>++++++++++>+++++++++++>++++++++++++>+++++++++++++>++++++++++++++>+++++++++++++++>++++++++++++++++<<<<<<<<<<<<<<<<-]>>>>>>>>>>>----.++++>>.+.->+++.---<<<<<<<<<<.>>>>>>>>>>.++.---.+<-.+>++.--<<+.->>---.+++<<<<<<<<<<.>>>>>>>>>>>-.+<<<+.->>+++.-----.++<<<<<<<<<-.+>>>>>>>>>>----.++++<<<<<<<<<<<.>>>>>>>>>>>-.+<++.--<+.->>----.++++----.++++<<---.+++>--.++<<<<<<<<<<.>>>>>>>>>+.->--.++<<<<<<<<<<.>>>>++.-->>>>>>++.--<<+.->+.->--.++<--.++<<<<<<<<++.--++.--++.-->----.++++<<.>>>>>>>>>+.->>----.++++<<<<<<<<<<<.>>>>>>>>>>>-.+<<<+.->>+++.---<<<<<<<<<<.>>>>>>>>++.-->>>---.+++<<+.->----.++++>----.++++<<<<<<<<<<<.>>>>>>>>>--.++>-.+++.--<<<<<<<<<<.>>>>>>>----.++++>>.>>---.+++<<---.+++<<<<<<<<<+.-<<<<.

MySQL (5) / Perl (5), 144 bytes
-- $_;print"This program wasn't written in Perl, it was built for MySQL!";
select"This program wasn't written in MySQL, it was built for Perl!";

h/t

BASH/JavaScript, 171 164 bytes
/* 2>&-;echo This program wasn\'t written in BASH, it was built for JavaScript\!;#*/console.log("This program wasn't written in JavaScript, it was built for BASH!")

First post to PPCG!

Python/Lisp 158 chars
""""(princ "This program wasn't written in Lisp, it was built for Python!")""";print 'This program wasn\'t written in Python, it was built for Lisp!';""" " """

Shells/Emacs Lisp (157 bytes)
:; echo "This program was not written for shells, it was built for Emacs!"; exit
(message "This program was not written in Emacs, it was built for shells!")

: is a nop in both languages.
; is a comment in Emacs Lisp and a delimiter in many shells. :; is used as a startup hack for Emacs Lisp scripts, if you need to pass more than one argument to Emacs itself by the command line.

Fuzzy Octo Guacamole and Jolf, 112 bytes
(non-competing, FOG is newer than the challenge)
a++++"This program wasn\'t written in ""Jolf"", it was built for ""Fuzzy Octo Guacamole""!"//__ssss.Z_sssts''.jX

Prints This program wasn't written in Fuzzy Octo Guacamole, it was built for Jolf! in FOG, and This program wasn't written in Jolf, it was built for Fuzzy Octo Guacamole! in Jolf.
This was fun.
FOG side is complicated, because there is no command to swap the top 2 items.
FOG Explanation:
a++++"This program wasn\'t written in ""Jolf"", it was built for ""Fuzzy Octo Guacamole""!"//__ssss.Z_sssts''.j_;

The a adds the 2 top items, adding 0 and 0 and pushing the result, 0.  Does nothing.
The + increment, so at the end the stack has [5].
The strings just push those to the stack.
The // does nothing but push '/' to the stack twice, but in Jolf it is a comment.
The __ pops the 2 '/'s we pushed, just removing them.
The ssss moves the top 4 strings, the parts that need rearranging, to the other stack. They are now in reverse order also.
The . switches stacks.
Z reverses the stack.
_ pops the '!', so we get it out of the way.  It is set to the temp var.
Then we move the 'Fuzzy Octo Guacamole', the 'was built for', and the 'Jolf' to the other stack in that order. That is the 3 s.
t pushes the temp var, which is still the '!' and then the next s puts it on the other stack.
We have all the strings, but how to print?
We first push '', the empty string.
Then we switch stacks with ..
Then we use j.  This is join.  It pushes the current stack as a string with the top of the inactive stack as a separator.
This is equivalent to the python ''.join(stack).
Then the X pops and prints, and we are done!
Side note: The poor 5 is left on the stack, all by himself. ;_;
Jolf Explanation:
Much simpler.
Jolf is prefix, so the a gets the alert function ready.
The + all concatenate the strings, so they just get stuck together.
So this just prints as-is, no need to rearrange. And the // is a comment, and hides the FOG side code.

Thanks to @CᴏɴᴏʀO'Bʀɪᴇɴ for making Jolf, a wonderful language to use.
Aʟsᴏ, ғʀᴇᴇ ᴘʟᴜɢ ғᴏʀ sᴍᴀʟʟ ᴄᴀᴘs!!!

Does FOG's interpreter complain with non-ASCII? If so, you could use Ά in place of pairs of +s (so s/++/Ά/g).

@CᴏɴᴏʀO'Bʀɪᴇɴ no, but it will push the letters to the stack as strings.  It ends up longer.

Python 2/C, 179 bytes
#if/*
"""*/1
main(){char*//"""
s="This program wasn't written in %s, it was built for %s!"
#if/*
"""*/1
;printf(s,"C","Python");}
#endif
#endif/*"""
print s%("Python","C")
#*/

Syntax-highlighted version:
Python:
#if/*
"""*/1
main(){char*//"""
s="This program wasn't written in %s, it was built for %s!"
#if/*
"""*/1
;printf(s,"C","Python");}
#endif
#endif/*"""
print s%("Python","C")
#*/

C (poor highlighting, sorry)
#if/*
"""*/1
main(){char*//"""
s="This program wasn't written in %s, it was built for %s!"
#if/*
"""*/1
;printf(s,"C","Python");}
#endif
#endif/*"""
print s%("Python","C")
#*/

C and ecpp, 140 bytes
#ifdef ECPP
#replace "C" "ECPP"
#replace "ECPP" "C"
#endif
main(){puts("This program wasn't written in ""C"", it was built for ""ECPP""!");}

Try ecpp online!
Try C online!
The #ifdef and #endif avoid syntax errors in C. #replace "C" "ECPP" replaces the string "C" with the string "ECPP", and #replace "ECPP" "C" replaces the string "ECPP" with "C".
This takes advantage of C's automatic string concatenation capabilities.

Haskell/Standard ML (MLton), 175 bytes
Explanation
Haskell's line comment marker, --, is a valid name for a Standard ML (SML) identifier. SML's function and value introduction keywords, fun and val, are valid Haskell identifiers. So we define -- in SML to be the identity function (which arbitrarily defines fun in Haskell to be id). We define i in SML to be the beginning of the output string, which makes val in Haskell a constant function evaluating to that string. Then we can hide our main Haskell program in an ML comment, and hide the ML comment delimiters from Haskell using --.
Haskell, 175 bytes
fun--id
 =id;
val i="This program wasn't written in ";--print(i^"Standard ML, it was built for Haskell!");(*
main=putStrLn$val 1++"Haskell, it was built for Standard ML!"-- *)

Try it online!
Standard ML (MLton), 175 bytes
fun--id
 =id;
val i="This program wasn't written in ";--print(i^"Standard ML, it was built for Haskell!");(*
main=putStrLn$val 1++"Haskell, it was built for Standard ML!"-- *)

Try it online!

"Then we can hide our main Haskell program in an ML comment that we hide from Haskell using --."?

@ASCII-only, is that better?

It's easier to use @ to hide (* from Haskell. 159 bytes

@ØrjanJohansen, oh, that's very clever. I would never have thought to use an as-pattern like that, since it's otherwise so useless!

Python/Clojure, 166 Bytes
#_()(println"This program wasn't written in Clojure, it was built for Python!")(comment
print("This program wasn't written in Python, it was built for Clojure!")#_())

Clojure – Try it online!
Python 3 – Try It Online!
Has room for improvement, not even a clever answer but I wanted to try it anyway.
Relies on the fact that #_() is an (unintentional?) reader no-op in Clojure (#_ will skip the next form, () is an empty form) yet starts a comment in python as python uses # for commenting.

Hello and welcome to PPCG. Would it be possible to provide two links to two online interpreters for ease fo verification?

Welcome to PPCG. I added some links to Try It Online (TIO), which is what we commonly use for easy demonstration.

@KirillL. Thanks, I forgot to add them.

@nihilazo "Ignore next form (#) The form following # is completely skipped by the reader." - from the official docs

156?

sadly, the smarter way is 159

135

121. finally looks like a true polyglot :P

@ASCII-only far smarter than my solution :D I don't want to edit my post with your changes as it's pretty much all your work so I would feel bad having it posted under my name

Haskell and ink, 160 bytes
--{i}ink{c}Haskell!->END
data K=VAR
g
 VAR i="This program wasn't written in "
f
 VAR c=", it was built for "
main=mapM putStr[g VAR 0,"Haskell",f VAR 0,"ink!"]

Try it online! (Haskell, ink)
In ink, the lines that begin with VAR are global variable declarations. Those happen at the start of the program regardless of whether those lines are ever reached during execution. This means we can end the program at the first line and not have to worry about printing anything we surround those with to make them look like valid Haskell.
In Haskell, the first line is a comment. We then define a datatype with VAR as a constructor. This lets us create functions that take VAR as a parameter, which is what lets us sneak ink's variable declarations in.
There is also a pretty boring 140-byte solution that abuses comment syntax to just concatenate two entirely separate programs (Haskell, ink)

Bash/Zsh, 86 bytes
a=({Z,Ba,Z}sh)
echo This program wasn\'t written in ${a[1]}, it was built for ${a[2]}!

Try it online! (Bash) | Try it online! (Zsh)
Bash indexes from 0, Zsh indexes from 1.

sed, sed -E, 105 bytes
s/^/This program wasn't written in sed, it was built for sed -E!/
s/(.*)(,.*)( -E)(\(\)\(\)\(\))?/\1\3\2/

Try sed -E Try sed
The second line rearranges the -E only when -E is provided. The extra (\(\)... mess is to keep sed from erroring out from invalid match groups otherwise.

Batch (.cmd or .bat), 92 bytes
If this counts...
@set[=.cmd.bat&call echo This program wasn't written for %~x0, it was built for %%[:%~x0=%%!

Neat. I wrote another answer that uses a different way to determine which is running. Mind adding an explanation for yours here? I can't quite follow how the variable expansion is working.

@AdmBorkBork you use a much more complete/formal method. call echo %%[:%~x0=%% first expands to call echo %[:bat=% (if it is a bat) and than expands to call echo .cmd

Python 2 and Zsh, 117 bytes
q="This program wasn't written in %s, it was built for %s!"
r='\';printf $q zsh Python;r=';print q%("Python","zsh")#'

Try it online! (Python)
Try it online! (zsh)
This works because of a difference in string tokenisation - in zsh, '\' is a whole string consisting of a backslash; in Python it's only the start.
Dead question, but as a Christmas project I'm working through the entire back catalogue of code-golf questions.

ARM64/ARM32 Assembly, 195 194 193 bytes
.globl main
main:@a:r0 .req x0;r1 .req x1;r2 .req x2
adr r0,s
adr r2,16
ldr r1,[r2],8
ldr r2,[r2]
b printf
.quad 64,32,64
s:.asciz"This program wasn't written in ARM%d, it was built for
ARM%d!"

Works only with Clang's assembler in GNU syntax (not Apple syntax)
Explanation:
Not the smallest thing in the world but pretty clever IMO
@a:r0 .req x0;r1 .req x1;r2 .req x2

ARM32 uses '@' for comments, and this line is ignored. In ARM64, this is interpreted as a label.
The .req lines are simply aliasing the ARM64 registers to the ARM32 names.
It is basically the same as this:
#define r0 x0
#define r1 x1
#define r2 x2

This is the magic, though:
adr r2,16

Load r2 with the address pc + 16. In ARM64, the PC register points to the current instruction, but in ARM32, the PC register points to the current instruction plus 8 bytes, thanks to some questionable design decisions.
A similar trick can be done with Thumb, as in Thumb mode, the PC register points to the current instruction plus 4 bytes, but that isn't as interesting.
Therefore, r2 will point to 64, 32 on ARM64, and 32, 64 on ARM32.
$ clang wrongasm.s -m64 && ./a.out
This program wasn't written in ARM64, it was built for ARM32!
$ clang wrongasm.s -m32 && ./a.out
This program wasn't written in ARM32, it was built for ARM64!

Python/Scratch, 181 bytes
In Python (and scratchblocks)
((1)+(2))//3;print("This program wasn't written in Python, it was built for Scratch!");"""
when gf clicked
say[This program wasn't written in Scratch, it was built for Python!]//"""

Explanation (for Python):
((1)+(2))//3 is evaluated as 1, and then the print is run; then a multiline comment comments out the rest of the program.
In Scratch:

Explanation (for Scratch):
The orphaned block ((1)+(2)) is ignored; only the script is executed.

Python 2.7/><> - 160 bytes
#v"This program wasn't made for ><>, it was built for Python 2.7!"
#l
#0
#)
#?
#!
#;
#o
#!
print"This program wasn't made for Python 2.7, it was built for ><>!"

Pretty simple program. Python ignores the everything after a # cause it's a comment, while a # in ><> makes the pointer turn around.

Mouse-2002 / Python 2, 157 bytes
These two languages don't share much.
' ''"This program wasn"!'' "t written in Mouse, it was built for Python"33!'"!"#A;$A@$
print"This program wasn't written in Python, it was built for Mouse!"

How Mouse sees this:
' ''"This program wasn"!'' "t written in Mouse, it was built for Python"33!'"!"#A;$A@$

Broken down:
'               ~ push space charcode
 ''             ~ push literal ' charcode

   "This program wasn"                              ~ print

!               ~ print TOS (a literal ' )
 ''             ~ push another literal '

   "t written in Mouse, it was built for Python"    ~ print

33!'            ~ push 33, then print that ASCII char (!)
    "!"         ~ print a newline
       #A;      ~ call a macro named A
          $A@   ~ define a bodiless macro named A
             $  ~ end the program; everything after will be pushed but not run

How Python sees this:
' ''"This program wasn"!'' "t written in Mouse, it was built for Python"33!'"!"#A;$A@$
print"This program wasn't written in Python, it was built for Mouse!"

Broken down:
# oh look, a bunch of pointless string literals and a comment!
' ''"This program wasn"!'' "t written in Mouse, it was built for Python"33!'"!"#A;$A@$
# oh look, a print statement!
print"This program wasn't written in Python, it was built for Mouse!"

Mouse-2002 / Factor, 192 bytes
These two languages also don't share much but this was fun.
IN: m
! '8!'"This program wasn"''!'"t written in Mouse, it was built for Factor"33!'"!"$
USING: io ;
: x ( -- ) "This program wasn't written in Factor, it was built for Mouse!" print ;
MAIN: x

How this looks to Mouse:
IN: m     ~  pointlessly assign 8 to N and push 12
!' 8 !'   ~  print the codepoint 12 (from m) and then a backspace
       "This program wasn"     ~ print this string
                         '' !' ~ push the codepoint for ', then print that

"t written in Mouse, it was built for Factor" ~ print this string

33 !' "!" $  ~ push 33, then print that ASCII char, then print a newline, and end the program

How this looks to Factor:
! project folder name
IN: m
! comment!
! '8!'"This program wasn"''!'"t written in Mouse, it was built for Factor"33!'"!"$
! import statement
USING: io ;
! macro definition
: x ( -- ) "This program wasn't written in Factor, it was built for Mouse!" print ;
! program start
MAIN: x

This was actually quite a lot of work to get right.

Pyke/Foo, 71
"This program wasn't written in ""Foo"", it was built for ""Pyke"R3"!"s

Try it in Pyke!
Foo just prints everything in double quotes.
R3 rotates the top 3 items of the stack and s  joins them together. It auto-prints the stack at the end

C/Java, 277 bytes
//\u000apublic class Main{static String s="This program wasn't written in Java, it was built for C!";public static void
main(//\u000aString[] a
)
{printf("This program wasn't written in C, it was built for Java!");}
//\u000astatic void printf(String a){System.out.println(s);}}

Python / CJam, 144 bytes.
Not gonna win this, but it's interesting.
"""This program wasn't written in CJam, it was built for Python!" """;print('This program wasn\'t written in Python, it was built for CJam!')#";

To Python:
"""This program wasn't written in CJam, it was built for Python!" """

A multi-line string with """ delimiters. This is evaluated and the result is discarded.
;

End a statement and begin a new one.
print('...')

Print the message.
#";

A single-line comment.
To CJam:
""

Push an empty string to the stack.
"..."

Push the message to the stack.
 ""

The leading space does nothing, and "" pushes the empty string to the stack.
";print('This program wasn\'t written in Python, it was built for CJam!')#"

Push another string literal.
;

Delete that string literal. Now the stack contains "" "message" "". The stack items are concatenated together and printed.

Jelly/Pyth, 104 bytes
_"!ylleJ rof tliub saw ti ,htyP ni nettirw t'nsaw margorp sihT".q."
“zỤÆ¦SṾƬỤƁɗe⁻ȷ6qḣ¢ƓṆ[²İ¦¥ỴȧỊ:Ċ¹ḃ$7f»

Run it in Jelly or Pyth

C (gcc) / Processing.org (Java mode) 174 bytes
void setup(){//\
System.out.
printf("This program wasn't written in %s it was built for %s !",//\
"Processing","C"//\
/*
"C","Processing"//\
*/
);}//\
/*
main(){setup();}//*/

VBScript/JScript, 117 bytes
a="J"
b="VB"
rem=c=a;a=b;b=c
WScript.echo("This program wasn't written in "+a+"Script, it was built for "+b+"Script")

Clever use of the rem comment keyword

Brainfuck/VBA (immediate), 568 bytes
?"This program wasn't written in VBA, it was built for Brainfuck!"'>--->->>>>-->>>>>>->>-->>->>>-->>-->>>>>>>>-->>>-->->>->>>>>>>-->-->>>-->>->>-->>>>>>-->>>>-->->->->-->+[-[>+++++++<-]<+++]>---->++>--->-->->+>->->-->--->->+++>-->+>>+++>->-->++>->+>>->-->->->--->-->+>-->-->+>->->+++>-->-->--->->--->-->+++>+>-->->+>>+++>->+>--->->-->-->->+>--->-->->+>++>->->+>+[-[>+++++++<-]<++++]>---->--->+++>--->>+>--->->+++>++>->+++>+>+>--->+++>>++>+>+>+>--->->--->+>+>>++>+>--->++>+>>->+++>--->++>+>++>-->->->+>--->+>+>--->+++>>+>--->++>--->>+>+>+>+++>->+>->>->++>+[-<++++]>[.>]

Try it online!
Pretty simple approach.

Haskell/Racket, 177 bytes
Just some simple comment play. I go to a bit of trouble to share strings.
Haskell
;p=putStr{-
#lang racket
(display(string-append;-};main=do{p
"This program wasn't written in ";p"Haskell"{-
"Racket";-};p
", it was built for ";p"Racket!\n"{-
"Haskell!\n"));-}}

Try it online!
Racket
;p=putStr{-
#lang racket
(display(string-append;-};main=do{p
"This program wasn't written in ";p"Haskell"{-
"Racket";-};p
", it was built for ";p"Racket!\n"{-
"Haskell!\n"));-}}

Try it online!

Racket/Standard ML, 166 bytes
;val p=print(*
#lang racket
(display(string-append;*);p
"This program wasn't written in ";p"SML"(*
"Racket"; *);p
", it was built for ";p"Racket!\n";(*
"SML!\n")); *)

Try it online!
This is a port of my Racket/Haskell solution to ML.

Python 3/Clojure, 121 112 bytes
Based off nihilazo's answer.
# is comment in Python, and strings appearing next to each other are concatenated together, as in C.
Clojure is a Lisp, so parentheses need to surround every function. Since Python's print needs parentheses, we add printf inside the parentheses since it's the closest to a no-op we can use. As a bonus, printf lets us choose format the arguments very flexibly.
#_ skips the next form (list () or literal, e.g. number 0). Note that this doubles as comment character in Python.
%s and %n$s are the the same as in C, resolving to the next argument and the nth argument respectively.
Python 3
#_0
print(#_0 printf"%s%4$s%3$s%s!"
"This program wasn't written in ""Clojure"
", it was built for ""Python""!")

Try it online!
Clojure
#_0
print(#_0 printf"%s%4$s%3$s%s!"
"This program wasn't written in ""Clojure"
", it was built for ""Python""!")

Try it online!

Java 7/Java 8: 230 bytes
class M{public static void main(String[]a){Class c=null;try{c=Class.forName("java.time.Period");}catch(Throwable t){}System.out.printf("This program wasn't written in Java %d, it was built for Java %d!",c==null?7:8,c==null?8:7);}}

Try it online

Explanation
The java.time package was added in Java 8, which means it doesn't exist in Java 7 (or older), which will cause Class.forName to throw a ClassNotFoundException. The variable c stays null, which is then checked for by the tenary statements.

Perl 6 / Perl 5, 106 bytes
my $a=5;my @a=6;print "This program wasn't written in Perl ",11-$a[0],", it was built for Perl ",$a[0],"!"

Pretty standard fare with sigil inflection.
Try it online!

This can be 96 bytes through how Perl treats lists

Aheui/Python3
'''
밣밙반따따밥다맣밙밚밤따따밥다맣밙밚밤따따밙다맣밙밚밤따따밙반따밙다다맣받밙반따따박다맣밙밚밤따따밙반따박다다맣밙밚밤따따밙반따밥다다맣밙밚밤따따밙반따반밧나다다맣밙밚밤따따받다맣밙밚밤따따밙반따밥다다맣밞밙반따따밠다맣밙밚밤따따밞다맣받밙반따따박다맣밙밚밤따따밙반따밞다다맣밞밙반따따밠다맣밙밚밤따따밙반따밙다다맣밙밚밤따따밙반따다맣받밙반따따밞다맣밙밚밤따따밙반따밦다다맣받밙반따따박다맣밙밚밤따따밙반따밞다다맣밙밚밤따따밙반따밥다다맣밙밚밤따따밙다맣밙밚밤따따밙반따밦다다맣밙밚밤따따밙반따밦다다맣밙밚밤따따반밧나다맣밙밚밤따따밙반따다맣받밙반따따박다맣밙밚밤따따밙다맣밙밚밤따따밙반따다맣받밙반따따박다맣밙밙밚밙밚밥밤따따따따따따밙밙밚밤따따따다맣밙밙밚밙밚밥밤따따따따따따밙밙밚밙밣따따따따밙밚밤따따밥밙반따따밣다다다다맣밥밙반따따밥다맣받밙반따따박다맣밙밚밤따따밙다맣밙밚밤따따밙반따밦다다맣받밙반따따박다맣밙밚밤따따밙반따밞다다맣밞밙반따따밠다맣밙밚밤따따밙반따밙다다맣받밙반따따박다맣밞밙반따따밣다맣밙밚밤따따밙반따밠다다맣밙밚밤따따밙다맣밙밚밤따따밣다맣밙밚밤따따밙반따밦다다맣받밙반따따박다맣밙밚밤따따박다맣밙밚밤따따밙반따반밧나다다맣밙밚밤따따밙반따밥다다맣받밙반따따박다맣밣밙반따따맣밙밚밤따따박밙반따따반밧나다다맣밙밚밤따따밙반따밦다다맣밙밚밤따따밥다맣밙밚밤따따밙반따반밧나다다맣밙밚밤따따밙반따다맣받밙반따따받다맣희
'''
print("This program wan't written in Python, it was built for 아희!")

Aheui code generated by https://apteryx.moe/straheui/.
Aheui code is in comment of python, while aheui dismiss every non-Korean characters.

Go/Java 10+, 308 bytes
Takes advantage of the var keyword introduced in Java 10. Will not run on earlier Java versions.
package main;/*\u002a\u002fpublic class Main{public static void main(String[]args){/**/var g="\u0022+";func main(){//";
g="Go";var j="Java";if(g!="Go"){var t=j;j=g;g=t;}
/*\u002a\u002fSystem.err./**/print("This program wasn't written in "+g+", it was built for "+j+"!");g="\u0022+"}//";
var w="\u0022+"//";}}

Ungolfed and commented:
// Required at the beginning of all Go programs.
// Consequently, the Java file needs to be saved in a directory called "main".
package main;
// Java substitutes unicode escape sequences like \u002a before lexing the code.
// It sees "/**/public class...", starting a main class and function.
// Go sees it as a comment.
/*\u002a\u002fpublic class Main{public static void main(String[]args){/**/

// Use another escape sequence to end a string for Java but not for Go, then
// declare Go's main function. Close the Java string with a quote hidden in a
// comment. Java sees "var g = ""+"...//";" while Go sees var g = "\"+";func...
var g = "\u0022+";func main() { //";
    // Reuse the variable g to save space
    g = "Go";
    var j = "Java";
    // The meat of detecting the language we're using.
    // Go's == compares strings by comparing their characters;
    // Java's == tests whether the strings are the same object.
    if (g == "Go") {
        var t = j;
        j = g;
        g = t;
    }
    // In Java, calls System.err.print. In Go, calls builtin "print",
    // which writes to stderr.
    /*\u002a\u002fSystem.err./**/print("This program wasn't written in " + g + ", it was built for " + j + "!");
    // Boilerplate to close Go. We can't close Java first nor let them share a
    // closing brace because Go needs and Java forbids "var" outside functions.
    g = "\u0022+"}//";
// Boilerplate to close Java.
var w = "\u0022+"  //";}}

Keg/><>, 246 123 103 bytes
 "This program wasn't written in ><> it was built for Keg!"r>o<ø“0⊂kB7≤1⑵“` in Keg, it` “034⊂06“` ><>!`

-23 bytes saved to using string compression methods
Try it online! (><>)
TIO will be added after Keg is updated.
Answer History
123 bytes
 "This program wasn't written in ><> it was built for Keg!"r>o<ø`This program wasn't written in Keg, it was built for ><>!`

Try it online! (Keg)
Try it online! (><>)
-123 bytes due to @JoKing pointing out that I clearly haven't used ><> for a while. ;)
246 bytes
 "This program wasn't written in ><> it was built for Keg!"rvø`This program wasn't written in Keg, it was built for ><>!`#
#                                                     vo;!?l<
#                                                     >     ^

Try it online! (Keg)
Try it online! (><>)
Apparently, Keg polyglots well with 2d languages. Probably because strings aren't delimited with "'s but backticks rather.

You can also push it in reverse before printing to save on the r instruction Try it online!

JavaScript (V8) and Python 2, 114 bytes
p=["Python","Javascript"]
x=3/2*2
print("This program wasn't written in "+p[x-2]+", it was built for "+p[3-x]+"!")

This takes advantages of the difference in division between Python 2 and Javascript, where Python 2 uses integer division, and that Javascript uses floating point division. This also uses the fact that V8 Javascript has a print() function.
Try it online! (JS)
Try it online! (Python)

PHP 8.2.x and PHP 8.3.x, 103 bytes
This program wasn't written in PHP 8.<?=$_=2+range("0","A")[1]?>.x, it was built for PHP 8.<?=5-$_?>.x!

Try on PHP Sandbox
How it works
According to PHP: Backward Incompatible Changes,

<?php
range('9', 'A');  // ["9", ":", ";", "<", "=", ">", "?", "@", "A"], as of PHP 8.3.0
range('9', 'A');  // [9, 8, 7, 6, 5, 4, 3, 2, 1, 0], prior to PHP 8.3.0
?>

The following code depends on version difference:
range("0", "A")

PHP 8.2.x: [0], so [0][1] is undefined
PHP 8.3.x: ["0", "1", ..., "A"]

JavaScript ES6 / Python2, 98 bytes, REPL ONLY
js = 'python'
python = 'js'
s = 'this program is not ' + `js` + ', it was built for ' + `python`
s

Tested with Python 2.7.10 and Chrome 52.
The caveat here is actually printing the output....Python uses print s and JS uses console.log(js). So instead I assume you are using a REPL and that s alone will print to stdout.

this doesn't actually print anything. I know Python and Javascript have different comment syntaxes

@muddyfish Updated to print via REPL

@muddyfish Additionally I wanted to see if it was possible to do it without comments.

Also you're not printing out the entire required string but I agree that not using comments makes it interesting

@muddyfish I added another answer below because it is an entirely different approach using python3 instead of python2.

Then write another answer!

@muddyfish Done!

brainfuck/C 749 bytes
//-[--->+<]>-.[---->+++++<]>-.+.++++++++++.+[---->+<]>+++.[-->+++++++<]>.++.---.--------.+++++++++++.+++[->+++<]>++.++++++++++++.[->+++++<]>-.--[->++++<]>-.-[->+++<]>-.--[--->+<]>--.-----.[++>---<]>++.[->+++<]>-.[---->+<]>+++.--[->++++<]>-.-----.---------.+++++++++++..+++[->+++<]>.+++++++++.-[->+++++<]>-.-[--->++<]>-.+++++.-[->+++++<]>-.[->+++<]>++.[--->+<]>----.+++[->+++<]>++.++++++++.+++++.--------.-[--->+<]>--.+[->+++<]>+.++++++++.-[++>---<]>+.-[--->++<]>-.+++++++++++.[---->+<]>+++.--[->++++<]>-.-[->+++<]>-.--[--->+<]>--.+[---->+<]>+++.[->+++<]>++.[--->+<]>-.------------.+++.++++++++.[---->+<]>+++.++[->+++<]>.+++++++++.+++.[-->+++++<]>+++.+[->++<]>+.-[-->+<]>.
main(){puts("This program wasn't written in C it was built for brainfuck!");}

You need the comma in the output string.

AWK/C++ (gcc), 201 bytes
#include <cstdio>
/*#\/* /
BEGIN{
#*/int main(){const char *a[2];
a[0]="AWK";a[1]="C++";
/*#\/* /
b=0
#*/int b=1;
printf("This program wasn't written in %s, it was built for %s!\n",a[b], a[(b+1)%2]);}

Try it online - AWK!
Try it online - C++(gcc)!
I suppose this is essentially and AWK/C, but I tested it with C++ and am using #include <cstdio> so that makes it C++ right? :)

Yabasic / VBA, 130 bytes
n=-8*(Now>0):?"This program wasn't written in "+Mid$("YabasicVBA",n,8)+", it was built for "+Trim$(Mid$("VBA    Yabasic",n,8))+"!"

Explaination
n=-8*(Now>0)                            ''  Key operation: Differentiates Between VBA and Yabasic
                                        ''  Now is defined in VBA with the system time, but not in
                                        ''  Yabasic; Evaluates to 0 in Yabasic, and 8 in VBA
?"This program wasn't written in "      ''  Print beginning of sentance
  +Mid$("YabasicVBA",n,8);              ''  Print current language
  +", it was built for "                ''  Print middle
  +Trim$(Mid$("VBA    Yabasic",n,8))    ''  Print other language
  +"!"                                  ''  Print Exclaimation mark

Try it online! (Yabasic)

Retina/JavaScript, 156 bytes
1/console.log("This program wasn't written in JavaScript, it was built for Retina!")///K`This program wasn't written in Retina, it was built for JavaScript!

Explained (explanations here with #):
1 # This is here so the following slash becomes division in JavaScript
 / # Start Retina RegEx; JavaScript treats this as division
  console.log("This program wasn't written in JavaScript, it was built for Retina!") # Print the message in JavaScript; in Retina this is treated as a RegEx
                                                                                /// # End Retina RegEx and start and end a blank one; in JavaScript the first two slashes treat the following code as a comment
                                                                                K`This program wasn't written in Retina, it was built for JavaScript! # Output the message in Retina

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/